diff --git a/package-lock.json b/package-lock.json
index 7d04b97..ee6e6c9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@apmg/mimas",
- "version": "0.2.0",
+ "version": "0.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 6f2174e..12ae76c 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "@apmg/mimas",
"description": "A React component that takes an image endpoint from APM's APIs and returns a proper image with srcset.",
- "version": "0.2.0",
+ "version": "0.3.0",
"main": "dist/index.js",
"module": "dist/index.js",
"license": "MIT",
diff --git a/src/Image/Image.js b/src/Image/Image.js
index a36b1a6..d248564 100644
--- a/src/Image/Image.js
+++ b/src/Image/Image.js
@@ -3,152 +3,106 @@ import PropTypes from 'prop-types';
// Ideally, this component will take in an image object formatted by our images API and spit out an image with a proper srcset. However, I also thought I should provide a couple of fallback options, in case you want to use an image from somewhere else entirely: fallbackSrcSet and fallbackSrc. The last one will just create a normal img tag, so I really don't recommend it.
-function generateSrcSet(imageProps, props) {
- let aspectRatio = 'uncropped';
-
- if (props.image.aspect_ratios) {
- if (
- props.aspectRatio in props.image.aspect_ratios &&
- props.image.aspect_ratios[props.aspectRatio] !== null
- ) {
- aspectRatio = props.aspectRatio;
+const Image = (props) => {
+ const determineAspectRatio = () => {
+ if (props.aspectRatio) {
+ return props.aspectRatio;
+ } else if (props.image.preferredAspectRatio) {
+ // forces getSrcSet() to use props.image.preferredAspectRatio if it exists, i.e. the function moves on to the next condition,
+ // this means that the aspectRatio prop acts as an override if there is a preferred value in the data
+ return false;
+ } else if (props.image && props.image.preferred_aspect_ratio_slug) {
+ return props.image.preferred_aspect_ratio_slug;
+ } else {
+ return 'uncropped';
}
-
- props.image.aspect_ratios[aspectRatio].instances.forEach(
- (image, i, dataSet) => {
- let set = `${image.url} ${image.width}w`;
- if (i !== dataSet.length - 1) {
- set = set.concat(',');
- }
-
- imageProps.srcSet = imageProps.srcSet.concat(set);
- return;
- }
- );
- } else {
- imageProps.srcSet = props.image.srcset;
- return;
- }
-}
-
-function generateAttrs(props) {
- let imageProps = {
- srcSet: '',
- src: '',
- alt: ''
};
- if (props.image) {
- imageProps.src = props.image.fallback;
- if (props.alt) {
- imageProps.alt = props.alt;
+ const getSrcSet = () => {
+ if (props.image) {
+ if (
+ props.image.aspect_ratios &&
+ determineAspectRatio() in props.image.aspect_ratios &&
+ props.image.aspect_ratios[props.aspectRatio] !== null
+ ) {
+ return generateSrcSet(
+ props.image.aspect_ratios[determineAspectRatio()].instances
+ );
+ } else if (props.image.preferredAspectRatio) {
+ return generateSrcSet(props.image.preferredAspectRatio.instances);
+ } else {
+ return props.image.srcset;
+ }
+ } else if (props.fallbackSrcSet) {
+ return props.fallbackSrcSet;
} else {
- imageProps.alt = props.image.short_caption;
+ return null;
}
- if (props.aspectRatio) {
- generateSrcSet(imageProps, props);
+ };
+
+ const getSrc = () => {
+ if (props.image && props.image.fallback) {
+ return props.image.fallback;
} else {
- imageProps.srcSet = props.image.srcset;
+ return props.fallbackSrc;
}
- } else if (props.fallbackSrcSet) {
- imageProps.srcSet = props.fallbackSrcSet;
- imageProps.src = props.fallbackSrc;
- imageProps.alt = props.alt;
- } else {
- imageProps.src = props.fallbackSrc;
- imageProps.alt = props.alt;
- }
+ };
- return imageProps;
-}
+ const generateSrcSet = (instances) => {
+ return instances
+ .map((instance) => `${instance.url} ${instance.width}w`)
+ .join(',');
+ };
-const Image = (props) => {
- const imageProps = generateAttrs(props);
+ const getAlt = () => {
+ if (props.alt) {
+ return props.alt;
+ } else if (props.image && props.image.short_caption) {
+ return props.image.short_caption;
+ } else {
+ return '';
+ }
+ };
return (
);
};
+const aspectRatioType = PropTypes.shape({
+ instances: PropTypes.arrayOf(
+ PropTypes.shape({
+ url: PropTypes.string,
+ width: PropTypes.number,
+ height: PropTypes.number
+ })
+ ),
+ slug: PropTypes.string
+});
+
Image.propTypes = {
image: PropTypes.shape({
+ preferredAspectRatio: aspectRatioType,
aspect_ratios: PropTypes.shape({
- normal: PropTypes.shape({
- instances: PropTypes.arrayOf(
- PropTypes.shape({
- width: PropTypes.number,
- url: PropTypes.string,
- height: PropTypes.number
- })
- ),
- slug: PropTypes.string
- }),
- square: PropTypes.shape({
- instances: PropTypes.arrayOf(
- PropTypes.shape({
- width: PropTypes.number,
- url: PropTypes.string,
- height: PropTypes.number
- })
- ),
- slug: PropTypes.string
- }),
- thumbnail: PropTypes.shape({
- instances: PropTypes.arrayOf(
- PropTypes.shape({
- width: PropTypes.number,
- url: PropTypes.string,
- height: PropTypes.number
- })
- ),
- slug: PropTypes.string
- }),
- widescreen: PropTypes.shape({
- instances: PropTypes.arrayOf(
- PropTypes.shape({
- width: PropTypes.number,
- url: PropTypes.string,
- height: PropTypes.number
- })
- ),
- slug: PropTypes.string
- }),
- portrait: PropTypes.shape({
- instances: PropTypes.arrayOf(
- PropTypes.shape({
- width: PropTypes.number,
- url: PropTypes.string,
- height: PropTypes.number
- })
- ),
- slug: PropTypes.string
- }),
- uncropped: PropTypes.shape({
- instances: PropTypes.arrayOf(
- PropTypes.shape({
- width: PropTypes.number,
- url: PropTypes.string,
- height: PropTypes.number
- })
- ),
- slug: PropTypes.string
- })
+ normal: aspectRatioType,
+ square: aspectRatioType,
+ thumbnail: aspectRatioType,
+ widescreen: aspectRatioType,
+ portrait: aspectRatioType,
+ uncropped: aspectRatioType
}),
+ fallback: PropTypes.string,
long_caption: PropTypes.string,
short_caption: PropTypes.string,
width: PropTypes.string,
preferred_aspect_ratio_slug: PropTypes.string,
id: PropTypes.string,
- credit_url: PropTypes.string,
- type: PropTypes.string,
- float: PropTypes.string,
- credit: PropTypes.string,
url: PropTypes.string,
srcset: PropTypes.string
}),
diff --git a/src/Image/Image.test.js b/src/Image/Image.test.js
index 0d89ddc..22a5b0d 100644
--- a/src/Image/Image.test.js
+++ b/src/Image/Image.test.js
@@ -1,20 +1,24 @@
import React from 'react';
import { render, cleanup } from 'react-testing-library';
import Image from './Image';
-import { image } from './testdata/image';
+import {
+ image,
+ imageWithPreferred,
+ imageWithoutPreferredSlug
+} from './testdata/image';
import 'jest-prop-type-error';
afterEach(cleanup);
// SUCCESSES
-test('Creates an img with the correct alt, src, and srcSet when aspectRatio prop is provided', () => {
+test('Creates an img with the correct alt, src, and srcSet when aspectRatio prop is provided, prioritizes aspectRatio prop over preferred', () => {
const props = {
aspectRatio: 'widescreen'
};
const { container } = render(
-
+
);
expect(container.firstChild.getAttribute('alt')).toBe(
@@ -52,6 +56,20 @@ test('Takes in an optional sizes string, specifying specific image behavior with
);
});
+test('Creates an img with the preferred aspect ratio when image.preferredAspectRatio is included and no aspectRatio prop is provided', () => {
+ const { container } = render();
+
+ expect(container.firstChild.getAttribute('alt')).toBe(
+ 'Serena Brook opens our show at The Town Hall'
+ );
+ expect(container.firstChild.getAttribute('src')).toBe(
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f5db37-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg'
+ );
+ expect(container.firstChild.getAttribute('srcset')).toBe(
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/5ecd52-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 400w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/de193e-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 600w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/7cb7e2-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1000w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/822d4e-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1400w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/f977a8-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 2000w'
+ );
+});
+
test('Creates an img with the correct alt, src, and srcSet and className when the elementClass property is provided', () => {
const props = {
aspectRatio: 'widescreen',
@@ -78,8 +96,8 @@ test('Creates an img with the correct alt, src, and srcSet and className when th
);
});
-test('Creates an img with the correct alt, src, and defaut srcSet when no aspectRatio prop is provided', () => {
- const { container } = render();
+test('Creates an img with the correct alt, src, and "uncropped" srcSet when no aspectRatio prop or image.preferred_aspect_ratio_slug is provided', () => {
+ const { container } = render();
expect(container.firstChild.getAttribute('alt')).toBe(
'Serena Brook opens our show at The Town Hall'
@@ -87,7 +105,9 @@ test('Creates an img with the correct alt, src, and defaut srcSet when no aspect
expect(container.firstChild.getAttribute('src')).toBe(
'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f5db37-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg'
);
- expect(container.firstChild.getAttribute('srcset')).toBe(image.srcset);
+ expect(container.firstChild.getAttribute('srcset')).toBe(
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/35bd3b-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 400w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f5db37-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 600w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/04a63f-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1000w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/72bc48-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1400w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f20034-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 2000w'
+ );
});
test('Creates an img when an image object is not provided, but a fallbackSrc, fallbackSrcSet and alt are provided', () => {
@@ -142,7 +162,9 @@ test('Creates the correct img when an image prop and all of the fallbacks are pr
expect(container.firstChild.getAttribute('src')).toBe(
'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f5db37-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg'
);
- expect(container.firstChild.getAttribute('srcset')).toBe(image.srcset);
+ expect(container.firstChild.getAttribute('srcset')).toBe(
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/e428bc-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 400w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/58b2ba-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 600w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/95c885-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1000w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/b3a373-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1400w,https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/6ceb83-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 2000w'
+ );
});
test('Creates the a basic img with an empty srcset if only a alt and fallbackSrc are provided', () => {
@@ -162,7 +184,7 @@ test('Creates the a basic img with an empty srcset if only a alt and fallbackSrc
expect(container.firstChild.getAttribute('src')).toBe(
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/298/wolf_20131015_003_1400.jpg'
);
- expect(container.firstChild.getAttribute('srcset')).toBe('');
+ expect(container.firstChild.getAttribute('srcset')).toBe(null);
});
// FAILURES
diff --git a/src/Image/testdata/image.js b/src/Image/testdata/image.js
index 8789935..dfd4753 100644
--- a/src/Image/testdata/image.js
+++ b/src/Image/testdata/image.js
@@ -207,3 +207,335 @@ export const image = {
srcset:
'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/e428bc-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 400w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/58b2ba-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 600w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/95c885-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1000w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/b3a373-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1400w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/6ceb83-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 2000w'
};
+
+export const imageWithoutPreferredSlug = {
+ aspect_ratios: {
+ widescreen: {
+ instances: [
+ {
+ width: 400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/e428bc-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 225
+ },
+ {
+ width: 600,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/58b2ba-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 337
+ },
+ {
+ width: 1000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/95c885-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 562
+ },
+ {
+ width: 1400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/b3a373-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 787
+ },
+ {
+ width: 2000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/6ceb83-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1124
+ }
+ ],
+ slug: 'widescreen'
+ },
+ uncropped: {
+ instances: [
+ {
+ width: 400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/35bd3b-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 320
+ },
+ {
+ width: 600,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f5db37-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 480
+ },
+ {
+ width: 1000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/04a63f-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 800
+ },
+ {
+ width: 1400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/72bc48-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1120
+ },
+ {
+ width: 2000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f20034-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1600
+ }
+ ],
+ slug: 'uncropped'
+ }
+ },
+ long_caption: 'Serena Brook opens our show at The Town Hall',
+ short_caption: 'Serena Brook opens our show at The Town Hall',
+ width: 'full',
+ id: 'c2c452354fbff94d720ba8f86e2c71ba7427b306',
+ credit_url: '',
+ type: 'apmImage',
+ float: 'none',
+ credit: 'American Public Media',
+ fallback:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f5db37-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ srcset:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/e428bc-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 400w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/58b2ba-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 600w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/95c885-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1000w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/b3a373-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1400w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/6ceb83-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 2000w'
+};
+
+export const imageWithPreferred = {
+ preferredAspectRatio: {
+ instances: [
+ {
+ width: 400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/5ecd52-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 400
+ },
+ {
+ width: 600,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/de193e-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 600
+ },
+ {
+ width: 1000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/7cb7e2-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1000
+ },
+ {
+ width: 1400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/822d4e-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1400
+ },
+ {
+ width: 2000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/f977a8-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 2000
+ }
+ ],
+ slug: 'square'
+ },
+ aspect_ratios: {
+ normal: {
+ instances: [
+ {
+ width: 400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/normal/fa6aa0-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 301
+ },
+ {
+ width: 600,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/normal/00b407-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 451
+ },
+ {
+ width: 1000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/normal/10ac72-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 752
+ },
+ {
+ width: 1400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/normal/6e721c-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1053
+ },
+ {
+ width: 2000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/normal/f49c92-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1504
+ }
+ ],
+ slug: 'normal'
+ },
+ square: {
+ instances: [
+ {
+ width: 400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/5ecd52-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 400
+ },
+ {
+ width: 600,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/de193e-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 600
+ },
+ {
+ width: 1000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/7cb7e2-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1000
+ },
+ {
+ width: 1400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/822d4e-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1400
+ },
+ {
+ width: 2000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/square/f977a8-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 2000
+ }
+ ],
+ slug: 'square'
+ },
+ thumbnail: {
+ instances: [
+ {
+ width: 120,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/thumbnail/e8796f-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 90
+ },
+ {
+ width: 300,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/thumbnail/dfad0f-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 226
+ }
+ ],
+ slug: 'thumbnail'
+ },
+ widescreen: {
+ instances: [
+ {
+ width: 400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/e428bc-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 225
+ },
+ {
+ width: 600,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/58b2ba-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 337
+ },
+ {
+ width: 1000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/95c885-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 562
+ },
+ {
+ width: 1400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/b3a373-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 787
+ },
+ {
+ width: 2000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/6ceb83-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1124
+ }
+ ],
+ slug: 'widescreen'
+ },
+ portrait: {
+ instances: [
+ {
+ width: 400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/portrait/e6415b-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 500
+ },
+ {
+ width: 600,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/portrait/0ebc89-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 750
+ },
+ {
+ width: 1000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/portrait/fed99c-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1250
+ },
+ {
+ width: 1400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/portrait/523b4b-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1750
+ },
+ {
+ width: 1883,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/portrait/766692-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 2354
+ }
+ ],
+ slug: 'portrait'
+ },
+ uncropped: {
+ instances: [
+ {
+ width: 400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/35bd3b-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 320
+ },
+ {
+ width: 600,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f5db37-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 480
+ },
+ {
+ width: 1000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/04a63f-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 800
+ },
+ {
+ width: 1400,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/72bc48-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1120
+ },
+ {
+ width: 2000,
+ url:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f20034-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ height: 1600
+ }
+ ],
+ slug: 'uncropped'
+ }
+ },
+ long_caption: 'Serena Brook opens our show at The Town Hall',
+ short_caption: 'Serena Brook opens our show at The Town Hall',
+ width: 'full',
+ preferred_aspect_ratio_slug: 'widescreen',
+ id: 'c2c452354fbff94d720ba8f86e2c71ba7427b306',
+ credit_url: '',
+ type: 'apmImage',
+ float: 'none',
+ credit: 'American Public Media',
+ fallback:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/uncropped/f5db37-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg',
+ srcset:
+ 'https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/e428bc-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 400w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/58b2ba-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 600w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/95c885-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1000w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/b3a373-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 1400w, https://img.apmcdn.org/c2c452354fbff94d720ba8f86e2c71ba7427b306/widescreen/6ceb83-20181220-serena-brook-opens-our-show-at-the-town-hall.jpg 2000w'
+};