{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://franki.wiki/skill/franki-deck/franki-deck.schema.json",
  "title": "Franki deck",
  "description": "A flashcard deck for Franki, saved as a .franki file. See https://franki.wiki/skill.",
  "type": "object",
  "required": ["name", "cards"],
  "properties": {
    "format": { "const": "franki-deck" },
    "formatVersion": { "const": 1 },
    "id": { "type": "string", "format": "uuid", "description": "Names the deck across versions of the file; opening a revised file adds only its new cards." },
    "name": { "type": "string", "minLength": 1, "maxLength": 100 },
    "details": { "type": "string", "maxLength": 2000 },
    "symbol": { "type": "string", "description": "An SF Symbol name for the deck's icon." },
    "frontLanguage": { "type": "string", "maxLength": 35, "description": "BCP 47 code, such as en or zh-Hans." },
    "backLanguage": { "type": "string", "maxLength": 35, "description": "BCP 47 code, such as en or zh-Hans." },
    "cards": {
      "type": "array",
      "minItems": 1,
      "maxItems": 20000,
      "items": { "$ref": "#/$defs/card" }
    }
  },
  "$defs": {
    "choices": {
      "type": "array",
      "description": "Wrong answers for the quiz: the same kind of thing as the answer, in its language, about its length, plausible and clearly wrong. Three is best; up to six are kept.",
      "items": { "type": "string", "minLength": 1, "maxLength": 300 },
      "maxItems": 6,
      "uniqueItems": true
    },
    "card": {
      "type": "object",
      "required": ["front"],
      "properties": {
        "kind": { "enum": ["basic", "typeIn", "cloze"], "default": "basic" },
        "front": { "type": "string", "minLength": 1, "maxLength": 10000 },
        "back": { "type": "string", "maxLength": 10000 },
        "reverse": { "type": "boolean", "default": false },
        "choices": { "$ref": "#/$defs/choices" },
        "reverseChoices": { "$ref": "#/$defs/choices" },
        "tags": { "type": "array", "items": { "type": "string", "minLength": 1, "maxLength": 50 }, "maxItems": 20 }
      },
      "allOf": [
        {
          "if": { "properties": { "kind": { "const": "cloze" } }, "required": ["kind"] },
          "then": { "properties": { "front": { "pattern": "\\{\\{c[0-9]+::" }, "reverse": { "const": false } } },
          "else": { "required": ["back"], "properties": { "back": { "minLength": 1 } } }
        }
      ]
    }
  }
}
