@revisium/formula 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +27 -0
  2. package/dist/__tests__/array-context.spec.d.ts +2 -0
  3. package/dist/__tests__/array-context.spec.d.ts.map +1 -0
  4. package/dist/__tests__/dependency-graph.spec.d.ts +2 -0
  5. package/dist/__tests__/dependency-graph.spec.d.ts.map +1 -0
  6. package/dist/__tests__/evaluate-complex.spec.d.ts +2 -0
  7. package/dist/__tests__/evaluate-complex.spec.d.ts.map +1 -0
  8. package/dist/__tests__/parse-formula.spec.d.ts +2 -0
  9. package/dist/__tests__/parse-formula.spec.d.ts.map +1 -0
  10. package/dist/__tests__/parser.spec.d.ts +2 -0
  11. package/dist/__tests__/parser.spec.d.ts.map +1 -0
  12. package/dist/__tests__/replace-dependencies.spec.d.ts +2 -0
  13. package/dist/__tests__/replace-dependencies.spec.d.ts.map +1 -0
  14. package/dist/__tests__/serialize-ast.spec.d.ts +2 -0
  15. package/dist/__tests__/serialize-ast.spec.d.ts.map +1 -0
  16. package/dist/__tests__/validate-syntax.spec.d.ts +2 -0
  17. package/dist/__tests__/validate-syntax.spec.d.ts.map +1 -0
  18. package/dist/dependency-graph.d.ts +17 -0
  19. package/dist/dependency-graph.d.ts.map +1 -0
  20. package/dist/editor/index.cjs +4 -19
  21. package/dist/editor/index.d.ts +8 -1
  22. package/dist/editor/index.d.ts.map +1 -0
  23. package/dist/editor/index.mjs +3 -0
  24. package/dist/formula-spec.cjs +808 -535
  25. package/dist/formula-spec.cjs.map +1 -1
  26. package/dist/formula-spec.d.ts +10 -5
  27. package/dist/formula-spec.d.ts.map +1 -0
  28. package/dist/formula-spec.mjs +1039 -0
  29. package/dist/formula-spec.mjs.map +1 -0
  30. package/dist/index.cjs +121 -123
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.ts +10 -20
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.mjs +130 -0
  35. package/dist/index.mjs.map +1 -0
  36. package/dist/ohm/core/parser.d.ts +30 -0
  37. package/dist/ohm/core/parser.d.ts.map +1 -0
  38. package/dist/ohm/core/replace-dependencies.d.ts +3 -0
  39. package/dist/ohm/core/replace-dependencies.d.ts.map +1 -0
  40. package/dist/ohm/core/serialize-ast.d.ts +3 -0
  41. package/dist/ohm/core/serialize-ast.d.ts.map +1 -0
  42. package/dist/ohm/core/types.d.ts +78 -0
  43. package/dist/ohm/core/types.d.ts.map +1 -0
  44. package/dist/ohm/grammar/index.d.ts +3 -0
  45. package/dist/ohm/grammar/index.d.ts.map +1 -0
  46. package/dist/ohm/index.d.ts +8 -0
  47. package/dist/ohm/index.d.ts.map +1 -0
  48. package/dist/ohm/semantics/index.d.ts +2 -0
  49. package/dist/ohm/semantics/index.d.ts.map +1 -0
  50. package/dist/parse-formula.d.ts +9 -0
  51. package/dist/parse-formula.d.ts.map +1 -0
  52. package/dist/types.d.ts +52 -0
  53. package/dist/types.d.ts.map +1 -0
  54. package/dist/validate-syntax-BGrLewnG.cjs +1502 -0
  55. package/dist/validate-syntax-BGrLewnG.cjs.map +1 -0
  56. package/dist/validate-syntax-CmqnFrsc.mjs +1421 -0
  57. package/dist/validate-syntax-CmqnFrsc.mjs.map +1 -0
  58. package/dist/validate-syntax.d.ts +9 -0
  59. package/dist/validate-syntax.d.ts.map +1 -0
  60. package/package.json +12 -11
  61. package/dist/chunk-5TM76LGI.js +0 -1216
  62. package/dist/chunk-5TM76LGI.js.map +0 -1
  63. package/dist/chunk-IM22W645.cjs +0 -1244
  64. package/dist/chunk-IM22W645.cjs.map +0 -1
  65. package/dist/editor/index.cjs.map +0 -1
  66. package/dist/editor/index.d.cts +0 -1
  67. package/dist/editor/index.js +0 -3
  68. package/dist/editor/index.js.map +0 -1
  69. package/dist/formula-spec.d.cts +0 -68
  70. package/dist/formula-spec.js +0 -765
  71. package/dist/formula-spec.js.map +0 -1
  72. package/dist/index-CPsOPCQ6.d.cts +0 -166
  73. package/dist/index-CPsOPCQ6.d.ts +0 -166
  74. package/dist/index.d.cts +0 -20
  75. package/dist/index.js +0 -111
  76. package/dist/index.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-syntax-BGrLewnG.cjs","names":["ohm"],"sources":["../src/ohm/grammar/index.ts","../src/ohm/semantics/index.ts","../src/ohm/core/parser.ts","../src/ohm/core/serialize-ast.ts","../src/ohm/core/replace-dependencies.ts","../src/parse-formula.ts","../src/validate-syntax.ts"],"sourcesContent":["import * as ohm from 'ohm-js';\n\n// Using String.raw to avoid double-escaping backslashes in Ohm grammar\n// In Ohm grammar, we need single backslashes for escape sequences\nconst grammarText = String.raw`Formula {\n Expression = Ternary\n\n // Ternary: condition ? then : else\n Ternary\n = LogicalOr \"?\" Ternary \":\" Ternary -- ternary\n | LogicalOr\n\n // Logical OR: a || b\n LogicalOr\n = LogicalOr \"||\" LogicalAnd -- or\n | LogicalAnd\n\n // Logical AND: a && b\n LogicalAnd\n = LogicalAnd \"&&\" Equality -- and\n | Equality\n\n // Equality: a == b, a != b\n Equality\n = Equality \"==\" Comparison -- eq\n | Equality \"!=\" Comparison -- neq\n | Comparison\n\n // Comparison: a > b, a < b, a >= b, a <= b\n Comparison\n = Comparison \">=\" Additive -- gte\n | Comparison \"<=\" Additive -- lte\n | Comparison \">\" Additive -- gt\n | Comparison \"<\" Additive -- lt\n | Additive\n\n // Additive: a + b, a - b\n Additive\n = Additive \"+\" Multiplicative -- plus\n | Additive \"-\" Multiplicative -- minus\n | Multiplicative\n\n // Multiplicative: a * b, a / b, a % b\n Multiplicative\n = Multiplicative \"*\" Unary -- times\n | Multiplicative \"/\" Unary -- div\n | Multiplicative \"%\" Unary -- mod\n | Unary\n\n // Unary: -a, !a\n Unary\n = \"-\" Unary -- neg\n | \"!\" Unary -- not\n | Postfix\n\n // Postfix: function calls, property access, array access\n Postfix\n = Postfix \"(\" Arguments? \")\" -- call\n | Postfix \".\" identifier -- property\n | Postfix \"[\" Expression \"]\" -- index\n | Postfix \"[\" \"*\" \"]\" -- wildcard\n | Primary\n\n // Arguments for function calls\n Arguments\n = Expression (\",\" Expression)*\n\n // Primary expressions\n Primary\n = \"(\" Expression \")\" -- paren\n | \"[\" string \"]\" -- bracketedField\n | number\n | string\n | boolean\n | null\n | rootPath\n | relativePath\n | contextToken\n | identifier\n\n // Literals\n number\n = \"-\"? digit+ \".\" digit+ -- float\n | \"-\"? digit+ -- int\n\n string\n = \"\\\"\" doubleStringChar* \"\\\"\"\n | \"'\" singleStringChar* \"'\"\n\n doubleStringChar\n = ~(\"\\\"\" | \"\\\\\") any -- regular\n | \"\\\\\" any -- escape\n\n singleStringChar\n = ~(\"'\" | \"\\\\\") any -- regular\n | \"\\\\\" any -- escape\n\n boolean\n = \"true\" ~identifierPart -- true\n | \"false\" ~identifierPart -- false\n\n null = \"null\" ~identifierPart\n\n // Identifiers and paths\n identifier = ~reserved identifierStart identifierPart*\n\n identifierStart = letter | \"_\"\n identifierPart = letter | digit | \"_\"\n\n // Special paths\n rootPath = \"/\" identifierPart+\n\n relativePathPrefix = \"..\" \"/\"\n relativePath = relativePathPrefix+ identifierPart+\n\n contextToken\n = \"@\" contextPath -- at\n | \"#\" contextPath -- hash\n\n contextPath\n = \"parent\" \".\" contextPath -- parent\n | \"root\" \".\" contextPathEnd -- root\n | contextPathEnd -- simple\n\n contextPathEnd = identifierPart+\n\n // Reserved words (cannot be used as identifiers)\n reserved\n = (\"true\" | \"false\" | \"null\") ~identifierPart\n\n // Whitespace (implicit, Ohm handles automatically)\n}`;\n\nexport const grammar = ohm.grammar(grammarText);\n","import type { NonterminalNode, TerminalNode, IterationNode } from 'ohm-js';\nimport { grammar } from '../grammar';\nimport type { ASTNode } from '../core/types';\nimport type { FormulaFeature } from '../../types';\n\ntype OhmNode = NonterminalNode | TerminalNode | IterationNode;\n\nfunction isSafePropertyName(name: string): boolean {\n return name !== '__proto__';\n}\n\nfunction childrenToAST(children: OhmNode[]): ASTNode[] {\n return children\n .filter((c): c is NonterminalNode => 'toAST' in c)\n .map((c) => c.toAST() as ASTNode);\n}\n\nfunction childrenDependencies(children: OhmNode[]): string[] {\n return children\n .filter((c): c is NonterminalNode => 'dependencies' in c)\n .flatMap((c) => c.dependencies() as string[]);\n}\n\nfunction childrenFeatures(children: OhmNode[]): FormulaFeature[] {\n return children\n .filter((c): c is NonterminalNode => 'features' in c)\n .flatMap((c) => c.features() as FormulaFeature[]);\n}\n\nexport const semantics = grammar.createSemantics();\n\n// ============ toAST Operation ============\nsemantics.addOperation<ASTNode>('toAST', {\n Expression(e) {\n return e.toAST();\n },\n\n Ternary_ternary(cond, _q, cons, _c, alt) {\n return {\n type: 'TernaryOp',\n condition: cond.toAST(),\n consequent: cons.toAST(),\n alternate: alt.toAST(),\n };\n },\n Ternary(e) {\n return e.toAST();\n },\n\n LogicalOr_or(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '||',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n LogicalOr(e) {\n return e.toAST();\n },\n\n LogicalAnd_and(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '&&',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n LogicalAnd(e) {\n return e.toAST();\n },\n\n Equality_eq(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '==',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Equality_neq(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '!=',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Equality(e) {\n return e.toAST();\n },\n\n Comparison_gte(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '>=',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Comparison_lte(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '<=',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Comparison_gt(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '>',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Comparison_lt(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '<',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Comparison(e) {\n return e.toAST();\n },\n\n Additive_plus(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '+',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Additive_minus(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '-',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Additive(e) {\n return e.toAST();\n },\n\n Multiplicative_times(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '*',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Multiplicative_div(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '/',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Multiplicative_mod(left, _op, right) {\n return {\n type: 'BinaryOp',\n op: '%',\n left: left.toAST(),\n right: right.toAST(),\n };\n },\n Multiplicative(e) {\n return e.toAST();\n },\n\n Unary_neg(_op, expr) {\n return { type: 'UnaryOp', op: '-', argument: expr.toAST() };\n },\n Unary_not(_op, expr) {\n return { type: 'UnaryOp', op: '!', argument: expr.toAST() };\n },\n Unary(e) {\n return e.toAST();\n },\n\n Postfix_call(callee, _lp, args, _rp) {\n const firstArg = args.children[0];\n const argList = firstArg ? firstArg.toAST() : [];\n return {\n type: 'CallExpression',\n callee: callee.toAST(),\n arguments: Array.isArray(argList) ? argList : [argList],\n };\n },\n Postfix_property(obj, _dot, prop) {\n return {\n type: 'MemberExpression',\n object: obj.toAST(),\n property: prop.sourceString,\n };\n },\n Postfix_index(obj, _lb, index, _rb) {\n const indexAST = index.toAST() as ASTNode;\n if (indexAST.type === 'StringLiteral') {\n return {\n type: 'BracketedMemberExpression',\n object: obj.toAST(),\n property: indexAST.value,\n };\n }\n return {\n type: 'IndexExpression',\n object: obj.toAST(),\n index: indexAST,\n };\n },\n Postfix_wildcard(obj, _lb, _star, _rb) {\n return {\n type: 'WildcardExpression',\n object: obj.toAST(),\n };\n },\n Postfix(e) {\n return e.toAST();\n },\n\n // Returns an array of arguments, not a single ASTNode\n // @ts-expect-error - intentionally returns array for function arguments\n Arguments(first, _comma, rest) {\n return [first.toAST(), ...rest.children.map((c) => c.toAST())];\n },\n\n Primary_paren(_lp, expr, _rp) {\n return expr.toAST();\n },\n Primary_bracketedField(_lb, str, _rb) {\n const strAST = str.toAST() as { type: 'StringLiteral'; value: string };\n return { type: 'BracketedIdentifier', name: strAST.value };\n },\n Primary(e) {\n return e.toAST();\n },\n\n number_float(_neg, _int, _dot, _frac) {\n return {\n type: 'NumberLiteral',\n value: Number.parseFloat(this.sourceString),\n };\n },\n number_int(_neg, _digits) {\n return {\n type: 'NumberLiteral',\n value: Number.parseInt(this.sourceString, 10),\n };\n },\n\n string(_open, chars, _close) {\n const raw = chars.sourceString;\n return { type: 'StringLiteral', value: raw.replaceAll(/\\\\(.)/g, '$1') };\n },\n\n boolean_true(_) {\n return { type: 'BooleanLiteral', value: true };\n },\n boolean_false(_) {\n return { type: 'BooleanLiteral', value: false };\n },\n\n null(_) {\n return { type: 'NullLiteral' };\n },\n\n identifier(_start, _rest) {\n return { type: 'Identifier', name: this.sourceString };\n },\n\n rootPath(_slash, _path) {\n return { type: 'RootPath', path: this.sourceString };\n },\n\n relativePath(_dotSlashes, _parts) {\n return { type: 'RelativePath', path: this.sourceString };\n },\n\n contextToken_at(_at, _path) {\n return { type: 'ContextToken', name: this.sourceString };\n },\n contextToken_hash(_hash, _path) {\n return { type: 'ContextToken', name: this.sourceString };\n },\n\n // @ts-expect-error - _iter returns array for iteration nodes\n _iter(...children) {\n return childrenToAST(children);\n },\n\n _terminal() {\n return { type: 'Identifier', name: this.sourceString };\n },\n});\n\n// ============ dependencies Operation ============\nsemantics.addOperation<string[]>('dependencies', {\n identifier(_start, _rest) {\n return [this.sourceString];\n },\n\n Primary_bracketedField(_lb, _str, _rb) {\n return [this.sourceString];\n },\n\n rootPath(_slash, _path) {\n return [this.sourceString];\n },\n\n relativePath(_dotSlashes, _parts) {\n return [this.sourceString];\n },\n\n contextToken_at(_at, _path) {\n return [];\n },\n contextToken_hash(_hash, _path) {\n return [];\n },\n\n Postfix_property(obj, _dot, prop) {\n const objDeps = obj.dependencies() as string[];\n if (objDeps.length === 1) {\n return [`${objDeps[0]}.${prop.sourceString}`];\n }\n return objDeps;\n },\n\n Postfix_index(obj, _lb, index, _rb) {\n const objDeps = obj.dependencies() as string[];\n const indexNode = index.toAST() as ASTNode;\n\n if (indexNode.type === 'StringLiteral') {\n const strValue = indexNode.value;\n const quote = this.sourceString.includes('\"') ? '\"' : \"'\";\n if (objDeps.length === 1) {\n return [`${objDeps[0]}[${quote}${strValue}${quote}]`];\n }\n return objDeps;\n }\n\n const getNumericIndex = (node: ASTNode): number | null => {\n if (node.type === 'NumberLiteral') {\n return node.value;\n }\n if (\n node.type === 'UnaryOp' &&\n node.op === '-' &&\n node.argument.type === 'NumberLiteral'\n ) {\n return -node.argument.value;\n }\n return null;\n };\n\n const numericIndex = getNumericIndex(indexNode);\n if (objDeps.length === 1 && numericIndex !== null) {\n return [`${objDeps[0]}[${numericIndex}]`];\n }\n return [...objDeps, ...(index.dependencies() as string[])];\n },\n\n Postfix_wildcard(obj, _lb, _star, _rb) {\n const objDeps = obj.dependencies() as string[];\n if (objDeps.length === 1) {\n return [`${objDeps[0]}[*]`];\n }\n return objDeps;\n },\n\n Postfix_call(callee, _lp, args, _rp) {\n const calleeDeps = callee.dependencies() as string[];\n const calleeAST = callee.toAST() as ASTNode;\n const argDeps = childrenDependencies(args.children);\n\n if (calleeAST.type === 'Identifier') {\n return argDeps;\n }\n return [...calleeDeps, ...argDeps];\n },\n\n number_float(_neg, _int, _dot, _frac) {\n return [];\n },\n number_int(_neg, _digits) {\n return [];\n },\n\n string(_open, _chars, _close) {\n return [];\n },\n\n boolean_true(_) {\n return [];\n },\n boolean_false(_) {\n return [];\n },\n\n null(_) {\n return [];\n },\n\n _nonterminal(...children) {\n return childrenDependencies(children);\n },\n\n _iter(...children) {\n return childrenDependencies(children);\n },\n\n _terminal() {\n return [];\n },\n});\n\n// ============ features Operation ============\nconst ARRAY_FUNCTIONS = new Set([\n 'sum',\n 'avg',\n 'count',\n 'first',\n 'last',\n 'join',\n 'includes',\n]);\n\nsemantics.addOperation<FormulaFeature[]>('features', {\n Primary_bracketedField(_lb, _str, _rb) {\n return ['bracket_notation'];\n },\n\n rootPath(_slash, _path) {\n const path = this.sourceString;\n const features: FormulaFeature[] = ['root_path'];\n if (path.includes('.')) {\n features.push('nested_path');\n }\n return features;\n },\n\n relativePath(_dotSlashes, _parts) {\n const path = this.sourceString;\n const features: FormulaFeature[] = ['relative_path'];\n const withoutPrefix = path.replace(/^(\\.\\.\\/)+/, '');\n if (withoutPrefix.includes('.')) {\n features.push('nested_path');\n }\n return features;\n },\n\n contextToken_at(_at, _path) {\n return ['context_token'];\n },\n contextToken_hash(_hash, _path) {\n return ['context_token'];\n },\n\n Postfix_property(obj, _dot, _prop) {\n const objFeatures = obj.features() as FormulaFeature[];\n return [...objFeatures, 'nested_path'];\n },\n\n Postfix_index(obj, _lb, index, _rb) {\n const objFeatures = obj.features() as FormulaFeature[];\n const indexFeatures = index.features() as FormulaFeature[];\n const indexNode = index.toAST() as ASTNode;\n if (indexNode.type === 'StringLiteral') {\n return [...objFeatures, ...indexFeatures, 'bracket_notation'];\n }\n return [...objFeatures, ...indexFeatures, 'array_index'];\n },\n\n Postfix_wildcard(obj, _lb, _star, _rb) {\n const objFeatures = obj.features() as FormulaFeature[];\n return [...objFeatures, 'array_wildcard'];\n },\n\n Postfix_call(callee, _lp, args, _rp) {\n const calleeAST = callee.toAST() as ASTNode;\n const argFeatures = childrenFeatures(args.children);\n\n if (\n calleeAST.type === 'Identifier' &&\n ARRAY_FUNCTIONS.has(calleeAST.name.toLowerCase())\n ) {\n return [...argFeatures, 'array_function'];\n }\n return argFeatures;\n },\n\n _nonterminal(...children) {\n return childrenFeatures(children);\n },\n\n _iter(...children) {\n return childrenFeatures(children);\n },\n\n _terminal() {\n return [];\n },\n});\n\n// ============ eval Operation ============\nconst BUILTINS: Record<string, (...args: unknown[]) => unknown> = {\n // Logical\n and: (a, b) => Boolean(a) && Boolean(b),\n or: (a, b) => Boolean(a) || Boolean(b),\n not: (a) => !a,\n\n // String\n concat: (...args) => args.map(String).join(''),\n upper: (s) => String(s).toUpperCase(),\n lower: (s) => String(s).toLowerCase(),\n trim: (s) => String(s).trim(),\n left: (s, n) => String(s).slice(0, Math.max(0, Math.floor(Number(n)))),\n right: (s, n) => {\n const str = String(s);\n const count = Math.max(0, Math.floor(Number(n)));\n return count === 0 ? '' : str.slice(-count);\n },\n replace: (s, search, repl) => String(s).replace(String(search), String(repl)),\n tostring: String,\n length: (s) => {\n if (Array.isArray(s)) return s.length;\n if (typeof s === 'string') return s.length;\n if (s !== null && typeof s === 'object') return Object.keys(s).length;\n return String(s).length;\n },\n contains: (s, search) => String(s).includes(String(search)),\n startswith: (s, search) => String(s).startsWith(String(search)),\n endswith: (s, search) => String(s).endsWith(String(search)),\n join: (arr: unknown, sep: unknown) => {\n if (!Array.isArray(arr)) return '';\n if (sep === undefined || sep === null) return arr.join(',');\n if (typeof sep !== 'string' && typeof sep !== 'number') {\n return arr.join(',');\n }\n return arr.join(String(sep));\n },\n\n // Numeric\n tonumber: Number,\n toboolean: Boolean,\n isnull: (v) => v === null || v === undefined,\n coalesce: (...args) =>\n args.find((v) => v !== null && v !== undefined) ?? null,\n round: (n, dec) => {\n const factor = 10 ** (dec === undefined ? 0 : Number(dec));\n return Math.round(Number(n) * factor) / factor;\n },\n floor: (n) => Math.floor(Number(n)),\n ceil: (n) => Math.ceil(Number(n)),\n abs: (n) => Math.abs(Number(n)),\n sqrt: (n) => Math.sqrt(Number(n)),\n pow: (base, exp) => Math.pow(Number(base), Number(exp)),\n min: (...args) =>\n args.length === 0 ? Number.NaN : Math.min(...args.map(Number)),\n max: (...args) =>\n args.length === 0 ? Number.NaN : Math.max(...args.map(Number)),\n log: (n) => Math.log(Number(n)),\n log10: (n) => Math.log10(Number(n)),\n exp: (n) => Math.exp(Number(n)),\n sign: (n) => Math.sign(Number(n)),\n\n // Array\n sum: (arr) =>\n Array.isArray(arr) ? arr.reduce((a, b) => a + Number(b), 0) : 0,\n avg: (arr) =>\n Array.isArray(arr) && arr.length > 0\n ? arr.reduce((a, b) => a + Number(b), 0) / arr.length\n : 0,\n count: (arr) => (Array.isArray(arr) ? arr.length : 0),\n first: (arr) => (Array.isArray(arr) ? arr[0] : undefined),\n last: (arr) => (Array.isArray(arr) ? arr.at(-1) : undefined),\n includes: (arr, val) => (Array.isArray(arr) ? arr.includes(val) : false),\n\n // Conditional\n if: (cond, ifTrue, ifFalse) => (cond ? ifTrue : ifFalse),\n};\n\nfunction getByPath(obj: unknown, path: string): unknown {\n const parts = path.split('.');\n let current = obj;\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n\nsemantics.addOperation<unknown>('eval(ctx)', {\n Expression(e) {\n return e.eval(this.args.ctx);\n },\n\n Ternary_ternary(cond, _q, cons, _c, alt) {\n return cond.eval(this.args.ctx)\n ? cons.eval(this.args.ctx)\n : alt.eval(this.args.ctx);\n },\n Ternary(e) {\n return e.eval(this.args.ctx);\n },\n\n LogicalOr_or(left, _op, right) {\n return left.eval(this.args.ctx) || right.eval(this.args.ctx);\n },\n LogicalOr(e) {\n return e.eval(this.args.ctx);\n },\n\n LogicalAnd_and(left, _op, right) {\n return left.eval(this.args.ctx) && right.eval(this.args.ctx);\n },\n LogicalAnd(e) {\n return e.eval(this.args.ctx);\n },\n\n Equality_eq(left, _op, right) {\n return left.eval(this.args.ctx) == right.eval(this.args.ctx);\n },\n Equality_neq(left, _op, right) {\n return left.eval(this.args.ctx) != right.eval(this.args.ctx);\n },\n Equality(e) {\n return e.eval(this.args.ctx);\n },\n\n Comparison_gte(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) >=\n (right.eval(this.args.ctx) as number)\n );\n },\n Comparison_lte(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) <=\n (right.eval(this.args.ctx) as number)\n );\n },\n Comparison_gt(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) >\n (right.eval(this.args.ctx) as number)\n );\n },\n Comparison_lt(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) <\n (right.eval(this.args.ctx) as number)\n );\n },\n Comparison(e) {\n return e.eval(this.args.ctx);\n },\n\n Additive_plus(left, _op, right): unknown {\n const l = left.eval(this.args.ctx);\n const r = right.eval(this.args.ctx);\n if (typeof l === 'string' || typeof r === 'string') {\n return String(l) + String(r);\n }\n return (l as number) + (r as number);\n },\n Additive_minus(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) -\n (right.eval(this.args.ctx) as number)\n );\n },\n Additive(e) {\n return e.eval(this.args.ctx);\n },\n\n Multiplicative_times(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) *\n (right.eval(this.args.ctx) as number)\n );\n },\n Multiplicative_div(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) /\n (right.eval(this.args.ctx) as number)\n );\n },\n Multiplicative_mod(left, _op, right) {\n return (\n (left.eval(this.args.ctx) as number) %\n (right.eval(this.args.ctx) as number)\n );\n },\n Multiplicative(e) {\n return e.eval(this.args.ctx);\n },\n\n Unary_neg(_op, expr) {\n return -(expr.eval(this.args.ctx) as number);\n },\n Unary_not(_op, expr) {\n return !expr.eval(this.args.ctx);\n },\n Unary(e) {\n return e.eval(this.args.ctx);\n },\n\n Postfix_call(callee, _lp, args, _rp) {\n const calleeAST = callee.toAST() as ASTNode;\n\n const getArgValues = (): unknown[] => {\n const argsNode = args.children[0];\n if (!argsNode) {\n return [];\n }\n return argsNode.eval(this.args.ctx) as unknown[];\n };\n\n if (calleeAST.type === 'Identifier') {\n const fnName = calleeAST.name.toLowerCase();\n const builtinFn = BUILTINS[fnName];\n if (builtinFn) {\n return builtinFn(...getArgValues());\n }\n }\n\n const fn = callee.eval(this.args.ctx);\n if (typeof fn === 'function') {\n return fn(...getArgValues());\n }\n\n const calleeName =\n calleeAST.type === 'Identifier' ? calleeAST.name : 'expression';\n throw new Error(`'${calleeName}' is not a function`);\n },\n Postfix_property(obj, _dot, prop) {\n const objVal = obj.eval(this.args.ctx) as Record<string, unknown>;\n return objVal?.[prop.sourceString];\n },\n Postfix_index(obj, _lb, index, _rb) {\n const objVal = obj.eval(this.args.ctx);\n const idx = index.eval(this.args.ctx);\n if (typeof idx === 'string') {\n if (!isSafePropertyName(idx)) {\n return undefined;\n }\n return (objVal as Record<string, unknown>)?.[idx];\n }\n const numIdx = idx as number;\n if (numIdx < 0) {\n return (objVal as unknown[])?.[(objVal as unknown[]).length + numIdx];\n }\n return (objVal as unknown[])?.[numIdx];\n },\n Postfix_wildcard(obj, _lb, _star, _rb) {\n return obj.eval(this.args.ctx);\n },\n Postfix(e) {\n return e.eval(this.args.ctx);\n },\n\n Arguments(first, _comma, rest) {\n return [\n first.eval(this.args.ctx),\n ...rest.children.map((c) => c.eval(this.args.ctx)),\n ];\n },\n\n Primary_paren(_lp, expr, _rp) {\n return expr.eval(this.args.ctx);\n },\n Primary_bracketedField(_lb, str, _rb) {\n const fieldName = str.eval(this.args.ctx) as string;\n if (!isSafePropertyName(fieldName)) {\n return undefined;\n }\n return this.args.ctx[fieldName];\n },\n Primary(e) {\n return e.eval(this.args.ctx);\n },\n\n number_float(_neg, _int, _dot, _frac) {\n return Number.parseFloat(this.sourceString);\n },\n number_int(_neg, _digits) {\n return Number.parseInt(this.sourceString, 10);\n },\n\n string(_open, chars, _close) {\n return chars.sourceString.replaceAll(/\\\\(.)/g, '$1');\n },\n\n boolean_true(_) {\n return true;\n },\n boolean_false(_) {\n return false;\n },\n\n null(_) {\n return null;\n },\n\n identifier(_start, _rest) {\n const name = this.sourceString;\n return this.args.ctx[name];\n },\n\n rootPath(_slash, _path) {\n const fullPath = this.sourceString;\n if (fullPath in this.args.ctx) {\n return this.args.ctx[fullPath];\n }\n const parts = fullPath.slice(1).split('.');\n const firstPart = parts[0];\n if (!firstPart) return undefined;\n const rootKey = '/' + firstPart;\n let value = this.args.ctx[rootKey];\n for (let i = 1; i < parts.length; i++) {\n if (value === null || value === undefined) return undefined;\n const part = parts[i];\n if (!part) continue;\n value = (value as Record<string, unknown>)[part];\n }\n return value;\n },\n\n relativePath(_dotSlashes, _parts) {\n const fullPath = this.sourceString;\n if (fullPath in this.args.ctx) {\n return this.args.ctx[fullPath];\n }\n const path = fullPath.replace(/^(\\.\\.\\/)+/, '');\n return getByPath(this.args.ctx, path);\n },\n\n contextToken_at(_at, _path) {\n return this.args.ctx[this.sourceString];\n },\n contextToken_hash(_hash, _path) {\n return this.args.ctx[this.sourceString];\n },\n\n _nonterminal(...children) {\n const ctx = this.args.ctx;\n for (const child of children) {\n if ('eval' in child) {\n return child.eval(ctx);\n }\n }\n return undefined;\n },\n\n _iter(...children) {\n return children.map((c) => c.eval(this.args.ctx));\n },\n\n _terminal() {\n return undefined;\n },\n});\n","import { grammar } from '../grammar';\nimport { semantics } from '../semantics';\nimport type { ASTNode } from './types';\nimport type {\n ArrayContext,\n ArrayLevelContext,\n FormulaFeature,\n FormulaMinorVersion,\n} from '../../types';\n\nfunction detectMinVersion(features: FormulaFeature[]): FormulaMinorVersion {\n if (features.includes('context_token')) {\n return '1.2';\n }\n if (features.length > 0) {\n return '1.1';\n }\n return '1.0';\n}\n\nexport interface ParseResult {\n ast: ASTNode;\n dependencies: string[];\n features: FormulaFeature[];\n minVersion: FormulaMinorVersion;\n}\n\nexport function parseFormula(expression: string): ParseResult {\n const trimmed = expression.trim();\n if (!trimmed) {\n throw new Error('Empty expression');\n }\n\n const matchResult = grammar.match(trimmed);\n if (matchResult.failed()) {\n throw new Error(matchResult.message ?? 'Parse error');\n }\n\n const adapter = semantics(matchResult);\n const ast = adapter.toAST() as ASTNode;\n const dependencies = [...new Set(adapter.dependencies() as string[])];\n const allFeatures = adapter.features() as FormulaFeature[];\n const features = [...new Set(allFeatures)];\n const minVersion: FormulaMinorVersion = detectMinVersion(features);\n\n return { ast, dependencies, features, minVersion };\n}\n\nexport function validateSyntax(\n expression: string,\n): { isValid: true } | { isValid: false; error: string; position?: number } {\n const trimmed = expression.trim();\n if (!trimmed) {\n return { isValid: false, error: 'Empty expression' };\n }\n\n const matchResult = grammar.match(trimmed);\n if (matchResult.failed()) {\n const pos = matchResult.getRightmostFailurePosition?.();\n return {\n isValid: false,\n error: matchResult.message ?? 'Parse error',\n position: pos,\n };\n }\n\n return { isValid: true };\n}\n\nexport function evaluate(\n expression: string,\n context: Record<string, unknown>,\n): unknown {\n const trimmed = expression.trim();\n if (!trimmed) {\n throw new Error('Empty expression');\n }\n\n const matchResult = grammar.match(trimmed);\n if (matchResult.failed()) {\n throw new Error(matchResult.message ?? 'Parse error');\n }\n\n const safeContext: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(context)) {\n if (typeof value !== 'function') {\n safeContext[key] = value;\n }\n }\n\n return semantics(matchResult).eval(safeContext);\n}\n\nexport interface EvaluateContextOptions {\n rootData: Record<string, unknown>;\n itemData?: Record<string, unknown>;\n currentPath?: string;\n arrayContext?: ArrayContext;\n}\n\nfunction parseCurrentPath(currentPath: string): string[] {\n const segments: string[] = [];\n let current = '';\n let inBracket = false;\n\n for (const char of currentPath) {\n if (char === '[') {\n inBracket = true;\n current += char;\n } else if (char === ']') {\n inBracket = false;\n current += char;\n } else if (char === '.' && !inBracket) {\n if (current) {\n segments.push(current);\n current = '';\n }\n } else {\n current += char;\n }\n }\n\n if (current) {\n segments.push(current);\n }\n\n return segments;\n}\n\nfunction getValueByPath(data: Record<string, unknown>, path: string): unknown {\n const segments = parseCurrentPath(path);\n let current: unknown = data;\n\n for (const segment of segments) {\n if (current === null || current === undefined) {\n return undefined;\n }\n if (typeof current !== 'object') {\n return undefined;\n }\n\n const bracketMatch = /^([^[]+)\\[(\\d+)\\]$/.exec(segment);\n if (bracketMatch?.[1] && bracketMatch[2]) {\n const fieldName = bracketMatch[1];\n const index = Number.parseInt(bracketMatch[2], 10);\n const arr = (current as Record<string, unknown>)[fieldName];\n if (!Array.isArray(arr)) {\n return undefined;\n }\n current = arr[index];\n } else {\n current = (current as Record<string, unknown>)[segment];\n }\n }\n\n return current;\n}\n\nfunction extractRootField(fieldPath: string): string {\n const dotIndex = fieldPath.indexOf('.');\n const bracketIndex = fieldPath.indexOf('[');\n\n if (dotIndex === -1 && bracketIndex === -1) {\n return fieldPath;\n }\n if (dotIndex === -1) {\n return fieldPath.slice(0, bracketIndex);\n }\n if (bracketIndex === -1) {\n return fieldPath.slice(0, dotIndex);\n }\n return fieldPath.slice(0, Math.min(dotIndex, bracketIndex));\n}\n\nfunction countParentLevels(path: string): number {\n let count = 0;\n let remaining = path;\n while (remaining.startsWith('../')) {\n count++;\n remaining = remaining.slice(3);\n }\n return count;\n}\n\nfunction getPathAfterParents(path: string): string {\n return path.replace(/^(\\.\\.\\/)+/, '');\n}\n\nfunction resolveRelativePath(\n rootData: Record<string, unknown>,\n currentPath: string | undefined,\n relativePath: string,\n): unknown {\n const parentLevels = countParentLevels(relativePath);\n const fieldPath = getPathAfterParents(relativePath);\n\n if (!currentPath) {\n return getValueByPath(rootData, fieldPath);\n }\n\n const pathSegments = parseCurrentPath(currentPath);\n const targetLevel = pathSegments.length - parentLevels;\n\n if (targetLevel <= 0) {\n return getValueByPath(rootData, fieldPath);\n }\n\n const basePath = pathSegments.slice(0, targetLevel).join('.');\n const fullPath = basePath ? `${basePath}.${fieldPath}` : fieldPath;\n\n return getValueByPath(rootData, fullPath);\n}\n\nfunction extractRelativeBase(relativePath: string): string {\n const pathAfterParents = getPathAfterParents(relativePath);\n const baseField = extractRootField(pathAfterParents);\n const prefix = relativePath.slice(\n 0,\n relativePath.length - pathAfterParents.length,\n );\n return prefix + baseField;\n}\n\nfunction buildArrayContextTokens(\n arrayContext: ArrayContext | undefined,\n): Record<string, unknown> {\n if (!arrayContext || arrayContext.levels.length === 0) {\n return {};\n }\n\n const tokens: Record<string, unknown> = {};\n const levels = arrayContext.levels;\n\n const buildLevelTokens = (level: ArrayLevelContext, prefix: string): void => {\n tokens[`${prefix}index`] = level.index;\n tokens[`${prefix}length`] = level.length;\n tokens[`${prefix}first`] = level.index === 0;\n tokens[`${prefix}last`] = level.index === level.length - 1;\n };\n\n const buildNeighborTokens = (\n level: ArrayLevelContext,\n prefix: string,\n ): void => {\n tokens[`${prefix}prev`] = level.prev;\n tokens[`${prefix}next`] = level.next;\n };\n\n if (levels[0]) {\n buildLevelTokens(levels[0], '#');\n buildNeighborTokens(levels[0], '@');\n }\n\n let parentPrefix = '#parent.';\n let atParentPrefix = '@parent.';\n for (let i = 1; i < levels.length; i++) {\n const level = levels[i];\n if (level) {\n buildLevelTokens(level, parentPrefix);\n buildNeighborTokens(level, atParentPrefix);\n }\n parentPrefix = '#parent.' + parentPrefix.slice(1);\n atParentPrefix = '@parent.' + atParentPrefix.slice(1);\n }\n\n const rootLevel = levels.at(-1);\n if (rootLevel) {\n tokens['#root.index'] = rootLevel.index;\n tokens['#root.length'] = rootLevel.length;\n tokens['#root.first'] = rootLevel.index === 0;\n tokens['#root.last'] = rootLevel.index === rootLevel.length - 1;\n tokens['@root.prev'] = rootLevel.prev;\n tokens['@root.next'] = rootLevel.next;\n }\n\n return tokens;\n}\n\nfunction buildPathReferences(\n rootData: Record<string, unknown>,\n dependencies: string[],\n currentPath?: string,\n): Record<string, unknown> {\n const refs: Record<string, unknown> = {};\n\n for (const dep of dependencies) {\n if (dep.startsWith('/')) {\n const fieldPath = dep.slice(1);\n const rootField = extractRootField(fieldPath);\n const contextKey = '/' + rootField;\n if (!(contextKey in refs)) {\n refs[contextKey] = getValueByPath(rootData, rootField);\n }\n } else if (dep.startsWith('../')) {\n const contextKey = extractRelativeBase(dep);\n if (!(contextKey in refs)) {\n refs[contextKey] = resolveRelativePath(\n rootData,\n currentPath,\n contextKey,\n );\n }\n }\n }\n\n return refs;\n}\n\nexport function evaluateWithContext(\n expression: string,\n options: EvaluateContextOptions,\n): unknown {\n const { rootData, itemData, currentPath, arrayContext } = options;\n const trimmed = expression.trim();\n\n if (!trimmed) {\n throw new Error('Empty expression');\n }\n\n const parsed = parseFormula(trimmed);\n const pathRefs = buildPathReferences(\n rootData,\n parsed.dependencies,\n currentPath,\n );\n const arrayTokens = buildArrayContextTokens(arrayContext);\n\n const context: Record<string, unknown> = {\n ...rootData,\n ...itemData,\n ...pathRefs,\n ...arrayTokens,\n };\n\n return evaluate(trimmed, context);\n}\n\nexport type InferredType = 'number' | 'boolean' | 'string' | 'unknown';\n\nexport interface FieldTypes {\n [fieldName: string]: 'number' | 'string' | 'boolean' | 'object' | 'array';\n}\n\nconst ARITHMETIC_OPS = new Set(['+', '-', '*', '/', '%']);\nconst COMPARISON_OPS = new Set(['<', '>', '<=', '>=', '==', '!=']);\nconst LOGICAL_OPS = new Set(['&&', '||', '!']);\nconst NUMERIC_FUNCTIONS = new Set([\n 'round',\n 'floor',\n 'ceil',\n 'abs',\n 'sqrt',\n 'pow',\n 'min',\n 'max',\n 'log',\n 'log10',\n 'exp',\n 'sign',\n 'sum',\n 'avg',\n 'count',\n 'tonumber',\n 'length',\n]);\nconst STRING_FUNCTIONS = new Set([\n 'concat',\n 'upper',\n 'lower',\n 'trim',\n 'left',\n 'right',\n 'replace',\n 'tostring',\n 'join',\n]);\nconst BOOLEAN_FUNCTIONS = new Set([\n 'and',\n 'or',\n 'not',\n 'contains',\n 'startswith',\n 'endswith',\n 'isnull',\n 'toboolean',\n 'includes',\n]);\n\nfunction getFieldType(path: string, fieldTypes: FieldTypes): InferredType {\n const rootField = path.split('.')[0]?.split('[')[0] || path;\n const schemaType = fieldTypes[rootField];\n if (schemaType === 'number') return 'number';\n if (schemaType === 'string') return 'string';\n if (schemaType === 'boolean') return 'boolean';\n return 'unknown';\n}\n\nfunction inferLiteralType(node: ASTNode): InferredType | null {\n switch (node.type) {\n case 'NumberLiteral':\n return 'number';\n case 'BooleanLiteral':\n return 'boolean';\n case 'StringLiteral':\n return 'string';\n case 'NullLiteral':\n return 'unknown';\n default:\n return null;\n }\n}\n\nfunction inferBinaryOpType(\n node: ASTNode & { type: 'BinaryOp' },\n fieldTypes: FieldTypes,\n): InferredType {\n const { op } = node;\n if (op === '+') {\n const leftType = inferTypeFromAST(node.left, fieldTypes);\n const rightType = inferTypeFromAST(node.right, fieldTypes);\n if (leftType === 'string' || rightType === 'string') return 'string';\n if (leftType === 'unknown' || rightType === 'unknown') return 'unknown';\n return 'number';\n }\n if (ARITHMETIC_OPS.has(op)) return 'number';\n if (COMPARISON_OPS.has(op)) return 'boolean';\n if (LOGICAL_OPS.has(op)) return 'boolean';\n return 'unknown';\n}\n\nfunction inferCallExpressionType(\n node: ASTNode & { type: 'CallExpression' },\n fieldTypes: FieldTypes,\n): InferredType {\n const funcName =\n node.callee.type === 'Identifier' ? node.callee.name.toLowerCase() : '';\n if (NUMERIC_FUNCTIONS.has(funcName)) return 'number';\n if (STRING_FUNCTIONS.has(funcName)) return 'string';\n if (BOOLEAN_FUNCTIONS.has(funcName)) return 'boolean';\n if (funcName === 'if' && node.arguments.length >= 3) {\n const thenArg = node.arguments[1];\n const elseArg = node.arguments[2];\n if (thenArg && elseArg) {\n const thenType = inferTypeFromAST(thenArg, fieldTypes);\n const elseType = inferTypeFromAST(elseArg, fieldTypes);\n if (thenType === elseType) return thenType;\n }\n }\n return 'unknown';\n}\n\nfunction inferTypeFromAST(node: ASTNode, fieldTypes: FieldTypes): InferredType {\n const literalType = inferLiteralType(node);\n if (literalType !== null) return literalType;\n\n switch (node.type) {\n case 'Identifier':\n return getFieldType(node.name, fieldTypes);\n case 'RootPath':\n case 'RelativePath':\n case 'ContextToken':\n case 'IndexExpression':\n case 'WildcardExpression':\n return 'unknown';\n case 'MemberExpression': {\n const objectType = inferTypeFromAST(node.object, fieldTypes);\n if (objectType !== 'unknown') return objectType;\n if (node.object.type === 'Identifier') {\n return getFieldType(`${node.object.name}.${node.property}`, fieldTypes);\n }\n return 'unknown';\n }\n case 'BinaryOp':\n return inferBinaryOpType(node, fieldTypes);\n case 'UnaryOp': {\n if (node.op === '-') return 'number';\n if (node.op === '!') return 'boolean';\n return 'unknown';\n }\n case 'TernaryOp': {\n const thenType = inferTypeFromAST(node.consequent, fieldTypes);\n const elseType = inferTypeFromAST(node.alternate, fieldTypes);\n return thenType === elseType ? thenType : 'unknown';\n }\n case 'CallExpression':\n return inferCallExpressionType(node, fieldTypes);\n default:\n return 'unknown';\n }\n}\n\nexport function inferFormulaType(\n expression: string,\n fieldTypes: FieldTypes = {},\n): InferredType {\n const trimmed = expression.trim();\n if (!trimmed) {\n return 'unknown';\n }\n\n try {\n const { ast } = parseFormula(trimmed);\n return inferTypeFromAST(ast, fieldTypes);\n } catch {\n return 'unknown';\n }\n}\n","import type { ASTNode } from './types';\n\nfunction escapeDoubleQuoted(value: string): string {\n let result = '';\n for (const char of value) {\n switch (char) {\n case '\\\\':\n result += String.raw`\\\\`;\n break;\n case '\"':\n result += String.raw`\\\"`;\n break;\n case '\\n':\n result += String.raw`\\n`;\n break;\n case '\\r':\n result += String.raw`\\r`;\n break;\n case '\\t':\n result += String.raw`\\t`;\n break;\n default:\n result += char;\n }\n }\n return result;\n}\n\nconst PRECEDENCE: Record<string, number> = {\n '||': 1,\n '&&': 2,\n '==': 3,\n '!=': 3,\n '>': 4,\n '<': 4,\n '>=': 4,\n '<=': 4,\n '+': 5,\n '-': 5,\n '*': 6,\n '/': 6,\n '%': 6,\n};\n\nfunction serializeBinaryOp(node: ASTNode & { type: 'BinaryOp' }): string {\n const prec = PRECEDENCE[node.op] ?? 0;\n\n const wrapLeft = (child: ASTNode): string => {\n const s = serializeNode(child);\n if (child.type === 'BinaryOp') {\n const childPrec = PRECEDENCE[child.op] ?? 0;\n if (childPrec < prec) {\n return `(${s})`;\n }\n }\n if (child.type === 'TernaryOp') {\n return `(${s})`;\n }\n return s;\n };\n\n const wrapRight = (child: ASTNode): string => {\n const s = serializeNode(child);\n if (child.type === 'BinaryOp') {\n const childPrec = PRECEDENCE[child.op] ?? 0;\n if (childPrec <= prec) {\n return `(${s})`;\n }\n }\n if (child.type === 'TernaryOp') {\n return `(${s})`;\n }\n return s;\n };\n\n return `${wrapLeft(node.left)} ${node.op} ${wrapRight(node.right)}`;\n}\n\nfunction serializeNode(node: ASTNode): string {\n switch (node.type) {\n case 'NumberLiteral':\n return String(node.value);\n case 'StringLiteral':\n return `\"${escapeDoubleQuoted(node.value)}\"`;\n case 'BooleanLiteral':\n return String(node.value);\n case 'NullLiteral':\n return 'null';\n case 'Identifier':\n return node.name;\n case 'BracketedIdentifier':\n return `[\"${escapeDoubleQuoted(node.name)}\"]`;\n case 'RootPath':\n return node.path;\n case 'RelativePath':\n return node.path;\n case 'ContextToken':\n return node.name;\n case 'BinaryOp':\n return serializeBinaryOp(node);\n case 'UnaryOp':\n return `${node.op}${serializeUnaryArgument(node)}`;\n case 'TernaryOp':\n return `${serializeTernaryCondition(node.condition)} ? ${serializeNode(node.consequent)} : ${serializeNode(node.alternate)}`;\n case 'CallExpression':\n return `${serializeNode(node.callee)}(${node.arguments.map(serializeNode).join(', ')})`;\n case 'MemberExpression':\n return `${serializePostfixObject(node.object)}.${node.property}`;\n case 'BracketedMemberExpression':\n return `${serializePostfixObject(node.object)}[\"${escapeDoubleQuoted(node.property)}\"]`;\n case 'IndexExpression':\n return `${serializePostfixObject(node.object)}[${serializeNode(node.index)}]`;\n case 'WildcardExpression':\n return `${serializePostfixObject(node.object)}[*]`;\n }\n}\n\nfunction serializeUnaryArgument(node: ASTNode & { type: 'UnaryOp' }): string {\n const s = serializeNode(node.argument);\n if (node.argument.type === 'BinaryOp' || node.argument.type === 'TernaryOp') {\n return `(${s})`;\n }\n return s;\n}\n\nfunction serializeTernaryCondition(node: ASTNode): string {\n const s = serializeNode(node);\n if (node.type === 'TernaryOp') {\n return `(${s})`;\n }\n return s;\n}\n\nfunction serializePostfixObject(node: ASTNode): string {\n const s = serializeNode(node);\n if (\n node.type === 'BinaryOp' ||\n node.type === 'TernaryOp' ||\n node.type === 'UnaryOp'\n ) {\n return `(${s})`;\n }\n return s;\n}\n\nexport function serializeAst(ast: ASTNode): string {\n return serializeNode(ast);\n}\n","import type { ASTNode } from './types';\nimport { parseFormula } from './parser';\n\nfunction collectDependencyPath(node: ASTNode): string | null {\n switch (node.type) {\n case 'Identifier':\n return node.name;\n case 'BracketedIdentifier':\n return `[\"${node.name}\"]`;\n case 'RootPath':\n return node.path;\n case 'RelativePath':\n return node.path;\n case 'MemberExpression': {\n const objPath = collectDependencyPath(node.object);\n if (objPath === null) {\n return null;\n }\n return `${objPath}.${node.property}`;\n }\n case 'BracketedMemberExpression': {\n const objPath = collectDependencyPath(node.object);\n if (objPath === null) {\n return null;\n }\n const quote = '\"';\n return `${objPath}[${quote}${node.property}${quote}]`;\n }\n case 'IndexExpression': {\n const objPath = collectDependencyPath(node.object);\n if (objPath === null) {\n return null;\n }\n const numericIndex = getNumericIndex(node.index);\n if (numericIndex !== null) {\n return `${objPath}[${numericIndex}]`;\n }\n return null;\n }\n case 'WildcardExpression': {\n const objPath = collectDependencyPath(node.object);\n if (objPath === null) {\n return null;\n }\n return `${objPath}[*]`;\n }\n default:\n return null;\n }\n}\n\nfunction getNumericIndex(node: ASTNode): number | null {\n if (node.type === 'NumberLiteral') {\n return node.value;\n }\n if (\n node.type === 'UnaryOp' &&\n node.op === '-' &&\n node.argument.type === 'NumberLiteral'\n ) {\n return -node.argument.value;\n }\n return null;\n}\n\nfunction findMatch(\n node: ASTNode,\n replacements: Record<string, string>,\n): string | null {\n const fullPath = collectDependencyPath(node);\n if (fullPath !== null) {\n const value = replacements[fullPath];\n if (value !== undefined) {\n return value;\n }\n }\n return null;\n}\n\nfunction pathToAst(path: string): ASTNode {\n const { ast } = parseFormula(path);\n return ast;\n}\n\nfunction replaceNode(\n node: ASTNode,\n replacements: Record<string, string>,\n): ASTNode {\n const replacement = findMatch(node, replacements);\n if (replacement !== null) {\n return pathToAst(replacement);\n }\n\n switch (node.type) {\n case 'NumberLiteral':\n case 'StringLiteral':\n case 'BooleanLiteral':\n case 'NullLiteral':\n case 'Identifier':\n case 'BracketedIdentifier':\n case 'RootPath':\n case 'RelativePath':\n case 'ContextToken':\n return node;\n\n case 'BinaryOp':\n return {\n ...node,\n left: replaceNode(node.left, replacements),\n right: replaceNode(node.right, replacements),\n };\n\n case 'UnaryOp':\n return {\n ...node,\n argument: replaceNode(node.argument, replacements),\n };\n\n case 'TernaryOp':\n return {\n ...node,\n condition: replaceNode(node.condition, replacements),\n consequent: replaceNode(node.consequent, replacements),\n alternate: replaceNode(node.alternate, replacements),\n };\n\n case 'CallExpression': {\n const isSimpleFunctionCall = node.callee.type === 'Identifier';\n return {\n ...node,\n callee: isSimpleFunctionCall\n ? node.callee\n : replaceNode(node.callee, replacements),\n arguments: node.arguments.map((arg) => replaceNode(arg, replacements)),\n };\n }\n\n case 'MemberExpression':\n case 'BracketedMemberExpression':\n case 'WildcardExpression':\n return {\n ...node,\n object: replaceNode(node.object, replacements),\n };\n\n case 'IndexExpression':\n return {\n ...node,\n object: replaceNode(node.object, replacements),\n index: replaceNode(node.index, replacements),\n };\n }\n}\n\nexport function replaceDependencies(\n ast: ASTNode,\n replacements: Record<string, string>,\n): ASTNode {\n return replaceNode(ast, replacements);\n}\n","import { FormulaFeature, FormulaMinorVersion } from './types';\nimport { parseFormula } from './ohm';\n\nexport interface ParsedExpression {\n expression: string;\n dependencies: string[];\n minVersion: FormulaMinorVersion;\n features: FormulaFeature[];\n}\n\n/**\n * Parse a formula expression string\n *\n * @param expression - Formula expression string\n * @returns Parsed expression with dependencies and version info\n *\n * @example\n * parseExpression('price * 1.1')\n * // { expression: 'price * 1.1', dependencies: ['price'], minVersion: '1.0', features: [] }\n *\n * parseExpression('stats.damage * multiplier')\n * // { expression: '...', dependencies: ['stats.damage', 'multiplier'], minVersion: '1.1', features: ['nested_path'] }\n */\nexport function parseExpression(expression: string): ParsedExpression {\n const result = parseFormula(expression);\n return {\n expression,\n dependencies: result.dependencies,\n minVersion: result.minVersion,\n features: result.features,\n };\n}\n","import { validateSyntax } from './ohm';\n\nexport type SyntaxValidationResult =\n | { isValid: true }\n | { isValid: false; error: string; position?: number };\n\n/**\n * Validate formula expression syntax\n *\n * @param expression - Formula expression string\n * @returns Validation result with error details if invalid\n *\n * @example\n * validateFormulaSyntax('price * 1.1')\n * // { isValid: true }\n *\n * validateFormulaSyntax('price * (1.1')\n * // { isValid: false, error: 'Unclosed (', position: 8 }\n */\nexport function validateFormulaSyntax(\n expression: string,\n): SyntaxValidationResult {\n const result = validateSyntax(expression);\n\n if (result.isValid) {\n return { isValid: true };\n }\n\n return {\n isValid: false,\n error: result.error,\n position: result.position,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,MAAM,cAAc,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiI9B,MAAa,UAAUA,OAAI,QAAQ,YAAY;;;;AC9H/C,SAAS,mBAAmB,MAAuB;AACjD,QAAO,SAAS;;AAGlB,SAAS,cAAc,UAAgC;AACrD,QAAO,SACJ,QAAQ,MAA4B,WAAW,EAAE,CACjD,KAAK,MAAM,EAAE,OAAO,CAAY;;AAGrC,SAAS,qBAAqB,UAA+B;AAC3D,QAAO,SACJ,QAAQ,MAA4B,kBAAkB,EAAE,CACxD,SAAS,MAAM,EAAE,cAAc,CAAa;;AAGjD,SAAS,iBAAiB,UAAuC;AAC/D,QAAO,SACJ,QAAQ,MAA4B,cAAc,EAAE,CACpD,SAAS,MAAM,EAAE,UAAU,CAAqB;;AAGrD,MAAa,YAAY,QAAQ,iBAAiB;AAGlD,UAAU,aAAsB,SAAS;CACvC,WAAW,GAAG;AACZ,SAAO,EAAE,OAAO;;CAGlB,gBAAgB,MAAM,IAAI,MAAM,IAAI,KAAK;AACvC,SAAO;GACL,MAAM;GACN,WAAW,KAAK,OAAO;GACvB,YAAY,KAAK,OAAO;GACxB,WAAW,IAAI,OAAO;GACvB;;CAEH,QAAQ,GAAG;AACT,SAAO,EAAE,OAAO;;CAGlB,aAAa,MAAM,KAAK,OAAO;AAC7B,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,UAAU,GAAG;AACX,SAAO,EAAE,OAAO;;CAGlB,eAAe,MAAM,KAAK,OAAO;AAC/B,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,WAAW,GAAG;AACZ,SAAO,EAAE,OAAO;;CAGlB,YAAY,MAAM,KAAK,OAAO;AAC5B,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,aAAa,MAAM,KAAK,OAAO;AAC7B,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,SAAS,GAAG;AACV,SAAO,EAAE,OAAO;;CAGlB,eAAe,MAAM,KAAK,OAAO;AAC/B,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,eAAe,MAAM,KAAK,OAAO;AAC/B,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,cAAc,MAAM,KAAK,OAAO;AAC9B,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,cAAc,MAAM,KAAK,OAAO;AAC9B,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,WAAW,GAAG;AACZ,SAAO,EAAE,OAAO;;CAGlB,cAAc,MAAM,KAAK,OAAO;AAC9B,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,eAAe,MAAM,KAAK,OAAO;AAC/B,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,SAAS,GAAG;AACV,SAAO,EAAE,OAAO;;CAGlB,qBAAqB,MAAM,KAAK,OAAO;AACrC,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,mBAAmB,MAAM,KAAK,OAAO;AACnC,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,mBAAmB,MAAM,KAAK,OAAO;AACnC,SAAO;GACL,MAAM;GACN,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,OAAO,MAAM,OAAO;GACrB;;CAEH,eAAe,GAAG;AAChB,SAAO,EAAE,OAAO;;CAGlB,UAAU,KAAK,MAAM;AACnB,SAAO;GAAE,MAAM;GAAW,IAAI;GAAK,UAAU,KAAK,OAAO;GAAE;;CAE7D,UAAU,KAAK,MAAM;AACnB,SAAO;GAAE,MAAM;GAAW,IAAI;GAAK,UAAU,KAAK,OAAO;GAAE;;CAE7D,MAAM,GAAG;AACP,SAAO,EAAE,OAAO;;CAGlB,aAAa,QAAQ,KAAK,MAAM,KAAK;EACnC,MAAM,WAAW,KAAK,SAAS;EAC/B,MAAM,UAAU,WAAW,SAAS,OAAO,GAAG,EAAE;AAChD,SAAO;GACL,MAAM;GACN,QAAQ,OAAO,OAAO;GACtB,WAAW,MAAM,QAAQ,QAAQ,GAAG,UAAU,CAAC,QAAQ;GACxD;;CAEH,iBAAiB,KAAK,MAAM,MAAM;AAChC,SAAO;GACL,MAAM;GACN,QAAQ,IAAI,OAAO;GACnB,UAAU,KAAK;GAChB;;CAEH,cAAc,KAAK,KAAK,OAAO,KAAK;EAClC,MAAM,WAAW,MAAM,OAAO;AAC9B,MAAI,SAAS,SAAS,gBACpB,QAAO;GACL,MAAM;GACN,QAAQ,IAAI,OAAO;GACnB,UAAU,SAAS;GACpB;AAEH,SAAO;GACL,MAAM;GACN,QAAQ,IAAI,OAAO;GACnB,OAAO;GACR;;CAEH,iBAAiB,KAAK,KAAK,OAAO,KAAK;AACrC,SAAO;GACL,MAAM;GACN,QAAQ,IAAI,OAAO;GACpB;;CAEH,QAAQ,GAAG;AACT,SAAO,EAAE,OAAO;;CAKlB,UAAU,OAAO,QAAQ,MAAM;AAC7B,SAAO,CAAC,MAAM,OAAO,EAAE,GAAG,KAAK,SAAS,KAAK,MAAM,EAAE,OAAO,CAAC,CAAC;;CAGhE,cAAc,KAAK,MAAM,KAAK;AAC5B,SAAO,KAAK,OAAO;;CAErB,uBAAuB,KAAK,KAAK,KAAK;AAEpC,SAAO;GAAE,MAAM;GAAuB,MADvB,IAAI,OAAO,CACyB;GAAO;;CAE5D,QAAQ,GAAG;AACT,SAAO,EAAE,OAAO;;CAGlB,aAAa,MAAM,MAAM,MAAM,OAAO;AACpC,SAAO;GACL,MAAM;GACN,OAAO,OAAO,WAAW,KAAK,aAAa;GAC5C;;CAEH,WAAW,MAAM,SAAS;AACxB,SAAO;GACL,MAAM;GACN,OAAO,OAAO,SAAS,KAAK,cAAc,GAAG;GAC9C;;CAGH,OAAO,OAAO,OAAO,QAAQ;AAE3B,SAAO;GAAE,MAAM;GAAiB,OADpB,MAAM,aACyB,WAAW,UAAU,KAAK;GAAE;;CAGzE,aAAa,GAAG;AACd,SAAO;GAAE,MAAM;GAAkB,OAAO;GAAM;;CAEhD,cAAc,GAAG;AACf,SAAO;GAAE,MAAM;GAAkB,OAAO;GAAO;;CAGjD,KAAK,GAAG;AACN,SAAO,EAAE,MAAM,eAAe;;CAGhC,WAAW,QAAQ,OAAO;AACxB,SAAO;GAAE,MAAM;GAAc,MAAM,KAAK;GAAc;;CAGxD,SAAS,QAAQ,OAAO;AACtB,SAAO;GAAE,MAAM;GAAY,MAAM,KAAK;GAAc;;CAGtD,aAAa,aAAa,QAAQ;AAChC,SAAO;GAAE,MAAM;GAAgB,MAAM,KAAK;GAAc;;CAG1D,gBAAgB,KAAK,OAAO;AAC1B,SAAO;GAAE,MAAM;GAAgB,MAAM,KAAK;GAAc;;CAE1D,kBAAkB,OAAO,OAAO;AAC9B,SAAO;GAAE,MAAM;GAAgB,MAAM,KAAK;GAAc;;CAI1D,MAAM,GAAG,UAAU;AACjB,SAAO,cAAc,SAAS;;CAGhC,YAAY;AACV,SAAO;GAAE,MAAM;GAAc,MAAM,KAAK;GAAc;;CAEzD,CAAC;AAGF,UAAU,aAAuB,gBAAgB;CAC/C,WAAW,QAAQ,OAAO;AACxB,SAAO,CAAC,KAAK,aAAa;;CAG5B,uBAAuB,KAAK,MAAM,KAAK;AACrC,SAAO,CAAC,KAAK,aAAa;;CAG5B,SAAS,QAAQ,OAAO;AACtB,SAAO,CAAC,KAAK,aAAa;;CAG5B,aAAa,aAAa,QAAQ;AAChC,SAAO,CAAC,KAAK,aAAa;;CAG5B,gBAAgB,KAAK,OAAO;AAC1B,SAAO,EAAE;;CAEX,kBAAkB,OAAO,OAAO;AAC9B,SAAO,EAAE;;CAGX,iBAAiB,KAAK,MAAM,MAAM;EAChC,MAAM,UAAU,IAAI,cAAc;AAClC,MAAI,QAAQ,WAAW,EACrB,QAAO,CAAC,GAAG,QAAQ,GAAG,GAAG,KAAK,eAAe;AAE/C,SAAO;;CAGT,cAAc,KAAK,KAAK,OAAO,KAAK;EAClC,MAAM,UAAU,IAAI,cAAc;EAClC,MAAM,YAAY,MAAM,OAAO;AAE/B,MAAI,UAAU,SAAS,iBAAiB;GACtC,MAAM,WAAW,UAAU;GAC3B,MAAM,QAAQ,KAAK,aAAa,SAAS,KAAI,GAAG,OAAM;AACtD,OAAI,QAAQ,WAAW,EACrB,QAAO,CAAC,GAAG,QAAQ,GAAG,GAAG,QAAQ,WAAW,MAAM,GAAG;AAEvD,UAAO;;EAGT,MAAM,mBAAmB,SAAiC;AACxD,OAAI,KAAK,SAAS,gBAChB,QAAO,KAAK;AAEd,OACE,KAAK,SAAS,aACd,KAAK,OAAO,OACZ,KAAK,SAAS,SAAS,gBAEvB,QAAO,CAAC,KAAK,SAAS;AAExB,UAAO;;EAGT,MAAM,eAAe,gBAAgB,UAAU;AAC/C,MAAI,QAAQ,WAAW,KAAK,iBAAiB,KAC3C,QAAO,CAAC,GAAG,QAAQ,GAAG,GAAG,aAAa,GAAG;AAE3C,SAAO,CAAC,GAAG,SAAS,GAAI,MAAM,cAAc,CAAc;;CAG5D,iBAAiB,KAAK,KAAK,OAAO,KAAK;EACrC,MAAM,UAAU,IAAI,cAAc;AAClC,MAAI,QAAQ,WAAW,EACrB,QAAO,CAAC,GAAG,QAAQ,GAAG,KAAK;AAE7B,SAAO;;CAGT,aAAa,QAAQ,KAAK,MAAM,KAAK;EACnC,MAAM,aAAa,OAAO,cAAc;EACxC,MAAM,YAAY,OAAO,OAAO;EAChC,MAAM,UAAU,qBAAqB,KAAK,SAAS;AAEnD,MAAI,UAAU,SAAS,aACrB,QAAO;AAET,SAAO,CAAC,GAAG,YAAY,GAAG,QAAQ;;CAGpC,aAAa,MAAM,MAAM,MAAM,OAAO;AACpC,SAAO,EAAE;;CAEX,WAAW,MAAM,SAAS;AACxB,SAAO,EAAE;;CAGX,OAAO,OAAO,QAAQ,QAAQ;AAC5B,SAAO,EAAE;;CAGX,aAAa,GAAG;AACd,SAAO,EAAE;;CAEX,cAAc,GAAG;AACf,SAAO,EAAE;;CAGX,KAAK,GAAG;AACN,SAAO,EAAE;;CAGX,aAAa,GAAG,UAAU;AACxB,SAAO,qBAAqB,SAAS;;CAGvC,MAAM,GAAG,UAAU;AACjB,SAAO,qBAAqB,SAAS;;CAGvC,YAAY;AACV,SAAO,EAAE;;CAEZ,CAAC;AAGF,MAAM,kBAAkB,IAAI,IAAI;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,UAAU,aAA+B,YAAY;CACnD,uBAAuB,KAAK,MAAM,KAAK;AACrC,SAAO,CAAC,mBAAmB;;CAG7B,SAAS,QAAQ,OAAO;EACtB,MAAM,OAAO,KAAK;EAClB,MAAM,WAA6B,CAAC,YAAY;AAChD,MAAI,KAAK,SAAS,IAAI,CACpB,UAAS,KAAK,cAAc;AAE9B,SAAO;;CAGT,aAAa,aAAa,QAAQ;EAChC,MAAM,OAAO,KAAK;EAClB,MAAM,WAA6B,CAAC,gBAAgB;AAEpD,MADsB,KAAK,QAAQ,cAAc,GAAG,CAClC,SAAS,IAAI,CAC7B,UAAS,KAAK,cAAc;AAE9B,SAAO;;CAGT,gBAAgB,KAAK,OAAO;AAC1B,SAAO,CAAC,gBAAgB;;CAE1B,kBAAkB,OAAO,OAAO;AAC9B,SAAO,CAAC,gBAAgB;;CAG1B,iBAAiB,KAAK,MAAM,OAAO;AAEjC,SAAO,CAAC,GADY,IAAI,UAAU,EACV,cAAc;;CAGxC,cAAc,KAAK,KAAK,OAAO,KAAK;EAClC,MAAM,cAAc,IAAI,UAAU;EAClC,MAAM,gBAAgB,MAAM,UAAU;AAEtC,MADkB,MAAM,OAAO,CACjB,SAAS,gBACrB,QAAO;GAAC,GAAG;GAAa,GAAG;GAAe;GAAmB;AAE/D,SAAO;GAAC,GAAG;GAAa,GAAG;GAAe;GAAc;;CAG1D,iBAAiB,KAAK,KAAK,OAAO,KAAK;AAErC,SAAO,CAAC,GADY,IAAI,UAAU,EACV,iBAAiB;;CAG3C,aAAa,QAAQ,KAAK,MAAM,KAAK;EACnC,MAAM,YAAY,OAAO,OAAO;EAChC,MAAM,cAAc,iBAAiB,KAAK,SAAS;AAEnD,MACE,UAAU,SAAS,gBACnB,gBAAgB,IAAI,UAAU,KAAK,aAAa,CAAC,CAEjD,QAAO,CAAC,GAAG,aAAa,iBAAiB;AAE3C,SAAO;;CAGT,aAAa,GAAG,UAAU;AACxB,SAAO,iBAAiB,SAAS;;CAGnC,MAAM,GAAG,UAAU;AACjB,SAAO,iBAAiB,SAAS;;CAGnC,YAAY;AACV,SAAO,EAAE;;CAEZ,CAAC;AAGF,MAAM,WAA4D;CAEhE,MAAM,GAAG,MAAM,QAAQ,EAAE,IAAI,QAAQ,EAAE;CACvC,KAAK,GAAG,MAAM,QAAQ,EAAE,IAAI,QAAQ,EAAE;CACtC,MAAM,MAAM,CAAC;CAGb,SAAS,GAAG,SAAS,KAAK,IAAI,OAAO,CAAC,KAAK,GAAG;CAC9C,QAAQ,MAAM,OAAO,EAAE,CAAC,aAAa;CACrC,QAAQ,MAAM,OAAO,EAAE,CAAC,aAAa;CACrC,OAAO,MAAM,OAAO,EAAE,CAAC,MAAM;CAC7B,OAAO,GAAG,MAAM,OAAO,EAAE,CAAC,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC,CAAC;CACtE,QAAQ,GAAG,MAAM;EACf,MAAM,MAAM,OAAO,EAAE;EACrB,MAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC;AAChD,SAAO,UAAU,IAAI,KAAK,IAAI,MAAM,CAAC,MAAM;;CAE7C,UAAU,GAAG,QAAQ,SAAS,OAAO,EAAE,CAAC,QAAQ,OAAO,OAAO,EAAE,OAAO,KAAK,CAAC;CAC7E,UAAU;CACV,SAAS,MAAM;AACb,MAAI,MAAM,QAAQ,EAAE,CAAE,QAAO,EAAE;AAC/B,MAAI,OAAO,MAAM,SAAU,QAAO,EAAE;AACpC,MAAI,MAAM,QAAQ,OAAO,MAAM,SAAU,QAAO,OAAO,KAAK,EAAE,CAAC;AAC/D,SAAO,OAAO,EAAE,CAAC;;CAEnB,WAAW,GAAG,WAAW,OAAO,EAAE,CAAC,SAAS,OAAO,OAAO,CAAC;CAC3D,aAAa,GAAG,WAAW,OAAO,EAAE,CAAC,WAAW,OAAO,OAAO,CAAC;CAC/D,WAAW,GAAG,WAAW,OAAO,EAAE,CAAC,SAAS,OAAO,OAAO,CAAC;CAC3D,OAAO,KAAc,QAAiB;AACpC,MAAI,CAAC,MAAM,QAAQ,IAAI,CAAE,QAAO;AAChC,MAAI,QAAQ,UAAa,QAAQ,KAAM,QAAO,IAAI,KAAK,IAAI;AAC3D,MAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,SAC5C,QAAO,IAAI,KAAK,IAAI;AAEtB,SAAO,IAAI,KAAK,OAAO,IAAI,CAAC;;CAI9B,UAAU;CACV,WAAW;CACX,SAAS,MAAM,MAAM,QAAQ,MAAM;CACnC,WAAW,GAAG,SACZ,KAAK,MAAM,MAAM,MAAM,QAAQ,MAAM,OAAU,IAAI;CACrD,QAAQ,GAAG,QAAQ;EACjB,MAAM,SAAS,OAAO,QAAQ,SAAY,IAAI,OAAO,IAAI;AACzD,SAAO,KAAK,MAAM,OAAO,EAAE,GAAG,OAAO,GAAG;;CAE1C,QAAQ,MAAM,KAAK,MAAM,OAAO,EAAE,CAAC;CACnC,OAAO,MAAM,KAAK,KAAK,OAAO,EAAE,CAAC;CACjC,MAAM,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;CAC/B,OAAO,MAAM,KAAK,KAAK,OAAO,EAAE,CAAC;CACjC,MAAM,MAAM,QAAQ,KAAK,IAAI,OAAO,KAAK,EAAE,OAAO,IAAI,CAAC;CACvD,MAAM,GAAG,SACP,KAAK,WAAW,IAAI,MAAa,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,CAAC;CAChE,MAAM,GAAG,SACP,KAAK,WAAW,IAAI,MAAa,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,CAAC;CAChE,MAAM,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;CAC/B,QAAQ,MAAM,KAAK,MAAM,OAAO,EAAE,CAAC;CACnC,MAAM,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;CAC/B,OAAO,MAAM,KAAK,KAAK,OAAO,EAAE,CAAC;CAGjC,MAAM,QACJ,MAAM,QAAQ,IAAI,GAAG,IAAI,QAAQ,GAAG,MAAM,IAAI,OAAO,EAAE,EAAE,EAAE,GAAG;CAChE,MAAM,QACJ,MAAM,QAAQ,IAAI,IAAI,IAAI,SAAS,IAC/B,IAAI,QAAQ,GAAG,MAAM,IAAI,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,SAC7C;CACN,QAAQ,QAAS,MAAM,QAAQ,IAAI,GAAG,IAAI,SAAS;CACnD,QAAQ,QAAS,MAAM,QAAQ,IAAI,GAAG,IAAI,KAAK;CAC/C,OAAO,QAAS,MAAM,QAAQ,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG;CAClD,WAAW,KAAK,QAAS,MAAM,QAAQ,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG;CAGlE,KAAK,MAAM,QAAQ,YAAa,OAAO,SAAS;CACjD;AAED,SAAS,UAAU,KAAc,MAAuB;CACtD,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,IAAI,UAAU;AACd,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,YAAY,QAAQ,YAAY,OAAW,QAAO;AACtD,YAAW,QAAoC;;AAEjD,QAAO;;AAGT,UAAU,aAAsB,aAAa;CAC3C,WAAW,GAAG;AACZ,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,gBAAgB,MAAM,IAAI,MAAM,IAAI,KAAK;AACvC,SAAO,KAAK,KAAK,KAAK,KAAK,IAAI,GAC3B,KAAK,KAAK,KAAK,KAAK,IAAI,GACxB,IAAI,KAAK,KAAK,KAAK,IAAI;;CAE7B,QAAQ,GAAG;AACT,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,aAAa,MAAM,KAAK,OAAO;AAC7B,SAAO,KAAK,KAAK,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK,KAAK,KAAK,IAAI;;CAE9D,UAAU,GAAG;AACX,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,eAAe,MAAM,KAAK,OAAO;AAC/B,SAAO,KAAK,KAAK,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK,KAAK,KAAK,IAAI;;CAE9D,WAAW,GAAG;AACZ,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,YAAY,MAAM,KAAK,OAAO;AAC5B,SAAO,KAAK,KAAK,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK,KAAK,KAAK,IAAI;;CAE9D,aAAa,MAAM,KAAK,OAAO;AAC7B,SAAO,KAAK,KAAK,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK,KAAK,KAAK,IAAI;;CAE9D,SAAS,GAAG;AACV,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,eAAe,MAAM,KAAK,OAAO;AAC/B,SACG,KAAK,KAAK,KAAK,KAAK,IAAI,IACxB,MAAM,KAAK,KAAK,KAAK,IAAI;;CAG9B,eAAe,MAAM,KAAK,OAAO;AAC/B,SACG,KAAK,KAAK,KAAK,KAAK,IAAI,IACxB,MAAM,KAAK,KAAK,KAAK,IAAI;;CAG9B,cAAc,MAAM,KAAK,OAAO;AAC9B,SACG,KAAK,KAAK,KAAK,KAAK,IAAI,GACxB,MAAM,KAAK,KAAK,KAAK,IAAI;;CAG9B,cAAc,MAAM,KAAK,OAAO;AAC9B,SACG,KAAK,KAAK,KAAK,KAAK,IAAI,GACxB,MAAM,KAAK,KAAK,KAAK,IAAI;;CAG9B,WAAW,GAAG;AACZ,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,cAAc,MAAM,KAAK,OAAgB;EACvC,MAAM,IAAI,KAAK,KAAK,KAAK,KAAK,IAAI;EAClC,MAAM,IAAI,MAAM,KAAK,KAAK,KAAK,IAAI;AACnC,MAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SACxC,QAAO,OAAO,EAAE,GAAG,OAAO,EAAE;AAE9B,SAAQ,IAAgB;;CAE1B,eAAe,MAAM,KAAK,OAAO;AAC/B,SACG,KAAK,KAAK,KAAK,KAAK,IAAI,GACxB,MAAM,KAAK,KAAK,KAAK,IAAI;;CAG9B,SAAS,GAAG;AACV,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,qBAAqB,MAAM,KAAK,OAAO;AACrC,SACG,KAAK,KAAK,KAAK,KAAK,IAAI,GACxB,MAAM,KAAK,KAAK,KAAK,IAAI;;CAG9B,mBAAmB,MAAM,KAAK,OAAO;AACnC,SACG,KAAK,KAAK,KAAK,KAAK,IAAI,GACxB,MAAM,KAAK,KAAK,KAAK,IAAI;;CAG9B,mBAAmB,MAAM,KAAK,OAAO;AACnC,SACG,KAAK,KAAK,KAAK,KAAK,IAAI,GACxB,MAAM,KAAK,KAAK,KAAK,IAAI;;CAG9B,eAAe,GAAG;AAChB,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,UAAU,KAAK,MAAM;AACnB,SAAO,CAAE,KAAK,KAAK,KAAK,KAAK,IAAI;;CAEnC,UAAU,KAAK,MAAM;AACnB,SAAO,CAAC,KAAK,KAAK,KAAK,KAAK,IAAI;;CAElC,MAAM,GAAG;AACP,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,aAAa,QAAQ,KAAK,MAAM,KAAK;EACnC,MAAM,YAAY,OAAO,OAAO;EAEhC,MAAM,qBAAgC;GACpC,MAAM,WAAW,KAAK,SAAS;AAC/B,OAAI,CAAC,SACH,QAAO,EAAE;AAEX,UAAO,SAAS,KAAK,KAAK,KAAK,IAAI;;AAGrC,MAAI,UAAU,SAAS,cAAc;GAEnC,MAAM,YAAY,SADH,UAAU,KAAK,aAAa;AAE3C,OAAI,UACF,QAAO,UAAU,GAAG,cAAc,CAAC;;EAIvC,MAAM,KAAK,OAAO,KAAK,KAAK,KAAK,IAAI;AACrC,MAAI,OAAO,OAAO,WAChB,QAAO,GAAG,GAAG,cAAc,CAAC;EAG9B,MAAM,aACJ,UAAU,SAAS,eAAe,UAAU,OAAO;AACrD,QAAM,IAAI,MAAM,IAAI,WAAW,qBAAqB;;CAEtD,iBAAiB,KAAK,MAAM,MAAM;AAEhC,SADe,IAAI,KAAK,KAAK,KAAK,IAAI,GACtB,KAAK;;CAEvB,cAAc,KAAK,KAAK,OAAO,KAAK;EAClC,MAAM,SAAS,IAAI,KAAK,KAAK,KAAK,IAAI;EACtC,MAAM,MAAM,MAAM,KAAK,KAAK,KAAK,IAAI;AACrC,MAAI,OAAO,QAAQ,UAAU;AAC3B,OAAI,CAAC,mBAAmB,IAAI,CAC1B;AAEF,UAAQ,SAAqC;;EAE/C,MAAM,SAAS;AACf,MAAI,SAAS,EACX,QAAQ,SAAwB,OAAqB,SAAS;AAEhE,SAAQ,SAAuB;;CAEjC,iBAAiB,KAAK,KAAK,OAAO,KAAK;AACrC,SAAO,IAAI,KAAK,KAAK,KAAK,IAAI;;CAEhC,QAAQ,GAAG;AACT,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,UAAU,OAAO,QAAQ,MAAM;AAC7B,SAAO,CACL,MAAM,KAAK,KAAK,KAAK,IAAI,EACzB,GAAG,KAAK,SAAS,KAAK,MAAM,EAAE,KAAK,KAAK,KAAK,IAAI,CAAC,CACnD;;CAGH,cAAc,KAAK,MAAM,KAAK;AAC5B,SAAO,KAAK,KAAK,KAAK,KAAK,IAAI;;CAEjC,uBAAuB,KAAK,KAAK,KAAK;EACpC,MAAM,YAAY,IAAI,KAAK,KAAK,KAAK,IAAI;AACzC,MAAI,CAAC,mBAAmB,UAAU,CAChC;AAEF,SAAO,KAAK,KAAK,IAAI;;CAEvB,QAAQ,GAAG;AACT,SAAO,EAAE,KAAK,KAAK,KAAK,IAAI;;CAG9B,aAAa,MAAM,MAAM,MAAM,OAAO;AACpC,SAAO,OAAO,WAAW,KAAK,aAAa;;CAE7C,WAAW,MAAM,SAAS;AACxB,SAAO,OAAO,SAAS,KAAK,cAAc,GAAG;;CAG/C,OAAO,OAAO,OAAO,QAAQ;AAC3B,SAAO,MAAM,aAAa,WAAW,UAAU,KAAK;;CAGtD,aAAa,GAAG;AACd,SAAO;;CAET,cAAc,GAAG;AACf,SAAO;;CAGT,KAAK,GAAG;AACN,SAAO;;CAGT,WAAW,QAAQ,OAAO;EACxB,MAAM,OAAO,KAAK;AAClB,SAAO,KAAK,KAAK,IAAI;;CAGvB,SAAS,QAAQ,OAAO;EACtB,MAAM,WAAW,KAAK;AACtB,MAAI,YAAY,KAAK,KAAK,IACxB,QAAO,KAAK,KAAK,IAAI;EAEvB,MAAM,QAAQ,SAAS,MAAM,EAAE,CAAC,MAAM,IAAI;EAC1C,MAAM,YAAY,MAAM;AACxB,MAAI,CAAC,UAAW,QAAO;EACvB,MAAM,UAAU,MAAM;EACtB,IAAI,QAAQ,KAAK,KAAK,IAAI;AAC1B,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,OAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;GAClD,MAAM,OAAO,MAAM;AACnB,OAAI,CAAC,KAAM;AACX,WAAS,MAAkC;;AAE7C,SAAO;;CAGT,aAAa,aAAa,QAAQ;EAChC,MAAM,WAAW,KAAK;AACtB,MAAI,YAAY,KAAK,KAAK,IACxB,QAAO,KAAK,KAAK,IAAI;EAEvB,MAAM,OAAO,SAAS,QAAQ,cAAc,GAAG;AAC/C,SAAO,UAAU,KAAK,KAAK,KAAK,KAAK;;CAGvC,gBAAgB,KAAK,OAAO;AAC1B,SAAO,KAAK,KAAK,IAAI,KAAK;;CAE5B,kBAAkB,OAAO,OAAO;AAC9B,SAAO,KAAK,KAAK,IAAI,KAAK;;CAG5B,aAAa,GAAG,UAAU;EACxB,MAAM,MAAM,KAAK,KAAK;AACtB,OAAK,MAAM,SAAS,SAClB,KAAI,UAAU,MACZ,QAAO,MAAM,KAAK,IAAI;;CAM5B,MAAM,GAAG,UAAU;AACjB,SAAO,SAAS,KAAK,MAAM,EAAE,KAAK,KAAK,KAAK,IAAI,CAAC;;CAGnD,YAAY;CAGb,CAAC;;;;AC51BF,SAAS,iBAAiB,UAAiD;AACzE,KAAI,SAAS,SAAS,gBAAgB,CACpC,QAAO;AAET,KAAI,SAAS,SAAS,EACpB,QAAO;AAET,QAAO;;AAUT,SAAgB,aAAa,YAAiC;CAC5D,MAAM,UAAU,WAAW,MAAM;AACjC,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,mBAAmB;CAGrC,MAAM,cAAc,QAAQ,MAAM,QAAQ;AAC1C,KAAI,YAAY,QAAQ,CACtB,OAAM,IAAI,MAAM,YAAY,WAAW,cAAc;CAGvD,MAAM,UAAU,UAAU,YAAY;CACtC,MAAM,MAAM,QAAQ,OAAO;CAC3B,MAAM,eAAe,CAAC,GAAG,IAAI,IAAI,QAAQ,cAAc,CAAa,CAAC;CACrE,MAAM,cAAc,QAAQ,UAAU;CACtC,MAAM,WAAW,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC;AAG1C,QAAO;EAAE;EAAK;EAAc;EAAU,YAFE,iBAAiB,SAAS;EAEhB;;AAGpD,SAAgB,eACd,YAC0E;CAC1E,MAAM,UAAU,WAAW,MAAM;AACjC,KAAI,CAAC,QACH,QAAO;EAAE,SAAS;EAAO,OAAO;EAAoB;CAGtD,MAAM,cAAc,QAAQ,MAAM,QAAQ;AAC1C,KAAI,YAAY,QAAQ,EAAE;EACxB,MAAM,MAAM,YAAY,+BAA+B;AACvD,SAAO;GACL,SAAS;GACT,OAAO,YAAY,WAAW;GAC9B,UAAU;GACX;;AAGH,QAAO,EAAE,SAAS,MAAM;;AAG1B,SAAgB,SACd,YACA,SACS;CACT,MAAM,UAAU,WAAW,MAAM;AACjC,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,mBAAmB;CAGrC,MAAM,cAAc,QAAQ,MAAM,QAAQ;AAC1C,KAAI,YAAY,QAAQ,CACtB,OAAM,IAAI,MAAM,YAAY,WAAW,cAAc;CAGvD,MAAM,cAAuC,EAAE;AAC/C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,CAChD,KAAI,OAAO,UAAU,WACnB,aAAY,OAAO;AAIvB,QAAO,UAAU,YAAY,CAAC,KAAK,YAAY;;AAUjD,SAAS,iBAAiB,aAA+B;CACvD,MAAM,WAAqB,EAAE;CAC7B,IAAI,UAAU;CACd,IAAI,YAAY;AAEhB,MAAK,MAAM,QAAQ,YACjB,KAAI,SAAS,KAAK;AAChB,cAAY;AACZ,aAAW;YACF,SAAS,KAAK;AACvB,cAAY;AACZ,aAAW;YACF,SAAS,OAAO,CAAC,WAC1B;MAAI,SAAS;AACX,YAAS,KAAK,QAAQ;AACtB,aAAU;;OAGZ,YAAW;AAIf,KAAI,QACF,UAAS,KAAK,QAAQ;AAGxB,QAAO;;AAGT,SAAS,eAAe,MAA+B,MAAuB;CAC5E,MAAM,WAAW,iBAAiB,KAAK;CACvC,IAAI,UAAmB;AAEvB,MAAK,MAAM,WAAW,UAAU;AAC9B,MAAI,YAAY,QAAQ,YAAY,OAClC;AAEF,MAAI,OAAO,YAAY,SACrB;EAGF,MAAM,eAAe,qBAAqB,KAAK,QAAQ;AACvD,MAAI,eAAe,MAAM,aAAa,IAAI;GACxC,MAAM,YAAY,aAAa;GAC/B,MAAM,QAAQ,OAAO,SAAS,aAAa,IAAI,GAAG;GAClD,MAAM,MAAO,QAAoC;AACjD,OAAI,CAAC,MAAM,QAAQ,IAAI,CACrB;AAEF,aAAU,IAAI;QAEd,WAAW,QAAoC;;AAInD,QAAO;;AAGT,SAAS,iBAAiB,WAA2B;CACnD,MAAM,WAAW,UAAU,QAAQ,IAAI;CACvC,MAAM,eAAe,UAAU,QAAQ,IAAI;AAE3C,KAAI,aAAa,MAAM,iBAAiB,GACtC,QAAO;AAET,KAAI,aAAa,GACf,QAAO,UAAU,MAAM,GAAG,aAAa;AAEzC,KAAI,iBAAiB,GACnB,QAAO,UAAU,MAAM,GAAG,SAAS;AAErC,QAAO,UAAU,MAAM,GAAG,KAAK,IAAI,UAAU,aAAa,CAAC;;AAG7D,SAAS,kBAAkB,MAAsB;CAC/C,IAAI,QAAQ;CACZ,IAAI,YAAY;AAChB,QAAO,UAAU,WAAW,MAAM,EAAE;AAClC;AACA,cAAY,UAAU,MAAM,EAAE;;AAEhC,QAAO;;AAGT,SAAS,oBAAoB,MAAsB;AACjD,QAAO,KAAK,QAAQ,cAAc,GAAG;;AAGvC,SAAS,oBACP,UACA,aACA,cACS;CACT,MAAM,eAAe,kBAAkB,aAAa;CACpD,MAAM,YAAY,oBAAoB,aAAa;AAEnD,KAAI,CAAC,YACH,QAAO,eAAe,UAAU,UAAU;CAG5C,MAAM,eAAe,iBAAiB,YAAY;CAClD,MAAM,cAAc,aAAa,SAAS;AAE1C,KAAI,eAAe,EACjB,QAAO,eAAe,UAAU,UAAU;CAG5C,MAAM,WAAW,aAAa,MAAM,GAAG,YAAY,CAAC,KAAK,IAAI;AAG7D,QAAO,eAAe,UAFL,WAAW,GAAG,SAAS,GAAG,cAAc,UAEhB;;AAG3C,SAAS,oBAAoB,cAA8B;CACzD,MAAM,mBAAmB,oBAAoB,aAAa;CAC1D,MAAM,YAAY,iBAAiB,iBAAiB;AAKpD,QAJe,aAAa,MAC1B,GACA,aAAa,SAAS,iBAAiB,OACxC,GACe;;AAGlB,SAAS,wBACP,cACyB;AACzB,KAAI,CAAC,gBAAgB,aAAa,OAAO,WAAW,EAClD,QAAO,EAAE;CAGX,MAAM,SAAkC,EAAE;CAC1C,MAAM,SAAS,aAAa;CAE5B,MAAM,oBAAoB,OAA0B,WAAyB;AAC3E,SAAO,GAAG,OAAO,UAAU,MAAM;AACjC,SAAO,GAAG,OAAO,WAAW,MAAM;AAClC,SAAO,GAAG,OAAO,UAAU,MAAM,UAAU;AAC3C,SAAO,GAAG,OAAO,SAAS,MAAM,UAAU,MAAM,SAAS;;CAG3D,MAAM,uBACJ,OACA,WACS;AACT,SAAO,GAAG,OAAO,SAAS,MAAM;AAChC,SAAO,GAAG,OAAO,SAAS,MAAM;;AAGlC,KAAI,OAAO,IAAI;AACb,mBAAiB,OAAO,IAAI,IAAI;AAChC,sBAAoB,OAAO,IAAI,IAAI;;CAGrC,IAAI,eAAe;CACnB,IAAI,iBAAiB;AACrB,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACtC,MAAM,QAAQ,OAAO;AACrB,MAAI,OAAO;AACT,oBAAiB,OAAO,aAAa;AACrC,uBAAoB,OAAO,eAAe;;AAE5C,iBAAe,aAAa,aAAa,MAAM,EAAE;AACjD,mBAAiB,aAAa,eAAe,MAAM,EAAE;;CAGvD,MAAM,YAAY,OAAO,GAAG,GAAG;AAC/B,KAAI,WAAW;AACb,SAAO,iBAAiB,UAAU;AAClC,SAAO,kBAAkB,UAAU;AACnC,SAAO,iBAAiB,UAAU,UAAU;AAC5C,SAAO,gBAAgB,UAAU,UAAU,UAAU,SAAS;AAC9D,SAAO,gBAAgB,UAAU;AACjC,SAAO,gBAAgB,UAAU;;AAGnC,QAAO;;AAGT,SAAS,oBACP,UACA,cACA,aACyB;CACzB,MAAM,OAAgC,EAAE;AAExC,MAAK,MAAM,OAAO,aAChB,KAAI,IAAI,WAAW,IAAI,EAAE;EAEvB,MAAM,YAAY,iBADA,IAAI,MAAM,EAAE,CACe;EAC7C,MAAM,aAAa,MAAM;AACzB,MAAI,EAAE,cAAc,MAClB,MAAK,cAAc,eAAe,UAAU,UAAU;YAE/C,IAAI,WAAW,MAAM,EAAE;EAChC,MAAM,aAAa,oBAAoB,IAAI;AAC3C,MAAI,EAAE,cAAc,MAClB,MAAK,cAAc,oBACjB,UACA,aACA,WACD;;AAKP,QAAO;;AAGT,SAAgB,oBACd,YACA,SACS;CACT,MAAM,EAAE,UAAU,UAAU,aAAa,iBAAiB;CAC1D,MAAM,UAAU,WAAW,MAAM;AAEjC,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,mBAAmB;CAIrC,MAAM,WAAW,oBACf,UAFa,aAAa,QAAQ,CAG3B,cACP,YACD;CACD,MAAM,cAAc,wBAAwB,aAAa;AASzD,QAAO,SAAS,SAPyB;EACvC,GAAG;EACH,GAAG;EACH,GAAG;EACH,GAAG;EACJ,CAEgC;;AASnC,MAAM,iBAAiB,IAAI,IAAI;CAAC;CAAK;CAAK;CAAK;CAAK;CAAI,CAAC;AACzD,MAAM,iBAAiB,IAAI,IAAI;CAAC;CAAK;CAAK;CAAM;CAAM;CAAM;CAAK,CAAC;AAClE,MAAM,cAAc,IAAI,IAAI;CAAC;CAAM;CAAM;CAAI,CAAC;AAC9C,MAAM,oBAAoB,IAAI,IAAI;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AACF,MAAM,mBAAmB,IAAI,IAAI;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AACF,MAAM,oBAAoB,IAAI,IAAI;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAS,aAAa,MAAc,YAAsC;CAExE,MAAM,aAAa,WADD,KAAK,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,MAAM;AAEvD,KAAI,eAAe,SAAU,QAAO;AACpC,KAAI,eAAe,SAAU,QAAO;AACpC,KAAI,eAAe,UAAW,QAAO;AACrC,QAAO;;AAGT,SAAS,iBAAiB,MAAoC;AAC5D,SAAQ,KAAK,MAAb;EACE,KAAK,gBACH,QAAO;EACT,KAAK,iBACH,QAAO;EACT,KAAK,gBACH,QAAO;EACT,KAAK,cACH,QAAO;EACT,QACE,QAAO;;;AAIb,SAAS,kBACP,MACA,YACc;CACd,MAAM,EAAE,OAAO;AACf,KAAI,OAAO,KAAK;EACd,MAAM,WAAW,iBAAiB,KAAK,MAAM,WAAW;EACxD,MAAM,YAAY,iBAAiB,KAAK,OAAO,WAAW;AAC1D,MAAI,aAAa,YAAY,cAAc,SAAU,QAAO;AAC5D,MAAI,aAAa,aAAa,cAAc,UAAW,QAAO;AAC9D,SAAO;;AAET,KAAI,eAAe,IAAI,GAAG,CAAE,QAAO;AACnC,KAAI,eAAe,IAAI,GAAG,CAAE,QAAO;AACnC,KAAI,YAAY,IAAI,GAAG,CAAE,QAAO;AAChC,QAAO;;AAGT,SAAS,wBACP,MACA,YACc;CACd,MAAM,WACJ,KAAK,OAAO,SAAS,eAAe,KAAK,OAAO,KAAK,aAAa,GAAG;AACvE,KAAI,kBAAkB,IAAI,SAAS,CAAE,QAAO;AAC5C,KAAI,iBAAiB,IAAI,SAAS,CAAE,QAAO;AAC3C,KAAI,kBAAkB,IAAI,SAAS,CAAE,QAAO;AAC5C,KAAI,aAAa,QAAQ,KAAK,UAAU,UAAU,GAAG;EACnD,MAAM,UAAU,KAAK,UAAU;EAC/B,MAAM,UAAU,KAAK,UAAU;AAC/B,MAAI,WAAW,SAAS;GACtB,MAAM,WAAW,iBAAiB,SAAS,WAAW;AAEtD,OAAI,aADa,iBAAiB,SAAS,WAAW,CAC3B,QAAO;;;AAGtC,QAAO;;AAGT,SAAS,iBAAiB,MAAe,YAAsC;CAC7E,MAAM,cAAc,iBAAiB,KAAK;AAC1C,KAAI,gBAAgB,KAAM,QAAO;AAEjC,SAAQ,KAAK,MAAb;EACE,KAAK,aACH,QAAO,aAAa,KAAK,MAAM,WAAW;EAC5C,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,qBACH,QAAO;EACT,KAAK,oBAAoB;GACvB,MAAM,aAAa,iBAAiB,KAAK,QAAQ,WAAW;AAC5D,OAAI,eAAe,UAAW,QAAO;AACrC,OAAI,KAAK,OAAO,SAAS,aACvB,QAAO,aAAa,GAAG,KAAK,OAAO,KAAK,GAAG,KAAK,YAAY,WAAW;AAEzE,UAAO;;EAET,KAAK,WACH,QAAO,kBAAkB,MAAM,WAAW;EAC5C,KAAK;AACH,OAAI,KAAK,OAAO,IAAK,QAAO;AAC5B,OAAI,KAAK,OAAO,IAAK,QAAO;AAC5B,UAAO;EAET,KAAK,aAAa;GAChB,MAAM,WAAW,iBAAiB,KAAK,YAAY,WAAW;AAE9D,UAAO,aADU,iBAAiB,KAAK,WAAW,WAAW,GAC9B,WAAW;;EAE5C,KAAK,iBACH,QAAO,wBAAwB,MAAM,WAAW;EAClD,QACE,QAAO;;;AAIb,SAAgB,iBACd,YACA,aAAyB,EAAE,EACb;CACd,MAAM,UAAU,WAAW,MAAM;AACjC,KAAI,CAAC,QACH,QAAO;AAGT,KAAI;EACF,MAAM,EAAE,QAAQ,aAAa,QAAQ;AACrC,SAAO,iBAAiB,KAAK,WAAW;SAClC;AACN,SAAO;;;;;;ACtfX,SAAS,mBAAmB,OAAuB;CACjD,IAAI,SAAS;AACb,MAAK,MAAM,QAAQ,MACjB,SAAQ,MAAR;EACE,KAAK;AACH,aAAU,OAAO,GAAG;AACpB;EACF,KAAK;AACH,aAAU,OAAO,GAAG;AACpB;EACF,KAAK;AACH,aAAU,OAAO,GAAG;AACpB;EACF,KAAK;AACH,aAAU,OAAO,GAAG;AACpB;EACF,KAAK;AACH,aAAU,OAAO,GAAG;AACpB;EACF,QACE,WAAU;;AAGhB,QAAO;;AAGT,MAAM,aAAqC;CACzC,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAM;CACN,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACL,KAAK;CACN;AAED,SAAS,kBAAkB,MAA8C;CACvE,MAAM,OAAO,WAAW,KAAK,OAAO;CAEpC,MAAM,YAAY,UAA2B;EAC3C,MAAM,IAAI,cAAc,MAAM;AAC9B,MAAI,MAAM,SAAS,YAEjB;QADkB,WAAW,MAAM,OAAO,KAC1B,KACd,QAAO,IAAI,EAAE;;AAGjB,MAAI,MAAM,SAAS,YACjB,QAAO,IAAI,EAAE;AAEf,SAAO;;CAGT,MAAM,aAAa,UAA2B;EAC5C,MAAM,IAAI,cAAc,MAAM;AAC9B,MAAI,MAAM,SAAS,YAEjB;QADkB,WAAW,MAAM,OAAO,MACzB,KACf,QAAO,IAAI,EAAE;;AAGjB,MAAI,MAAM,SAAS,YACjB,QAAO,IAAI,EAAE;AAEf,SAAO;;AAGT,QAAO,GAAG,SAAS,KAAK,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG,UAAU,KAAK,MAAM;;AAGnE,SAAS,cAAc,MAAuB;AAC5C,SAAQ,KAAK,MAAb;EACE,KAAK,gBACH,QAAO,OAAO,KAAK,MAAM;EAC3B,KAAK,gBACH,QAAO,IAAI,mBAAmB,KAAK,MAAM,CAAC;EAC5C,KAAK,iBACH,QAAO,OAAO,KAAK,MAAM;EAC3B,KAAK,cACH,QAAO;EACT,KAAK,aACH,QAAO,KAAK;EACd,KAAK,sBACH,QAAO,KAAK,mBAAmB,KAAK,KAAK,CAAC;EAC5C,KAAK,WACH,QAAO,KAAK;EACd,KAAK,eACH,QAAO,KAAK;EACd,KAAK,eACH,QAAO,KAAK;EACd,KAAK,WACH,QAAO,kBAAkB,KAAK;EAChC,KAAK,UACH,QAAO,GAAG,KAAK,KAAK,uBAAuB,KAAK;EAClD,KAAK,YACH,QAAO,GAAG,0BAA0B,KAAK,UAAU,CAAC,KAAK,cAAc,KAAK,WAAW,CAAC,KAAK,cAAc,KAAK,UAAU;EAC5H,KAAK,iBACH,QAAO,GAAG,cAAc,KAAK,OAAO,CAAC,GAAG,KAAK,UAAU,IAAI,cAAc,CAAC,KAAK,KAAK,CAAC;EACvF,KAAK,mBACH,QAAO,GAAG,uBAAuB,KAAK,OAAO,CAAC,GAAG,KAAK;EACxD,KAAK,4BACH,QAAO,GAAG,uBAAuB,KAAK,OAAO,CAAC,IAAI,mBAAmB,KAAK,SAAS,CAAC;EACtF,KAAK,kBACH,QAAO,GAAG,uBAAuB,KAAK,OAAO,CAAC,GAAG,cAAc,KAAK,MAAM,CAAC;EAC7E,KAAK,qBACH,QAAO,GAAG,uBAAuB,KAAK,OAAO,CAAC;;;AAIpD,SAAS,uBAAuB,MAA6C;CAC3E,MAAM,IAAI,cAAc,KAAK,SAAS;AACtC,KAAI,KAAK,SAAS,SAAS,cAAc,KAAK,SAAS,SAAS,YAC9D,QAAO,IAAI,EAAE;AAEf,QAAO;;AAGT,SAAS,0BAA0B,MAAuB;CACxD,MAAM,IAAI,cAAc,KAAK;AAC7B,KAAI,KAAK,SAAS,YAChB,QAAO,IAAI,EAAE;AAEf,QAAO;;AAGT,SAAS,uBAAuB,MAAuB;CACrD,MAAM,IAAI,cAAc,KAAK;AAC7B,KACE,KAAK,SAAS,cACd,KAAK,SAAS,eACd,KAAK,SAAS,UAEd,QAAO,IAAI,EAAE;AAEf,QAAO;;AAGT,SAAgB,aAAa,KAAsB;AACjD,QAAO,cAAc,IAAI;;;;;AC/I3B,SAAS,sBAAsB,MAA8B;AAC3D,SAAQ,KAAK,MAAb;EACE,KAAK,aACH,QAAO,KAAK;EACd,KAAK,sBACH,QAAO,KAAK,KAAK,KAAK;EACxB,KAAK,WACH,QAAO,KAAK;EACd,KAAK,eACH,QAAO,KAAK;EACd,KAAK,oBAAoB;GACvB,MAAM,UAAU,sBAAsB,KAAK,OAAO;AAClD,OAAI,YAAY,KACd,QAAO;AAET,UAAO,GAAG,QAAQ,GAAG,KAAK;;EAE5B,KAAK,6BAA6B;GAChC,MAAM,UAAU,sBAAsB,KAAK,OAAO;AAClD,OAAI,YAAY,KACd,QAAO;GAET,MAAM,QAAQ;AACd,UAAO,GAAG,QAAQ,GAAG,QAAQ,KAAK,WAAW,MAAM;;EAErD,KAAK,mBAAmB;GACtB,MAAM,UAAU,sBAAsB,KAAK,OAAO;AAClD,OAAI,YAAY,KACd,QAAO;GAET,MAAM,eAAe,gBAAgB,KAAK,MAAM;AAChD,OAAI,iBAAiB,KACnB,QAAO,GAAG,QAAQ,GAAG,aAAa;AAEpC,UAAO;;EAET,KAAK,sBAAsB;GACzB,MAAM,UAAU,sBAAsB,KAAK,OAAO;AAClD,OAAI,YAAY,KACd,QAAO;AAET,UAAO,GAAG,QAAQ;;EAEpB,QACE,QAAO;;;AAIb,SAAS,gBAAgB,MAA8B;AACrD,KAAI,KAAK,SAAS,gBAChB,QAAO,KAAK;AAEd,KACE,KAAK,SAAS,aACd,KAAK,OAAO,OACZ,KAAK,SAAS,SAAS,gBAEvB,QAAO,CAAC,KAAK,SAAS;AAExB,QAAO;;AAGT,SAAS,UACP,MACA,cACe;CACf,MAAM,WAAW,sBAAsB,KAAK;AAC5C,KAAI,aAAa,MAAM;EACrB,MAAM,QAAQ,aAAa;AAC3B,MAAI,UAAU,OACZ,QAAO;;AAGX,QAAO;;AAGT,SAAS,UAAU,MAAuB;CACxC,MAAM,EAAE,QAAQ,aAAa,KAAK;AAClC,QAAO;;AAGT,SAAS,YACP,MACA,cACS;CACT,MAAM,cAAc,UAAU,MAAM,aAAa;AACjD,KAAI,gBAAgB,KAClB,QAAO,UAAU,YAAY;AAG/B,SAAQ,KAAK,MAAb;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,eACH,QAAO;EAET,KAAK,WACH,QAAO;GACL,GAAG;GACH,MAAM,YAAY,KAAK,MAAM,aAAa;GAC1C,OAAO,YAAY,KAAK,OAAO,aAAa;GAC7C;EAEH,KAAK,UACH,QAAO;GACL,GAAG;GACH,UAAU,YAAY,KAAK,UAAU,aAAa;GACnD;EAEH,KAAK,YACH,QAAO;GACL,GAAG;GACH,WAAW,YAAY,KAAK,WAAW,aAAa;GACpD,YAAY,YAAY,KAAK,YAAY,aAAa;GACtD,WAAW,YAAY,KAAK,WAAW,aAAa;GACrD;EAEH,KAAK,kBAAkB;GACrB,MAAM,uBAAuB,KAAK,OAAO,SAAS;AAClD,UAAO;IACL,GAAG;IACH,QAAQ,uBACJ,KAAK,SACL,YAAY,KAAK,QAAQ,aAAa;IAC1C,WAAW,KAAK,UAAU,KAAK,QAAQ,YAAY,KAAK,aAAa,CAAC;IACvE;;EAGH,KAAK;EACL,KAAK;EACL,KAAK,qBACH,QAAO;GACL,GAAG;GACH,QAAQ,YAAY,KAAK,QAAQ,aAAa;GAC/C;EAEH,KAAK,kBACH,QAAO;GACL,GAAG;GACH,QAAQ,YAAY,KAAK,QAAQ,aAAa;GAC9C,OAAO,YAAY,KAAK,OAAO,aAAa;GAC7C;;;AAIP,SAAgB,oBACd,KACA,cACS;AACT,QAAO,YAAY,KAAK,aAAa;;;;;;;;;;;;;;;;;;ACvIvC,SAAgB,gBAAgB,YAAsC;CACpE,MAAM,SAAS,aAAa,WAAW;AACvC,QAAO;EACL;EACA,cAAc,OAAO;EACrB,YAAY,OAAO;EACnB,UAAU,OAAO;EAClB;;;;;;;;;;;;;;;;;;ACXH,SAAgB,sBACd,YACwB;CACxB,MAAM,SAAS,eAAe,WAAW;AAEzC,KAAI,OAAO,QACT,QAAO,EAAE,SAAS,MAAM;AAG1B,QAAO;EACL,SAAS;EACT,OAAO,OAAO;EACd,UAAU,OAAO;EAClB"}