{
  "type": "object",
  "properties": {
    "format": {
      "const": "calcbe-draw"
    },
    "schemaVersion": {
      "const": 1
    },
    "documentId": {
      "$ref": "#/$defs/id"
    },
    "title": {
      "type": "string",
      "maxLength": 120
    },
    "canvas": {
      "type": "object",
      "properties": {
        "width": {
          "type": "integer",
          "minimum": 64,
          "maximum": 4096
        },
        "height": {
          "type": "integer",
          "minimum": 64,
          "maximum": 4096
        },
        "background": {
          "anyOf": [
            {
              "type": "string",
              "pattern": "^#[0-9a-f]{6}$",
              "minLength": 7,
              "maxLength": 7
            },
            {
              "type": "null"
            }
          ]
        }
      },
      "required": [
        "width",
        "height",
        "background"
      ],
      "additionalProperties": false
    },
    "assets": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/$defs/id"
          },
          "mime": {
            "enum": [
              "image/png",
              "image/jpeg"
            ]
          },
          "width": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2048
          },
          "height": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2048
          },
          "sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$"
          },
          "dataBase64": {
            "type": "string",
            "minLength": 4,
            "maxLength": 11184812,
            "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"
          }
        },
        "required": [
          "id",
          "mime",
          "width",
          "height",
          "sha256",
          "dataBase64"
        ],
        "additionalProperties": false
      },
      "minItems": 0,
      "maxItems": 1
    },
    "reference": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "assetId": {
              "$ref": "#/$defs/id"
            },
            "transform": {
              "$ref": "#/$defs/transform"
            },
            "opacity": {
              "type": "number",
              "minimum": 0,
              "maximum": 1
            },
            "visible": {
              "type": "boolean"
            },
            "locked": {
              "const": true
            }
          },
          "required": [
            "assetId",
            "transform",
            "opacity",
            "visible",
            "locked"
          ],
          "additionalProperties": false
        },
        {
          "type": "null"
        }
      ]
    },
    "objects": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/shape"
      },
      "minItems": 0,
      "maxItems": 1000
    }
  },
  "required": [
    "format",
    "schemaVersion",
    "documentId",
    "title",
    "canvas",
    "assets",
    "reference",
    "objects"
  ],
  "additionalProperties": false,
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://calcbe.com/common/data/draw/project.schema.json",
  "title": "CalcBE Draw project v1",
  "$defs": {
    "id": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9-]{0,63}$",
      "maxLength": 64
    },
    "transform": {
      "type": "object",
      "properties": {
        "x": {
          "type": "number",
          "minimum": -32768,
          "maximum": 32768
        },
        "y": {
          "type": "number",
          "minimum": -32768,
          "maximum": 32768
        },
        "scale": {
          "type": "number",
          "minimum": 0.05,
          "maximum": 20
        },
        "rotation": {
          "type": "number",
          "minimum": -180,
          "maximum": 180
        }
      },
      "required": [
        "x",
        "y",
        "scale",
        "rotation"
      ],
      "additionalProperties": false
    },
    "style": {
      "type": "object",
      "properties": {
        "stroke": {
          "anyOf": [
            {
              "type": "string",
              "pattern": "^#[0-9a-f]{6}$",
              "minLength": 7,
              "maxLength": 7
            },
            {
              "type": "null"
            }
          ]
        },
        "fill": {
          "anyOf": [
            {
              "type": "string",
              "pattern": "^#[0-9a-f]{6}$",
              "minLength": 7,
              "maxLength": 7
            },
            {
              "type": "null"
            }
          ]
        },
        "strokeWidth": {
          "type": "number",
          "minimum": 0.25,
          "maximum": 256
        }
      },
      "required": [
        "stroke",
        "fill",
        "strokeWidth"
      ],
      "additionalProperties": false
    },
    "line": {
      "type": "object",
      "properties": {
        "id": {
          "$ref": "#/$defs/id"
        },
        "type": {
          "const": "line"
        },
        "label": {
          "type": "string",
          "maxLength": 80
        },
        "visible": {
          "type": "boolean"
        },
        "locked": {
          "type": "boolean"
        },
        "opacity": {
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "transform": {
          "$ref": "#/$defs/transform"
        },
        "style": {
          "$ref": "#/$defs/style"
        },
        "geometry": {
          "type": "object",
          "properties": {
            "x1": {
              "type": "number",
              "minimum": -32768,
              "maximum": 32768
            },
            "y1": {
              "type": "number",
              "minimum": -32768,
              "maximum": 32768
            },
            "x2": {
              "type": "number",
              "minimum": -32768,
              "maximum": 32768
            },
            "y2": {
              "type": "number",
              "minimum": -32768,
              "maximum": 32768
            }
          },
          "required": [
            "x1",
            "y1",
            "x2",
            "y2"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "type",
        "label",
        "visible",
        "locked",
        "opacity",
        "transform",
        "style",
        "geometry"
      ],
      "additionalProperties": false
    },
    "rect": {
      "type": "object",
      "properties": {
        "id": {
          "$ref": "#/$defs/id"
        },
        "type": {
          "const": "rect"
        },
        "label": {
          "type": "string",
          "maxLength": 80
        },
        "visible": {
          "type": "boolean"
        },
        "locked": {
          "type": "boolean"
        },
        "opacity": {
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "transform": {
          "$ref": "#/$defs/transform"
        },
        "style": {
          "$ref": "#/$defs/style"
        },
        "geometry": {
          "type": "object",
          "properties": {
            "x": {
              "type": "number",
              "minimum": -32768,
              "maximum": 32768
            },
            "y": {
              "type": "number",
              "minimum": -32768,
              "maximum": 32768
            },
            "width": {
              "type": "number",
              "exclusiveMinimum": 0,
              "maximum": 32768
            },
            "height": {
              "type": "number",
              "exclusiveMinimum": 0,
              "maximum": 32768
            }
          },
          "required": [
            "x",
            "y",
            "width",
            "height"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "type",
        "label",
        "visible",
        "locked",
        "opacity",
        "transform",
        "style",
        "geometry"
      ],
      "additionalProperties": false
    },
    "ellipse": {
      "type": "object",
      "properties": {
        "id": {
          "$ref": "#/$defs/id"
        },
        "type": {
          "const": "ellipse"
        },
        "label": {
          "type": "string",
          "maxLength": 80
        },
        "visible": {
          "type": "boolean"
        },
        "locked": {
          "type": "boolean"
        },
        "opacity": {
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "transform": {
          "$ref": "#/$defs/transform"
        },
        "style": {
          "$ref": "#/$defs/style"
        },
        "geometry": {
          "type": "object",
          "properties": {
            "cx": {
              "type": "number",
              "minimum": -32768,
              "maximum": 32768
            },
            "cy": {
              "type": "number",
              "minimum": -32768,
              "maximum": 32768
            },
            "rx": {
              "type": "number",
              "exclusiveMinimum": 0,
              "maximum": 32768
            },
            "ry": {
              "type": "number",
              "exclusiveMinimum": 0,
              "maximum": 32768
            }
          },
          "required": [
            "cx",
            "cy",
            "rx",
            "ry"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "type",
        "label",
        "visible",
        "locked",
        "opacity",
        "transform",
        "style",
        "geometry"
      ],
      "additionalProperties": false
    },
    "path": {
      "type": "object",
      "properties": {
        "id": {
          "$ref": "#/$defs/id"
        },
        "type": {
          "const": "path"
        },
        "label": {
          "type": "string",
          "maxLength": 80
        },
        "visible": {
          "type": "boolean"
        },
        "locked": {
          "type": "boolean"
        },
        "opacity": {
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "transform": {
          "$ref": "#/$defs/transform"
        },
        "style": {
          "$ref": "#/$defs/style"
        },
        "geometry": {
          "type": "object",
          "properties": {
            "commands": {
              "type": "array",
              "items": {
                "oneOf": [
                  {
                    "type": "array",
                    "prefixItems": [
                      {
                        "const": "M"
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      }
                    ],
                    "items": false,
                    "minItems": 3,
                    "maxItems": 3
                  },
                  {
                    "type": "array",
                    "prefixItems": [
                      {
                        "const": "L"
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      }
                    ],
                    "items": false,
                    "minItems": 3,
                    "maxItems": 3
                  },
                  {
                    "type": "array",
                    "prefixItems": [
                      {
                        "const": "Q"
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      }
                    ],
                    "items": false,
                    "minItems": 5,
                    "maxItems": 5
                  },
                  {
                    "type": "array",
                    "prefixItems": [
                      {
                        "const": "C"
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      },
                      {
                        "type": "number",
                        "minimum": -32768,
                        "maximum": 32768
                      }
                    ],
                    "items": false,
                    "minItems": 7,
                    "maxItems": 7
                  },
                  {
                    "type": "array",
                    "prefixItems": [
                      {
                        "const": "Z"
                      }
                    ],
                    "items": false,
                    "minItems": 1,
                    "maxItems": 1
                  }
                ]
              },
              "minItems": 1,
              "maxItems": 2048
            }
          },
          "required": [
            "commands"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "type",
        "label",
        "visible",
        "locked",
        "opacity",
        "transform",
        "style",
        "geometry"
      ],
      "additionalProperties": false
    },
    "text": {
      "type": "object",
      "properties": {
        "id": {
          "$ref": "#/$defs/id"
        },
        "type": {
          "const": "text"
        },
        "label": {
          "type": "string",
          "maxLength": 80
        },
        "visible": {
          "type": "boolean"
        },
        "locked": {
          "type": "boolean"
        },
        "opacity": {
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "transform": {
          "$ref": "#/$defs/transform"
        },
        "style": {
          "$ref": "#/$defs/style"
        },
        "geometry": {
          "type": "object",
          "properties": {
            "x": {
              "type": "number",
              "minimum": -32768,
              "maximum": 32768
            },
            "y": {
              "type": "number",
              "minimum": -32768,
              "maximum": 32768
            },
            "text": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2000
            },
            "fontSize": {
              "type": "number",
              "minimum": 4,
              "maximum": 512
            },
            "fontFamily": {
              "enum": [
                "sans-serif",
                "serif",
                "monospace"
              ]
            }
          },
          "required": [
            "x",
            "y",
            "text",
            "fontSize",
            "fontFamily"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "id",
        "type",
        "label",
        "visible",
        "locked",
        "opacity",
        "transform",
        "style",
        "geometry"
      ],
      "additionalProperties": false
    },
    "shape": {
      "oneOf": [
        {
          "$ref": "#/$defs/line"
        },
        {
          "$ref": "#/$defs/rect"
        },
        {
          "$ref": "#/$defs/ellipse"
        },
        {
          "$ref": "#/$defs/path"
        },
        {
          "$ref": "#/$defs/text"
        }
      ]
    }
  }
}
