micnews / story-json-to-amp

Compile story-json documents into AMP stories
Other
25 stars 8 forks source link

Images distorted #37

Open pietrop opened 6 years ago

pietrop commented 6 years ago

Using story-json to create AMP stories for BBC News Labs, we found that the amp-img tag shows the image as distorted. The image width is squashed in the various mobile screen sizes, breaking the aspect ratio of the image. And was wondering if it something we are doing wrong in the use of the json file schema as we didn't see this issue in Mic News published AMP stories.

Here's a test example:

screen shot 2018-06-01 at 13 55 12

But if we "manually" move it, using the browser inspector, outside of the two divs that you can see in the screenshots above seem to be containing it, it is no longer distorted. As you can see below.

screen shot 2018-06-01 at 13 55 24

This is the story-json we have been working with, I left only one page in it for simplicity.

{
  "version": 1,
  "languageCode": "en",
  "title": "Template test story",
  "canonicalUrl": "/ampstories/storyboard-template/index.html",
  "meta": {
    "datePublished": "2018-05-21",
    "dateModified": "1527857615255",
    "author": "BBC",
    "authorType": "Organization",
    "images": [
      "poster-square.jpg",
      "poster-portrait.jpg",
      "poster-landscape.jpg"
    ],
    "publisher": {
      "name": "BBC",
      "logo": {
        "url": "/bbc-news.png",
        "width": 600,
        "height": 60
      }
    },
    "description": "Some story description"
  },
  "bookendConfigSrc": "bookend.json",
  "pages": [
    {
      "layers": [
        {
          "type": "container",
          "styles": {
            "background-color": "black"
          }
        },
        {
          "annotation": "a image element",
          "type": "image",
          "source": "https://thumbs.mic.com/YTVkMmU3NTA5MCMvdFg1b3dGd0tBaEFWT2RjWkRwSlVZRmQxRVRjPS8weDA6MTA4MHgxOTE5L2ZpbHRlcnM6Zm9ybWF0KGpwZWcpOnF1YWxpdHkoODApL2h0dHA6Ly9zMy5hbWF6b25hd3MuY29tL3BvbGljeW1pYy1pbWFnZXMvN2V0M2Rvdndpc2thbTdpb2FjdWFyMWlvc2FkYmhkYXhxbXhvcTQ2d2JqcjR3cW9zcjdmZnFiYmRwejZneGpkNS5qcGc.jpg",
          "layout": "responsive",
          "width": "720",
          "height": "1080",
          "alt": "an image"
        },
        {
          "type": "container",
          "styles": {
            "flexDirection": "column",
            "justifyContent": "flex-start",
            "alignItems": "flex-start",
            "padding-left": "24px",
            "padding-top": "22px",
            "backgroundLinearGradient": {
              "direction": "180deg",
              "stops": [
                {
                  "color": "rgba(0, 0, 0, 0.5)",
                  "distance": "40px"
                },
                {
                  "color": "rgba(0, 0, 0, 0)",
                  "distance": "100px"
                }
              ]
            }
          },
          "elements": []
        },
        {
          "type": "container",
          "styles": {
            "flexDirection": "column",
            "justifyContent": "flex-start",
            "alignItems": "flex-start",
            "padding-left": "24px",
            "padding-top": "22px",
            "backgroundLinearGradient": {
              "direction": "0deg",
              "stops": [
                {
                  "color": "black",
                  "distance": 30
                },
                {
                  "color": "transparent",
                  "distance": "50%"
                },
                {
                  "color": "rgba(0,0,0,0)"
                }
              ]
            }
          },
          "elements": [
            {
              "type": "image",
              "source": "https://news.files.bbci.co.uk/include/newslabs/ampstories/en/clear_strip_logo_22.png",
              "width": "147",
              "height": "22",
              "alt": "BBC News logo"
            }
          ]
        },
        {
          "type": "container",
          "styles": {
            "flexDirection": "column",
            "justifyContent": "flex-end",
            "alignItems": "flex-start",
            "paddingLeft": "32px",
            "paddingRight": "32px",
            "padding": "25px"
          },
          "elements": [
            {
              "type": "paragraph",
              "text": "Some text",
              "styles": {
                "color": "#ffffff",
                "fontFamily": "BBCReithSans"
              }
            },
            {
              "type": "container",
              "styles": {
                "border-bottom": "4px solid #bb1919",
                "animate-in": "fade-in",
                "width": "70px",
                "padding-top": "10px"
              }
            }
          ]
        },
        {
          "type": "container",
          "styles": {
            "flexDirection": "column",
            "justifyContent": "flex-end",
            "alignItems": "flex-end",
            "padding-right": "0px"
          },
          "elements": [
            {
              "type": "paragraph",
              "text": "Credit TEST",
              "styles": {
                "color": "#ececec",
                "backgroundColor": "rgba(0,0,0,0.6)",
                "fontFamily": "BBCReithSansLight",
                "padding": "3px 8px 1px",
                "fontSize": 13
              }
            }
          ]
        }
      ]
    }
  ],
  "analytics": []
}

And these are some of the errors from the validator for that page, they seem a bit cryptic, so not sure what to make of it.

[
  {
    "property": "instance.pages[1].layers[1].type",
    "message": "does not exactly match expected constant: container",
    "schema": {
      "const": "container",
      "required": true
    },
    "instance": "image",
    "name": "const",
    "argument": "container",
    "stack": "instance.pages[1].layers[1].type does not exactly match expected constant: container"
  },
  {
    "property": "instance.pages[1].layers[1].type",
    "message": "is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6",
    "schema": {
      "enum": [
        "paragraph",
        "heading",
        "heading1",
        "heading2",
        "heading3",
        "heading4",
        "heading5",
        "heading6"
      ],
      "required": true
    },
    "instance": "image",
    "name": "enum",
    "argument": [
      "paragraph",
      "heading",
      "heading1",
      "heading2",
      "heading3",
      "heading4",
      "heading5",
      "heading6"
    ],
    "stack": "instance.pages[1].layers[1].type is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6"
  },
  {
    "property": "instance.pages[1].layers[1].type",
    "message": "does not exactly match expected constant: video",
    "schema": {
      "const": "video",
      "required": true
    },
    "instance": "image",
    "name": "const",
    "argument": "video",
    "stack": "instance.pages[1].layers[1].type does not exactly match expected constant: video"
  },
  {
    "property": "instance.pages[1].layers[1].width",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number",
      "required": true
    },
    "instance": "720",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[1].width is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[1].height",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number",
      "required": true
    },
    "instance": "1080",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[1].height is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[1].width",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number",
      "required": true
    },
    "instance": "720",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[1].width is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[1].height",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number",
      "required": true
    },
    "instance": "1080",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[1].height is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[1]",
    "message": "is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>",
    "schema": "/Element",
    "instance": {
      "annotation": "a image element",
      "type": "image",
      "source": "https://thumbs.mic.com/YTVkMmU3NTA5MCMvdFg1b3dGd0tBaEFWT2RjWkRwSlVZRmQxRVRjPS8weDA6MTA4MHgxOTE5L2ZpbHRlcnM6Zm9ybWF0KGpwZWcpOnF1YWxpdHkoODApL2h0dHA6Ly9zMy5hbWF6b25hd3MuY29tL3BvbGljeW1pYy1pbWFnZXMvN2V0M2Rvdndpc2thbTdpb2FjdWFyMWlvc2FkYmhkYXhxbXhvcTQ2d2JqcjR3cW9zcjdmZnFiYmRwejZneGpkNS5qcGc.jpg",
      "layout": "responsive",
      "width": "720",
      "height": "1080",
      "alt": "an image"
    },
    "name": "oneOf",
    "argument": [
      "</ContainerElement>",
      "</HeadingElement>",
      "</VideoElement>",
      "</ImageElement>"
    ],
    "stack": "instance.pages[1].layers[1] is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "40px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "40px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "40px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "100px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "100px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "100px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[2].type",
    "message": "is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6",
    "schema": {
      "enum": [
        "paragraph",
        "heading",
        "heading1",
        "heading2",
        "heading3",
        "heading4",
        "heading5",
        "heading6"
      ],
      "required": true
    },
    "instance": "container",
    "name": "enum",
    "argument": [
      "paragraph",
      "heading",
      "heading1",
      "heading2",
      "heading3",
      "heading4",
      "heading5",
      "heading6"
    ],
    "stack": "instance.pages[1].layers[2].type is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "40px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "40px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "40px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "100px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "100px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "100px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[2].type",
    "message": "does not exactly match expected constant: video",
    "schema": {
      "const": "video",
      "required": true
    },
    "instance": "container",
    "name": "const",
    "argument": "video",
    "stack": "instance.pages[1].layers[2].type does not exactly match expected constant: video"
  },
  {
    "property": "instance.pages[1].layers[2].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[2].width is required"
  },
  {
    "property": "instance.pages[1].layers[2].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[2].height is required"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "40px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "40px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "40px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "100px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "100px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "100px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[2].type",
    "message": "does not exactly match expected constant: image",
    "schema": {
      "const": "image",
      "required": true
    },
    "instance": "container",
    "name": "const",
    "argument": "image",
    "stack": "instance.pages[1].layers[2].type does not exactly match expected constant: image"
  },
  {
    "property": "instance.pages[1].layers[2].source",
    "message": "is required",
    "schema": {
      "type": "string",
      "format": "uri",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[2].source is required"
  },
  {
    "property": "instance.pages[1].layers[2].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[2].width is required"
  },
  {
    "property": "instance.pages[1].layers[2].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[2].height is required"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "40px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "40px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "40px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[0].distance is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "100px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "100px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "100px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[2].styles.backgroundLinearGradient.stops[1].distance is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[2]",
    "message": "is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>",
    "schema": "/Element",
    "instance": {
      "type": "container",
      "styles": {
        "flexDirection": "column",
        "justifyContent": "flex-start",
        "alignItems": "flex-start",
        "padding-left": "24px",
        "padding-top": "22px",
        "backgroundLinearGradient": {
          "direction": "180deg",
          "stops": [
            {
              "color": "rgba(0, 0, 0, 0.5)",
              "distance": "40px"
            },
            {
              "color": "rgba(0, 0, 0, 0)",
              "distance": "100px"
            }
          ]
        }
      },
      "elements": []
    },
    "name": "oneOf",
    "argument": [
      "</ContainerElement>",
      "</HeadingElement>",
      "</VideoElement>",
      "</ImageElement>"
    ],
    "stack": "instance.pages[1].layers[2] is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>"
  },
  {
    "property": "instance.pages[1].layers[3].elements[0].type",
    "message": "does not exactly match expected constant: container",
    "schema": {
      "const": "container",
      "required": true
    },
    "instance": "image",
    "name": "const",
    "argument": "container",
    "stack": "instance.pages[1].layers[3].elements[0].type does not exactly match expected constant: container"
  },
  {
    "property": "instance.pages[1].layers[3].elements[0].type",
    "message": "is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6",
    "schema": {
      "enum": [
        "paragraph",
        "heading",
        "heading1",
        "heading2",
        "heading3",
        "heading4",
        "heading5",
        "heading6"
      ],
      "required": true
    },
    "instance": "image",
    "name": "enum",
    "argument": [
      "paragraph",
      "heading",
      "heading1",
      "heading2",
      "heading3",
      "heading4",
      "heading5",
      "heading6"
    ],
    "stack": "instance.pages[1].layers[3].elements[0].type is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6"
  },
  {
    "property": "instance.pages[1].layers[3].elements[0].type",
    "message": "does not exactly match expected constant: video",
    "schema": {
      "const": "video",
      "required": true
    },
    "instance": "image",
    "name": "const",
    "argument": "video",
    "stack": "instance.pages[1].layers[3].elements[0].type does not exactly match expected constant: video"
  },
  {
    "property": "instance.pages[1].layers[3].elements[0].width",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number",
      "required": true
    },
    "instance": "147",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[3].elements[0].width is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[3].elements[0].height",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number",
      "required": true
    },
    "instance": "22",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[3].elements[0].height is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[3].elements[0].width",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number",
      "required": true
    },
    "instance": "147",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[3].elements[0].width is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[3].elements[0].height",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number",
      "required": true
    },
    "instance": "22",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[3].elements[0].height is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[3].elements[0]",
    "message": "is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>",
    "schema": "/Element",
    "instance": {
      "type": "image",
      "source": "https://news.files.bbci.co.uk/include/newslabs/ampstories/en/clear_strip_logo_22.png",
      "width": "147",
      "height": "22",
      "alt": "BBC News logo"
    },
    "name": "oneOf",
    "argument": [
      "</ContainerElement>",
      "</HeadingElement>",
      "</VideoElement>",
      "</ImageElement>"
    ],
    "stack": "instance.pages[1].layers[3].elements[0] is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>"
  },
  {
    "property": "instance.pages[1].layers[3].type",
    "message": "is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6",
    "schema": {
      "enum": [
        "paragraph",
        "heading",
        "heading1",
        "heading2",
        "heading3",
        "heading4",
        "heading5",
        "heading6"
      ],
      "required": true
    },
    "instance": "container",
    "name": "enum",
    "argument": [
      "paragraph",
      "heading",
      "heading1",
      "heading2",
      "heading3",
      "heading4",
      "heading5",
      "heading6"
    ],
    "stack": "instance.pages[1].layers[3].type is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6"
  },
  {
    "property": "instance.pages[1].layers[3].type",
    "message": "does not exactly match expected constant: video",
    "schema": {
      "const": "video",
      "required": true
    },
    "instance": "container",
    "name": "const",
    "argument": "video",
    "stack": "instance.pages[1].layers[3].type does not exactly match expected constant: video"
  },
  {
    "property": "instance.pages[1].layers[3].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[3].width is required"
  },
  {
    "property": "instance.pages[1].layers[3].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[3].height is required"
  },
  {
    "property": "instance.pages[1].layers[3].type",
    "message": "does not exactly match expected constant: image",
    "schema": {
      "const": "image",
      "required": true
    },
    "instance": "container",
    "name": "const",
    "argument": "image",
    "stack": "instance.pages[1].layers[3].type does not exactly match expected constant: image"
  },
  {
    "property": "instance.pages[1].layers[3].source",
    "message": "is required",
    "schema": {
      "type": "string",
      "format": "uri",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[3].source is required"
  },
  {
    "property": "instance.pages[1].layers[3].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[3].width is required"
  },
  {
    "property": "instance.pages[1].layers[3].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[3].height is required"
  },
  {
    "property": "instance.pages[1].layers[3]",
    "message": "is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>",
    "schema": "/Element",
    "instance": {
      "type": "container",
      "styles": {
        "flexDirection": "column",
        "justifyContent": "flex-start",
        "alignItems": "flex-start",
        "padding-left": "24px",
        "padding-top": "22px",
        "backgroundLinearGradient": {
          "direction": "0deg",
          "stops": [
            {
              "color": "black",
              "distance": 30
            },
            {
              "color": "transparent",
              "distance": "50%"
            },
            {
              "color": "rgba(0,0,0,0)"
            }
          ]
        }
      },
      "elements": [
        {
          "type": "image",
          "source": "https://news.files.bbci.co.uk/include/newslabs/ampstories/en/clear_strip_logo_22.png",
          "width": "147",
          "height": "22",
          "alt": "BBC News logo"
        }
      ]
    },
    "name": "oneOf",
    "argument": [
      "</ContainerElement>",
      "</HeadingElement>",
      "</VideoElement>",
      "</ImageElement>"
    ],
    "stack": "instance.pages[1].layers[3] is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "70px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].elements[1].styles.width is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "70px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].elements[1].styles.width does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "70px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].elements[1].styles.width is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].type",
    "message": "is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6",
    "schema": {
      "enum": [
        "paragraph",
        "heading",
        "heading1",
        "heading2",
        "heading3",
        "heading4",
        "heading5",
        "heading6"
      ],
      "required": true
    },
    "instance": "container",
    "name": "enum",
    "argument": [
      "paragraph",
      "heading",
      "heading1",
      "heading2",
      "heading3",
      "heading4",
      "heading5",
      "heading6"
    ],
    "stack": "instance.pages[1].layers[4].elements[1].type is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "70px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].elements[1].styles.width is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "70px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].elements[1].styles.width does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "70px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].elements[1].styles.width is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].type",
    "message": "does not exactly match expected constant: video",
    "schema": {
      "const": "video",
      "required": true
    },
    "instance": "container",
    "name": "const",
    "argument": "video",
    "stack": "instance.pages[1].layers[4].elements[1].type does not exactly match expected constant: video"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[4].elements[1].width is required"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[4].elements[1].height is required"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "70px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].elements[1].styles.width is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "70px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].elements[1].styles.width does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "70px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].elements[1].styles.width is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].type",
    "message": "does not exactly match expected constant: image",
    "schema": {
      "const": "image",
      "required": true
    },
    "instance": "container",
    "name": "const",
    "argument": "image",
    "stack": "instance.pages[1].layers[4].elements[1].type does not exactly match expected constant: image"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].source",
    "message": "is required",
    "schema": {
      "type": "string",
      "format": "uri",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[4].elements[1].source is required"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[4].elements[1].width is required"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[4].elements[1].height is required"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "70px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].elements[1].styles.width is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "70px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].elements[1].styles.width does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1].styles.width",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "70px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].elements[1].styles.width is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].elements[1]",
    "message": "is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>",
    "schema": "/Element",
    "instance": {
      "type": "container",
      "styles": {
        "border-bottom": "4px solid #bb1919",
        "animate-in": "fade-in",
        "width": "70px",
        "padding-top": "10px"
      }
    },
    "name": "oneOf",
    "argument": [
      "</ContainerElement>",
      "</HeadingElement>",
      "</VideoElement>",
      "</ImageElement>"
    ],
    "stack": "instance.pages[1].layers[4].elements[1] is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "25px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.padding is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "25px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.padding does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "25px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.padding is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "32px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingLeft is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "32px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.paddingLeft does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "32px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingLeft is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "32px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingRight is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "32px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.paddingRight does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "32px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingRight is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].type",
    "message": "is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6",
    "schema": {
      "enum": [
        "paragraph",
        "heading",
        "heading1",
        "heading2",
        "heading3",
        "heading4",
        "heading5",
        "heading6"
      ],
      "required": true
    },
    "instance": "container",
    "name": "enum",
    "argument": [
      "paragraph",
      "heading",
      "heading1",
      "heading2",
      "heading3",
      "heading4",
      "heading5",
      "heading6"
    ],
    "stack": "instance.pages[1].layers[4].type is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "25px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.padding is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "25px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.padding does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "25px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.padding is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "32px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingLeft is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "32px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.paddingLeft does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "32px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingLeft is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "32px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingRight is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "32px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.paddingRight does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "32px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingRight is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].type",
    "message": "does not exactly match expected constant: video",
    "schema": {
      "const": "video",
      "required": true
    },
    "instance": "container",
    "name": "const",
    "argument": "video",
    "stack": "instance.pages[1].layers[4].type does not exactly match expected constant: video"
  },
  {
    "property": "instance.pages[1].layers[4].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[4].width is required"
  },
  {
    "property": "instance.pages[1].layers[4].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[4].height is required"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "25px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.padding is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "25px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.padding does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "25px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.padding is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "32px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingLeft is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "32px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.paddingLeft does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "32px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingLeft is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "32px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingRight is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "32px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.paddingRight does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "32px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingRight is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].type",
    "message": "does not exactly match expected constant: image",
    "schema": {
      "const": "image",
      "required": true
    },
    "instance": "container",
    "name": "const",
    "argument": "image",
    "stack": "instance.pages[1].layers[4].type does not exactly match expected constant: image"
  },
  {
    "property": "instance.pages[1].layers[4].source",
    "message": "is required",
    "schema": {
      "type": "string",
      "format": "uri",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[4].source is required"
  },
  {
    "property": "instance.pages[1].layers[4].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[4].width is required"
  },
  {
    "property": "instance.pages[1].layers[4].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[4].height is required"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "25px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.padding is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "25px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.padding does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.padding",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "25px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.padding is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "32px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingLeft is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "32px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.paddingLeft does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingLeft",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "32px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingLeft is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "32px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingRight is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "32px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[4].styles.paddingRight does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[4].styles.paddingRight",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "32px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[4].styles.paddingRight is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[4]",
    "message": "is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>",
    "schema": "/Element",
    "instance": {
      "type": "container",
      "styles": {
        "flexDirection": "column",
        "justifyContent": "flex-end",
        "alignItems": "flex-start",
        "paddingLeft": "32px",
        "paddingRight": "32px",
        "padding": "25px"
      },
      "elements": [
        {
          "type": "paragraph",
          "text": "Ilya Brodsky, 15, was born and raised in the Russian city of Novosibirsk. \n\nHe learned how to read when he was two and started to code at the age of nine. Playing complex Rachmaninoff piano concerts is his favourite hobby and way to relax.",
          "styles": {
            "color": "#ffffff",
            "fontFamily": "BBCReithSans"
          }
        },
        {
          "type": "container",
          "styles": {
            "border-bottom": "4px solid #bb1919",
            "animate-in": "fade-in",
            "width": "70px",
            "padding-top": "10px"
          }
        }
      ]
    },
    "name": "oneOf",
    "argument": [
      "</ContainerElement>",
      "</HeadingElement>",
      "</VideoElement>",
      "</ImageElement>"
    ],
    "stack": "instance.pages[1].layers[4] is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].type",
    "message": "does not exactly match expected constant: container",
    "schema": {
      "const": "container",
      "required": true
    },
    "instance": "paragraph",
    "name": "const",
    "argument": "container",
    "stack": "instance.pages[1].layers[5].elements[0].type does not exactly match expected constant: container"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "3px 8px 1px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "3px 8px 1px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "3px 8px 1px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "3px 8px 1px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "3px 8px 1px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "3px 8px 1px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].type",
    "message": "does not exactly match expected constant: video",
    "schema": {
      "const": "video",
      "required": true
    },
    "instance": "paragraph",
    "name": "const",
    "argument": "video",
    "stack": "instance.pages[1].layers[5].elements[0].type does not exactly match expected constant: video"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[5].elements[0].width is required"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[5].elements[0].height is required"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "3px 8px 1px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "3px 8px 1px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "3px 8px 1px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].type",
    "message": "does not exactly match expected constant: image",
    "schema": {
      "const": "image",
      "required": true
    },
    "instance": "paragraph",
    "name": "const",
    "argument": "image",
    "stack": "instance.pages[1].layers[5].elements[0].type does not exactly match expected constant: image"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].source",
    "message": "is required",
    "schema": {
      "type": "string",
      "format": "uri",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[5].elements[0].source is required"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[5].elements[0].width is required"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[5].elements[0].height is required"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "is not of a type(s) number",
    "schema": {
      "type": "number"
    },
    "instance": "3px 8px 1px",
    "name": "type",
    "argument": [
      "number"
    ],
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding is not of a type(s) number"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "does not match pattern {}",
    "schema": {
      "type": "string",
      "pattern": {}
    },
    "instance": "3px 8px 1px",
    "name": "pattern",
    "argument": {},
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding does not match pattern {}"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0].styles.padding",
    "message": "is not exactly one from [subschema 0],[subschema 1]",
    "schema": "/Distance",
    "instance": "3px 8px 1px",
    "name": "oneOf",
    "argument": [
      "[subschema 0]",
      "[subschema 1]"
    ],
    "stack": "instance.pages[1].layers[5].elements[0].styles.padding is not exactly one from [subschema 0],[subschema 1]"
  },
  {
    "property": "instance.pages[1].layers[5].elements[0]",
    "message": "is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>",
    "schema": "/Element",
    "instance": {
      "type": "paragraph",
      "text": "TEST TEST TEST",
      "styles": {
        "color": "#ececec",
        "backgroundColor": "rgba(0,0,0,0.6)",
        "fontFamily": "BBCReithSansLight",
        "padding": "3px 8px 1px",
        "fontSize": 13
      }
    },
    "name": "oneOf",
    "argument": [
      "</ContainerElement>",
      "</HeadingElement>",
      "</VideoElement>",
      "</ImageElement>"
    ],
    "stack": "instance.pages[1].layers[5].elements[0] is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>"
  },
  {
    "property": "instance.pages[1].layers[5].type",
    "message": "is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6",
    "schema": {
      "enum": [
        "paragraph",
        "heading",
        "heading1",
        "heading2",
        "heading3",
        "heading4",
        "heading5",
        "heading6"
      ],
      "required": true
    },
    "instance": "container",
    "name": "enum",
    "argument": [
      "paragraph",
      "heading",
      "heading1",
      "heading2",
      "heading3",
      "heading4",
      "heading5",
      "heading6"
    ],
    "stack": "instance.pages[1].layers[5].type is not one of enum values: paragraph,heading,heading1,heading2,heading3,heading4,heading5,heading6"
  },
  {
    "property": "instance.pages[1].layers[5].type",
    "message": "does not exactly match expected constant: video",
    "schema": {
      "const": "video",
      "required": true
    },
    "instance": "container",
    "name": "const",
    "argument": "video",
    "stack": "instance.pages[1].layers[5].type does not exactly match expected constant: video"
  },
  {
    "property": "instance.pages[1].layers[5].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[5].width is required"
  },
  {
    "property": "instance.pages[1].layers[5].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[5].height is required"
  },
  {
    "property": "instance.pages[1].layers[5].type",
    "message": "does not exactly match expected constant: image",
    "schema": {
      "const": "image",
      "required": true
    },
    "instance": "container",
    "name": "const",
    "argument": "image",
    "stack": "instance.pages[1].layers[5].type does not exactly match expected constant: image"
  },
  {
    "property": "instance.pages[1].layers[5].source",
    "message": "is required",
    "schema": {
      "type": "string",
      "format": "uri",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[5].source is required"
  },
  {
    "property": "instance.pages[1].layers[5].width",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[5].width is required"
  },
  {
    "property": "instance.pages[1].layers[5].height",
    "message": "is required",
    "schema": {
      "type": "number",
      "required": true
    },
    "name": "required",
    "stack": "instance.pages[1].layers[5].height is required"
  },
  {
    "property": "instance.pages[1].layers[5]",
    "message": "is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>",
    "schema": "/Element",
    "instance": {
      "type": "container",
      "styles": {
        "flexDirection": "column",
        "justifyContent": "flex-end",
        "alignItems": "flex-end",
        "padding-right": "0px"
      },
      "elements": [
        {
          "type": "paragraph",
          "text": "TEST TEST TEST",
          "styles": {
            "color": "#ececec",
            "backgroundColor": "rgba(0,0,0,0.6)",
            "fontFamily": "BBCReithSansLight",
            "padding": "3px 8px 1px",
            "fontSize": 13
          }
        }
      ]
    },
    "name": "oneOf",
    "argument": [
      "</ContainerElement>",
      "</HeadingElement>",
      "</VideoElement>",
      "</ImageElement>"
    ],
    "stack": "instance.pages[1].layers[5] is not exactly one from </ContainerElement>,</HeadingElement>,</VideoElement>,</ImageElement>"
  }
]

Looking at this story from Mic News arctic-sea-ice-is-disappearing-heres-why-you-should-care

The background images get cropped on the right size when changing device size. eg from iphone 5 to iphone X. (look at the nose of the polar bear).

iphone 5

iphone 5

Iphone X

iphone X

This is what the AMP HTML for that card/page looks like in the inspector

<amp-story-page id="cover-page" class="i-amphtml-element i-amphtml-layout-container i-amphtml-layout i-amphtml-story-page-loaded" active="" distance="0">
        <amp-story-grid-layer template="fill" class="i-amphtml-element i-amphtml-layout-container i-amphtml-story-layer i-amphtml-story-grid-template-fill i-amphtml-layout">
          <amp-img layout="responsive" width="9" height="16" src="https://thumbs.mic.com/YTVkMmU3NTA5MCMvdFg1b3dGd0tBaEFWT2RjWkRwSlVZRmQxRVRjPS8weDA6MTA4MHgxOTE5L2ZpbHRlcnM6Zm9ybWF0KGpwZWcpOnF1YWxpdHkoODApL2h0dHA6Ly9zMy5hbWF6b25hd3MuY29tL3BvbGljeW1pYy1pbWFnZXMvN2V0M2Rvdndpc2thbTdpb2FjdWFyMWlvc2FkYmhkYXhxbXhvcTQ2d2JqcjR3cW9zcjdmZnFiYmRwejZneGpkNS5qcGc.jpg" class="i-amphtml-element i-amphtml-layout-responsive i-amphtml-layout-size-defined i-amphtml-layout"><i-amphtml-sizer style="display: block; padding-top: 177.778%;"></i-amphtml-sizer><img decoding="async" class="i-amphtml-fill-content i-amphtml-replaced-content" src="https://thumbs.mic.com/YTVkMmU3NTA5MCMvdFg1b3dGd0tBaEFWT2RjWkRwSlVZRmQxRVRjPS8weDA6MTA4MHgxOTE5L2ZpbHRlcnM6Zm9ybWF0KGpwZWcpOnF1YWxpdHkoODApL2h0dHA6Ly9zMy5hbWF6b25hd3MuY29tL3BvbGljeW1pYy1pbWFnZXMvN2V0M2Rvdndpc2thbTdpb2FjdWFyMWlvc2FkYmhkYXhxbXhvcTQ2d2JqcjR3cW9zcjdmZnFiYmRwejZneGpkNS5qcGc.jpg"></amp-img>
        </amp-story-grid-layer>
        <amp-story-grid-layer template="fill" class="s-1 i-amphtml-element i-amphtml-layout-container i-amphtml-story-layer i-amphtml-story-grid-template-fill i-amphtml-layout"></amp-story-grid-layer>
        <amp-story-grid-layer template="vertical" class="s-7 i-amphtml-element i-amphtml-layout-container i-amphtml-story-layer i-amphtml-story-grid-template-vertical i-amphtml-layout">
          <div class="s-3">
            <h1 class="s-2">Arctic sea ice is disappearing. Here's why you should care.</h1>
          </div>
          <div class="s-6">
            <div class="s-4">
              <amp-img layout="fixed" alt="Mic" width="45" height="22" src="https://files.mic.com/uploads/rnymubjhn2vl708quehdv01dbjpnaadjfsqcv2lpukv3edoxfys3cklwahteyjh1.svg" class="i-amphtml-element i-amphtml-layout-fixed i-amphtml-layout-size-defined i-amphtml-layout" style="width: 45px; height: 22px;"><img decoding="async" alt="Mic" class="i-amphtml-fill-content i-amphtml-replaced-content" src="https://files.mic.com/uploads/rnymubjhn2vl708quehdv01dbjpnaadjfsqcv2lpukv3edoxfys3cklwahteyjh1.svg"></amp-img>
            </div>
            <p class="s-5">Dec. 22, 2017</p>
          </div>
        </amp-story-grid-layer>
        <amp-story-grid-layer template="horizontal" class="s-10 i-amphtml-element i-amphtml-layout-container i-amphtml-story-layer i-amphtml-story-grid-template-horizontal i-amphtml-layout">
          <div class="s-9">
            <p class="s-8">Luis Domingo/Mic</p>
          </div>
        </amp-story-grid-layer>
      <div class="i-amphtml-story-spinner" aria-hidden="true" aria-label="Loading video"><div class="i-amphtml-story-spinner-container"><div class="i-amphtml-story-spinner-layer"><div class="i-amphtml-story-spinner-circle-clipper left"></div><div class="i-amphtml-story-spinner-circle-clipper right"></div></div></div></div></amp-story-page>

The first amp-img for the background image in the in the amp html page is a sibling of amp-story-grid-layer without any nested divs.

If possible, it could be useful for us to see what that page looks like in the story-json format for troubleshooting?

Thanks for your time

iefserge commented 6 years ago

@pietrop this definitely looks like a bug/missing feature in the latest version of this module, as there is no way to stretch image to fill the entire height while cropping on the sides. Our previous version of this module had somewhat different json structure that allowed this, but it also had other issues.

I think what's missing is something similar to resizeMode=cover from react native https://facebook.github.io/react-native/docs/image.html#style. Otherwise, not sure this can be expressed through flexbox only.

iefserge commented 6 years ago

On validator tool, it's pretty experimental, might not always be accurate and errors aren't great. I've been looking into another json validator tool that can handle union types better, but haven't found anything yet.

iefserge commented 6 years ago

Oh, and the reason we wrap everything into a div is to abstract layout from AMP default styles and rely fully on flexbox. This should allow us to make it less dependent on AMP default container styles/layout, so it's portable to react native / video etc.

pietrop commented 6 years ago

Thanks @iefserge, Any thoughts on what would be the best way to address the image distortion in this module? Happy to have a go at it with some guidance.

iefserge commented 6 years ago

@pietrop I think we add resizeMode property to images, which can use AMP layout mode and/or extra div/css to scale it correctly. https://www.ampproject.org/docs/design/responsive/control_layout https://ampbyexample.com/advanced/how_to_support_images_with_unknown_dimensions/

pietrop commented 6 years ago

@iefserge how would that be different from the current layout option?

iefserge commented 6 years ago

@pietrop We copied it from AMP initially, but actually ignore it at the moment. I'll remove it from the example. I think flexbox should cover most layout cases, except for the image sizing mode.

When rendering stories into videos, we use https://github.com/facebook/yoga to compute layout, so it would be hard to implement non-flex layout options.

eagerterrier commented 6 years ago

If anyone faces the same issues, I added a align-self: center; to the amp-img container.