summaryrefslogtreecommitdiffhomepage
path: root/shared.764f9fe054eaa120c46e.js.map
blob: 90a401b8630f4d5f40974ded76152a7521284ba6 (plain)
1
{"version":3,"file":"shared.764f9fe054eaa120c46e.js","mappings":"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","sources":["webpack:///../api/packages/devicetree/index.js","webpack:///../api/packages/devicetree/lib/formatters.js","webpack:///../api/packages/devicetree/lib/helpers/index.js","webpack:///../api/packages/devicetree/lib/helpers/nodes.js","webpack:///../api/packages/devicetree/lib/helpers/properties.js","webpack:///../api/packages/devicetree/lib/helpers/trees.js","webpack:///../api/packages/devicetree/lib/helpers/values.js","webpack:///../api/packages/devicetree/lib/node-collection.js","webpack:///../api/packages/devicetree/lib/parser.js","webpack:///../api/packages/keymap-editor-zmk-backend/lib/apply-keymap-changes.js","webpack:///../api/packages/keymap-editor-zmk-backend/lib/devicetree/bindings.js","webpack:///../api/packages/keymap-editor-zmk-backend/lib/devicetree/collections/behaviors.js","webpack:///../api/packages/keymap-editor-zmk-backend/lib/devicetree/collections/combos.js","webpack:///../api/packages/keymap-editor-zmk-backend/lib/devicetree/collections/layers.js","webpack:///../api/packages/keymap-editor-zmk-backend/lib/devicetree/collections/macros.js","webpack:///../api/packages/keymap-editor-zmk-backend/lib/devicetree/keymap-document.js","webpack:///../api/packages/keymap-editor-zmk-backend/lib/devicetree/sanity-checks.js","webpack:///../api/packages/keymap-editor-zmk-backend/lib/extract-keymap-data.js","webpack:///../api/packages/keymap-editor-zmk-backend/lib/keymap.js","webpack:///../api/packages/keymap-layout-tools/lib/render.js","webpack:///../api/packages/string-utils/index.js","webpack:///../api/packages/zmk-data/behaviors.js","webpack:///../api/packages/zmk-data/keycode-mappings.js","webpack:///../api/packages/zmk-data/keycodes.js","webpack:///../api/packages/zmk-data/parameters.js"],"sourcesContent":["module.exports = require('./lib/parser')\n","const {\n  removeStartingWhitespace,\n  removeTrailingWhitespace,\n  reindent,\n  dedent\n} = require('string-utils')\nconst { getLabeledItem, getNodeLabels } = require('./helpers/nodes')\n\nconst DEFAULT_INDENT = '    '\nconst DEFAULT_MULTILINE_INTEGER_CELLS_INDENT = 'keep'\n\nfunction isMultilineNode (node) {\n  return node.text.indexOf('\\n') !== -1\n}\n\nfunction isMultilinePropertyNode (node) {\n  return node?.type === 'property' && (\n    node.namedChildren.length > 2 ||\n    node.namedChildren.slice(1).some(isMultilineNode)\n  )\n}\n\nfunction isInlineComment (node) {\n  return (\n    node.type === 'comment' &&\n    node.previousSibling &&\n    // Nodes for pre-processor directives include trailing newline characters.\n    // For simplicity, a preproc cannot have an inline comment.\n    node.previousSibling.type !== 'preproc_def' &&\n    node.previousSibling.type !== 'preproc_function_def' &&\n    node.previousSibling.type !== 'preproc_include' &&\n    node.previousSibling.endPosition.row === node.startPosition.row\n  )\n}\n\nfunction getNodeIndentation (node, tab) {\n  return tab.repeat(getNodeDepth(node))\n}\n\nfunction getModelineConfiguration (tree) {\n  return tree.rootNode.namedChildren.reduce((config, node) => {\n    if (node.type === 'comment') {\n      const contents = node.text.startsWith('//')\n        ? node.text.slice(2).trim()\n        : node.text.slice(2, -2).trim()\n\n      for (const line of contents.split('\\n')) {\n        const match = line.match(/dt-formatter:\\s*(\\w+)\\s*=\\s*(.+)$/)\n        if (match) {\n          const [key, jsonValue] = match.slice(1)\n          try {\n            const value = JSON.parse(jsonValue)\n            config[key] = value\n          } catch {}\n        }\n      }\n    }\n\n    return config\n  }, {})\n}\n\n/**\n * Determine the depth of the node in the device tree\n *\n * A depth of 0 is anything at the document level -- this includes the \"/\" node\n *\n * @param {SyntaxNode} node any kind of syntax node\n * @returns {Integer} depth\n */\nfunction getNodeDepth (node) {\n  let n = node\n  let depth = 0\n  const stop = node.tree.rootNode\n\n  while ((n = n.parent) && n && n.id !== stop.id) {\n    if (n.type !== 'labeled_item') {\n      depth++\n    }\n  }\n\n  return depth\n}\n\nfunction shouldIncludeBlank (nodeA, nodeB) {\n  if (!nodeB) {\n    return false\n  }\n\n  const sameType = nodeA.type === nodeB.type\n  const isAdjacentDeviceTreeNode = sameType && nodeA.type === 'node'\n\n  // TODO: this should probably just not insert whitespace around comments\n  return (\n    isAdjacentDeviceTreeNode ||\n    isMultilinePropertyNode(nodeA) ||\n    (!sameType && !isInlineComment(nodeB))\n  )\n}\n\n/**\n * Apply formatting (indentation and whitespace) to a node and its descendents\n *\n * Indentation is based on the node's depth in the full tree (not just relative\n * to the supplied `node` parameter) and currently limited to 4-space tabs.\n *\n * The existing formatting of `integer_cells` nodes (ie, `bindings = <...>;`) is\n * considered sacred and 0 levels of indentation will be applied to those lines.\n * @param {SyntaxNode} node any node in the devicetree\n * @returns {String} the newly-formatted text for the syntax node\n */\nfunction formatNode (node, options = {}) {\n  const { indent = DEFAULT_INDENT } = options\n\n  if (node.type === 'labeled_item') {\n    node = getLabeledItem(node)\n  }\n\n  const [identifier, ...children] = node.namedChildren\n  const indentation = getNodeIndentation(node, indent)\n\n  function formatChildren (children) {\n    return children.reduce((lines, childNode, i, arr) => {\n      // Merge inline comments onto the previous node's line.\n      // This feels a bit hacky but it must be performed on the \"unformatted\"\n      // comment syntax node (this check is also happening when the previous\n      // node is being formatted and the extra blank line is being considered).\n      if (isInlineComment(childNode)) {\n        lines[lines.length - 1] += childNode.text\n        return lines\n      }\n      lines.push(...formatNode(childNode, options))\n\n      if (shouldIncludeBlank(childNode, children[i + 1])) {\n        lines.push('')\n      }\n\n      return lines\n    }, [])\n  }\n\n  switch (node.type) {\n    case 'document':\n      return [...formatChildren(node.namedChildren), '']\n\n    case 'node':\n      return [\n        indentation + `${formatLabels(getNodeLabels(node))}${identifier.text}${getAddress(node)} {`,\n        ...formatChildren(hasAddress(node) ? node.namedChildren.slice(2) : children),\n        indentation + '};'\n      ]\n\n    case 'property':\n      return formatPropertyNode(node, options)\n\n    case 'preproc_include':\n    case 'preproc_def':\n    case 'preproc_function_def':\n      return [node.text.trimEnd()]\n\n    default:\n      // this is mainly for things I didn't expect to see, but also includes\n      // commonly used features like preproc_includes that technically work when\n      // used inside nodes but aren't recognized by the grammar at the moment.\n      // See: https://github.com/joelspadin/tree-sitter-devicetree/issues/1\n      return [indentation + node.text]\n  }\n}\n\nfunction hasAddress (node) {\n  return !!node.childForFieldName('address')\n}\n\nfunction getAddress (node) {\n  return hasAddress(node)\n    // note address field doesn't give the actual value yet\n    ? `@${node.namedChildren[1].text}`\n    : ''\n}\n\nfunction formatLabels (labels) {\n  return labels.map(text => `${text}: `).join('')\n}\n\nfunction formatPropertyNode (node, options = {}) {\n  const {\n    indent = DEFAULT_INDENT,\n    multilineIntegerCellsIndent = DEFAULT_MULTILINE_INTEGER_CELLS_INDENT\n  } = options\n\n  const [identifier, ...children] = node.namedChildren\n  const indentation = getNodeIndentation(node, indent)\n\n  const noValue = children.length === 0\n  const simpleValue = children.length === 1 && !isMultilineNode(children[0])\n  const singleIntegerCell = children.length === 1 && children[0].type === 'integer_cells'\n  const labels = formatLabels(getNodeLabels(node))\n\n  // TODO: get smarter about different property value types\n  if (noValue) return [indentation + node.text]\n\n  if (simpleValue) {\n    return [indentation + `${labels}${identifier.text} = ${children[0].text};`]\n  } else if (singleIntegerCell) {\n    let bindingsLines = removeStartingWhitespace(\n      removeTrailingWhitespace(\n        children[0].text.slice(1, -2)\n      )\n    )\n\n    switch (multilineIntegerCellsIndent) {\n      case 'reindent':\n        bindingsLines = reindent(bindingsLines, indentation + indent)\n        break\n\n      case 'dedent':\n        bindingsLines = dedent(bindingsLines)\n        break\n\n      case 'keep':\n      default:\n        break\n    }\n\n    return [\n      indentation + `${labels}${identifier.text} = <`,\n      ...bindingsLines.split('\\n'),\n      indentation + '>;'\n    ]\n  }\n\n  return [\n    indentation + `${identifier.text} =`,\n    ...[].concat(...children.map(node => formatNode(node, options)))\n      .map((line, i, arr) => {\n        const suffix = i === arr.length - 1 ? ';' : ','\n        return [line, suffix].join('')\n      })\n  ]\n}\n\nmodule.exports = {\n  formatNode,\n  getModelineConfiguration,\n  getNodeDepth,\n  isInlineComment,\n  shouldIncludeBlank\n}\n","module.exports = Object.assign(\n  {},\n  require('./nodes'),\n  require('./properties'),\n  require('./trees'),\n  require('./values')\n)\n","const assert = require('assert')\nconst reverse = require('lodash/reverse')\n\n/**\n * Check if an ordered list of nodes are consecutive\n * Nodes are consecutive if each node is adjacent to the next, so that no other\n * sibling nodes exist between them.\n * @param {Array<SyntaxNode>} nodes\n * @returns {Boolean}\n */\nfunction nodesAreConsecutive (nodes) {\n  return nodes.every((node, i) => (\n    i < nodes.length - 1\n      ? node.nextSibling.id === nodes[i + 1].id\n      : true\n  ))\n}\n\n/**\n * Get the string value of each reference label attached to the given node.\n * Labels are in in descending order of depth.\n * @param {SyntaxNode} node\n * @returns {Array<String>}\n */\nfunction getNodeLabels (node) {\n  return getNodeLabelNodes(node).map(label => label.text)\n}\n\n// blech\nfunction getNodeLabelNodes (node) {\n  return getNodeChildrenByFieldName(node.parent, 'label')\n}\n\n/**\n * Descend into a chain of labeled_item nodes to get at the actual item\n * @param {SyntaxNode} labeledItemNode syntax node for a devicetree label\n * @returns {SyntaxNode}\n */\nfunction getLabeledItem (labeledItemNode) {\n  assert(labeledItemNode.type === 'labeled_item')\n  return labeledItemNode.childForFieldName('item')\n}\n\nfunction getNodeChildrenByFieldName (node, fieldName) {\n  const children = []\n\n  // Iteration is done with a cursor here because only TreeCursor will directly\n  // tell us what field is associated with the current node. The node itself\n  // will not tell us about its own field, and Node.childForFieldName(field)\n  // will only tell us about a single child with the specified field.\n  const cursor = node.walk()\n  cursor.gotoFirstChild()\n\n  do {\n    const isNamed = cursor.currentNode().isNamed()\n    const isField = cursor.currentFieldName() === fieldName\n    if (isNamed && isField) {\n      children.push(cursor.currentNode())\n    }\n  } while (cursor.gotoNextSibling())\n\n  cursor.delete()\n\n  return children\n}\n\n/**\n * Find a single child of the given node with a matching identifier\n * @param {SyntaxNode} node\n * @param {Function|String} nameOrMatch\n * @returns {SyntaxNode}\n */\nfunction findChildrenByIdentifier (node, nameOrMatch) {\n  const match = typeof nameOrMatch === 'string'\n    ? text => text === nameOrMatch\n    : nameOrMatch\n\n  return node.namedChildren.filter(node => (\n    node.type === 'node' &&\n    node.children.find(sub => (\n      sub.type === 'identifier' &&\n      match(sub.text)\n    ))\n  ))\n}\n\n/**\n * Find a child of the given node(s) with a matching name.\n * If multiple nodes are given to search through, they will be searched in\n * reverse order so that the \"latest\" instance of a node takes precedence.\n * @param {Array<SyntaxNode>|SyntaxNode} nodes\n * @param {RegExp|String} nameOrMatch\n */\nfunction findChildByIdentifier (nodes, nameOrMatch) {\n  nodes = [].concat(nodes)\n  for (const node of reverse(nodes)) {\n    const match = findChildrenByIdentifier(node, nameOrMatch)[0]\n    if (match) {\n      return match\n    }\n  }\n}\n\nfunction listNodes (nodes, opts = {}) {\n  const { stripNewlines = true, limit = 50 } = opts\n  for (const node of nodes) {\n    let value = node.text\n    if (stripNewlines) value = value.replace(/\\n/g, '')\n    if (limit) value = value.slice(0, limit)\n\n    console.log(node.id, `[${node.type}]`, '->', value)\n  }\n}\n\nmodule.exports = {\n  nodesAreConsecutive,\n  getNodeLabels,\n  getNodeLabelNodes,\n  getLabeledItem,\n  getNodeChildrenByFieldName,\n  findChildByIdentifier,\n  findChildrenByIdentifier,\n  listNodes\n}\n","const { getNodeChildrenByFieldName } = require('./nodes')\nconst {\n  parseStringLiteral,\n  parseIntegerCells,\n  parseIntegerArray,\n  parsePhandles,\n  parsePhandle,\n  parsePhandleArray,\n  parseIntegerUnion,\n  serializeIntValue,\n  serializeArrayValue\n} = require('./values')\n\n/** @typedef {{ parsed: any, raw: string, useRaw?: boolean }} PropertyValue */\n/** @typedef {Object.<string, PropertyValue>} Properties */\n\n/**\n * Get a property with the given name in this node, if it exists.\n * @param {SyntaxNode} node\n * @param {String} propertyName\n * @returns {SyntaxNode|undefined}\n */\nfunction findNodeProperty (node, propertyName) {\n  return node.children.find(node => (\n    node.type === 'property' &&\n    node.children[0].text === propertyName\n  ))\n}\n\nfunction getPropertyNode (node, propertyName) {\n  return node.namedChildren.find(child => (\n    child.type === 'property' &&\n    child.childForFieldName('name')?.text === propertyName\n  ))\n}\n\nfunction getProperty (node, property) {\n  const propertyNode = node.children.find(node => (\n    node.type === 'property' &&\n    node.children[0].text === property\n  ))\n\n  return propertyNode && {\n    syntaxNode: propertyNode,\n    name: property,\n    value: propertyNode.children[2]?.text\n  }\n}\n\nfunction getPropertyValue (node, property) {\n  property = typeof property === 'string'\n    ? getPropertyNode(node, property)\n    : property\n\n  return property?.childForFieldName('value')\n}\n\nfunction getPropertyValues (node, property) {\n  const propertyNode = getPropertyNode(node, property)\n  return propertyNode && getNodeChildrenByFieldName(propertyNode, 'value')\n}\n\n/**\n * @param {SyntaxNode} node devicetree node from which to extract property values\n * @param {Object} schema devicetree schema of a spcecific node\n * @return {Properties} properties\n */\nfunction parsePropertiesFromSchema (node, schema) {\n  return Object.keys(schema).reduce((properties, prop) => {\n    const propSchema = schema[prop]\n    const values = parsePropertyFromSchema(node, prop, propSchema)\n\n    if (values !== undefined) {\n      properties[prop] = {\n        parsed: values\n      }\n    }\n\n    return properties\n  }, {})\n}\n\n/**\n * @param {SyntaxNode} node devicetree node from which to extract a property value\n * @param {String} property name of property\n * @param {Object} schema devicetree schema of specific property\n */\nfunction parsePropertyFromSchema (node, property, schema) {\n  const propertyNode = findNodeProperty(node, property)\n  const values = getPropertyValues(node, property)\n\n  switch (schema.type) {\n    case 'string':\n      return parseStringLiteral(values?.[0])\n\n    case 'boolean':\n      return !!propertyNode\n\n    case 'int':\n      return parseIntegerCells(values)?.[0]\n\n    case 'array':\n      return parseIntegerArray(values)\n\n    case 'phandle':\n      return parsePhandle(values)\n\n    case 'phandles':\n      return parsePhandles(values)\n\n    case 'phandle-array':\n      return parsePhandleArray(values)\n\n    case 'integer-union':\n      return parseIntegerUnion(values)\n  }\n}\n\nfunction serializePropertyFromSchema (property, schema) {\n  // TODO: Probably make separate functions?\n  switch (schema.type) {\n    case 'string':\n      return `\"${property.parsed}\"`\n\n    case 'boolean':\n      // This is a weird case because instead of an explicit value we use the\n      // presense of the property (name) to indicate true or false. Note that\n      // this will get more complicated when supporting the `/delete-property/`\n      // flag (?)\n      return property.parsed\n\n    case 'int':\n      return serializeIntValue(property.parsed)\n\n    case 'array':\n      return serializeArrayValue(property.parsed)\n\n    case 'phandle':\n      return property.parsed.map(phandle => `<${phandle}>`).join(', ')\n\n    case 'phandles':\n    case 'phandle-array':\n      // TODO: Grouping binding cells into separate phandle-arrays shouldn't\n      // be the default behavior but right now the only place this would be\n      // unacceptably weird is the bindings property for layer and macro nodes\n      // which already do their own formatting explicitly.\n      return property.parsed\n        .reduce((bindings, node) => {\n          if (node.startsWith('&')) {\n            bindings.push([node])\n          } else {\n            const last = bindings[bindings.length - 1]\n            last.push(node)\n          }\n\n          return bindings\n        }, [])\n        .map(group => `<${group.join(' ')}>`)\n        .join(', ')\n\n    case 'integer-union':\n      return `<(${property.parsed.map(v => v.toString()).join('|')})>`\n  }\n}\n\nmodule.exports = {\n  findNodeProperty,\n  getProperty,\n  getPropertyNode,\n  getPropertyValue,\n  getPropertyValues,\n  parsePropertiesFromSchema,\n  parsePropertyFromSchema,\n  serializePropertyFromSchema\n}\n","\n/**\n *\n * @param {Tree|Node} tree Starting point for breadth-first traversal\n * @param {Object} [options={}]\n * @param {Integer} [options.maxDepth=-1]\n * @returns {Function} get next node, or undefined when traversal is complete\n */\nfunction BreadthFirstIterator (tree, options = {}) {\n  const { maxDepth = -1 } = options\n  const queue = [{ depth: 0, node: tree.rootNode || tree }]\n\n  return function next () {\n    const current = queue.shift()\n    if (current && (maxDepth === -1 || current.depth < maxDepth)) {\n      queue.push(...current.node.namedChildren.map(node => ({\n        node, depth: current.depth + 1\n      })))\n    }\n    return current?.node\n  }\n}\n\n/**\n *\n * @param {Tree|Node} tree Starting point for depth-first traversal\n * @param {Object} [options={}]\n * @param {Integer} [options.maxDepth=-1]\n * @returns {Function} get next node, or undefined when traversal is complete\n */\nfunction DepthFirstIterator (tree, options = {}) {\n  const { maxDepth = -1 } = options\n  const stack = [{ depth: 0, node: tree.rootNode || tree }]\n\n  return function next () {\n    const current = stack.shift()\n    if (current && (maxDepth === -1 || current.depth < maxDepth)) {\n      stack.unshift(...current.node.namedChildren.map(node => ({\n        node, depth: current.depth + 1\n      })))\n    }\n    return current?.node\n  }\n}\n\n/**\n * Find nodes in `tree` that satisfy the given `predicate` function.\n *\n * @param {Tree|SyntaxNode} tree\n * @param {Function} predicate\n * @param {Object} [options={}]\n * @param {Boolean} [options.single=false]\n * @param {Integer} [options.maxDepth=-1]\n * @param {Boolean} [options.depthFirst=false]\n * @returns {Array<SyntaxNode>|SyntaxNode} use options.single to return only the first matching node\n */\nfunction searchTree (tree, predicate, options = {}) {\n  const {\n    single = false,\n    maxDepth = -1,\n    depthFirst = false\n  } = options\n\n  const iter = depthFirst\n    ? DepthFirstIterator(tree, { maxDepth })\n    : BreadthFirstIterator(tree, { maxDepth })\n\n  const matches = []\n  let node\n\n  while ((node = iter())) {\n    if (predicate(node)) {\n      if (single) {\n        return node\n      }\n\n      matches.push(node)\n    }\n  }\n\n  if (single) {\n    return undefined\n  }\n\n  return matches\n}\n\nfunction findNodeByIdentifier (tree, name) {\n  return searchTree(tree, node => (\n    node.type === 'node' &&\n    node.childForFieldName('name').text === name\n  ), { single: true })\n}\n\nfunction findLabeledItem (tree, name) {\n  let node = searchTree(tree, node => (\n    node.type === 'labeled_item' &&\n    node.children[0].type === 'identifier' &&\n    node.children[0].text === name\n  ), { single: true })\n\n  if (!node) {\n    return null\n  }\n\n  do {\n    node = node.childForFieldName('item')\n  } while (node.type === 'labeled_item')\n\n  return node\n}\n\nfunction createPredicateForCompatible (compatible) {\n  let match\n\n  if (compatible instanceof RegExp) {\n    match = text => compatible.test(text)\n  } else if (typeof compatible === 'string') {\n    match = text => text === `\"${compatible}\"`\n  } else if (typeof compatible === 'function') {\n    match = compatible\n  } else {\n    throw new TypeError('Unexpected type ' + typeof compatible)\n  }\n\n  return node => (\n    node.type === 'property' &&\n    node.childForFieldName('name').text === 'compatible' &&\n    match(node.childForFieldName('value').text)\n  )\n}\n\n/**\n * Find single node including a `compatible` property with the given value.\n *\n * @param {Tree|SyntaxNode} tree\n * @param {String|RegExp|Function} compatible\n * @returns {SyntaxNode|undefined}\n */\nfunction findNodeWithCompatible (tree, compatible) {\n  // TODO: look into tree sitter queries again, doing these searches within web\n  // assembly is probably much faster. Alternatively, performing this lookup as\n  // a breadth-first search would likely save a lot of time since we're often\n  // expecting to match nodes just inside the devicetree root node. It may also\n  // be worth refining the depth-first search to avoid going deeper in some\n  // situations -- if I'm matching a property string it doesn't make sense to\n  // recurse into the property values.\n  const predicate = createPredicateForCompatible(compatible)\n  const propertyNode = searchTree(tree, predicate, { single: true })\n\n  return propertyNode?.parent\n}\n/**\n * Find descendent nodes including a `compatible` property with the given value.\n *\n * @param {Tree|SyntaxNode} tree\n * @param {String|RegExp|Function} compatible\n * @returns {Array<SyntaxNode>}\n */\nfunction findNodesWithCompatible (tree, compatible) {\n  const predicate = createPredicateForCompatible(compatible)\n  return searchTree(tree, predicate).map(property => property.parent)\n}\n\nmodule.exports = {\n  BreadthFirstIterator,\n  DepthFirstIterator,\n  searchTree,\n  findLabeledItem,\n  findNodeByIdentifier,\n  findNodeWithCompatible,\n  findNodesWithCompatible\n}\n","const { searchTree } = require('./trees')\n\nconst isNegativeInteger = node => (\n  node.type === 'unary_expression' &&\n  node.childForFieldName('operator').type === '-' &&\n  node.childForFieldName('argument').type === 'integer_literal'\n)\n\nconst isNumberishType = node => (\n  ['identifier', 'integer_literal'].includes(node.type) || isNegativeInteger(node)\n)\n\nconst isBindingType = node => (\n  // call_expression node includes modifier functions like `LC(A)`\n  ['identifier', 'integer_literal', 'reference', 'call_expression'].includes(node.type)\n)\n\nconst isBindingRef = node => node.type === 'reference'\n\nconst extractInteger = node => (\n  node.type === 'integer_literal' || isNegativeInteger(node)\n    ? Number(node.text)\n    : node.text\n)\n\nfunction parseStringLiteral (value) {\n  return value?.text?.slice(1, -1)\n}\n\nfunction parseIntegerCells (values) {\n  return parseIntegerArray(values)\n}\n\nfunction parseIntegerArray (values) {\n  return values?.flatMap(cells => (\n    cells.namedChildren\n      .filter(isNumberishType)\n      .map(extractInteger)\n  ))\n}\n\nfunction parsePhandle (values) {\n  return parsePhandles(values)[0]\n}\n\nfunction parsePhandles (values) {\n  return values?.flatMap(cells => (\n    cells.namedChildren\n      .filter(isBindingRef)\n      .map(value => value.text)\n  ))\n}\n\nfunction parsePhandleArray (values) {\n  return values?.flatMap(cells => (\n    cells.namedChildren\n      .filter(isBindingType)\n      .map(value => value.text)\n  ))\n}\n\nfunction parseIntegerUnion (values) {\n  return values?.flatMap(value => (\n    searchTree(value, isNumberishType, { depthFirst: true })\n  )).map(extractInteger)\n}\n\nfunction sanitizeIdentifier (name) {\n  return name\n    .replace(/[^a-zA-Z0-9,._+-]/g, '_')\n    .slice(0, 31)\n}\n\nfunction serializeIntegerCell (value) {\n  value = value.toString()\n  if (value.match(/-\\d+/)) {\n    value = `(${value})`\n  }\n\n  return value\n}\n\nfunction serializeIntValue (value) {\n  return `<${serializeIntegerCell(value)}>`\n}\n\nfunction serializeArrayValue (values) {\n  return `<${values.map(serializeIntegerCell).join(' ')}>`\n}\n\nmodule.exports = {\n  parseStringLiteral,\n  parseIntegerCells,\n  parseIntegerArray,\n  parsePhandle,\n  parsePhandleArray,\n  parsePhandles,\n  parseIntegerUnion,\n  sanitizeIdentifier,\n  serializeIntValue,\n  serializeArrayValue\n}\n","const assert = require('assert')\nconst { ReferenceError } = assert\nconst difference = require('lodash/difference')\nconst filter = require('lodash/filter')\nconst isEqual = require('lodash/isEqual')\nconst map = require('lodash/map')\nconst partition = require('lodash/partition')\nconst reverse = require('lodash/reverse')\n\nconst { getNodeLabels, getLabeledItem } = require('./helpers/nodes')\nconst { getPropertyValues } = require('./helpers/properties')\nconst { sanitizeIdentifier } = require('./helpers/values')\n\nclass NodeCollection {\n  managedProperties = []\n  _cached_container_node = null\n  _cached_container_tree_version = 0\n  _cached_collection_nodes = null\n  _cached_collection_tree_version = 0\n\n  constructor (document, options = {}) {\n    this.document = document\n    if (options.managedProperties) { this.managedProperties = options.managedProperties }\n    if (options.lookupContainerNode) { this.lookupContainerNode = options.lookupContainerNode.bind(this) }\n    if (options.injectContainerNode) { this.injectContainerNode = options.injectContainerNode.bind(this) }\n    if (options.lookupNodes) { this.lookupNodes = options.lookupNodes.bind(this) }\n    if (options.injectNode) { this.injectNode = options.injectNode.bind(this) }\n  }\n\n  lookupContainerNode () { throw new ReferenceError('Provide `lookupContainerNode` in constructor or override this method') }\n  injectContainerNode () { throw new ReferenceError('Provide `injectContainerNode` in constructor or override this method') }\n\n  lookupNodes () { throw new ReferenceError('Provide `lookupNodes` in constructor or override this method') }\n  injectNode () { throw new ReferenceError('Provide `injectNode` in constructor or override this method') }\n\n  get container () {\n    if (this._cached_container_tree_version !== this.document._parse_version) {\n      delete this._cached_container_node\n    }\n    if (!this._cached_container_node) {\n      this._cached_container_node = this.lookupContainerNode(this.document)\n      this._cached_container_tree_version = this.document._parse_version\n    }\n\n    return this._cached_container_node\n  }\n\n  get nodes () {\n    if (this._cached_collection_tree_version !== this.document._parse_version) {\n      delete this._cached_collection_nodes\n    }\n    if (!this._cached_collection_nodes) {\n      this._cached_collection_nodes = this.lookupNodes(this.document)\n      this._cached_collection_tree_version = this.document._parse_version\n    }\n\n    return this._cached_collection_nodes\n  }\n\n  updateCollection (collection) {\n    if (collection.length && !this.container) {\n      this.injectContainerNode(this)\n      this.document.flushChanges()\n    }\n\n    const originalIndices = [...this.nodes.keys()]\n    const reusedIndices = filter(map(collection, 'index'), index => this.nodes[index])\n    const removedIndices = difference(originalIndices, reusedIndices)\n    const [updates, additions] = partition(collection, node => this.nodes[node.index])\n\n    for (const node of updates) {\n      this.updateNode(node.index, node)\n    }\n\n    for (const index of reverse(removedIndices)) {\n      this.document.removeNode(this.nodes[index])\n    }\n\n    for (const node of additions) {\n      this.injectNode(this, node)\n      this.document.flushChanges()\n      this.updateNode(this.nodes.length - 1, node)\n    }\n  }\n\n  /**\n   * Update an existing devicetree node\n   * @param {Integer} index the position of the existing node to update\n   * @param {Object} update the new node state to apply to devicetree\n   * @param {String} update.name the devicetree node name\n   * @param {Array<String>} update.labels zero or more devictree labels to apply to the node\n   * @param {Object} update.properties mapping of property name to (serialized) property values\n   */\n  updateNode (index, update) {\n    const existing = this.extractNode(this.nodes[index])\n    this.updateNodeName(index, update, existing)\n    this.updateNodeLabels(index, update, existing)\n    this.updateNodeProperties(index, update, existing)\n    this.cleanupNodeProperties(index, update, existing)\n  }\n\n  updateNodeName (index, update, existing) {\n    if (existing.name !== update.name) {\n      const identifier = this.nodes[index].childForFieldName('name')\n      this.document.replaceNode(identifier, sanitizeIdentifier(update.name), {\n        removeStartingWhitespace: false\n      })\n    }\n  }\n\n  updateNodeLabels (index, update, existing) {\n    if (!isEqual(existing.labels, update.labels)) {\n      this.document.replaceNodeLabels(this.nodes[index], update.labels)\n    }\n  }\n\n  updateNodeProperties (index, update, existing) {\n    const { properties } = update\n\n    for (const name in properties) {\n      const values = properties[name]\n\n      if (!isEqual(values, existing.properties[name])) {\n        this.document.setProperty(\n          this.nodes[index],\n          name,\n          values\n        )\n      }\n    }\n  }\n\n  cleanupNodeProperties (index, update, existing) {\n    const { properties } = update\n    for (const name of this.managedProperties) {\n      if (name in existing.properties && !(name in properties)) {\n        this.document.deleteProperty(this.nodes[index], name)\n      }\n    }\n  }\n\n  /**\n   * Extract basic information from a devicetree node for convenience.\n   * The output of this function is an object with structure:\n   *  {\n   *    name: String,\n   *    labels: Array<String>\n   *    properties: Object<name:values>\n   *  }\n   * This can be overridden to include additional details.\n   * @param {SyntaxNode} node a devicetree node from which to extract info\n   * @returns {Object}\n   */\n  extractNode (node) {\n    // TODO: should there be a `Node` class?\n    // TODO: Should there be a `PropertyCollection` with similar abstractions?\n    assert(node.type === 'node')\n\n    const name = node.childForFieldName('name').text\n    const labels = getNodeLabels(node)\n    const properties = node.namedChildren.reduce((acc, child) => {\n      if (child.type === 'labeled_item') {\n        child = getLabeledItem(child)\n      }\n      if (child.type === 'property') {\n        const name = child.childForFieldName('name').text\n        const values = getPropertyValues(node, name)\n        const parsed = map(values, 'text')\n        const raw = parsed.join(', ')\n        acc[name] = { parsed, raw }\n      }\n\n      return acc\n    }, {})\n\n    return {\n      name,\n      labels,\n      properties\n    }\n  }\n\n  /**\n   * Evaluate each node with `extractNode` and include an `index` property\n   * @returns {Array<Object>}\n   */\n  extractCollection () {\n    return this.nodes.map((node, index) => ({\n      index, ...this.extractNode(node)\n    }))\n  }\n}\n\nmodule.exports = {\n  NodeCollection\n}\n","const assert = require('assert')\nconst { sortBy } = require('lodash')\n\nconst TreeSitter = require('web-tree-sitter')\n\nconst { getPosition } = require('string-utils')\nconst { getNodeLabelNodes } = require('./helpers/nodes')\nconst { getProperty } = require('./helpers/properties')\n\nlet _parser\n\nasync function getParser () {\n  if (!_parser) {\n    await TreeSitter.init()\n    const language = await TreeSitter.Language.load(\n\n      // This is meant to make loading possible in a browser.\n      global.window\n        ? require('../data/tree-sitter-devicetree.wasm')\n        : __dirname + '/../data/tree-sitter-devicetree.wasm'\n    )\n    _parser = new TreeSitter()\n    _parser.setLanguage(language)\n  }\n\n  return _parser\n}\n\nclass DevicetreeDocument {\n  constructor (parser, text) {\n    this.parser = parser\n    this._parse_version = 0\n    this._enableChangeBuffering = false\n    this._bufferedChanges = []\n    this.update(text)\n  }\n\n  cleanup () {\n    this.tree.delete()\n  }\n\n  update (text, inputEdit = null) {\n    if (inputEdit && this.tree && this._enableChangeBuffering) {\n      const replacementText = text.slice(inputEdit.startIndex, inputEdit.newEndIndex)\n      this._bufferedChanges.push({\n        startIndex: inputEdit.startIndex,\n        update: inputEdit,\n        replacementText\n      })\n    } else {\n      this.text = text\n      this._reparse()\n    }\n  }\n\n  _reparse () {\n    this.tree && this.tree.delete()\n    this.tree = this.parser.parse(this.text)\n    this._parse_version++\n  }\n\n  flushChanges () {\n    if (this._bufferedChanges.length === 0) {\n      return\n    }\n\n    const updates = sortBy(this._bufferedChanges, 'startIndex')\n\n    // console.log('flushing updates', updates)\n    // console.log({ original: this.text })\n\n    const chunks = updates.reduce((chunks, { update, replacementText }, i) => {\n      const nextUpdate = updates[i + 1]\n      const prevEnd = i > 0\n        ? updates[i - 1].update.oldEndIndex\n        : 0\n\n      const preChunk = this.text.slice(prevEnd, update.startIndex)\n      const chunk = replacementText\n      chunks.push(preChunk)\n      chunks.push(chunk)\n\n      // console.log({\n      //   preChunk,\n      //   chunk\n      // })\n\n      if (!nextUpdate) {\n        // console.log('selecting final cunk', {\n        //   original: this.text,\n        //   update,\n        //   postChunk: this.text.slice(update.oldEndIndex)\n        // })\n        chunks.push(this.text.slice(update.oldEndIndex))\n      }\n\n      return chunks\n    }, [])\n\n    // console.log('generated chunks', chunks)\n\n    this.text = chunks.join('')\n    // console.log('generated text', this.text)\n    this._reparse()\n    this._bufferedChanges = []\n  }\n\n  removeNode (node) {\n    this.replaceNode(node, '')\n  }\n\n  /**\n   * Replace the contents of a syntax node with other (serialized) content.\n   *\n   * @param {SyntaxNode} node the node to be replaced\n   * @param {String} newContent the devicetree source replacing the original node\n   * @param {Object} options\n   * @param {Bool} options.removeStartingWhitespace whether to attempt to start replacing at the start of `node`'s line\n   */\n  replaceNode (node, newContent, options = {}) {\n    const { removeStartingWhitespace = true } = options\n    const { text: documentText } = this\n\n    // TODO: this all should probably go\n    const precedingNewline = documentText.lastIndexOf('\\n', node.startIndex)\n    const hasStartingWhitespace = precedingNewline !== -1 && documentText.slice(precedingNewline + 1, node.startIndex).match(/\\s+/)\n    const start = hasStartingWhitespace && removeStartingWhitespace\n      ? precedingNewline\n      : node.startIndex\n\n    const replacement = [\n      documentText.slice(0, start),\n      newContent,\n      documentText.slice(node.endIndex)\n    ].join('')\n\n    const inputEdit = {\n      startIndex: start,\n      startPosition: getPosition(newContent, start),\n      oldEndIndex: node.endIndex,\n      oldEndPosition: node.endPosition,\n      newEndIndex: start + newContent.length,\n      newEndPosition: getPosition(replacement, start + newContent.length)\n    }\n\n    this.update(replacement, inputEdit)\n  }\n\n  replaceRange (startIndex, skipToIndex, newContent) {\n    const { text: source } = this\n    const pre = source.slice(0, startIndex)\n    const post = source.slice(skipToIndex)\n    const replacement = [pre, newContent, post].join('')\n    const newEndIndex = startIndex + newContent.length\n    const inputEdit = {\n      startIndex,\n      startPosition: getPosition(source, startIndex),\n      oldEndIndex: skipToIndex,\n      oldEndPosition: getPosition(source, skipToIndex),\n      newEndIndex,\n      newEndPosition: getPosition(replacement, newEndIndex)\n    }\n\n    return this.update(replacement, inputEdit)\n  }\n\n  /**\n   * Replace any existing labels attached to the specified node.\n   * @param {SyntaxNode} labeledNode\n   * @param {Array<String>} newLabels\n   */\n  replaceNodeLabels (labeledNode, newLabels) {\n    const labelNodes = getNodeLabelNodes(labeledNode)\n    const sorted = sortBy(labelNodes, 'startIndex')\n    const serializedLabels = newLabels.map(label => `${label}:`).join(' ')\n    const start = (sorted[0] && sorted[0].parent) || labeledNode\n\n    this.replaceRange(start.startIndex, labeledNode.startIndex, serializedLabels)\n  }\n\n  /**\n   * Insert text content before a specified node\n   * @param {SyntaxNode} node the node before which to insert\n   * @param {String} newContent the new devicetree source to be inserted\n   */\n  insertTextBeforeNode (node, newContent) {\n    this.replaceRange(node.startIndex, node.startIndex, newContent)\n  }\n\n  /**\n   * Insert text content after a specified node\n   * @param {SyntaxNode} node the node after which to insert\n   * @param {String} newContent the new devicetree source to be inserted\n   */\n  insertTextAfterNode (node, newContent) {\n    this.replaceRange(node.endIndex, node.endIndex, newContent)\n  }\n\n  /**\n   * Append devicetree source to the specified node\n   * @param {SyntaxNode} parentNode parent node in which to add content\n   * @param {*} newContent the new devicetree source to be inserted\n   */\n  addChildNode (parentNode, newContent) {\n    assert(parentNode.type === 'node')\n\n    const closingBrace = parentNode.children.find(node => node.type === '}')\n    return this.replaceRange(\n      closingBrace.startIndex,\n      closingBrace.startIndex,\n      newContent\n    )\n  }\n\n  /**\n   * Set/create a property with the specified value in the specified node\n   * @param {SyntaxNode} node target node in which to set property\n   * @param {String} property name of property to set\n   * @param {String|Boolean} value serialized devicetree value.\n   */\n  setProperty (node, property, value) {\n    const existing = getProperty(node, property)\n\n    if (typeof value === 'boolean' && !value) {\n      if (existing) {\n        this.deleteProperty(node, property)\n      }\n\n      return\n    }\n\n    const newText = value.length\n      ? `${property} = ${value};`\n      : `${property};`\n\n    if (existing) {\n      return this.replaceNode(\n        existing.syntaxNode,\n        newText,\n        { removeStartingWhitespace: false }\n      )\n    }\n\n    return this.addChildNode(node, `\\n         ${newText}`)\n  }\n\n  /**\n   * Remove a property from a specified devicetree node.\n   * @param {SyntaxNode} node where to search for the named property\n   * @param {String} property name of property to remove\n   */\n  deleteProperty (node, property) {\n    const existing = getProperty(node, property)\n    if (existing) {\n      this.replaceNode(existing.syntaxNode, '')\n    }\n  }\n}\n\nmodule.exports = {\n  getParser,\n  DevicetreeDocument\n}\n","const flatten = require('lodash/flatten')\nconst get = require('lodash/get')\nconst keyBy = require('lodash/keyBy')\nconst map = require('lodash/map')\nconst uniq = require('lodash/uniq')\n\nconst { getParser } = require('devicetree')\nconst { formatNode, getModelineConfiguration } = require('devicetree/lib/formatters')\nconst { behaviorBindings } = require('zmk-data/behaviors')\n\nconst KeymapDocument = require('./devicetree/keymap-document')\nconst { encodeKeymap } = require('./keymap')\n\nconst behavioursByBind = keyBy(behaviorBindings, 'code')\n\nasync function applyKeymapChanges (layout, keymap, original, featureFlags = {}) {\n  // TODO: generate this higher up in the call stack, I don't think we need the\n  // original keymap object anymore except for the `layer_names` property\n  const encoded = encodeKeymap(layout, keymap)\n  const behaviourHeaders = flatten(getBehavioursUsed(keymap).map(\n    bind => get(behavioursByBind, [bind, 'includes'], [])\n  ))\n\n  const devicetreeKeymap = new KeymapDocument(await getParser(), original)\n  devicetreeKeymap._enableChangeBuffering = true\n  devicetreeKeymap.mergeUpdated(encoded, featureFlags)\n  devicetreeKeymap.replaceBehaviourIncludes(behaviourHeaders)\n  devicetreeKeymap.flushChanges()\n\n  try {\n    const config = getModelineConfiguration(devicetreeKeymap.tree)\n    return formatNode(devicetreeKeymap.tree.rootNode, config).join('\\n')\n  } catch (err) {\n    console.error('Failed to format devictree', err)\n    return devicetreeKeymap.text\n  } finally {\n    devicetreeKeymap.cleanup()\n  }\n}\n\nfunction getBehavioursUsed (keymap) {\n  const keybinds = flatten(map(keymap.layers, layer => layer.properties?.bindings?.parsed || layer.bindings))\n  const comboBinds = flatten(map(keymap.combos, 'bindings'))\n  const macroBinds = flatten(map(keymap.macros, 'properties.bindings.parsed'))\n\n  return uniq(map([\n    ...keybinds,\n    ...comboBinds,\n    ...macroBinds\n  ], 'value'))\n}\n\nmodule.exports = applyKeymapChanges\n","const filter = require('lodash/filter')\nconst get = require('lodash/get')\nconst { parsePropertyFromSchema } = require('devicetree/lib/helpers/properties')\n\n/** @typedef {String} IntegerCell */\n/** @typedef {String} Bind */\n/** @typedef {{ value: String, params: Array<BindValue> }} BindValue */\n\n/**\n * @param {SyntaxNode} node\n * @param {String} [propertyName='bindings']\n * @returns {Array<Bind>|undefined} bind strings\n */\nfunction parseBindings (node, propertyName = 'bindings') {\n  const bindings = parsePropertyFromSchema(node, propertyName, {\n    type: 'phandle-array'\n  })\n\n  return bindings\n    ? groupPhandleArrayBindings([].concat(...bindings))\n    : undefined\n}\n\n/**\n * @param {Array<IntegerCell>} bindingCells\n * @returns {Array<Bind>}\n */\nfunction groupPhandleArrayBindings (bindingCells) {\n  return bindingCells.reduce((bindings, node) => {\n    if (node.startsWith('&')) {\n      bindings.push([node])\n    } else {\n      const last = bindings[bindings.length - 1]\n      last.push(node)\n    }\n\n    return bindings\n  }, []).map(binding => binding.join(' '))\n}\n\nconst MACRO_CONTROL_BEHAVIOURS = [\n  '&macro_tap',\n  '&macro_press',\n  '&macro_release',\n  '&macro_tap_time',\n  '&macro_wait_time',\n  '&macro_pause_for_release'\n]\n\n/**\n * Group a flat list of bind strings at macro activation mode change\n * @param {Array<Bind>} bindings\n * @returns {Array<Array<Bind>>}\n */\nfunction groupMacroBindings (bindings) {\n  return bindings.reduce((rows, binding, i, arr) => {\n    const behaviourBind = binding.split(' ')[0]\n\n    if (MACRO_CONTROL_BEHAVIOURS.includes(behaviourBind)) {\n      if (rows.at(-1).length > 0) {\n        rows.push([])\n      }\n\n      rows.at(-1).push(binding)\n      if (i < arr.length - 1) {\n        rows.push([])\n      }\n    } else {\n      rows.at(-1).push(binding)\n    }\n\n    return rows\n  }, [[]])\n}\n\n/**\n * Parse a bind string into a tree of values and parameters\n * @param {Bind} binding\n * @returns {BindValue}\n */\nfunction parseKeyBinding (binding, keymap) {\n  const paramsPattern = /\\((.+)\\)/\n\n  function parse (code) {\n    const value = code.replace(paramsPattern, '')\n    const params = get(code.match(paramsPattern), '[1]', '').split(',')\n      .map(s => s.trim())\n      .filter(s => s.length > 0)\n      .map(parse)\n\n    return {\n      // TODO: some defines (e.g., in bat43) can involve multiple bind values\n      // this replacement should happen before the bindings array is parsed\n      value: get(keymap.defines, value, value),\n      params\n    }\n  }\n\n  const value = binding.match(/^(&.+?)\\b/)[1]\n  const params = filter(binding.replace(/^&.+?\\b\\s*/, '')\n    .split(' '))\n    .map(parse)\n\n  return { value, params }\n}\n\n/**\n * Serialize a node of a BindValue tree\n * @param {BindValue} parsed\n * @returns {Bind}\n */\nfunction encodeBindValue (parsed) {\n  const params = (parsed.params || []).map(encodeBindValue)\n  const paramString = params.length > 0 ? `(${params.join(',')})` : ''\n  return parsed.value + paramString\n}\n\n/**\n * Serialize a top-level BindValue object\n * @param {BindValue} parsed\n * @returns {Bind}\n */\nfunction encodeKeyBinding (parsed) {\n  const { value, params } = parsed\n\n  return `${value} ${params.map(encodeBindValue).join(' ')}`.trim()\n}\n\nmodule.exports = {\n  parseBindings,\n  parseKeyBinding,\n  groupMacroBindings,\n  groupPhandleArrayBindings,\n  encodeKeyBinding\n}\n","const isEqual = require('lodash/isEqual')\n\nconst {\n  findChildByIdentifier,\n  findChildrenByIdentifier,\n  findNodesWithCompatible,\n  findNodeProperty,\n  getPropertyValues,\n  parsePropertyFromSchema,\n  sanitizeIdentifier,\n  serializePropertyFromSchema\n} = require('devicetree/lib/helpers')\nconst { NodeCollection } = require('devicetree/lib/node-collection')\nconst { behaviorSchemas } = require('zmk-data/behaviors')\n\nconst { parseKeyBinding, encodeKeyBinding } = require('../bindings')\n\nfunction resolveBehaviorBindings (behavior) {\n  const bindingsValues = getPropertyValues(behavior, 'bindings') || []\n  const bindings = bindingsValues.flatMap(bindingsValue => (\n    bindingsValue.namedChildren.flatMap(bindCode => bindCode.text)\n  ))\n\n  return { bindings }\n}\n\nclass BehaviorCollection extends NodeCollection {\n  lookupContainerNode () {\n    const rootNodes = findChildrenByIdentifier(this.document.tree.rootNode, '/')\n    return findChildByIdentifier(rootNodes, 'behaviors')\n  }\n\n  injectContainerNode () {\n    const keymap = findNodesWithCompatible(this.document.tree.rootNode, 'zmk,keymap').at(-1)\n    this.document.insertTextBeforeNode(keymap, '\\nbehaviors {};\\n')\n  }\n\n  lookupNodes () {\n    return findNodesWithCompatible(this.document.tree.rootNode, value => (\n      value.startsWith('\"zmk,behavior-') &&\n      value !== '\"zmk,behavior-macro\"'\n    ))\n  }\n\n  injectNode (_, behavior) {\n    const name = sanitizeIdentifier(behavior.name)\n    const last = this.nodes.at(-1)\n    const nodeContent = `${behavior.labels[0]}: ${name} {\n      compatible = ${behavior.properties.compatible.raw};\n    };`\n\n    // new node will be updated with full set of properties later, but for now\n    // a known behavior has to be set to make sure this node is not filtered out\n    if (last) {\n      this.document.insertTextAfterNode(last, nodeContent)\n    } else {\n      this.document.addChildNode(this.container, nodeContent)\n    }\n  }\n\n  extractNode (node) {\n    const compatible = findNodeProperty(node, 'compatible')?.namedChildren[1].text.slice(1, -1)\n\n    const schema = behaviorSchemas[compatible]\n    const extracted = super.extractNode(node)\n    const { name: identifier, labels } = extracted\n\n    extracted.properties.compatible.parsed = compatible\n\n    if (schema) {\n      for (const prop in schema.properties) {\n        const propSchema = schema.properties[prop]\n        const extractedProp = extracted.properties[prop]\n        if (extractedProp) {\n          extractedProp.parsed = parsePropertyFromSchema(node, prop, propSchema)\n\n          if (propSchema.type === 'phandle-array') {\n            const bindStrings = extractedProp.parsed\n              .reduce((bindings, node) => {\n                if (node.startsWith('&')) {\n                  bindings.push([node])\n                } else {\n                  const last = bindings[bindings.length - 1]\n                  last.push(node)\n                }\n\n                return bindings\n              }, [])\n              .map(group => group.join(' '))\n\n            extractedProp.parsed = bindStrings.map(bind => parseKeyBinding(bind, {}))\n          }\n        }\n      }\n    }\n\n    const bindingCells = extracted.properties['#binding-cells']?.parsed || 0\n    const label = extracted.properties.label?.parsed\n\n    return Object.assign(\n      extracted,\n      { binding: `&${labels[0]}` },\n      { code: `&${labels[0]}` },\n      { aliases: labels.map(label => `&${label}`) },\n      { identifier },\n      { bindingCells },\n      label && { label },\n      compatible && { compatible },\n\n      resolveBehaviorBindings(node)\n    )\n  }\n\n  legacyParseNodes () {\n    return this.nodes.map(node => this.extractNode(node))\n  }\n\n  updateNodeProperties (index, update, existing) {\n    const { properties } = update\n    const compatible = findNodeProperty(this.nodes[index], 'compatible')?.namedChildren[1].text.slice(1, -1)\n    const schema = behaviorSchemas[compatible]\n\n    for (const name in properties) {\n      const prop = properties[name]\n      const propSchema = schema?.properties?.[name]\n\n      if (!isEqual(prop, existing.properties[name])) {\n        const serialized = propSchema && !prop.useRaw\n          ? (\n              // Not ideal to have this type-check here, but our handling of this\n              // type goes beyond devicetree.\n              propSchema.type !== 'phandle-array'\n                ? serializePropertyFromSchema(prop, propSchema)\n                : prop.parsed\n                  .map(binding => encodeKeyBinding(binding))\n                  .map(bindString => `<${bindString}>`)\n                  .join(', ')\n            )\n          : prop.raw\n\n        this.document.setProperty(this.nodes[index], name, serialized)\n      }\n    }\n  }\n\n  cleanupNodeProperties (index, update, existing) {\n    for (const prop in existing.properties) {\n      if (!(prop in update.properties)) {\n        this.document.deleteProperty(this.nodes[index], prop)\n      }\n    }\n  }\n}\n\nmodule.exports = BehaviorCollection\n","const isEqual = require('lodash/isEqual')\n\nconst {\n  findNodeWithCompatible,\n  findNodesWithCompatible,\n  getLabeledItem,\n  getNodeLabels,\n  parsePropertiesFromSchema,\n  serializePropertyFromSchema\n} = require('devicetree/lib/helpers')\nconst { NodeCollection } = require('devicetree/lib/node-collection')\n\nconst { groupPhandleArrayBindings, parseKeyBinding, encodeKeyBinding } = require('../bindings')\n\n// TODO: extract the `zmk,combos` schema and handle the `childProperties` prop\nconst comboSchema = {\n  bindings: { type: 'phandle-array' },\n  'key-positions': { type: 'array' },\n  'timeout-ms': { type: 'int' },\n  'slow-release': { type: 'boolean' },\n  layers: { type: 'array' }\n}\n\nclass ComboCollection extends NodeCollection {\n  managedProperties = [\n    'bindings',\n    'key-positions',\n    'timeout-ms',\n    'layers',\n    'slow-release'\n  ]\n\n  lookupContainerNode () {\n    return findNodeWithCompatible(this.document.tree.rootNode, 'zmk,combos')\n  }\n\n  injectContainerNode () {\n    // TODO: this sucks and is making many other things worse.\n    // I've encountered keymap files that specify multiple root devicetree nodes\n    // which ZMK accepts and merges together, and multiple keymap nodes which\n    // devicetree accepts and selects the last one.\n    // Working around this is a pain in the ass and is hurting performance so\n    // the best thing to do is stop supporting this and present a warning to the\n    // user explaining why their keymap isn't being parsed as expected.\n    const keymap = findNodesWithCompatible(this.document.tree.rootNode, 'zmk,keymap').at(-1)\n    this.document.insertTextBeforeNode(keymap, `\n      combos {\n        compatible = \"zmk,combos\";\n      };\n    `)\n  }\n\n  lookupNodes () {\n    if (!this.container) {\n      return []\n    }\n\n    return this.container.namedChildren.reduce((nodes, syntaxNode) => {\n      if (syntaxNode.type === 'labeled_item') {\n        syntaxNode = getLabeledItem(syntaxNode)\n      }\n      if (syntaxNode.type === 'node') {\n        nodes.push(syntaxNode)\n      }\n\n      return nodes\n    }, [])\n  }\n\n  injectNode (_, combo) {\n    const name = combo.name.replace(/[^a-zA-Z0-9_]/g, '_')\n    const last = this.nodes.at(-1)\n    const nodeContent = `${name} {};`\n\n    if (last) {\n      this.document.insertTextAfterNode(last, nodeContent)\n    } else {\n      this.document.addChildNode(this.container, nodeContent)\n    }\n  }\n\n  updateNodeProperties (index, update, existing) {\n    const { properties } = update\n    for (const name in properties) {\n      const prop = properties[name]\n      const propSchema = comboSchema[name]\n\n      if (!isEqual(prop, existing.properties[name])) {\n        const serialized = propSchema && !prop.useRaw\n          ? (\n              // Not ideal to have this type-check here, but our handling of this\n              // type goes beyond devicetree.\n              propSchema.type !== 'phandle-array'\n                ? serializePropertyFromSchema(prop, propSchema)\n                : prop.parsed\n                  .map(binding => encodeKeyBinding(binding))\n                  .map(bindString => `<${bindString}>`)\n                  .join(', ')\n            )\n          : prop.raw\n\n        this.document.setProperty(this.nodes[index], name, serialized)\n      }\n    }\n\n    if (!update.properties.layers) {\n      this.document.deleteProperty(this.nodes[index], 'layers')\n    }\n  }\n\n  extractNode (node) {\n    const name = node.childForFieldName('name').text\n    const labels = getNodeLabels(node)\n    const properties = parsePropertiesFromSchema(node, comboSchema)\n\n    if (properties.bindings) {\n      properties.bindings.parsed = (\n        groupPhandleArrayBindings(properties.bindings.parsed)\n          .map(parseKeyBinding)\n      )\n    }\n\n    return { name, labels, properties }\n  }\n\n  legacyParse (node) {\n    const { name, labels, properties } = this.extractNode(node)\n    const legacyNode = {\n      name,\n      labels,\n      properties,\n      identifier: name\n    }\n\n    const legacyMapping = {\n      bindings: 'bindings',\n      'timeout-ms': 'timeoutMs',\n      'key-positions': 'keyPositions',\n      'slow-release': 'slowRelease',\n      layers: 'layers'\n    }\n\n    for (const prop of Object.keys(legacyMapping)) {\n      if (properties[prop]) {\n        legacyNode[legacyMapping[prop]] = properties[prop].parsed\n      }\n    }\n\n    if (legacyNode.layers?.length === 0 || isEqual(legacyNode.layers, [-1])) {\n      delete legacyNode.layers\n    }\n\n    return legacyNode\n  }\n\n  legacyParseNodes () {\n    return this.nodes.map(node => this.legacyParse(node))\n  }\n}\n\nmodule.exports = ComboCollection\n","const difference = require('lodash/difference')\nconst filter = require('lodash/filter')\nconst isEqual = require('lodash/isEqual')\nconst map = require('lodash/map')\n\nconst {\n  findChildrenByIdentifier,\n  findNodesWithCompatible,\n  getLabeledItem,\n  getNodeLabels,\n  parsePropertiesFromSchema,\n  serializePropertyFromSchema\n} = require('devicetree/lib/helpers')\nconst { NodeCollection } = require('devicetree/lib/node-collection')\n\nconst { groupPhandleArrayBindings, parseKeyBinding, encodeKeyBinding } = require('../bindings')\n\nfunction isSorted (array) {\n  return array.every((value, i, arr) => (\n    i === arr.length - 1 ||\n    arr[i] < arr[i + 1]\n  ))\n}\n\n// TODO: extract the `zmk,keymap` schema and handle the `childProperties` prop\nconst layerSchema = {\n  label: {\n    type: 'string'\n  },\n  bindings: {\n    type: 'phandle-array'\n  },\n  'sensor-bindings': {\n    type: 'phandle-array'\n  }\n}\n\nclass LayerCollection extends NodeCollection {\n  managedProperties = [\n    'label',\n    'bindings',\n    'sensor-bindings'\n  ]\n\n  lookupContainerNode () {\n    return findNodesWithCompatible(this.document.tree.rootNode, 'zmk,keymap').at(-1)\n  }\n\n  injectContainerNode () {\n    const rootNodes = findChildrenByIdentifier(this.document.tree.rootNode, '/')\n    this.document.addChildNode(\n      rootNodes.at(-1),\n      '\\nkeymap { compatible = \"zmk,keymap\"; };\\n'\n    )\n  }\n\n  lookupNodes () {\n    if (!this.container) {\n      return []\n    }\n\n    return this.container.namedChildren.reduce((nodes, syntaxNode) => {\n      if (syntaxNode.type === 'labeled_item') {\n        syntaxNode = getLabeledItem(syntaxNode)\n      }\n      if (syntaxNode.type === 'node') {\n        nodes.push(syntaxNode)\n      }\n\n      return nodes\n    }, [])\n  }\n\n  injectNode (_, layer) {\n    const last = this.nodes.at(-1)\n    const name = (layer.name || 'new_layer').replace(/[^a-zA-Z0-9_]/g, '_')\n    const nodeContent = `${name} {};`\n\n    if (last) {\n      this.document.insertTextAfterNode(last, nodeContent)\n    } else {\n      this.document.addChildNode(this.container, nodeContent)\n    }\n  }\n\n  updateCollection (collection) {\n    const originalIndices = [...this.nodes.keys()]\n\n    super.updateCollection(collection)\n    this.updateLayerPositions(collection, originalIndices)\n  }\n\n  /**\n   * Sort layer nodes according to the updates array ordering.\n   * This could perhaps be implemented generically in NodeCollection or even in\n   * DevicetreeDocument but that's complicated, especially considering scenarios\n   * like BehaviorCollection and MacroCollection which may be dealing with nodes\n   * that are subsets of a single nodes children, or even nodes that aren't even\n   * children of the same parent.\n   *\n   * For now it only makes sense for layer nodes to be sortable, so here you go.\n   *\n   * @param {Array<Object>} updates same argument passed to updateCollection\n   * @param {Array<Integer>} originalIndices node indices from before updates were applied\n   */\n  updateLayerPositions (updates, originalIndices) {\n    const reusedIndices = filter(map(updates, 'index'), index => this.nodes[index])\n    const removedIndices = difference(originalIndices, reusedIndices)\n    const positionMap = [...originalIndices]\n\n    // Add new nodes to the end of the position map. Their current position does\n    // not matter because they're already sorted relative to eachother and the\n    // mapping will let us reorder everything at the end.\n    for (const index in updates) {\n      const update = updates[index]\n      const nextIndex = positionMap.length\n      if (update.index === undefined || !originalIndices.includes(update.index)) {\n        update.index = nextIndex\n        positionMap[nextIndex] = nextIndex\n      }\n    }\n\n    // Shift every mapped position for nodes following removed nodes.\n    for (let i = removedIndices.length - 1; i >= 0; --i) {\n      const index = removedIndices[i]\n      positionMap[index] = null\n      for (let j = index + 1; j < positionMap.length; j++) {\n        if (positionMap[j] !== null) {\n          positionMap[j] -= 1\n        }\n      }\n    }\n\n    const targetIndexOrder = map(updates, 'index')\n    if (targetIndexOrder.length > 0 && !isSorted(targetIndexOrder)) {\n      this.document.flushChanges()\n      this.document.replaceRange(\n        this.nodes[0].startIndex,\n        this.nodes.at(-1).endIndex,\n        targetIndexOrder\n          .map(index => positionMap[index])\n          .map(index => this.nodes[index].text)\n          .join('\\n')\n      )\n    }\n  }\n\n  updateNodeProperties (index, update, existing) {\n    const { properties } = update\n    for (const name in properties) {\n      const prop = properties[name]\n      const propSchema = layerSchema[name]\n\n      if (!isEqual(prop, existing.properties[name])) {\n        const serialized = propSchema && !prop.useRaw\n          ? (\n              // Not ideal to have this type-check here, but our handling of this\n              // type goes beyond devicetree.\n              propSchema.type !== 'phandle-array'\n                ? serializePropertyFromSchema(prop, propSchema)\n                : prop.parsed\n                  .map(binding => encodeKeyBinding(binding))\n                  .map(bindString => `<${bindString}>`)\n                  .join(', ')\n            )\n          : prop.raw\n\n        this.document.setProperty(this.nodes[index], name, serialized)\n      }\n    }\n  }\n\n  extractNode (node) {\n    const name = node.childForFieldName('name').text\n    const labels = getNodeLabels(node)\n    const properties = parsePropertiesFromSchema(node, layerSchema)\n\n    if (properties.bindings) {\n      properties.bindings.parsed = (\n        groupPhandleArrayBindings(properties.bindings.parsed)\n          .map(parseKeyBinding)\n      )\n    }\n\n    if (properties['sensor-bindings']) {\n      properties['sensor-bindings'].parsed = (\n        groupPhandleArrayBindings(properties['sensor-bindings'].parsed)\n          .map(parseKeyBinding)\n      )\n    }\n\n    return { name, labels, properties }\n  }\n\n  legacyParse (node) {\n    const { name, labels, properties } = this.extractNode(node)\n    const legacyNode = {\n      name,\n      labels,\n      properties,\n      identifier: name\n    }\n\n    if (properties.label) {\n      legacyNode.label = properties.label.parsed\n    }\n    if (properties.bindings) {\n      legacyNode.bindings = properties.bindings.parsed\n    }\n    if (properties['sensor-bindings']) {\n      legacyNode.sensorBindings = properties['sensor-bindings'].parsed\n    }\n\n    return legacyNode\n  }\n\n  legacyParseNodes () {\n    return this.nodes.map(node => this.legacyParse(node))\n  }\n}\n\nmodule.exports = LayerCollection\n","const pick = require('lodash/pick')\n\nconst {\n  findChildByIdentifier,\n  findChildrenByIdentifier,\n  findNodesWithCompatible\n} = require('devicetree/lib/helpers')\nconst { NodeCollection } = require('devicetree/lib/node-collection')\n\nconst BehaviorCollection = require('./behaviors')\nconst { groupMacroBindings, encodeKeyBinding } = require('../bindings')\n\nclass MacroCollection extends BehaviorCollection {\n  managedProperties = [\n    'label',\n    'tap-ms',\n    'wait-ms'\n  ]\n\n  lookupContainerNode () {\n    const rootNodes = findChildrenByIdentifier(this.document.tree.rootNode, '/')\n    return findChildByIdentifier(rootNodes, 'macros')\n  }\n\n  injectContainerNode () {\n    const keymap = findNodesWithCompatible(this.document.tree.rootNode, 'zmk,keymap').at(-1)\n    this.document.insertTextBeforeNode(keymap, '\\nmacros {};\\n')\n  }\n\n  lookupNodes () {\n    return findNodesWithCompatible(\n      this.document.tree.rootNode,\n      'zmk,behavior-macro'\n    )\n  }\n\n  injectNode (_, macro) {\n    const name = macro.name.replace(/[^a-zA-Z0-9_]/g, '_')\n    const last = this.nodes.at(-1)\n    const nodeContent = (\n      `${name}: ${name} {\n        compatible = \"zmk,behavior-macro\";\n      };`\n    )\n\n    if (last) {\n      this.document.insertTextAfterNode(last, nodeContent)\n    } else {\n      this.document.addChildNode(this.container, nodeContent)\n    }\n  }\n\n  updateNode (index, update) {\n    const serialized = serializeMacroBindings(update.properties.bindings?.parsed || [])\n    update.properties.bindings = {\n      useRaw: true,\n      raw: serialized\n    }\n\n    super.updateNode(index, update)\n  }\n\n  legacyParse (node) {\n    return pick(this.extractNode(node), ['name', 'labels', 'properties'])\n  }\n\n  legacyParseNodes () {\n    return this.nodes.map(node => this.legacyParse(node))\n  }\n\n  cleanupNodeProperties (index, update, existing) {\n    const { cleanupNodeProperties } = NodeCollection.prototype\n    return cleanupNodeProperties.call(this, index, update, existing)\n  }\n}\n\nfunction serializeMacroBindings (bindings) {\n  const serialized = groupMacroBindings(\n    bindings.map(encodeKeyBinding)\n  ).map(row => row.join(' '))\n\n  return serialized.length === 1\n    ? [`<${serialized[0]}>`]\n    : serialized.map(row => `<${row}>`)\n}\n\nmodule.exports = MacroCollection\n","const filter = require('lodash/filter')\nconst last = require('lodash/last')\nconst reverse = require('lodash/reverse')\n\nconst { DevicetreeDocument } = require('devicetree')\nconst {\n  nodesAreConsecutive,\n  findChildByIdentifier,\n  findChildrenByIdentifier,\n  getLabeledItem\n} = require('devicetree/lib/helpers')\nconst { standardBehaviorIncludeFiles } = require('zmk-data/behaviors')\n\nconst MacroCollection = require('./collections/macros')\nconst ComboCollection = require('./collections/combos')\nconst LayerCollection = require('./collections/layers')\nconst BehaviorCollection = require('./collections/behaviors')\n\nclass KeymapDocument extends DevicetreeDocument {\n  constructor (...args) {\n    super(...args)\n    this.macroCollection = new MacroCollection(this)\n    this.comboCollection = new ComboCollection(this)\n    this.layerCollection = new LayerCollection(this)\n    this.behaviorCollection = new BehaviorCollection(this)\n  }\n\n  cleanup () {\n    super.cleanup()\n    delete this.layerCollection\n    delete this.comboCollection\n    delete this.macroCollection\n    delete this.behaviorCollection\n  }\n\n  getChosenProperties () {\n    const rootNodes = findChildrenByIdentifier(this.tree.rootNode, '/')\n    const chosen = findChildByIdentifier(rootNodes, 'chosen')\n\n    if (!chosen) {\n      return {}\n    }\n\n    return chosen.namedChildren.reduce((acc, child) => {\n      if (child.type === 'labeled_item') {\n        child = getLabeledItem(child)\n      }\n      if (child.type === 'property') {\n        const name = child.childForFieldName('name').text\n        const value = child.childForFieldName('value').text\n        acc[name] = value\n      }\n\n      return acc\n    }, {})\n  }\n\n  mergeUpdated (updated, featureFlags = {}) {\n    this.layerCollection.updateCollection(updated.layers)\n    this.comboCollection.updateCollection(updated.combos)\n    this.macroCollection.updateCollection(updated.macros)\n\n    if (featureFlags.enableBehaviorEditing) {\n      this.behaviorCollection.updateCollection(updated.behaviors)\n    }\n  }\n\n  replaceBehaviourIncludes (updated) {\n    const replacementText = updated.join('\\n') + '\\n'\n    const behaviorIncludes = this.tree.rootNode.namedChildren.filter(node => (\n      node.type === 'preproc_include' &&\n      // TODO: update behavior overlays to just specify the include path and not\n      // the include pre-processor statement. `startsWith` is necessary here\n      // because preproc_include node parsing includes trailing newline(s).\n      standardBehaviorIncludeFiles.some(line => node.text.startsWith(line))\n    ))\n\n    if (behaviorIncludes.length) {\n      if (nodesAreConsecutive(behaviorIncludes)) {\n        this.replaceRange(\n          behaviorIncludes[0].startIndex,\n          behaviorIncludes.at(-1).endIndex,\n          ''\n        )\n      } else {\n        for (const node of reverse(behaviorIncludes)) {\n          this.removeNode(node)\n        }\n      }\n    }\n\n    const lastInclude = last(filter(\n      this.tree.rootNode.children,\n      { type: 'preproc_include' }\n    ))\n    const firstDefine = this.tree.rootNode.children.find(node => node.type === 'preproc_def')\n    const firstDtNode = this.tree.rootNode.children.find(node => node.type === 'node')\n\n    if (lastInclude) {\n      this.insertTextAfterNode(lastInclude, replacementText)\n    } else if (firstDefine || firstDtNode) {\n      this.insertTextBeforeNode(\n        firstDefine || firstDtNode,\n        replacementText\n      )\n    }\n  }\n}\n\nmodule.exports = KeymapDocument\n","const { getPropertyValues } = require('devicetree/lib/helpers/properties')\n\nconst MISSING_ROOT_NODE = 'MISSING_ROOT_NODE'\nconst USING_ZMK_NODEFREE_MACROS = 'USING_ZMK_NODEFREE_MACROS'\nconst USING_ZMK_MACRO_MACRO = 'USING_ZMK_MACRO_MACRO'\nconst USING_MULTIPLE_ROOT_NODES = 'USING_MULTIPLE_ROOT_NODES'\nconst USING_MIRYOKU_DTSI = 'USING_MIRYOKU_DTSI'\nconst USING_NON_ZMK_MACRO = 'USING_NON_ZMK_MACRO'\n\nfunction keymapUsesNodefreeConfigHelpers (document) {\n  const macroNames = [\n    'ZMK_BEHAVIOR',\n    'ZMK_COMBO',\n    'ZMK_CONDITIONAL_LAYER',\n    'ZMK_LAYER',\n    'UC_MACRO'\n  ]\n\n  for (const node of document.tree.rootNode.namedChildren) {\n    if (node.type === 'ERROR') {\n      const { text } = node\n      if (macroNames.some(name => text.startsWith(name))) {\n        return USING_ZMK_NODEFREE_MACROS\n      }\n    }\n  }\n}\n\nfunction keymapUsesMiryoku (document) {\n  for (const node of document.tree.rootNode.namedChildren) {\n    if (node.type === 'preproc_include') {\n      if (node.childForFieldName('path').text.includes('miryoku.dtsi')) {\n        return USING_MIRYOKU_DTSI\n      }\n    }\n  }\n}\n\nfunction keymapBindingsUsePreprocessorMacros (document) {\n  const zmkPreprocFunctions = [\n    'LA', 'LC', 'LG', 'LS',\n    'RA', 'RC', 'RG', 'RS',\n    'RGB_COLOR_HSB'\n  ]\n\n  for (const layerNode of document.layerCollection.nodes) {\n    const [bindingsNode] = getPropertyValues(layerNode, 'bindings')\n    const nonZmkPreprocFunction = bindingsNode.namedChildren.find(node => (\n      node.type === 'call_expression' &&\n      !zmkPreprocFunctions.includes(node.childForFieldName('function').text)\n    ))\n\n    if (nonZmkPreprocFunction) {\n      return USING_NON_ZMK_MACRO\n    }\n  }\n}\n\nfunction keymapHasNoRootNodes (document) {\n  for (let node of document.tree.rootNode.namedChildren) {\n    if (node.type === 'labeled_item') {\n      node = node.childForFieldName('item')\n    }\n    if (node.type === 'node' && node.childForFieldName('name').text === '/') {\n      return\n    }\n  }\n\n  return MISSING_ROOT_NODE\n}\n\n/**\n * Check if a devicetree document uses multiple root nodes.\n *\n * People sometimes organize different parts of a keymap (like behaviors and\n * combos) into separate instances of a root node. The devicetree compiler will\n * merge these root nodes into one, but preserving this for editing is annoying\n * and inefficient so I don't want to support it anymore.\n *\n * @param {DevicetreeDocument} document\n * @returns {String|undefined}\n */\nfunction keymapHasMultipleRootNodes (document) {\n  let firstRootNode = null\n\n  for (let node of document.tree.rootNode.namedChildren) {\n    if (node.type === 'labeled_item') {\n      node = node.childForFieldName('item')\n    }\n    if (node.type === 'node' && node.childForFieldName('name').text === '/') {\n      if (firstRootNode !== null) {\n        return USING_MULTIPLE_ROOT_NODES\n      }\n\n      firstRootNode = node\n    }\n  }\n}\n\n/**\n * This is just a last-ditch check to see if keymap parsing failed because of a\n * custom define that replaced the initial binding cell's behavior. This would\n * otherwise be caught by `keymapBindingsUsePreprocessorMacros` except that the\n * initial grouping fails.\n * @param {DevicetreeDocument} document\n */\nfunction keymapHasLayerBindingsWithNonBehaviorStarter (document) {\n  return document.layerCollection.nodes.some(node => {\n    const bindingCells = [].concat(...getPropertyValues(node, 'bindings'))\n      .flatMap(integerCells => integerCells.namedChildren)\n    const firstBindType = bindingCells[0]?.type\n\n    return firstBindType && firstBindType !== 'reference'\n  })\n}\n\nmodule.exports = {\n  keymapHasNoRootNodes,\n  keymapUsesNodefreeConfigHelpers,\n  keymapUsesMiryoku,\n  keymapBindingsUsePreprocessorMacros,\n  keymapHasMultipleRootNodes,\n  keymapHasLayerBindingsWithNonBehaviorStarter,\n  warningFlags: {\n    MISSING_ROOT_NODE,\n    USING_ZMK_NODEFREE_MACROS,\n    USING_ZMK_MACRO_MACRO,\n    USING_MULTIPLE_ROOT_NODES,\n    USING_MIRYOKU_DTSI,\n    USING_NON_ZMK_MACRO\n  }\n}\n","const compact = require('lodash/compact')\nconst { getParser } = require('devicetree')\nconst { resolveBehaviorParams } = require('zmk-data/parameters')\n\nconst KeymapDocument = require('./devicetree/keymap-document')\nconst {\n  keymapUsesNodefreeConfigHelpers,\n  keymapUsesMiryoku,\n  keymapBindingsUsePreprocessorMacros,\n  keymapHasNoRootNodes,\n  keymapHasLayerBindingsWithNonBehaviorStarter,\n  warningFlags: { USING_NON_ZMK_MACRO }\n} = require('./devicetree/sanity-checks')\nconst { parseStringLiteral } = require('devicetree/lib/helpers/values')\n\nasync function extractKeymapData (keymapText) {\n  const parser = await getParser()\n  const document = new KeymapDocument(parser, keymapText)\n\n  try {\n    // Behaviors need post-processing to determine types for their binding cells\n    const behaviors = document.behaviorCollection.legacyParseNodes()\n    resolveBehaviorParams(behaviors)\n\n    return {\n      warningFlags: extractWarnings(document),\n      defines: extractDefines(document),\n      headers: extractLocalHeaders(document),\n      chosen: document.getChosenProperties(),\n      behaviors,\n      layers: document.layerCollection.legacyParseNodes(),\n      combos: document.comboCollection.legacyParseNodes(),\n      macros: document.macroCollection.legacyParseNodes()\n    }\n  } catch (err) {\n    if (keymapHasLayerBindingsWithNonBehaviorStarter(document)) {\n      return {\n        warningFlags: [USING_NON_ZMK_MACRO],\n        defines: {},\n        headers: [],\n        chosen: {},\n        behaviors: [],\n        layers: [],\n        combos: [],\n        macros: []\n      }\n    }\n    console.error(err)\n    return {\n      warningFlags: ['KEYMAP_PARSING_FAILED'],\n      defines: {},\n      headers: [],\n      chosen: {},\n      behaviors: [],\n      layers: [],\n      combos: [],\n      macros: []\n    }\n  } finally {\n    document.cleanup()\n  }\n}\n\nfunction extractWarnings (document) {\n  return compact([\n    keymapHasNoRootNodes(document),\n    keymapUsesNodefreeConfigHelpers(document),\n    keymapUsesMiryoku(document),\n    keymapBindingsUsePreprocessorMacros(document)\n  ])\n}\n\nfunction extractDefines (document) {\n  return document.tree.rootNode.namedChildren.reduce((acc, node) => {\n    if (node.type === 'preproc_def') {\n      const name = node.childForFieldName('name').text\n      const value = node.childForFieldName('value')?.text.trim()\n\n      acc[name] = value\n    }\n\n    return acc\n  }, {})\n}\n\nfunction extractLocalHeaders (document) {\n  return document.tree.rootNode.namedChildren.reduce((acc, node) => {\n    if (node.type === 'preproc_include') {\n      const path = node.childForFieldName('path')\n      if (path.type === 'string_literal') {\n        acc.push(parseStringLiteral(path))\n      }\n    }\n\n    return acc\n  }, [])\n}\n\nmodule.exports = extractKeymapData\n","const omitBy = require('lodash/omitBy')\nconst renderLayout = require('keymap-layout-tools/lib/render')\n\nconst { encodeKeyBinding } = require('./devicetree/bindings')\n\nclass KeymapValidationError extends Error {\n  constructor (errors) {\n    super()\n    this.name = 'KeymapValidationError'\n    this.errors = errors\n  }\n}\n\n// TODO: Rename this to something like \"hydrate\"?\nfunction encodeKeymap (layout, parsedKeymap) {\n  /*\n  This should basically become the standard format for a keymap when passed\n  around the various layers of the backend.\n\n  TODO: what do I want to do about keymap.json formatting? Should I call this a\n  new version and update existing files on-the-fly?\n\n  Also layer_names should be removed and the name (idenfitier?) + \"label\" should\n  be given in the layer object.\n\n  We can also analyze the unique set of behaviours used across all layers to\n  determine ahead of time which headers to include.\n  */\n  return Object.assign({}, parsedKeymap, {\n    layers: encodeLayers(parsedKeymap.layers, layout),\n    combos: encodeCombos(parsedKeymap.combos)\n  })\n}\n\nfunction encodeLayers (layers, layout) {\n  return layers.map(layer => {\n    // Newly created layers will specify name instead of identifier but still\n    // use `layer.bindings` and `layer.label`\n    if (layer.identifier || layer.bindings) {\n      layer = {\n        index: layer.index,\n        name: layer.identifier || layer.name,\n        labels: [],\n        properties: {\n          label: layer.label && { parsed: layer.label },\n          bindings: layer.bindings && { parsed: layer.bindings },\n          'sensor-bindings': layer.sensorBindings && { parsed: layer.sensorBindings }\n        }\n      }\n    }\n\n    if (layer.properties.bindings?.parsed) {\n      const { parsed } = layer.properties.bindings\n      layer.properties.bindings = {\n        parsed,\n        useRaw: true,\n        raw: `<\\n${renderLayout(layout, parsed.map(encodeKeyBinding))}\\n>`\n      }\n    }\n\n    if (layer.properties.label && !layer.properties.label.parsed) {\n      delete layer.properties.label\n    }\n\n    layer.properties = omitBy(layer.properties, value => !value)\n\n    return layer\n  })\n}\n\nfunction encodeCombos (combos) {\n  return combos.map(combo => {\n    if (combo.identifier) {\n      combo = {\n        index: combo.index,\n        name: combo.identifier,\n        labels: [],\n        properties: {\n          bindings: combo.bindings && { parsed: combo.bindings },\n          'key-positions': combo.keyPositions && { parsed: combo.keyPositions },\n          'timeout-ms': combo.timeoutMs && { parsed: combo.timeoutMs },\n          'slow-release': combo.slowRelease && { parsed: combo.slowRelease },\n          layers: combo.layers?.length && { parsed: combo.layers }\n        }\n      }\n    }\n\n    combo.properties = omitBy(combo.properties, value => !value)\n\n    if (!combo.properties.layers?.parsed?.length) {\n      delete combo.properties.layers\n    }\n\n    return combo\n  })\n}\n\nfunction parseKeymap (keymap) {\n  // TODO: move all of this into extractKeymapData\n  return Object.assign({}, keymap, {\n    layers: keymap.layers.map((layer, i) => ({ ...layer, index: i })),\n    combos: keymap.combos.map((combo, i) => ({ ...combo, index: i })),\n    macros: keymap.macros.map((macro, i) => ({ ...macro, index: i })),\n    behaviors: keymap.behaviors.map((behavior, i) => ({ ...behavior, index: i }))\n  })\n}\n\nmodule.exports = {\n  KeymapValidationError,\n  encodeKeymap,\n  encodeLayers,\n  encodeCombos,\n  parseKeymap\n}\n","const times = require('lodash/times')\n\nfunction renderLayout (layout, layer, opts = {}) {\n  const { margin = 2 } = opts\n  const table = layer.reduce((map, code, i) => {\n    // TODO: this would be better as a loop over `layout`, checking for a\n    // matching element in the `layer` array. Or, alternatively, an earlier\n    // validation that asserts each layer is equal in length to the number of\n    // keys in the layout.\n    if (layout[i]) {\n      const { row = 0, col } = layout[i]\n      map[row] = map[row] || []\n      map[row][col || map[row].length] = code\n    }\n\n    return map\n  }, [])\n\n  const rowIndices = Object.keys(table)\n  const columns = Math.max(...rowIndices.map(i => table[i].length))\n  const columnIndices = times(columns, n => n)\n  const columnWidths = columnIndices.map(col => Math.max(\n    ...rowIndices.map(row => table[row][col]?.length || 0)\n  ))\n\n  return table.map((row, i) => {\n    return columnIndices.map(i => {\n      const noMoreValues = row.slice(i).every(col => col === undefined)\n      const padding = columnWidths[i] + (\n        i === 0 ? '' : margin\n      )\n\n      if (noMoreValues) return ''\n      if (!row[i]) return ' '.repeat(padding)\n      return row[i].padStart(padding)\n    }).join('').replace(/\\s+$/, '')\n  }).join('\\n')\n}\n\nmodule.exports = renderLayout\n","/**\n * Remove common indentation from lines of a multiline string\n * @param {String} text a multiline string\n * @returns {String}\n */\nfunction dedent (text) {\n  return _dedentedLines(text).join('\\n')\n}\n\nfunction _dedentedLines (text) {\n  const lines = text.split('\\n')\n  const minIndentation = lines.reduce((leastIndentation, line) => {\n    const match = line.match(/^(\\s*)\\S/)\n\n    if (!match) {\n      return leastIndentation\n    }\n\n    return Math.min(leastIndentation, match[1].length)\n  }, Infinity)\n\n  return lines.map(line => (\n    line.slice(0, minIndentation).match(/^\\s+$/)\n      ? line.slice(minIndentation)\n      : line\n  ))\n}\n\n/**\n * Replace base indentation with a custom indentation string on all lines\n * @param {String} text\n * @param {String} indentation\n * @returns {String}\n */\nfunction reindent (text, indentation) {\n  return _dedentedLines(text)\n    .map(line => indentation + line)\n    .join('\\n')\n}\n\nfunction getPosition (text, index) {\n  let row, idx\n  for (\n    row = 0, idx = 0;\n    idx !== -1;\n    row++, idx = text.indexOf('\\n', idx + 1)\n  );\n\n  return { row, col: index - idx }\n}\n\nfunction removeStartingWhitespace (text) {\n  return text.split('\\n')\n    .reduce((lines, line) => {\n      if (lines.length > 0 || line.match(/\\S/)) {\n        lines.push(line)\n      }\n      return lines\n    }, [])\n    .join('\\n')\n}\n\nfunction removeTrailingWhitespace (text) {\n  return text.split('\\n')\n    .reverse()\n    .reduce((lines, line) => {\n      if (lines.length > 0 || line.match(/\\S/)) {\n        lines.push(line)\n      }\n      return lines\n    }, [])\n    .reverse()\n    .join('\\n')\n}\n\nmodule.exports = {\n  dedent,\n  reindent,\n  getPosition,\n  removeStartingWhitespace,\n  removeTrailingWhitespace\n}\n","const merge = require('lodash/merge')\nconst isMatch = require('lodash/isMatch')\nconst uniq = require('lodash/uniq')\n\n/** @typedef {('string' | 'boolean' | 'int' | 'array' | 'phandle' | 'phandles' | 'phandle-array' | 'integer-union')} PropertyType */\n/** @typedef {{ type: PropertyType, required?: boolean, const?: any, default?: any, enum?: Array<any>, description?: string }} PropertyDefinition */\n/** @typedef {Object.<string, PropertyDefinition>} Properties */\n/** @typedef {{ description?: string, compatible: string, include: string, properties: Properties }} BehaviorSchema  */\n/** @typedef {Object.<string, BehaviorSchema} BehaviorSchemas */\n/** @typedef {} BehaviorSchema */\n\n/** @type {BehaviorSchemas} */\nconst behaviorSchemas = require('./data/extracted-data/behavior-schemas.json')\n/** @type {BehaviorSchemas} */\nconst behaviorSchemaAdditions = require('./data/overlay-data/behavior-schemas-additions.json')\n\n/** @typedef {{ parsed: any, raw: string, useRaw?: boolean }} PropertyValue */\n/** @typedef {Object.<string, PropertyValue} ParsedProperties */\n/** @typedef {{ code: string, compatible: string, '#binding-cells': number, properties: ParsedProperties }} Behavior */\n\n/** @type {Array<Behavior>} */\nconst behaviorBindings = require('./data/extracted-data/behaviors.json')\n/** @type {Array<Behavior>} */\nconst behaviorAdditions = require('./data/overlay-data/behaviors-additions.json')\nconst behaviorSchemaOverlays = require('./data/overlay-data/behavior-schemas-overlay.json')\nconst behaviorOverlays = require('./data/overlay-data/behaviors-overlay.json')\n\nObject.assign(behaviorSchemas, behaviorSchemaAdditions)\nbehaviorBindings.push(...behaviorAdditions)\n\nfunction mergeBehaviorOverlays (base, overlays) {\n  const baseValues = Array.isArray(base) ? base : Object.values(base)\n\n  for (const value of baseValues) {\n    for (const { match, ...overlay } of overlays) {\n      if (isMatch(value, match)) {\n        merge(value, overlay)\n      }\n    }\n  }\n}\n\nmergeBehaviorOverlays(behaviorSchemas, behaviorSchemaOverlays)\nmergeBehaviorOverlays(behaviorBindings, behaviorOverlays)\n\nconst standardBehaviorIncludeFiles = uniq(\n  behaviorOverlays.flatMap(overlay => overlay.includes || [])\n)\n\nfor (const behavior of behaviorBindings) {\n  const schema = behaviorSchemas[behavior.compatible]\n  merge(behavior, { schema })\n}\n\nmodule.exports = {\n  behaviorSchemas,\n  behaviorBindings,\n  behaviorOverlays,\n  behaviorSchemaOverlays,\n  standardBehaviorIncludeFiles,\n  mergeBehaviorOverlays\n}\n","const singleValue = value => ({ value: '&kp', params: [{ value, params: [] }] })\n\nconst patternMappings = [\n  { pattern: /^[0-9]$/, convert: digit => singleValue(`N${digit}`) },\n  { pattern: /^[a-z]$/, convert: char => singleValue(char.toUpperCase()) },\n  {\n    pattern: /^[A-Z]$/,\n    convert: char => ({\n      value: '&kp',\n      params: [{\n        value: 'LS',\n        params: [{\n          value: char.toUpperCase(),\n          params: []\n        }]\n      }]\n    })\n  }\n]\n\nconst simpleMappings = {\n  '!': singleValue('EXCL'),\n  '@': singleValue('AT'),\n  '#': singleValue('POUND'),\n  '$': singleValue('DLLR'),\n  '%': singleValue('PRCNT'),\n  '^': singleValue('CARET'),\n  '&': singleValue('AMPS'),\n  '*': singleValue('STAR'),\n  '(': singleValue('LPAR'),\n  ')': singleValue('RPAR'),\n  '\\n': singleValue('RET'),\n  ' ': singleValue('SPACE'),\n  '-': singleValue('MINUS'),\n  '_': singleValue('UNDER'),\n  '=': singleValue('EQUAL'),\n  '+': singleValue('PLUS'),\n  '[': singleValue('LBKT'),\n  ']': singleValue('LBRC'),\n  '{': singleValue('RBKT'),\n  '}': singleValue('RBRC'),\n  '\\\\': singleValue('BSLH'),\n  '|': singleValue('PIPE'),\n  '': singleValue('TILDE2'),\n  ';': singleValue('SEMI'),\n  ':': singleValue('COLON'),\n  '\\'': singleValue('SQT'),\n  '\"': singleValue('DQT'),\n  '`': singleValue('GRAVE'),\n  '~': singleValue('TILDE'),\n  ',': singleValue('COMMA'),\n  '<': singleValue('LT'),\n  '.': singleValue('DOT'),\n  '>': singleValue('GT'),\n  '/': singleValue('FSLH'),\n  '?': singleValue('QMARK')\n}\n\nfunction mapCharacter (char) {\n  if (simpleMappings[char]) {\n    return simpleMappings[char]\n  }\n\n  for (const { pattern, convert } of patternMappings) {\n    if (char.match(pattern)) {\n      return convert(char)\n    }\n  }\n}\n\nmodule.exports = {\n  mapCharacter\n}\n","const keycodes = require('./data/extracted-data/keycodes.json')\nconst keycodeGlyphs = {\n  basic: require('./data/overlay-data/keycode-glyphs.json'),\n  unicode: require('./data/overlay-data/keycode-glyphs-unicode.json'),\n  platforms: {\n    mac: require('./data/overlay-data/keycode-glyphs-macos.json'),\n    win: require('./data/overlay-data/keycode-glyphs-windows.json')\n  }\n}\n\nmodule.exports = {\n  keycodes,\n  keycodeGlyphs\n}\n","const times = require('lodash/times')\nconst { behaviorSchemas, behaviorBindings } = require('./behaviors')\n\n/**\n * Parsing keymap gives us a number of custom behaviour definitions\n * Some custom behaviours may reference other behaviours\n * Some custom behaviours may reference other custom behaviours\n *\n * We need to add all new behaviour to a new map upon loading\n * After populating the map with all new behaviours we can resolve bind params\n *\n * Keep a list of \"visited\" behaviours\n * For each behaviour\n * For each behaviour referenced in bindings\n * Resolve behaviour reference to get params list\n * If behaviour reference already exists in list of visited behaviours, bail\n * If number of references to resolve exceeds X, bail\n */\n\nfunction BehaviorResolutionError (message) {\n  this.message = message\n  this.name = 'BehaviorResolutionError'\n}\n\n/** @typedef {string} Identifier */\n/** @typedef {string} Label */\n/** @typedef {{ parsed: any, raw: string, useRaw?: boolean }} PropertyValue */\n/** @typedef {Object.<string, PropertyValue>} Properties */\n/** @typedef {{ name: string, labels: Array<string>, properties: Properties }} ParsedBehavior  */\n\nfunction parseNumBindingCells (behavior, prop = '#binding-cells') {\n  const parsed = behavior.properties?.[prop]?.parsed\n\n  if (typeof parsed === 'number') {\n    return parsed\n  }\n\n  // For unrecognized behaviors we don't have the schema to parse the\n  // \"#binding-cells\" property like we'd expect, so let's assume its a single\n  // integer literal and parse the raw value\n  const raw = behavior.properties?.[prop]?.raw || '<>'\n  const match = raw.match(/<(\\d+)>/)\n\n  if (match) {\n    return Number(match[1])\n  }\n}\n\nfunction behaviorMap (map, behavior) {\n  for (const label of behavior.labels) {\n    map[`&${label}`] = behavior\n  }\n  return map\n}\n\n/**\n * Attempt to provide parameter types for behaviours with binding-cells.\n * @param {Array<ParsedBehavior>} behaviors - custom behavior definitions\n */\nfunction resolveBehaviorParams (behaviors) {\n  const standardBindingsMap = behaviorBindings.reduce(behaviorMap, {})\n  // Here we attempt to resolve the binding to a \"known\" behaviour for which\n  // I have already manually described the parameters. Failing that, this\n  // would fall back to a single \"code\" parameter for each. This assumes\n  // that a custom hold-tap wouldn't want something like \"hold for layer\"\n  // and \"tap to connect to BT profile 1\".\n  const newBindingsMap = behaviors.reduce(behaviorMap, {})\n\n  /**\n   * @param {ParsedBehavior} behavior\n   * @param {Array<string>} [queue=[]]\n   * @returns {void}\n   */\n  function resolve (behavior, queue = []) {\n    if ('params' in behavior) {\n      return behavior.params\n    }\n\n    const compatible = behavior.properties?.compatible?.parsed\n    const schema = behaviorSchemas[compatible]\n\n    const bindingsType = schema?.properties?.bindings?.type\n    const bindingCells = parseNumBindingCells(behavior) ?? parseNumBindingCells(behavior, '#sensor-binding-cells')\n    const bindings = (behavior.properties?.bindings?.parsed || [])\n\n    // console.log('resolving for', {\n    //   compatible,\n    //   schema,\n    //   bindingsType,\n    //   bindingCells,\n    //   bindings\n    // })\n\n    if (!bindingCells) {\n      return []\n    }\n\n    // A `bindings` prop of type `phandle-array` means the bindings are already\n    // given along with binding cell values and don't need further params.\n    if (bindingsType === 'phandle-array') {\n      return []\n    }\n\n    if (!bindings.length) {\n      return times(bindingCells, () => ({ type: 'string', raw: true }))\n    }\n\n    // This implementation relies on the existing pattern for behaviors which\n    // reference other behaviors without parameters (hold-tap and sticky-key)\n    // will only provide a single parameter to each referenced behavior without\n    // concerning itself with the referenced behavior's binding cell count.\n    // A possible future exception to this is parameterized macros:\n    //  https://github.com/zmkfirmware/zmk/pull/1232#issuecomment-1478977559\n    // This will require re-visiting this solution.\n    return bindings.reduce((params, binding) => {\n      // This implies the bindings property we're inspecting is actually a\n      // phandles-array type (behavior with params) and not phandle/phandles.\n      // This shouldn't happen and stricter checking earlier on would be wise.\n      if (!binding.startsWith('&')) {\n        return params\n      }\n\n      if (queue.includes(binding)) {\n        throw new BehaviorResolutionError(`Circular reference in bindings: \"&${behavior.labels[0]}\" -> \"${binding}\".`)\n      } else if (queue.length > 3) {\n        throw new BehaviorResolutionError('Reference depth limit exceeded.')\n      }\n\n      const nextBehavior = newBindingsMap[binding] || standardBindingsMap[binding]\n\n      // Not sure if I'm ok with this. Previously the idea was that a behavior\n      // referencing an unrecognized behavior cannot resolve parameters at all,\n      // whereas now it just treats that as having a single raw parameter and\n      // includes an error message property that nothing else uses.\n      if (!nextBehavior) {\n        behavior.error = `Unrecognized behavior binding \"${binding}\".`\n        return [...params, { raw: true }]\n      }\n\n      try {\n        nextBehavior.params = resolve(nextBehavior, [...queue, binding])\n        params.push(nextBehavior.params[0] || { type: 'placeholder' })\n      } catch (error) {\n        if (error instanceof BehaviorResolutionError) {\n          nextBehavior.error = error.message\n          nextBehavior.params = []\n        }\n        throw error\n      }\n\n      return params\n    }, [])\n  }\n\n  for (const behavior of behaviors) {\n    // if (!behavior.properties.bindings) {\n    //   continue\n    // }\n\n    try {\n      behavior.params = resolve(behavior)\n    } catch (error) {\n      if (!(error instanceof BehaviorResolutionError)) {\n        throw error\n      }\n\n      console.error('Failed to resolve behavior parameters', error)\n      behavior.error = error.message\n      behavior.params = times(parseNumBindingCells(behavior) || 0, () => ({ raw: true }))\n    }\n  }\n}\n\nmodule.exports = {\n  resolveBehaviorParams\n}\n"],"names":["module","exports","removeStartingWhitespace","removeTrailingWhitespace","reindent","dedent","require","getLabeledItem","getNodeLabels","DEFAULT_INDENT","DEFAULT_MULTILINE_INTEGER_CELLS_INDENT","isMultilineNode","node","text","indexOf","isInlineComment","type","previousSibling","endPosition","row","startPosition","getNodeIndentation","tab","repeat","getNodeDepth","n","depth","stop","tree","rootNode","parent","id","shouldIncludeBlank","nodeA","nodeB","sameType","namedChildren","length","slice","some","hasAddress","childForFieldName","getAddress","formatLabels","labels","map","join","formatNode","options","indent","identifier","children","indentation","formatChildren","reduce","lines","childNode","i","arr","push","multilineIntegerCellsIndent","noValue","simpleValue","singleIntegerCell","bindingsLines","split","concat","line","formatPropertyNode","trimEnd","getModelineConfiguration","config","contents","startsWith","trim","match","key","jsonValue","value","JSON","parse","Object","assign","assert","reverse","getNodeLabelNodes","getNodeChildrenByFieldName","fieldName","cursor","walk","gotoFirstChild","isNamed","currentNode","isField","currentFieldName","gotoNextSibling","delete","findChildrenByIdentifier","nameOrMatch","filter","find","sub","nodesAreConsecutive","nodes","every","nextSibling","label","labeledItemNode","findChildByIdentifier","listNodes","opts","stripNewlines","limit","replace","console","log","parseStringLiteral","parseIntegerCells","parseIntegerArray","parsePhandles","parsePhandle","parsePhandleArray","parseIntegerUnion","serializeIntValue","serializeArrayValue","findNodeProperty","propertyName","getPropertyNode","child","getPropertyValues","property","propertyNode","parsePropertyFromSchema","schema","values","getProperty","syntaxNode","name","getPropertyValue","parsePropertiesFromSchema","keys","properties","prop","propSchema","undefined","parsed","serializePropertyFromSchema","phandle","bindings","group","v","toString","BreadthFirstIterator","maxDepth","queue","current","shift","DepthFirstIterator","stack","unshift","searchTree","predicate","single","depthFirst","iter","matches","createPredicateForCompatible","compatible","RegExp","test","TypeError","findLabeledItem","findNodeByIdentifier","findNodeWithCompatible","findNodesWithCompatible","isNegativeInteger","isNumberishType","includes","isBindingType","isBindingRef","extractInteger","Number","flatMap","cells","serializeIntegerCell","sanitizeIdentifier","ReferenceError","difference","isEqual","partition","NodeCollection","managedProperties","_cached_container_node","_cached_container_tree_version","_cached_collection_nodes","_cached_collection_tree_version","constructor","document","this","lookupContainerNode","bind","injectContainerNode","lookupNodes","injectNode","container","_parse_version","updateCollection","collection","flushChanges","originalIndices","reusedIndices","index","removedIndices","updates","additions","updateNode","removeNode","update","existing","extractNode","updateNodeName","updateNodeLabels","updateNodeProperties","cleanupNodeProperties","replaceNode","replaceNodeLabels","setProperty","deleteProperty","acc","raw","extractCollection","sortBy","TreeSitter","getPosition","_parser","getParser","async","init","language","Language","load","global","window","__dirname","setLanguage","DevicetreeDocument","parser","_enableChangeBuffering","_bufferedChanges","cleanup","inputEdit","replacementText","startIndex","newEndIndex","_reparse","chunks","nextUpdate","prevEnd","oldEndIndex","preChunk","chunk","newContent","documentText","precedingNewline","lastIndexOf","start","replacement","endIndex","oldEndPosition","newEndPosition","replaceRange","skipToIndex","source","labeledNode","newLabels","labelNodes","sorted","serializedLabels","insertTextBeforeNode","insertTextAfterNode","addChildNode","parentNode","closingBrace","newText","flatten","get","keyBy","uniq","behaviorBindings","KeymapDocument","encodeKeymap","behavioursByBind","layout","keymap","original","featureFlags","encoded","behaviourHeaders","keybinds","layers","layer","comboBinds","combos","macroBinds","macros","getBehavioursUsed","devicetreeKeymap","mergeUpdated","replaceBehaviourIncludes","err","error","groupPhandleArrayBindings","bindingCells","binding","MACRO_CONTROL_BEHAVIOURS","encodeBindValue","params","paramString","parseBindings","parseKeyBinding","paramsPattern","code","s","defines","groupMacroBindings","rows","behaviourBind","at","encodeKeyBinding","behaviorSchemas","rootNodes","_","behavior","last","nodeContent","extracted","super","extractedProp","bindStrings","aliases","bindingsValue","bindCode","legacyParseNodes","serialized","useRaw","bindString","comboSchema","combo","legacyParse","legacyNode","legacyMapping","layerSchema","updateLayerPositions","positionMap","nextIndex","j","targetIndexOrder","sensorBindings","pick","BehaviorCollection","macro","serializeMacroBindings","prototype","call","standardBehaviorIncludeFiles","MacroCollection","ComboCollection","LayerCollection","args","macroCollection","comboCollection","layerCollection","behaviorCollection","getChosenProperties","chosen","updated","enableBehaviorEditing","behaviors","behaviorIncludes","lastInclude","firstDefine","firstDtNode","MISSING_ROOT_NODE","USING_ZMK_NODEFREE_MACROS","USING_MULTIPLE_ROOT_NODES","USING_MIRYOKU_DTSI","USING_NON_ZMK_MACRO","keymapHasNoRootNodes","keymapUsesNodefreeConfigHelpers","macroNames","keymapUsesMiryoku","keymapBindingsUsePreprocessorMacros","zmkPreprocFunctions","layerNode","bindingsNode","keymapHasMultipleRootNodes","firstRootNode","keymapHasLayerBindingsWithNonBehaviorStarter","firstBindType","integerCells","warningFlags","USING_ZMK_MACRO_MACRO","compact","resolveBehaviorParams","extractWarnings","extractDefines","extractLocalHeaders","path","keymapText","headers","omitBy","renderLayout","KeymapValidationError","Error","errors","encodeLayers","encodeCombos","keyPositions","timeoutMs","slowRelease","parsedKeymap","parseKeymap","times","margin","table","col","rowIndices","columns","Math","max","columnIndices","columnWidths","noMoreValues","padding","padStart","_dedentedLines","minIndentation","leastIndentation","min","Infinity","idx","merge","isMatch","behaviorSchemaAdditions","behaviorAdditions","behaviorSchemaOverlays","behaviorOverlays","mergeBehaviorOverlays","base","overlays","baseValues","Array","isArray","overlay","singleValue","patternMappings","pattern","convert","digit","char","toUpperCase","simpleMappings","mapCharacter","keycodes","keycodeGlyphs","basic","unicode","platforms","mac","win","BehaviorResolutionError","message","parseNumBindingCells","behaviorMap","standardBindingsMap","newBindingsMap","resolve","bindingsType","nextBehavior"],"sourceRoot":""}