{
  "definitions": {
    "jmespathProp": {
      "type": "object",
      "$id": "#/props/jmespathProp",
      "title": "JMESPath function expression",
      "additionalProperties": false,
      "properties": {
        "fn:jmespath": {
          "type": "string"
        }
      }
    },
    "ramblerModule": {
      "$id": "#/definitions/ramblerModule",
      "title": "The Rambler Module Schema",
      "oneOf": [
        {
          "type": "string"
        },
        {
          "type": "array",
          "items": {
            "allOf": [
              {"type": "string"}
            ]
          }
        }
      ]
    },
    "ramblerProp": {
      "type": "object",
      "$id": "#/props/ramblerProp",
      "title": "Rambler function expression",
      "additionalProperties": false,
      "properties": {
        "fn:rambler": {
          "type": "string"
        }
      }
    },
    "streamConfig": {
      "$id": "#/definitions/streamConfig",
      "title": "Event listener configuration",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "stream"
      ],
      "properties": {
        "stream": {
          "type": "string",
          "pattern": "^\\w(.*)$"
        },
        "cache": {
          "type": "number",
          "minimum": 1,
          "default": 1
        },
        "debounce": {
          "type": "number",
          "minimum": 0,
          "default": 0
        }
      }
    },
    "channel": {
      "$id": "#/definitions/channel",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "channel",
        "shape"
      ],
      "properties": {
        "channel": {
          "type": "string",
          "default": "cronkite:stream"
        },
        "filtered": {
          "type": "boolean"
        },
        "listen": {
          "type": "string"
        },
        "shape": {
          "$ref": "#/definitions/componentProps",
          "default": {
            "fn:jmespath": "@"
          }
        }
      }
    },
    "componentArray": {
      "$id": "#/definitions/componentArray",
      "type": "array",
      "title": "The Component Array Schema",
      "items": {
        "$ref": "#/definitions/component"
      }
    },
    "component": {
      "$id": "#/definitions/component",
      "type": "object",
      "title": "The Component Schema",
      "required": [
        "element"
      ],
      "patternProperties": {
        "^@[a-z]+[A-Za-z]": {
          "$ref": "#/definitions/componentProps"
        }
      },
      "properties": {
        "element": {
          "$id": "#/definitions/component/properties/element",
          "type": "string",
          "title": "The Element Schema",
          "default": "",
          "examples": [
            "div",
            "h1",
            "epi-headlinevalue"
          ],
          "pattern": "^(.*)$"
        },
        "heading": {
          "$id": "#/definitions/component/properties/heading",
          "title": "The Heading Schema",
          "oneOf": [
            {
              "type": "string"
            },
            {
              "$ref": "#/definitions/jmespathProp"
            },
            {
              "$ref": "#/definitions/ramblerProp"
            }
          ]
        },
        "rambler": {
          "$id": "#/definitions/component/properties/rambler",
          "title": "The Rambler Schema",
          "type": "object",
          "additionalProperties": true
        },
        "when": {
          "$id": "#/definitions/component/properties/when",
          "title": "The When Schema",
          "oneOf": [
            {
              "type": "boolean",
              "default": true
            },
            {
              "$ref": "#/definitions/jmespathProp"
            },
            {
              "$ref": "#/definitions/ramblerProp"
            }
          ],
          "examples": [
            {
              "fn:jmespath": "@ != `null`"
            },
            true
          ]
        },
        "listen": {
          "$id": "#/definitions/component/properties/listen",
          "title": "The Listen Schema",
          "examples": [
            "mousemove",
            {
              "stream": "mousemove",
              "cache": 4,
              "debounce": 100
            }
          ],
          "oneOf": [
            {
              "type": "string",
              "pattern": "^\\w(.*)$",
              "minLength": 1
            },
            {
              "$ref": "#/definitions/streamConfig"
            }
          ]
        },
        "style": {
          "$id": "#/definitions/component/properties/style",
          "type": "object",
          "title": "The Style Schema",
          "propertyNames": {
            "pattern": "^[a-z][A-Za-z]*$"
          },
          "additionalProperties": {
            "type": [
              "string",
              "number"
            ]
          }
        },
        "layout": {
          "$id": "#/definitions/component/properties/layout",
          "type": "object",
          "title": "The Layout Schema",
          "additionalProperties": false,
          "properties": {
            "width": {
              "$id": "#/definitions/component/properties/layout/properties/width",
              "type": "integer",
              "title": "The Width Schema",
              "minimum": 1,
              "default": 4,
              "examples": [
                4
              ]
            },
            "position": {
              "$id": "#/definitions/component/properties/layout/properties/position",
              "type": "string",
              "title": "The Position Schema",
              "enum": [
                "header",
                "footer"
              ],
              "examples": [
                "header",
                "footer"
              ]
            }
          }
        },
        "components": {
          "$id": "#/definitions/component/properties/components",
          "$ref": "#/definitions/componentArray"
        }
      }
    },
    "datastream": {
      "type": "object",
      "properties": {
        "@channels": {
          "$id": "#/definitions/datastream/properties/@channels",
          "type": "array",
          "title": "The @channels Schema",
          "items": {
            "$ref": "#/definitions/channel"
          }
        },
        "@poll-frequency": {
          "$id": "#/definitions/datastream/properties/@poll-frequency",
          "type": "integer",
          "title": "The @poll-frequency Schema",
          "default": 15000,
          "examples": [
            1000000000
          ]
        },
        "@acceptsFilters": {
          "$id": "#/definitions/datastream/properties/@acceptsFilters",
          "type": "boolean",
          "title": "The @acceptsFilters Schema",
          "default": false,
          "examples": [
            true,
            false
          ]
        },
        "@responseFormat": {
          "$id": "#/definitions/datastream/properties/@responseFormat",
          "type": "string",
          "title": "The @responseFormat Schema",
          "default": "json",
          "enum": [
            "json",
            "csv",
            "tsv",
            "text"
          ],
          "examples": [
            "json",
            "csv",
            "tsv",
            "text"
          ]
        },
        "@mode": {
          "$id": "#/definitions/datastream/properties/@mode",
          "type": "string",
          "title": "The @mode Schema",
          "default": "cors",
          "enum": [
            "cors",
            "no-cors",
            "same-origin"
          ],
          "examples": [
            "cors",
            "no-cors",
            "same-origin"
          ]
        },
        "@cache": {
          "$id": "#/definitions/datastream/properties/@cache",
          "type": "string",
          "title": "The @cache Schema",
          "default": "default",
          "enum": [
            "default",
            "no-store",
            "reload",
            "no-cache",
            "force-cache",
            "only-if-cached"
          ],
          "examples": [
            "default",
            "no-store",
            "reload",
            "no-cache",
            "force-cache",
            "only-if-cached"
          ]
        },
        "@credentials": {
          "$id": "#/definitions/datastream/properties/@credentials",
          "type": "string",
          "title": "The @credentials Schema",
          "default": "include",
          "enum": [
            "include",
            "omit",
            "same-origin"
          ],
          "examples": [
            "include",
            "omit",
            "same-origin"
          ]
        },
        "@url": {
          "$id": "#/definitions/datastream/properties/@url",
          "type": "string",
          "title": "The @url Schema",
          "examples": [
            "https://example.com/example.json"
          ],
          "pattern": "^([a-zA-Z][a-zA-Z0-9+.-]*):(?:\\/\\/((?:(?=((?:[a-zA-Z0-9-._~!$&'()*+,;=:]|%[0-9a-fA-F]{2})*))(\\3)@)?(?=((?:\\[?(?:::[a-fA-F0-9]+(?::[a-fA-F0-9]+)?|(?:[a-fA-F0-9]+:)+(?::[a-fA-F0-9]+)+|(?:[a-fA-F0-9]+:)+(?::|(?:[a-fA-F0-9]+:?)*))\\]?)|(?:[a-zA-Z0-9-._~!$&'()*+,;=]|%[0-9a-fA-F]{2})*))\\5(?::(?=(\\d*))\\6)?)(\\/(?=((?:[a-zA-Z0-9-._~!$&'()*+,;=:@\\/]|%[0-9a-fA-F]{2})*))\\8)?|(\\/?(?!\\/)(?=((?:[a-zA-Z0-9-._~!$&'()*+,;=:@\\/]|%[0-9a-fA-F]{2})*))\\10)?)(?:\\?(?=((?:[a-zA-Z0-9-._~!$&'()*+,;=:@\\/?]|%[0-9a-fA-F]{2})*))\\11)?(?:#(?=((?:[a-zA-Z0-9-._~!$&'()*+,;=:@\\/?]|%[0-9a-fA-F]{2})*))\\12)?$"
        }
      }
    },
    "componentProps": {
      "oneOf": [
        {
          "type": [
            "array",
            "string",
            "number",
            "boolean"
          ]
        },
        {
          "type": "object",
          "$ref": "#/definitions/jmespathProp"
        },
        {
          "$ref": "#/definitions/ramblerProp"
        },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "fn:formatDate": {
              "type": "array",
              "additionalItems": false,
              "minItems": 2,
              "maxItems": 2,
              "items": [
                {
                  "oneOf": [
                    {
                      "type": "number"
                    },
                    {
                      "type": "object",
                      "$ref": "#/definitions/jmespathProp"
                    },
                    {
                      "$ref": "#/definitions/ramblerProp"
                    }
                  ]
                },
                {
                  "type": "string",
                  "enum": [
                    "toDateString",
                    "toISOString",
                    "toJSON",
                    "toLocaleDateString",
                    "toLocaleString",
                    "toLocaleTimeString",
                    "toString",
                    "toTimeString",
                    "toUTCString"
                  ]
                }
              ]
            },
            "fn:toLocaleString": {
              "oneOf": [
                {
                  "type": "number"
                },
                {
                  "type": "object",
                  "$ref": "#/definitions/jmespathProp"
                },
                {
                  "$ref": "#/definitions/ramblerProp"
                }
              ]
            },
            "fn:formatNumber": {
              "type": "array",
              "additionalItems": false,
              "minItems": 3,
              "items": [
                {
                  "$ref": "#/definitions/componentProps"
                },
                {
                  "type": "integer"
                },
                {
                  "type": "string"
                }
              ]
            }
          }
        }
      ]
    }
  },
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://epi2me.io/report.json",
  "type": "object",
  "title": "Metrichor dashboard config schema",
  "required": [
    "components"
  ],
  "properties": {
    "id": {
      "$id": "#/properties/id",
      "type": "string",
      "title": "The Id Schema",
      "examples": [
        "cronkite:demo",
        "my-dashboard"
      ],
      "pattern": "^(.*)$"
    },
    "listen": {
      "$id": "#/properties/listen",
      "type": "string",
      "title": "Which context to bind listeners 'window' | 'document' | 'host' [default: host]",
      "enum": [
        "host",
        "document",
        "window"
      ],
      "default": "host"
    },
    "components": {
      "$id": "#/properties/components",
      "$ref": "#/definitions/componentArray",
      "default": [],
      "examples": [
        [],
        [
          {
            "element": "h1",
            "@innerHTML": "Hello world!"
          }
        ],
        [
          {
            "element": "div",
            "components": [
              {
                "element": "h1",
                "@innerHTML": "Hello world!"
              }
            ]
          }
        ]
      ]
    },
    "streams": {
      "$id": "#/properties/streams",
      "type": "array",
      "title": "Dashboard data streams",
      "default": [],
      "examples": [
        [],
        [
          {
            "element": "cronk-poll-datastream",
            "@url": "https://example.com/exampl.json",
            "@channels": [
              {
                "channel": "example:json",
                "shape": {
                  "fn:jmespath": "@"
                }
              }
            ]
          }
        ]
      ],
      "items": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "element",
              "@channels",
              "@url"
            ],
            "additionalProperties": false,
            "properties": {
              "element": {
                "type": "string",
                "title": "Generic polling datastream",
                "const": "cronk-poll-datastream"
              },
              "@url": {
                "$ref": "#/definitions/datastream/properties/@url"
              },
              "@channels": {
                "$ref": "#/definitions/datastream/properties/@channels"
              },
              "@poll-frequency": {
                "$ref": "#/definitions/datastream/properties/@poll-frequency"
              },
              "@credentials": {
                "$ref": "#/definitions/datastream/properties/@credentials"
              },
              "@acceptsFilters": {
                "$ref": "#/definitions/datastream/properties/@acceptsFilters"
              },
              "@responseFormat": {
                "$ref": "#/definitions/datastream/properties/@responseFormat"
              },
              "@mode": {
                "$ref": "#/definitions/datastream/properties/@mode"
              },
              "@cache": {
                "$ref": "#/definitions/datastream/properties/@cache"
              },
              "@rambler": {
                "type": "string"
              }
            }
          }
        ]
      }
    },
    "rambler": {
      "$ref": "#/definitions/ramblerModule"
    }
  },
  "default": {
    "id": "YOUR-REPORT-ID",
    "components": [],
    "streams": [],
    "listen": "window",
    "rambler": []
  },
  "examples": [
    {},
    {
      "id": "hello:world",
      "components": [
        {
          "element": "h1",
          "@innerHTML": "Hello World!"
        }
      ],
      "streams": []
    }
  ]
}
