{"version":3,"file":"shared.4185c55cea8319e48321.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-layout-tools/lib/render.js","webpack:///../api/packages/keymap-layout-tools/lib/validate.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} 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}\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} 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.} 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} 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}\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} 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\n * properties: Object\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}\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} 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 compact = require('lodash/compact')\nconst flatten = require('lodash/flatten')\nconst get = require('lodash/get')\nconst keyBy = require('lodash/keyBy')\nconst map = require('lodash/map')\nconst omitBy = require('lodash/omitBy')\nconst uniq = require('lodash/uniq')\n\nconst { getParser } = require('devicetree')\nconst { formatNode, getModelineConfiguration } = require('devicetree/lib/formatters')\nconst { behaviorBindings } = require('zmk-data/behaviors')\nconst renderLayout = require('keymap-layout-tools/lib/render')\n\nconst { encodeKeyBinding } = require('./devicetree/bindings')\nconst KeymapDocument = require('./devicetree/keymap-document')\n\nconst behavioursByBind = keyBy(behaviorBindings, 'code')\n\nasync function applyKeymapChanges (layout, keymap, original, featureFlags = {}) {\n formatLayerKeybinds(keymap, layout)\n const behaviorHeaders = flatten(getBehaviorsUsed(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(keymap, featureFlags)\n devicetreeKeymap.replaceBehaviourIncludes(behaviorHeaders)\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 formatLayerKeybinds (keymap, layout) {\n for (const layer of keymap.layers) {\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}\n\nfunction getBehaviorsUsed (keymap) {\n const bindings = [\n ...flatten(compact(map(keymap.layers, 'properties.bindings.parsed'))),\n ...flatten(compact(map(keymap.layers, 'properties.sensor-bindings.parsed'))),\n ...flatten(compact(map(keymap.combos, 'properties.bindings.parsed'))),\n ...flatten(compact(map(keymap.macros, 'properties.bindings.parsed'))),\n ...flatten(compact(map(keymap.behaviors, 'properties.bindings.parsed')))\n ]\n\n const behaviors = bindings.map(binding => (\n typeof binding === 'object'\n ? binding.value\n : binding\n ))\n\n return uniq(behaviors)\n}\n\nmodule.exports = applyKeymapChanges\nmodule.exports.getBehaviorsUsed = getBehaviorsUsed\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 */\n\n/**\n * @param {SyntaxNode} node\n * @param {String} [propertyName='bindings']\n * @returns {Array|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} bindingCells\n * @returns {Array}\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 '¯o_tap',\n '¯o_press',\n '¯o_release',\n '¯o_tap_time',\n '¯o_wait_time',\n '¯o_pause_for_release'\n]\n\n/**\n * Group a flat list of bind strings at macro activation mode change\n * @param {Array} bindings\n * @returns {Array>}\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\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 resolveBehaviorBindings(node)\n\n return extracted\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?.parsed?.length) {\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} updates same argument passed to updateCollection\n * @param {Array} 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 : (\n prop.parsed.length === 0\n ? false\n : propSchema.parsed\n .map(binding => encodeKeyBinding(binding))\n .map(bindString => `<${bindString}>`)\n .join(', ')\n )\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\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.sort().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 const ranges = behaviorIncludes.map(node => [node.startIndex, node.endIndex])\n for (const [startIndex, endIndex] of reverse(ranges)) {\n this.replaceRange(startIndex, endIndex, '\\n')\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')\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 return {\n warningFlags: extractWarnings(document),\n defines: extractDefines(document),\n headers: extractLocalHeaders(document),\n chosen: document.getChosenProperties(),\n behaviors: document.behaviorCollection.extractCollection(),\n layers: document.layerCollection.extractCollection(),\n combos: document.comboCollection.extractCollection(),\n macros: document.macroCollection.extractCollection()\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 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","const isNumber = require('lodash/isNumber')\n\nclass InfoValidationError extends Error {\n constructor (errors) {\n super()\n this.name = 'InfoValidationError'\n this.errors = errors\n }\n}\n\nfunction validateInfoJson (info) {\n const errors = []\n\n if (typeof info !== 'object' || info === null) {\n errors.push('info.json root must be an object')\n } else if (!info.layouts) {\n errors.push('info must define \"layouts\"')\n } else if (typeof info.layouts !== 'object' || info.layouts === null) {\n errors.push('layouts must be an object')\n } else if (Object.values(info.layouts).length === 0) {\n errors.push('layouts must define at least one layout')\n } else {\n for (const name in info.layouts) {\n const layout = info.layouts[name]\n if (typeof layout !== 'object' || layout === null) {\n errors.push(`layout ${name} must be an object`)\n } else if (!Array.isArray(layout.layout)) {\n errors.push(`layout ${name} must define \"layout\" array`)\n } else {\n const anyKeyHasPosition = layout.layout.some(key => (\n key?.row !== undefined ||\n key?.col !== undefined\n ))\n\n for (const i in layout.layout) {\n const key = layout.layout[i]\n const keyPath = `layouts[${name}].layout[${i}]`\n\n if (typeof key !== 'object' || key === null) {\n errors.push(`Key definition at ${keyPath} must be an object`)\n } else {\n const optionalNumberProps = ['u', 'h', 'r', 'rx', 'ry']\n if (!isNumber(key.x)) {\n errors.push(`Key definition at ${keyPath} must include \"x\" position`)\n }\n if (!isNumber(key.y)) {\n errors.push(`Key definition at ${keyPath} must include \"y\" position`)\n }\n for (const prop of optionalNumberProps) {\n if (prop in key && !isNumber(key[prop])) {\n errors.push(`Key definition at ${keyPath} optional \"${prop}\" must be number`)\n }\n }\n for (const prop of ['row', 'col']) {\n if (anyKeyHasPosition && !(prop in key)) {\n errors.push(`Key definition at ${keyPath} is missing property \"${prop}\"`)\n } else if (prop in key && (!Number.isInteger(key[prop]) || key[prop] < 0)) {\n errors.push(`Key definition at ${keyPath} \"${prop}\" must be a non-negative integer`)\n }\n }\n }\n }\n\n const keysByPosition = layout.layout.reduce((acc, key, i) => {\n const { row, col } = key\n const position = `(${row},${col})`\n\n if (row !== undefined && col !== undefined) {\n acc[position] = [...(acc[position] || []), i]\n }\n\n return acc\n }, {})\n\n for (const group of Object.values(keysByPosition)) {\n if (group.length <= 1) {\n continue\n }\n\n const { row, col } = layout.layout[group[0]]\n const coords = `{row: ${row}, col: ${col}}`\n for (const index of group) {\n const keyPath = `layouts[${name}].layout[${index}]`\n errors.push(`Key definition at ${keyPath} has overlapping position ${coords}`)\n }\n }\n\n errors.push(...validateSequentialRows(name, layout.layout))\n errors.push(...validateSequentialColumns(name, layout.layout))\n }\n }\n }\n\n if (errors.length) {\n throw new InfoValidationError(errors)\n }\n}\n\nfunction validateSequentialRows (name, layout) {\n let currentRow = -Infinity\n const errors = []\n\n for (const index of layout.keys()) {\n const { row } = layout[index]\n if (row === undefined) {\n continue\n }\n\n if (row < currentRow) {\n const keyPath = `layouts[${name}].layout[${index}]`\n errors.push(`Row index at ${keyPath} is not sequential`)\n } else {\n currentRow = row\n }\n }\n\n return errors\n}\n\nfunction validateSequentialColumns (name, layout) {\n let currentRow = 0\n let currentCol = -Infinity\n const errors = []\n\n for (const index of layout.keys()) {\n const { row, col } = layout[index]\n if (row === undefined || col === undefined) {\n continue\n }\n\n if (currentRow !== row) {\n currentRow = row\n currentCol = -Infinity\n }\n\n if (col < currentCol) {\n const keyPath = `layouts[${name}].layout[${index}]`\n errors.push(`Column index at ${keyPath} is not sequential`)\n } else {\n currentCol = col\n }\n }\n\n return errors\n}\n\nmodule.exports = {\n InfoValidationError,\n validateInfoJson\n}\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, description?: string }} PropertyDefinition */\n/** @typedef {Object.} Properties */\n/** @typedef {{ description?: string, compatible: string, include: string, properties: Properties }} BehaviorSchema */\n/** @typedef {Object.} */\nconst behaviorBindings = require('./data/extracted-data/behaviors.json')\n/** @type {Array} */\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\nconst parameterOverlays = require('./data/overlay-data/behavior-parameters.json')\nconst overlaysByCode = parameterOverlays.reduce((map, overlay) => {\n if (overlay.match.code) {\n map[`&${overlay.match.code}`] = overlay\n }\n\n return map\n}, {})\n\nconst overlaysByCompatible = parameterOverlays.reduce((map, overlay) => {\n if (overlay.match.compatible) {\n map[overlay.match.compatible] = overlay\n }\n\n return map\n}, {})\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\nfunction matchOverlay (behavior) {\n const refs = behavior.labels.map(label => `&${label}`)\n const compatible = behavior.properties.compatible?.parsed\n\n for (const ref of refs) {\n if (overlaysByCode[ref]) {\n return overlaysByCode[ref]\n }\n }\n\n if (overlaysByCompatible[compatible]) {\n return overlaysByCompatible[compatible]\n }\n}\n\n/** @typedef {string} Identifier */\n/** @typedef {string} Label */\n/** @typedef {{ parsed: any, raw: string, useRaw?: boolean }} PropertyValue */\n/** @typedef {Object.} Properties */\n/** @typedef {{ name: string, labels: Array, 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} 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 const parameters = {}\n\n /**\n * @param {ParsedBehavior} behavior\n * @param {Array} [queue=[]]\n * @returns {void}\n */\n function resolve (behavior, queue = []) {\n const code = `&${behavior.labels[0]}`\n\n if (parameters[code]) {\n return parameters[code]\n }\n\n const overlay = matchOverlay(behavior)\n\n if (overlay) {\n return overlay.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 const resolved = resolve(nextBehavior, [...queue, binding])\n for (const label of nextBehavior.labels) {\n parameters[`&${label}`] = resolved\n }\n params.push(resolved[0] || { type: 'placeholder' })\n } catch (error) {\n if (error instanceof BehaviorResolutionError) {\n nextBehavior.error = error.message\n parameters[binding] = []\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 const resolved = resolve(behavior)\n for (const alias of behavior.labels) {\n parameters[`&${alias}`] = resolved\n }\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 const resolved = times(parseNumBindingCells(behavior) || 0, () => ({ raw: true }))\n for (const alias of behavior.labels) {\n parameters[`&${alias}`] = resolved\n }\n }\n }\n\n return parameters\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","compact","flatten","get","keyBy","omitBy","uniq","behaviorBindings","renderLayout","encodeKeyBinding","KeymapDocument","behavioursByBind","getBehaviorsUsed","keymap","behaviors","layers","combos","macros","binding","layout","original","featureFlags","layer","useRaw","formatLayerKeybinds","behaviorHeaders","devicetreeKeymap","mergeUpdated","replaceBehaviourIncludes","err","error","groupPhandleArrayBindings","bindingCells","MACRO_CONTROL_BEHAVIOURS","encodeBindValue","params","paramString","parseBindings","parseKeyBinding","paramsPattern","code","s","defines","groupMacroBindings","rows","behaviourBind","at","behaviorSchemas","rootNodes","_","behavior","last","nodeContent","extracted","super","extractedProp","bindStrings","bindingsValue","bindCode","serialized","bindString","comboSchema","combo","legacyParse","legacyNode","legacyMapping","legacyParseNodes","layerSchema","updateLayerPositions","positionMap","nextIndex","j","targetIndexOrder","pick","BehaviorCollection","macro","serializeMacroBindings","prototype","call","standardBehaviorIncludeFiles","MacroCollection","ComboCollection","LayerCollection","args","macroCollection","comboCollection","layerCollection","behaviorCollection","getChosenProperties","chosen","updated","enableBehaviorEditing","sort","behaviorIncludes","ranges","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","extractWarnings","extractDefines","extractLocalHeaders","path","keymapText","headers","times","margin","table","col","rowIndices","columns","Math","max","columnIndices","columnWidths","noMoreValues","padding","padStart","isNumber","InfoValidationError","Error","errors","validateSequentialRows","currentRow","keyPath","validateSequentialColumns","currentCol","validateInfoJson","info","layouts","Array","isArray","anyKeyHasPosition","optionalNumberProps","x","y","isInteger","keysByPosition","position","coords","_dedentedLines","minIndentation","leastIndentation","min","Infinity","idx","merge","isMatch","behaviorSchemaAdditions","behaviorAdditions","behaviorSchemaOverlays","behaviorOverlays","mergeBehaviorOverlays","base","overlays","baseValues","overlay","singleValue","patternMappings","pattern","convert","digit","char","toUpperCase","simpleMappings","mapCharacter","keycodes","keycodeGlyphs","basic","unicode","platforms","mac","win","parameterOverlays","overlaysByCode","overlaysByCompatible","BehaviorResolutionError","message","parseNumBindingCells","behaviorMap","resolveBehaviorParams","standardBindingsMap","newBindingsMap","parameters","resolve","refs","ref","matchOverlay","bindingsType","nextBehavior","resolved","alias"],"sourceRoot":""}