{
  "type": "object",
  "properties": {
    "protocolVersion": {
      "const": 1
    },
    "documentId": {
      "$ref": "#/$defs/id"
    },
    "sessionId": {
      "$ref": "#/$defs/id"
    },
    "requestId": {
      "$ref": "#/$defs/id"
    },
    "expectedRevision": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "contextRevision": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "grantId": {
      "$ref": "#/$defs/id"
    },
    "operations": {
      "type": "array",
      "items": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "op": {
                "const": "create"
              },
              "object": {
                "$ref": "#/$defs/shape"
              }
            },
            "required": [
              "op",
              "object"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "op": {
                "const": "replace"
              },
              "object": {
                "$ref": "#/$defs/shape"
              }
            },
            "required": [
              "op",
              "object"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "op": {
                "const": "delete"
              },
              "id": {
                "$ref": "#/$defs/id"
              }
            },
            "required": [
              "op",
              "id"
            ],
            "additionalProperties": false
          }
        ]
      },
      "minItems": 1,
      "maxItems": 100
    }
  },
  "required": [
    "protocolVersion",
    "documentId",
    "sessionId",
    "requestId",
    "expectedRevision",
    "contextRevision",
    "grantId",
    "operations"
  ],
  "additionalProperties": false,
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://calcbe.com/common/data/draw/batch.schema.json",
  "title": "CalcBE Draw batch 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"
        }
      ]
    }
  }
}
