{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://egatari.org/schema/egatari-index.schema.json",
  "title": "Egatari 1.0 archive index (#egatari-index)",
  "type": "object",
  "required": [
    "format",
    "version",
    "profile",
    "requires",
    "contracts",
    "generator",
    "docId",
    "entry",
    "sourceSha256",
    "files",
    "blobs",
    "metadata"
  ],
  "properties": {
    "format": {
      "const": "egatari"
    },
    "version": {
      "type": "object",
      "required": [
        "major",
        "minor"
      ],
      "properties": {
        "major": {
          "const": 1
        },
        "minor": {
          "type": "integer",
          "minimum": 0
        }
      }
    },
    "profile": {
      "enum": [
        "core",
        "extended"
      ]
    },
    "requires": {
      "type": "array",
      "uniqueItems": true,
      "items": {
        "type": "string",
        "pattern": "^[a-z0-9-]+$"
      }
    },
    "contracts": {
      "type": "object",
      "required": [
        "source",
        "runtime"
      ],
      "properties": {
        "source": {
          "type": "integer",
          "minimum": 1
        },
        "runtime": {
          "type": "integer",
          "minimum": 1
        }
      }
    },
    "generator": {
      "type": "object",
      "required": [
        "name",
        "version"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1
        },
        "version": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "docId": {
      "type": "string",
      "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
    },
    "entry": {
      "$ref": "#/$defs/archivePath"
    },
    "sourceSha256": {
      "$ref": "#/$defs/sha256"
    },
    "files": {
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "$ref": "#/$defs/archivePath"
      },
      "additionalProperties": {
        "$ref": "#/$defs/blobId"
      }
    },
    "blobs": {
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "$ref": "#/$defs/blobId"
      },
      "additionalProperties": {
        "$ref": "#/$defs/blob"
      }
    },
    "audio": {
      "type": "object",
      "propertyNames": {
        "$ref": "#/$defs/stepKey"
      },
      "additionalProperties": {
        "$ref": "egatari-audio.schema.json"
      }
    },
    "components": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/component"
      }
    },
    "metadata": {
      "$ref": "egatari-metadata.schema.json"
    },
    "excluded": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "extensions": {
      "type": "object",
      "propertyNames": {
        "pattern": "^[a-z][a-z0-9]{0,31}$"
      },
      "additionalProperties": {
        "type": "object",
        "required": [
          "v"
        ],
        "properties": {
          "v": {
            "type": "integer",
            "minimum": 1
          }
        }
      }
    },
    "themes": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "version",
          "sha256",
          "source"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "version": {
            "type": "string",
            "minLength": 1
          },
          "sha256": {
            "$ref": "#/$defs/sha256"
          },
          "source": {
            "enum": [
              "registry",
              "embedded"
            ]
          },
          "path": {
            "$ref": "#/$defs/archivePath"
          }
        }
      }
    }
  },
  "$defs": {
    "sha256": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$"
    },
    "blobId": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_]{1,32}$"
    },
    "stepKey": {
      "type": "string",
      "description": "<slideKey>:<stepKey>, split at the last colon; step in canonical decimal 0-999 or concl",
      "pattern": "^.+:(0|[1-9][0-9]{0,2}|concl)$",
      "maxLength": 200
    },
    "archivePath": {
      "type": "string",
      "description": "Relative /-separated path. Further checks (reserved device names, case-folded collisions, file/directory prefix collisions, prototype keys, 10 segments, 1024 bytes) are normative in spec §3.3 and MUST be enforced by readers beyond schema validation.",
      "minLength": 1,
      "maxLength": 1024,
      "pattern": "^(?![/])(?!.*\\\\)(?!.*(^|/)\\.{1,2}(/|$))(?!.*//)(?!.*/$)(?!.*[\\u0000-\\u001f\\u007f-\\u009f<>:\"|?*]).+$"
    },
    "blob": {
      "type": "object",
      "required": [
        "mime",
        "bytes",
        "sha256",
        "chunks"
      ],
      "properties": {
        "mime": {
          "type": "string",
          "pattern": "^[a-z0-9.+-]+/[a-z0-9.+-]+$"
        },
        "bytes": {
          "type": "integer",
          "minimum": 0
        },
        "sha256": {
          "$ref": "#/$defs/sha256"
        },
        "chunks": {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string",
            "pattern": "^egatari-b-[A-Za-z0-9_]{1,32}-(0|[1-9][0-9]{0,3})$"
          }
        }
      }
    },
    "component": {
      "type": "object",
      "required": [
        "tag",
        "name",
        "version",
        "sha256",
        "source"
      ],
      "properties": {
        "tag": {
          "type": "string",
          "pattern": "^[a-z][a-z0-9]*-[a-z0-9-]+$"
        },
        "name": {
          "type": "string",
          "minLength": 1
        },
        "version": {
          "type": "string",
          "minLength": 1
        },
        "sha256": {
          "$ref": "#/$defs/sha256"
        },
        "source": {
          "enum": [
            "registry",
            "embedded"
          ]
        },
        "path": {
          "$ref": "#/$defs/archivePath"
        }
      },
      "if": {
        "properties": {
          "source": {
            "const": "embedded"
          }
        }
      },
      "then": {
        "required": [
          "path"
        ]
      }
    }
  }
}
