{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "title": "The Keymap definition",
  "required": [
    "keys",
    "parameters",
    "layers",
    "chord_sets",
    "pseudolayers",
    "leader_sequences",
    "extra_code",
    "extra_dependencies"
  ],
  "properties": {
    "keys": {
      "type": "array",
      "title": "The Internal Keycodes",
      "description": "Name Keycodes for the Chording Engine. These can be any string except already valid QMK keycodes.",
      "items": {
        "type": "string",
        "title": "Individual Keycode",
        "examples": [
          "L1",
          "R1",
          "TOP1",
          "THUMB_3",
          "Bottom_6"
        ]
      }
    },
    "parameters": {
      "type": "object",
      "title": "Keyboard Parameters",
      "description": "Keyboard, user and layout specific parameters like timers, max length for buffers and default pseudolayer.",
      "required": [
        "layout_function_name",
        "chord_timeout",
        "dance_timeout",
        "leader_timeout",
        "tap_timeout",
        "command_max_length",
        "leader_max_length",
        "dynamic_macro_max_length",
        "string_max_length",
        "long_press_multiplier",
        "default_pseudolayer"
      ],
      "properties": {
        "layout_function_name": {
          "type": "string",
          "examples": [
            "LAYOUT_ginny",
            ""
          ]
        },
        "chord_timeout": {
          "type": "integer",
          "title": "The Chord Timeout",
          "description": "The time in ms you have to press additional keys before the engine assumes you finished pressing keys that are part of a chord.",
          "default": 100
        },
        "dance_timeout": {
          "type": "integer",
          "title": "The Dance Timeout",
          "description": "The time in ms you have to repeatedly activate a chord before the engine assumes you finished a dance.",
          "default": 200
        },
        "leader_timeout": {
          "type": "integer",
          "title": "The Leader Timeout",
          "description": "The time in ms you have to activate additional chords before the engine assumes you finished adding chords to a leader sequence.",
          "default": 750
        },
        "tap_timeout": {
          "type": "integer",
          "title": "The Tap Timeout",
          "description": "The time in ms you have to finish pressing a chord before the engine assumes that you didn't just tap it but are holding it down.",
          "default": 50
        },
        "command_max_length": {
          "type": "integer",
          "title": "Command Max Length",
          "description": "The maximum length for chords buffered in command mode.",
          "default": 5
        },
        "leader_max_length": {
          "type": "integer",
          "title": "Leader Max Length",
          "description": "The maximum length of leader sequences you can define in your keymap",
          "default": 5
        },
        "dynamic_macro_max_length": {
          "type": "integer",
          "title": "Dynamic Macro Max Length",
          "description": "The maximum number of chords (including Dynamic Macro Next) you can record to a Dynamic Macro",
          "default": 20
        },
        "string_max_length": {
          "type": "integer",
          "title": "String Max Length",
          "description": "The maximum length of a string that the STR() chord can accept.",
          "default": 16
        },
        "long_press_multiplier": {
          "type": "integer",
          "title": "Long Press Multiplier",
          "description": "How many times does the chord timer have expire before a chord is registered as not only held but in a long press (for example for Autoshift). Has to be integer.",
          "default": 3
        },
        "default_pseudolayer": {
          "type": "string",
          "title": "Default Pseudolayer",
          "description": "Which pseudolayer should be active when the keyboard starts / restarts.",
          "examples": [
            "BASE",
            "QWERTY"
          ]
        }
      }
    },
    "layers": {
      "type": "array",
      "title": "QMK Layers",
      "description": "The layers QMK needs to know about. Can contain chording engine's internal keycodes or QMK's keycodes. Do not define chords here, those belong in pseudolayers.",
      "minItems": 1,
      "uniqueItems": false,
      "items": {
        "type": "object",
        "title": "Individual Layers",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "title": "Type of Individual Layers",
            "description": "Auto layer fills all keycodes to be chording engine's internal keycodes, manual let's you place internal and QMK's keycodes however you wish.",
            "examples": [
              "auto",
              "manual"
            ]
          },
          "keycodes": {
            "type": "array",
            "title": "Individual Chord",
            "description": "A list of of keys that need to be pressed to activate this chord",
            "items": {
              "type": "string",
              "title": "Individual Keycodes",
              "description": "A keycode that is a part of the individual chord. Has to be an internal keycode."
            }
          }
        }
      }
    },
    "chord_sets": {
      "type": "array",
      "title": "Chord Sets Definitions",
      "description": "Describes predefined sets of chords to ease defining a number of chords in a pseudolayer.",
      "items": {
        "type": "object",
        "required": [
          "name",
          "chords"
        ],
        "properties": {
          "name": {
            "type": "string",
            "title": "Name of the Set",
            "examples": [
              "rows",
              "asetniop"
            ]
          },
          "chords": {
            "type": "array",
            "title": "Chords",
            "description": "List of all chords in this set",
            "minItems": 1,
            "uniqueItems": true,
            "items": {
              "type": "array",
              "title": "Individual Chord",
              "description": "A list of of keys that need to be pressed to activate this chord",
              "items": {
                "type": "string",
                "title": "Individual Keycodes",
                "description": "A keycode that is a part of the individual chord. Has to be an internal keycode."
              }
            }
          }
        }
      }
    },
    "pseudolayers": {
      "type": "array",
      "title": "Pseudolayers",
      "description": "The pseudolayers holding the chords to be processed by the chording engine.",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "title": "Name of the Pseudolayer",
            "default": null,
            "examples": [
              "ALWAYS_ON",
              "QWERTY"
            ]
          },
          "chords": {
            "type": "array",
            "title": "Chords",
            "description": "List of chords belonging on the pseudolayer.",
            "items": {
              "type": "object",
              "required": [
                "type"
              ],
              "properties": {
                "type": {
                  "type": "string",
                  "title": "Type of the chord array",
                  "description": "Defines how this objects describes one or more chords.",
                  "examples": [
                    "visual_array",
                    "visual",
                    "simple",
                    "chord_set"
                  ]
                },
                "keys": {
                  "type": "array",
                  "title": "Subset of keys",
                  "description": "Subset of internal keycodes that will be used when defining the chords. For visual_array type only.",
                  "examples": [
                    "[\"L1\", \"L2\", \"L3\", \"L4\", \"R1\", \"R2\", \"R3\", \"R4\"]"
                  ],
                  "items": {
                    "type": "string"
                  }
                },
                "dictionary": {
                  "type": "array",
                  "title": "Dictionary",
                  "description": "A table. Each row defines in a visual way which keys have to be pressed and what is the desired outcome. For visual_array type only.",
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "examples": [
                        "[\"X"\, \" "\, \" "\, \"X"\, \"X"\, \" "\, \" "\, \"X"\, \"MO(BASE, NUM)\"]
                      ]
                    }
                  }
                },
                "keycode": {
                  "type": "string",
                  "title": "Keycode",
                  "description": "A keycode to be assigned to the chord when it is registered. For simple and visual types only."
                },
                "set": {
                  "type": "string",
                  "title": "Chord set",
                  "description": "Name of the chord set to be used. Has to be one already defined in the chord_sets array. For chord_set type only."
                },
                "keycodes": {
                  "type": "array",
                  "title": "Keycodes",
                  "description": "List of keycodes to be assigned to each chord when it is registered. For set type only.",
                  "items": {
                    "type": "string"
                  }
                },
                "chord": {
                  "type": "array",
                  "title": "Chord",
                  "description": "Array of \"X\"'s and \" \"'s that shows which keys have to be pressed to activate the chord. For visual type only ",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "leader_sequences": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "examples": ["fn_L1"]
          },
          "function": {
            "type": "string",
            "description": "C code the sequence should run. Instead of here, can be defined in extra_dependencies or extra_code",
            "examples": ["void fn_L1(void) { SEND(KC_LCTL); SEND(KC_LALT); SEND(KC_DEL); }"]
          },
          "sequence": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "examples": [["KC_Q", "KC_Z"]]
          }
        }
      }
    },
    "extra_code": {
      "type": "string",
      "label": "Extra Code",
      "description": "C code to be inserted into the generated keymap",
      "examples": ["void fn_L1(void) {\n    SEND(KC_LCTL);\n    SEND(KC_LALT);\n    SEND(KC_DEL);\n}\n"],
      "default": ""
    },
    "extra_dependencies": {
      "type": "array",
      "label": "Extra Dependencies",
      "description": "List of files to be #include'd in the generated keymap",
      "examples": [
        "[\"user_functions.c\"]"
      ],
      "default": ""
    }
  }
}