{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema",
  "definitions": {
    "actionObject": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "definition": "The action type"
        }
      },
      "additionalProperties": true,
      "required": ["type"]
    },
    "baseStateNode": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "key": {
          "type": "string"
        },
        "type": {
          "type": "string",
          "enum": ["atomic", "compound", "parallel", "final", "history"]
        },
        "order": {
          "$ref": "#/definitions/order"
        },
        "description": {
          "type": "string",
          "description": "The description of the state node, in Markdown"
        }
      },
      "required": ["id", "key", "type"]
    },
    "compoundStateNode": {
      "allOf": [
        { "$ref": "#/definitions/baseStateNode" },
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "pattern": "compound"
            },
            "entry": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/actionObject"
              }
            },
            "exit": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/actionObject"
              }
            },
            "initial": {
              "type": "string"
            },
            "invoke": {
              "$ref": "#/definitions/invokeArray"
            },
            "on": {
              "$ref": "#/definitions/transitionsObject"
            },
            "states": {
              "$ref": "#/definitions/statesObject"
            }
          },
          "required": ["states"]
        }
      ]
    },
    "parallelStateNode": {
      "allOf": [
        { "$ref": "#/definitions/baseStateNode" },
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "pattern": "parallel"
            },
            "entry": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/actionObject"
              }
            },
            "exit": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/actionObject"
              }
            },
            "invoke": {
              "$ref": "#/definitions/invokeArray"
            },
            "on": {
              "$ref": "#/definitions/transitionsObject"
            },
            "states": {
              "$ref": "#/definitions/statesObject"
            }
          },
          "required": ["states"]
        }
      ]
    },
    "atomicStateNode": {
      "allOf": [
        { "$ref": "#/definitions/baseStateNode" },
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "pattern": "atomic"
            },
            "entry": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/actionObject"
              }
            },
            "exit": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/actionObject"
              }
            },
            "invoke": {
              "$ref": "#/definitions/invokeArray"
            },
            "on": {
              "$ref": "#/definitions/transitionsObject"
            }
          },
          "required": ["on"]
        }
      ]
    },
    "historyStateNode": {
      "allOf": [
        { "$ref": "#/definitions/baseStateNode" },
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "pattern": "history"
            },
            "history": {
              "type": "string",
              "enum": ["shallow", "deep"]
            }
          },
          "required": ["history"]
        }
      ]
    },
    "finalStateNode": {
      "allOf": [
        { "$ref": "#/definitions/baseStateNode" },
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "pattern": "final"
            },
            "data": {
              "type": "object"
            }
          }
        }
      ]
    },
    "statesObject": {
      "type": "object",
      "patternProperties": {
        "^.*$": {
          "oneOf": [
            { "$ref": "#/definitions/atomicStateNode" },
            { "$ref": "#/definitions/compoundStateNode" },
            { "$ref": "#/definitions/parallelStateNode" },
            { "$ref": "#/definitions/historyStateNode" },
            { "$ref": "#/definitions/finalStateNode" }
          ]
        }
      }
    },
    "transitionsObject": {
      "type": "object",
      "patternProperties": {
        "^.*$": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/transitionObject"
          }
        }
      }
    },
    "transitionObject": {
      "type": "object",
      "properties": {
        "actions": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/actionObject"
          }
        },
        "cond": {
          "type": "object"
        },
        "eventType": {
          "type": "string"
        },
        "source": {
          "type": "string"
        },
        "target": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "required": ["actions", "eventType", "source", "target"]
    },
    "invokeObject": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string"
        },
        "id": {
          "type": "string"
        },
        "src": {
          "type": "object",
          "properties": {
            "type": { "type": "string" }
          }
        },
        "autoForward": {
          "type": "boolean",
          "default": false
        }
      },
      "required": ["type", "id", "src"],
      "additionalProperties": false
    },
    "invokeArray": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/invokeObject"
      }
    },
    "functionObject": {
      "type": "object",
      "properties": {
        "$function": {
          "type": "string"
        }
      }
    },
    "order": {
      "type": "integer"
    }
  },
  "properties": {
    "id": {
      "title": "ID",
      "type": "string"
    },
    "initial": {
      "type": "string"
    },
    "key": {
      "type": "string"
    },
    "type": {
      "type": "string",
      "enum": ["compound", "parallel"]
    },
    "context": {
      "type": "object"
    },
    "states": {
      "$ref": "#/definitions/statesObject"
    },
    "on": {
      "$ref": "#/definitions/transitionsObject"
    },
    "transitions": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/transitionObject"
      }
    },
    "entry": {
      "type": "array"
    },
    "exit": {
      "type": "array"
    },
    "order": {
      "$ref": "#/definitions/order"
    },
    "invoke": {
      "$ref": "#/definitions/invokeArray"
    },
    "version": {
      "type": "string"
    }
  },
  "required": ["id", "key", "type", "states"]
}