{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schemaVersion",
    "title",
    "photo",
    "pins"
  ],
  "properties": {
    "schemaVersion": {
      "const": "1.0",
      "type": "string"
    },
    "title": {
      "type": "string",
      "maxLength": 120,
      "minLength": 1
    },
    "occasion": {
      "type": "string",
      "maxLength": 60
    },
    "photo": {
      "type": "string",
      "maxLength": 11200000,
      "description": "One of the four bundled sample paths, or a base64 PNG/JPEG/WebP data URL (decoded maximum 8 MiB). No remote URLs."
    },
    "eventPlan": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "count",
        "singular",
        "plural"
      ],
      "properties": {
        "count": {
          "type": "integer",
          "minimum": 1,
          "maximum": 10000
        },
        "singular": {
          "type": "string",
          "maxLength": 30,
          "minLength": 1
        },
        "plural": {
          "type": "string",
          "maxLength": 30,
          "minLength": 1
        }
      }
    },
    "pins": {
      "type": "array",
      "minItems": 1,
      "maxItems": 100,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "title",
          "x",
          "y"
        ],
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1
          },
          "instruction": {
            "type": "string",
            "maxLength": 2000
          },
          "x": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "y": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "quantity": {
            "type": "string",
            "maxLength": 64,
            "description": "Amount per repeating unit or once per event. Use a numeric string for calculated totals; empty means unknown."
          },
          "unit": {
            "type": "string",
            "maxLength": 64
          },
          "supplyBasis": {
            "type": "string",
            "enum": [
              "fixed",
              "repeat"
            ]
          },
          "location": {
            "type": "string",
            "maxLength": 120
          },
          "assignee": {
            "type": "string",
            "maxLength": 120
          },
          "packingNote": {
            "type": "string",
            "maxLength": 2000
          }
        }
      }
    }
  }
}
