{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://opengdd.org/schema/core/v0.7/direction.schema.json",
  "title": "OpenGDD v0.7 direction file",
  "type": "object",
  "additionalProperties": false,
  "minProperties": 1,
  "properties": {
    "palette": {
      "type": "object",
      "minProperties": 1,
      "propertyNames": { "$ref": "#/$defs/paletteKey" },
      "additionalProperties": {
        "type": "array",
        "minItems": 1,
        "items": { "$ref": "#/$defs/paletteEntry" }
      }
    },
    "pillars": { "$ref": "#/$defs/sentenceMap" },
    "mood": {
      "type": "object",
      "minProperties": 1,
      "propertyNames": { "$ref": "#/$defs/kebabId" },
      "additionalProperties": { "$ref": "#/$defs/moodEntry" }
    },
    "anti": {
      "type": "object",
      "minProperties": 1,
      "propertyNames": { "$ref": "#/$defs/kebabId" },
      "additionalProperties": { "$ref": "#/$defs/antiEntry" }
    },
    "must_keep": { "$ref": "#/$defs/sentenceMap" },
    "colors": {
      "type": "object",
      "minProperties": 1,
      "propertyNames": { "$ref": "#/$defs/kebabId" },
      "additionalProperties": { "$ref": "#/$defs/colorEntry" }
    },
    "contrast": {
      "type": "object",
      "minProperties": 1,
      "propertyNames": { "$ref": "#/$defs/kebabId" },
      "additionalProperties": { "$ref": "#/$defs/contrastEntry" }
    },
    "timing": {
      "type": "object",
      "minProperties": 1,
      "propertyNames": { "$ref": "#/$defs/kebabId" },
      "additionalProperties": { "$ref": "#/$defs/timingEntry" }
    },
    "viewing": { "$ref": "#/$defs/viewingEntry" }
  },
  "$defs": {
    "kebabId": {
      "type": "string",
      "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
    },
    "packagePath": {
      "type": "string",
      "minLength": 1
    },
    "paletteKey": {
      "type": "string",
      "pattern": "^(?!(?:json|md)(?:\\.|$))(?=[a-z0-9-]*[a-z])[a-z0-9]+(?:-[a-z0-9]+)*(?:\\.(?!(?:json|md)(?:\\.|$))(?=[a-z0-9-]*[a-z])[a-z0-9]+(?:-[a-z0-9]+)*)*$"
    },
    "paletteColorName": {
      "type": "string",
      "pattern": "^(?!(?:json|md)$)(?=[a-z0-9-]*[a-z])[a-z0-9]+(?:-[a-z0-9]+)*$"
    },
    "hexColor": {
      "type": "string",
      "pattern": "^#[0-9A-Fa-f]{6}$"
    },
    "paletteEntry": {
      "oneOf": [
        { "$ref": "#/$defs/hexColor" },
        {
          "type": "object",
          "minProperties": 1,
          "maxProperties": 1,
          "propertyNames": { "$ref": "#/$defs/paletteColorName" },
          "additionalProperties": { "$ref": "#/$defs/hexColor" }
        }
      ]
    },
    "sentenceMap": {
      "type": "object",
      "minProperties": 1,
      "propertyNames": { "$ref": "#/$defs/kebabId" },
      "additionalProperties": { "type": "string", "minLength": 1 }
    },
    "antiEntry": {
      "oneOf": [
        { "type": "string", "minLength": 1 },
        {
          "type": "object",
          "required": ["not"],
          "additionalProperties": false,
          "properties": {
            "not": { "type": "string", "minLength": 1 },
            "image": { "$ref": "#/$defs/packagePath" },
            "license": { "type": "string", "minLength": 1 }
          },
          "if": { "required": ["image"] },
          "then": { "required": ["license"] }
        }
      ]
    },
    "borrowEntry": {
      "type": "object",
      "required": ["from", "what"],
      "additionalProperties": false,
      "properties": {
        "from": { "type": "string", "minLength": 1 },
        "what": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } },
        "image": { "$ref": "#/$defs/packagePath" },
        "license": { "type": "string", "minLength": 1 }
      },
      "if": { "required": ["image"] },
      "then": { "required": ["license"] }
    },
    "moodEntry": {
      "type": "object",
      "required": ["intent", "anti"],
      "additionalProperties": false,
      "properties": {
        "intent": { "type": "string", "minLength": 1 },
        "anti": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/antiEntry" } },
        "borrows": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/borrowEntry" } },
        "palette": { "$ref": "#/$defs/paletteAddress" }
      }
    },
    "paletteColorAddress": {
      "type": "string",
      "pattern": "^palette\\.[a-z0-9]+(?:-[a-z0-9]+)*(?:\\.[a-z0-9]+(?:-[a-z0-9]+)*)+$"
    },
    "paletteAddress": {
      "type": "string",
      "pattern": "^palette\\.[a-z0-9]+(?:-[a-z0-9]+)*(?:\\.[a-z0-9]+(?:-[a-z0-9]+)*)*$"
    },
    "while": {
      "type": "array",
      "minItems": 1,
      "items": { "type": "string", "minLength": 1 }
    },
    "colorEntry": {
      "type": "object",
      "required": ["is", "within", "where"],
      "additionalProperties": false,
      "properties": {
        "is": { "$ref": "#/$defs/paletteColorAddress" },
        "within": { "type": "number", "minimum": 0 },
        "where": { "type": "string", "minLength": 1 },
        "while": { "$ref": "#/$defs/while" }
      }
    },
    "contrastEntry": {
      "type": "object",
      "required": ["colors", "against", "at_least", "where"],
      "additionalProperties": false,
      "properties": {
        "colors": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/paletteColorAddress" } },
        "against": { "$ref": "#/$defs/paletteColorAddress" },
        "at_least": { "type": "number", "exclusiveMinimum": 0 },
        "where": { "type": "string", "minLength": 1 },
        "while": { "$ref": "#/$defs/while" }
      }
    },
    "timingEntry": {
      "type": "object",
      "required": ["key", "where"],
      "additionalProperties": false,
      "properties": {
        "key": { "type": "string", "pattern": "^[A-Za-z0-9_](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?(?:\\.[A-Za-z0-9_](?:[A-Za-z0-9_-]*[A-Za-z0-9_])?)+$" },
        "where": { "type": "string", "minLength": 1 },
        "while": { "$ref": "#/$defs/while" }
      }
    },
    "viewingEntry": {
      "type": "object",
      "required": ["speed_and_size", "calibration"],
      "additionalProperties": false,
      "properties": {
        "speed_and_size": { "type": "string", "minLength": 1 },
        "calibration": { "type": "string", "minLength": 1 },
        "sequence": { "type": "string", "minLength": 1 }
      }
    }
  }
}
