{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://pen-und-paper.local/kampagne.schema.json",
  "title": "Kapitel der Kampagne",
  "description": "Eine Datei je Kapitel unter Kampagne/. Die Datei enthält \"window.KAPITEL = \" gefolgt von genau diesem JSON und einem Semikolon; wer diese beiden Stücke abschneidet, hat reines JSON.",
  "$defs": {
    "baustein": {
      "oneOf": [
        {
          "title": "absatz",
          "description": "Ein Absatz Fließtext.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "text"
          ],
          "properties": {
            "typ": {
              "const": "absatz"
            },
            "text": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            }
          }
        },
        {
          "title": "beat",
          "description": "Ein Spielbeat: nummerierter Kasten mit eigenem Lesezeichen.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "inhalt"
          ],
          "properties": {
            "typ": {
              "const": "beat"
            },
            "inhalt": {
              "$ref": "#/$defs/bausteine"
            },
            "nr": {
              "type": "string"
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "marke": {
              "enum": [
                "▣",
                "▢",
                "✎"
              ],
              "description": "▣ feststehend · ✎ ergänzt, änderbar · ▢ noch offen"
            }
          }
        },
        {
          "title": "bild",
          "description": "Ein Bild oder eine Galerie. \"lz\" ist die Beschriftung im Lesezeichenbaum.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "bilder"
          ],
          "properties": {
            "typ": {
              "const": "bild"
            },
            "bilder": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "datei"
                ],
                "properties": {
                  "datei": {
                    "type": "string"
                  },
                  "bu": {
                    "type": "string"
                  }
                }
              }
            },
            "stil": {
              "enum": [
                "einzel",
                "galerie",
                "karte"
              ]
            },
            "lz": {
              "type": "string"
            }
          }
        },
        {
          "title": "code",
          "description": "Vorformatierter Text.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "text"
          ],
          "properties": {
            "typ": {
              "const": "code"
            },
            "text": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            }
          }
        },
        {
          "title": "gefahr",
          "description": "Kasten: wo es kippen kann.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ"
          ],
          "properties": {
            "typ": {
              "const": "gefahr"
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "marke": {
              "enum": [
                "▣",
                "▢",
                "✎"
              ],
              "description": "▣ feststehend · ✎ ergänzt, änderbar · ▢ noch offen"
            },
            "inhalt": {
              "$ref": "#/$defs/bausteine"
            }
          },
          "anyOf": [
            {
              "required": [
                "titel"
              ]
            },
            {
              "required": [
                "inhalt"
              ]
            }
          ]
        },
        {
          "title": "gegner",
          "description": "Wer in dieser Szene auftritt. \"ziel\" verweist ins Wörterbuch; Name und Gefahrstufe kommen von dort.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "zeilen"
          ],
          "properties": {
            "typ": {
              "const": "gegner"
            },
            "zeilen": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "ziel",
                  "anzahl"
                ],
                "properties": {
                  "ziel": {
                    "type": "string",
                    "pattern": "^(person|kreatur)/[a-z0-9-]+$",
                    "description": "Schlüssel in verweise.js → ziele"
                  },
                  "variante": {
                    "type": "string",
                    "description": "id einer Variante aus ziele[…].varianten, z. B. \"eis\""
                  },
                  "zusatz": {
                    "type": "string",
                    "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                  },
                  "marke": {
                    "enum": [
                      "▣",
                      "▢",
                      "✎"
                    ]
                  },
                  "anzahl": {
                    "type": "string",
                    "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                  },
                  "hinweis": {
                    "type": "string",
                    "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                  }
                }
              }
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            }
          }
        },
        {
          "title": "liste",
          "description": "Aufzählung; \"geordnet\": true nummeriert sie.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "punkte"
          ],
          "properties": {
            "typ": {
              "const": "liste"
            },
            "punkte": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
              }
            },
            "geordnet": {
              "type": "boolean"
            }
          }
        },
        {
          "title": "merksatz",
          "description": "Kasten: Rastpunkt oder Merksatz.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ"
          ],
          "properties": {
            "typ": {
              "const": "merksatz"
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "marke": {
              "enum": [
                "▣",
                "▢",
                "✎"
              ],
              "description": "▣ feststehend · ✎ ergänzt, änderbar · ▢ noch offen"
            },
            "inhalt": {
              "$ref": "#/$defs/bausteine"
            }
          },
          "anyOf": [
            {
              "required": [
                "titel"
              ]
            },
            {
              "required": [
                "inhalt"
              ]
            }
          ]
        },
        {
          "title": "nsc",
          "description": "Kasten zu einer Person.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ"
          ],
          "properties": {
            "typ": {
              "const": "nsc"
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "marke": {
              "enum": [
                "▣",
                "▢",
                "✎"
              ],
              "description": "▣ feststehend · ✎ ergänzt, änderbar · ▢ noch offen"
            },
            "inhalt": {
              "$ref": "#/$defs/bausteine"
            }
          },
          "anyOf": [
            {
              "required": [
                "titel"
              ]
            },
            {
              "required": [
                "inhalt"
              ]
            }
          ]
        },
        {
          "title": "probe",
          "description": "Ein Wurf mit vier festen Ausgängen.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "fertigkeit",
            "ergebnisse"
          ],
          "properties": {
            "typ": {
              "const": "probe"
            },
            "fertigkeit": {
              "type": "string"
            },
            "ergebnisse": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "array",
                "minItems": 2,
                "maxItems": 2,
                "prefixItems": [
                  {
                    "enum": [
                      "kritisch",
                      "erfolg",
                      "misserfolg",
                      "patzer"
                    ]
                  },
                  {
                    "type": "string",
                    "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                  }
                ]
              }
            },
            "spalte": {
              "type": "string"
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            }
          }
        },
        {
          "title": "regel",
          "description": "Regelkasten.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ"
          ],
          "properties": {
            "typ": {
              "const": "regel"
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "marke": {
              "enum": [
                "▣",
                "▢",
                "✎"
              ],
              "description": "▣ feststehend · ✎ ergänzt, änderbar · ▢ noch offen"
            },
            "inhalt": {
              "$ref": "#/$defs/bausteine"
            }
          },
          "anyOf": [
            {
              "required": [
                "titel"
              ]
            },
            {
              "required": [
                "inhalt"
              ]
            }
          ]
        },
        {
          "title": "sl",
          "description": "Kasten für die Spielleitung.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ"
          ],
          "properties": {
            "typ": {
              "const": "sl"
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "marke": {
              "enum": [
                "▣",
                "▢",
                "✎"
              ],
              "description": "▣ feststehend · ✎ ergänzt, änderbar · ▢ noch offen"
            },
            "inhalt": {
              "$ref": "#/$defs/bausteine"
            }
          },
          "anyOf": [
            {
              "required": [
                "titel"
              ]
            },
            {
              "required": [
                "inhalt"
              ]
            }
          ]
        },
        {
          "title": "tabelle",
          "description": "Freie Tabelle. \"kopf\" ist die Kopfzeile, \"zeilen\" der Rumpf.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "kopf",
            "zeilen"
          ],
          "properties": {
            "typ": {
              "const": "tabelle"
            },
            "kopf": {
              "type": "array",
              "items": {
                "type": "string",
                "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
              },
              "minItems": 1
            },
            "zeilen": {
              "type": "array",
              "items": {
                "type": "array",
                "items": {
                  "type": "string",
                  "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                }
              }
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            }
          }
        },
        {
          "title": "uebersicht",
          "description": "Die Schritte oder Szenen daneben, mit Verweis auf jeden Eintrag.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "was",
            "zeilen"
          ],
          "properties": {
            "typ": {
              "const": "uebersicht"
            },
            "was": {
              "type": "string"
            },
            "zeilen": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "titel"
                ],
                "properties": {
                  "nr": {
                    "type": "string"
                  },
                  "titel": {
                    "type": "string",
                    "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                  },
                  "ziel": {
                    "type": "string",
                    "description": "\"#lesezeichen\" in dieser Datei, oder ein Dateipfad"
                  },
                  "marke": {
                    "enum": [
                      "▣",
                      "▢",
                      "✎"
                    ]
                  },
                  "felder": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                    }
                  }
                }
              }
            },
            "spalten": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            }
          }
        },
        {
          "title": "vorlesen",
          "description": "Vorlesetext.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ"
          ],
          "properties": {
            "typ": {
              "const": "vorlesen"
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "marke": {
              "enum": [
                "▣",
                "▢",
                "✎"
              ],
              "description": "▣ feststehend · ✎ ergänzt, änderbar · ▢ noch offen"
            },
            "inhalt": {
              "$ref": "#/$defs/bausteine"
            }
          },
          "anyOf": [
            {
              "required": [
                "titel"
              ]
            },
            {
              "required": [
                "inhalt"
              ]
            }
          ]
        },
        {
          "title": "wahl",
          "description": "Eine Verzweigung: eine Frage, mehrere Fälle.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "optionen"
          ],
          "properties": {
            "typ": {
              "const": "wahl"
            },
            "optionen": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "marke": {
                    "type": "string"
                  },
                  "titel": {
                    "type": "string",
                    "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                  },
                  "text": {
                    "type": "string",
                    "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                  },
                  "felder": {
                    "type": "array",
                    "items": {
                      "type": "array",
                      "minItems": 2,
                      "maxItems": 2,
                      "items": {
                        "type": "string",
                        "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                      }
                    }
                  },
                  "inhalt": {
                    "$ref": "#/$defs/bausteine"
                  }
                }
              }
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "frage": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "einleitung": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "marke": {
              "enum": [
                "▣",
                "▢",
                "✎"
              ],
              "description": "▣ feststehend · ✎ ergänzt, änderbar · ▢ noch offen"
            }
          }
        },
        {
          "title": "wuerfeltabelle",
          "description": "Zufallstabelle zu einem Würfel.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ",
            "wuerfel",
            "zeilen"
          ],
          "properties": {
            "typ": {
              "const": "wuerfeltabelle"
            },
            "wuerfel": {
              "type": "string",
              "pattern": "^W[0-9]+$"
            },
            "zeilen": {
              "type": "array",
              "minItems": 1,
              "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "wurf",
                  "text"
                ],
                "properties": {
                  "wurf": {
                    "type": "string"
                  },
                  "text": {
                    "type": "string",
                    "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
                  }
                }
              }
            },
            "spalte": {
              "type": "string"
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            }
          }
        },
        {
          "title": "zitat",
          "description": "Wie vorlesen, aber mit Überschrift.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "typ"
          ],
          "properties": {
            "typ": {
              "const": "zitat"
            },
            "titel": {
              "type": "string",
              "description": "Text in der Schreibweise des Hefts: **fett**, *kursiv*, `code`, [Text](ziel), und die Marken ▣ ▢ ✎. Namen aus verweise.js werden beim Anzeigen automatisch verlinkt."
            },
            "marke": {
              "enum": [
                "▣",
                "▢",
                "✎"
              ],
              "description": "▣ feststehend · ✎ ergänzt, änderbar · ▢ noch offen"
            },
            "inhalt": {
              "$ref": "#/$defs/bausteine"
            }
          },
          "anyOf": [
            {
              "required": [
                "titel"
              ]
            },
            {
              "required": [
                "inhalt"
              ]
            }
          ]
        }
      ]
    },
    "bausteine": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/baustein"
      }
    },
    "abschnitt": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "titel"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "titel": {
          "type": "string"
        },
        "bausteine": {
          "$ref": "#/$defs/bausteine"
        },
        "teile": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/abschnitt"
          }
        },
        "stufe": {
          "type": "integer",
          "minimum": 2,
          "maximum": 5
        }
      }
    },
    "szene": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "art",
        "id",
        "titel"
      ],
      "properties": {
        "art": {
          "enum": [
            "szene",
            "teil"
          ]
        },
        "id": {
          "type": "string"
        },
        "titel": {
          "type": "string"
        },
        "bausteine": {
          "$ref": "#/$defs/bausteine"
        },
        "teile": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/abschnitt"
          }
        },
        "nr": {
          "type": "string"
        },
        "dauer": {
          "type": "string"
        },
        "marke": {
          "type": "string",
          "pattern": "^[▣▢✎]( [▣▢✎])*$",
          "description": "eine oder mehrere Marken, durch Leerzeichen getrennt"
        },
        "szenen": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/szene"
          }
        }
      }
    }
  },
  "type": "object",
  "additionalProperties": false,
  "required": [
    "datei",
    "eyebrow",
    "titel",
    "sub",
    "vorspann",
    "szenen"
  ],
  "properties": {
    "datei": {
      "type": "string"
    },
    "eyebrow": {
      "type": "string"
    },
    "titel": {
      "type": "string"
    },
    "sub": {
      "type": "string"
    },
    "vorspann": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "bausteine": {
          "$ref": "#/$defs/bausteine"
        },
        "teile": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/abschnitt"
          }
        }
      }
    },
    "szenen": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/szene"
      }
    }
  }
}
