@kaskad/formula-parser 0.0.6 → 0.0.7

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.
@@ -20,6 +20,7 @@ const tokenConfig = {
20
20
  minus: { literal: '-', category: 'operator' },
21
21
  multiply: { literal: '*', category: 'operator' },
22
22
  divide: { literal: '/', category: 'operator' },
23
+ modulo: { literal: '%', category: 'operator' },
23
24
  invert: { literal: '!', category: 'operator' },
24
25
  questionMark: { literal: '?', category: 'operator' },
25
26
  eq: { literal: '==', category: 'operator' },
@@ -28,6 +29,9 @@ const tokenConfig = {
28
29
  lt: { literal: '<', category: 'operator' },
29
30
  gte: { literal: '>=', category: 'operator' },
30
31
  lte: { literal: '<=', category: 'operator' },
32
+ and: { literal: '&&', category: 'operator' },
33
+ or: { literal: '||', category: 'operator' },
34
+ nullCoalesce: { literal: '??', category: 'operator' },
31
35
  comma: { literal: ',', category: 'punctuation' },
32
36
  colon: { literal: ':', category: 'punctuation' },
33
37
  identifier: { category: 'entity' },
@@ -82,16 +86,25 @@ class Token {
82
86
  if (isNumber(value)) {
83
87
  return Number(value);
84
88
  }
85
- return value.replace(/((^'|'$)|(?:^"|"$))/g, '');
89
+ return value.replace(/((^'|'$)|(?:^"|"$))/g, '').replace(/\\(.)/g, (_, ch) => {
90
+ switch (ch) {
91
+ case 'n':
92
+ return '\n';
93
+ case 't':
94
+ return '\t';
95
+ default:
96
+ return ch;
97
+ }
98
+ });
86
99
  }
87
100
  }
88
101
 
89
102
  const LITERAL_REGEX = /^(null|NULL|true|TRUE|false|FALSE)(?=[^\w]|$)/;
90
103
  // Matches identifiers including those with -> for component property access
91
104
  // Allows $ at start and after -> (e.g., $value, &ref->$value)
92
- const IDENTIFIER_REGEX = /^[a-zA-Z$&%][\w\-_.?>$]+/;
105
+ const IDENTIFIER_REGEX = /^[a-zA-Z$&](?:[\w\-_.>$]|\?[-.>])*/;
93
106
  const NUMBER_REGEX = /^\d+\.?\d*/;
94
- const STRING_PATTERNS = [/^'[^']+'/, /^"[^"]+"/, /^''/, /^""/];
107
+ const STRING_PATTERNS = [/^'(?:[^'\\]|\\.)*'/, /^"(?:[^"\\]|\\.)*"/, /^''/, /^""/];
95
108
  const MULTI_CHAR_LITERALS = new Map();
96
109
  const SINGLE_CHAR_LITERALS = new Map();
97
110
  for (const [tokenType, config] of Object.entries(tokenConfig)) {
@@ -132,7 +145,7 @@ class Lexer {
132
145
  return new Token('endOfFile', 'EOF', this.index, this.text);
133
146
  }
134
147
  let skipSpaces = 0;
135
- while (skipSpaces < remaining.length && remaining[skipSpaces] === ' ') {
148
+ while (skipSpaces < remaining.length && /\s/.test(remaining[skipSpaces])) {
136
149
  skipSpaces++;
137
150
  }
138
151
  if (skipSpaces > 0) {
@@ -144,6 +157,14 @@ class Lexer {
144
157
  this.advance(literal[0].length);
145
158
  return new Token('value', literal[0], this.index, this.text);
146
159
  }
160
+ // Check multi-char literals (&&, ||, ==, etc.) before identifiers
161
+ // so that & followed by & is parsed as && rather than two & identifiers
162
+ for (const [literal, type] of MULTI_CHAR_LITERALS) {
163
+ if (remaining.startsWith(literal)) {
164
+ this.advance(literal.length);
165
+ return new Token(type, literal, this.index, this.text);
166
+ }
167
+ }
147
168
  // Check for identifier BEFORE single-character tokens
148
169
  // This allows ?-> to be part of identifiers (e.g., &ref?->value)
149
170
  const identifier = remaining.match(IDENTIFIER_REGEX);
@@ -151,12 +172,6 @@ class Lexer {
151
172
  this.advance(identifier[0].length);
152
173
  return new Token('identifier', identifier[0], this.index, this.text);
153
174
  }
154
- for (const [literal, type] of MULTI_CHAR_LITERALS) {
155
- if (remaining.startsWith(literal)) {
156
- this.advance(literal.length);
157
- return new Token(type, literal, this.index, this.text);
158
- }
159
- }
160
175
  const firstChar = remaining[0];
161
176
  const tokenType = SINGLE_CHAR_LITERALS.get(firstChar);
162
177
  if (tokenType) {
@@ -195,6 +210,7 @@ class Parser {
195
210
  leftBracket: () => this.parseArray(),
196
211
  leftBrace: () => this.parseObject(),
197
212
  invert: () => this.parseUnaryNot(),
213
+ minus: () => this.parseUnaryMinus(),
198
214
  };
199
215
  parse(tokens, allowIncomplete = false) {
200
216
  this.tokens = tokens;
@@ -283,7 +299,7 @@ class Parser {
283
299
  }
284
300
  parseTerm() {
285
301
  let result = this.parseAtom();
286
- while (['multiply', 'divide'].includes(this.getCurrentToken().type)) {
302
+ while (['multiply', 'divide', 'modulo'].includes(this.getCurrentToken().type)) {
287
303
  const operator = this.getCurrentToken().type;
288
304
  result = this.parseMultiplicationOperator(result, operator);
289
305
  }
@@ -301,7 +317,7 @@ class Parser {
301
317
  return parser();
302
318
  }
303
319
  parseTernary() {
304
- const condition = this.parseComparison();
320
+ const condition = this.parseNullCoalesce();
305
321
  if (this.getCurrentToken().type !== 'questionMark') {
306
322
  return condition;
307
323
  }
@@ -344,6 +360,16 @@ class Parser {
344
360
  result.closed = true;
345
361
  return result;
346
362
  }
363
+ parseUnaryMinus() {
364
+ this.consume('minus');
365
+ const result = { type: 'negate', operand: null, closed: false };
366
+ if (this.getCurrentToken().type === 'endOfFile') {
367
+ return result;
368
+ }
369
+ result.operand = this.parseAtom();
370
+ result.closed = true;
371
+ return result;
372
+ }
347
373
  parseAdditionOperator(left, operator) {
348
374
  this.consume(operator);
349
375
  const isEOF = this.getCurrentToken().type === 'endOfFile';
@@ -372,6 +398,37 @@ class Parser {
372
398
  }
373
399
  return left;
374
400
  }
401
+ parseNullCoalesce() {
402
+ let result = this.parseLogicalOr();
403
+ while (this.getCurrentToken().type === 'nullCoalesce') {
404
+ result = this.parseLogicalOperator(result, 'nullCoalesce', () => this.parseLogicalOr());
405
+ }
406
+ return result;
407
+ }
408
+ parseLogicalOr() {
409
+ let result = this.parseLogicalAnd();
410
+ while (this.getCurrentToken().type === 'or') {
411
+ result = this.parseLogicalOperator(result, 'or', () => this.parseLogicalAnd());
412
+ }
413
+ return result;
414
+ }
415
+ parseLogicalAnd() {
416
+ let result = this.parseComparison();
417
+ while (this.getCurrentToken().type === 'and') {
418
+ result = this.parseLogicalOperator(result, 'and', () => this.parseComparison());
419
+ }
420
+ return result;
421
+ }
422
+ parseLogicalOperator(left, operator, parseOperand) {
423
+ this.consume(operator);
424
+ const isEOF = this.getCurrentToken().type === 'endOfFile';
425
+ return {
426
+ type: operator,
427
+ left,
428
+ right: isEOF ? null : parseOperand(),
429
+ closed: !isEOF,
430
+ };
431
+ }
375
432
  parseComparisonOperator(left) {
376
433
  const operator = this.getCurrentToken().type;
377
434
  this.consume(operator);
@@ -457,16 +514,21 @@ class Stringifier {
457
514
  array: (node) => this.visitArrayNode(node),
458
515
  object: (node) => this.visitObjectNode(node),
459
516
  not: (node) => this.visitInvertNode(node),
517
+ negate: (node) => this.visitNegateNode(node),
460
518
  plus: (node) => this.visitOperatorNode(node),
461
519
  minus: (node) => this.visitOperatorNode(node),
462
520
  multiply: (node) => this.visitOperatorNode(node),
463
521
  divide: (node) => this.visitOperatorNode(node),
522
+ modulo: (node) => this.visitOperatorNode(node),
464
523
  eq: (node) => this.visitOperatorNode(node),
465
524
  neq: (node) => this.visitOperatorNode(node),
466
525
  gt: (node) => this.visitOperatorNode(node),
467
526
  lt: (node) => this.visitOperatorNode(node),
468
527
  gte: (node) => this.visitOperatorNode(node),
469
528
  lte: (node) => this.visitOperatorNode(node),
529
+ and: (node) => this.visitOperatorNode(node),
530
+ or: (node) => this.visitOperatorNode(node),
531
+ nullCoalesce: (node) => this.visitOperatorNode(node),
470
532
  group: (node) => this.visitGroup(node),
471
533
  ternary: (node) => this.visitTernaryNode(node),
472
534
  };
@@ -499,8 +561,8 @@ class Stringifier {
499
561
  }
500
562
  processStringValue(item) {
501
563
  if (typeof item === 'string') {
502
- const escaped = he.escape(item.toString());
503
- return `'${String(escaped)}'`;
564
+ const escaped = item.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
565
+ return `'${escaped}'`;
504
566
  }
505
567
  return String(item);
506
568
  }
@@ -565,6 +627,14 @@ class DefaultStringifier extends Stringifier {
565
627
  result += this.visitNode(node.operand);
566
628
  return result;
567
629
  }
630
+ visitNegateNode(node) {
631
+ let result = '-';
632
+ if (node.operand == null) {
633
+ return result;
634
+ }
635
+ result += this.visitNode(node.operand);
636
+ return result;
637
+ }
568
638
  visitGroup(node) {
569
639
  let result = '';
570
640
  result += `(`;
@@ -613,7 +683,12 @@ class HtmlStringifier extends Stringifier {
613
683
  return this.createHtmlSpan('identifier', node.name);
614
684
  }
615
685
  processStringValue(value) {
616
- return this.createHtmlSpan('value', super.processStringValue(value));
686
+ if (typeof value === 'string') {
687
+ const formulaEscaped = value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
688
+ const htmlEscaped = he.escape(formulaEscaped);
689
+ return this.createHtmlSpan('value', `'${htmlEscaped}'`);
690
+ }
691
+ return this.createHtmlSpan('value', String(value));
617
692
  }
618
693
  visitArrayNode(node) {
619
694
  let result = '';
@@ -657,6 +732,15 @@ class HtmlStringifier extends Stringifier {
657
732
  result += this.visitNode(node.operand);
658
733
  return result;
659
734
  }
735
+ visitNegateNode(node) {
736
+ const paren = `paren-deep-${this.currentDeep}`;
737
+ let result = this.createHtmlSpan(paren, '-');
738
+ if (node.operand == null) {
739
+ return result;
740
+ }
741
+ result += this.visitNode(node.operand);
742
+ return result;
743
+ }
660
744
  visitGroup(node) {
661
745
  let result = '';
662
746
  const paren = `paren-deep-${this.currentDeep}`;
@@ -1 +1 @@
1
- {"version":3,"file":"kaskad-formula-parser.mjs","sources":["../../../../libs/formula-parser/src/lib/utils.ts","../../../../libs/formula-parser/src/lib/lexer/token-config.ts","../../../../libs/formula-parser/src/lib/lexer/token.ts","../../../../libs/formula-parser/src/lib/lexer/lexer.ts","../../../../libs/formula-parser/src/lib/parser/parser.ts","../../../../libs/formula-parser/src/lib/stringifier/stringifier.ts","../../../../libs/formula-parser/src/lib/stringifier/default-stringifier.ts","../../../../libs/formula-parser/src/lib/stringifier/html-stringifier.ts","../../../../libs/formula-parser/src/lib/formula-parser.ts","../../../../libs/formula-parser/src/kaskad-formula-parser.ts"],"sourcesContent":["export function isNumber(str: string): boolean {\n const trimmed = str.trim();\n\n if (!trimmed) {\n return false;\n }\n\n const num = Number(trimmed);\n return !Number.isNaN(num) && Number.isFinite(num);\n}\n","export const tokenConfig = {\n leftParen: { literal: '(', category: 'delimiter' },\n rightParen: { literal: ')', category: 'delimiter' },\n leftBracket: { literal: '[', category: 'delimiter' },\n rightBracket: { literal: ']', category: 'delimiter' },\n leftBrace: { literal: '{', category: 'delimiter' },\n rightBrace: { literal: '}', category: 'delimiter' },\n plus: { literal: '+', category: 'operator' },\n minus: { literal: '-', category: 'operator' },\n multiply: { literal: '*', category: 'operator' },\n divide: { literal: '/', category: 'operator' },\n invert: { literal: '!', category: 'operator' },\n questionMark: { literal: '?', category: 'operator' },\n eq: { literal: '==', category: 'operator' },\n neq: { literal: '!=', category: 'operator' },\n gt: { literal: '>', category: 'operator' },\n lt: { literal: '<', category: 'operator' },\n gte: { literal: '>=', category: 'operator' },\n lte: { literal: '<=', category: 'operator' },\n comma: { literal: ',', category: 'punctuation' },\n colon: { literal: ':', category: 'punctuation' },\n identifier: { category: 'entity' },\n value: { category: 'entity' },\n endOfFile: { literal: 'EOF', category: 'misc' },\n} as const;\n\nexport type TokenType = keyof typeof tokenConfig;\n\nexport type TokenTypeMap = {\n [K in keyof typeof tokenConfig]: K extends 'identifier'\n ? string\n : K extends 'value'\n ? string | boolean | number\n : (typeof tokenConfig)[K] extends { literal: infer L }\n ? L\n : never;\n};\n\nexport const getTokenCategory = (type: TokenType): string => {\n return tokenConfig[type].category;\n};\n","import { isNumber } from '../utils';\nimport { getTokenCategory, TokenType, TokenTypeMap } from './token-config';\n\nexport type TokenValue = string | boolean | number | null;\n\nexport class Token<T extends TokenType = TokenType> {\n public readonly type: T;\n public readonly value: TokenTypeMap[T];\n public readonly column: number;\n public readonly line: string;\n\n constructor(type: T, value: string, column = -1, line = '') {\n this.type = type;\n this.column = column;\n this.line = line;\n\n this.value = this.parseValue(type, value) as TokenTypeMap[T];\n }\n\n private parseValue(type: T, value: string): TokenValue {\n if (type === 'endOfFile') {\n return 'EOF' as TokenValue;\n }\n\n if (this.isDelimiterOrOperator(type)) {\n return value as TokenValue;\n }\n\n if (type === 'value') {\n return this.parseValueToken(value);\n }\n\n if (type === 'identifier') {\n return value;\n }\n\n return value;\n }\n\n private isDelimiterOrOperator(type: T): boolean {\n const category = getTokenCategory(type);\n return category === 'delimiter' || category === 'operator' || category === 'punctuation';\n }\n\n private parseValueToken(value: string): TokenValue {\n const normalizedValue = value.toLowerCase();\n\n if (normalizedValue === 'null') {\n return null;\n }\n\n if (normalizedValue === 'true') {\n return true;\n }\n\n if (normalizedValue === 'false') {\n return false;\n }\n\n if (isNumber(value)) {\n return Number(value);\n }\n\n return value.replace(/((^'|'$)|(?:^\"|\"$))/g, '');\n }\n}\n","import { Token } from './token';\nimport { tokenConfig, TokenType } from './token-config';\n\nconst LITERAL_REGEX = /^(null|NULL|true|TRUE|false|FALSE)(?=[^\\w]|$)/;\n// Matches identifiers including those with -> for component property access\n// Allows $ at start and after -> (e.g., $value, &ref->$value)\nconst IDENTIFIER_REGEX = /^[a-zA-Z$&%][\\w\\-_.?>$]+/;\nconst NUMBER_REGEX = /^\\d+\\.?\\d*/;\nconst STRING_PATTERNS = [/^'[^']+'/, /^\"[^\"]+\"/, /^''/, /^\"\"/];\n\nconst MULTI_CHAR_LITERALS = new Map<string, TokenType>();\nconst SINGLE_CHAR_LITERALS = new Map<string, TokenType>();\nfor (const [tokenType, config] of Object.entries(tokenConfig)) {\n if ('literal' in config && config.literal !== 'EOF') {\n if (config.literal.length > 1) {\n MULTI_CHAR_LITERALS.set(config.literal, tokenType as TokenType);\n } else {\n SINGLE_CHAR_LITERALS.set(config.literal, tokenType as TokenType);\n }\n }\n}\n\nexport class Lexer {\n private text = '';\n private index = 0;\n private allowIncomplete = false;\n private incompletePatterns: RegExp[] | null = null;\n\n tokenize(text: string, allowIncomplete = false): Array<Token> {\n this.text = text;\n this.index = 0;\n this.allowIncomplete = allowIncomplete;\n\n const result: Array<Token> = [];\n while (this.index < this.text.length + 1) {\n result.push(this.getNextToken());\n }\n\n return result;\n }\n\n private advance(step = 1): void {\n this.index += step;\n }\n\n private getCurrentLine(): string {\n return this.index < this.text.length ? this.text.substring(this.index) : '';\n }\n\n private getNextToken(): Token {\n const remaining = this.getCurrentLine();\n if (remaining === '') {\n this.advance();\n return new Token('endOfFile', 'EOF', this.index, this.text);\n }\n\n let skipSpaces = 0;\n while (skipSpaces < remaining.length && remaining[skipSpaces] === ' ') {\n skipSpaces++;\n }\n if (skipSpaces > 0) {\n this.advance(skipSpaces);\n return this.getNextToken();\n }\n\n const literal = remaining.match(LITERAL_REGEX);\n if (literal) {\n this.advance(literal[0].length);\n return new Token('value', literal[0], this.index, this.text);\n }\n\n // Check for identifier BEFORE single-character tokens\n // This allows ?-> to be part of identifiers (e.g., &ref?->value)\n const identifier = remaining.match(IDENTIFIER_REGEX);\n if (identifier) {\n this.advance(identifier[0].length);\n return new Token('identifier', identifier[0], this.index, this.text);\n }\n\n for (const [literal, type] of MULTI_CHAR_LITERALS) {\n if (remaining.startsWith(literal)) {\n this.advance(literal.length);\n return new Token(type, literal, this.index, this.text);\n }\n }\n\n const firstChar = remaining[0];\n const tokenType = SINGLE_CHAR_LITERALS.get(firstChar);\n if (tokenType) {\n this.advance(1);\n return new Token(tokenType, firstChar, this.index, this.text);\n }\n\n const patterns = this.getValuePatterns();\n for (const pattern of patterns) {\n const value = remaining.match(pattern);\n if (value) {\n this.advance(value[0].length);\n return new Token('value', value[0], this.index, this.text);\n }\n }\n\n throw new SyntaxError(\n `Invalid syntax at position ${this.index}\\n` + `Formula: ${this.text}\\n` + ` ${' '.repeat(this.index)}^`,\n );\n }\n\n private getValuePatterns(): RegExp[] {\n if (this.allowIncomplete) {\n if (!this.incompletePatterns) {\n this.incompletePatterns = STRING_PATTERNS.map((pattern) => new RegExp(pattern.source + '?')).concat(\n NUMBER_REGEX,\n );\n }\n return this.incompletePatterns;\n }\n return [...STRING_PATTERNS, NUMBER_REGEX];\n }\n}\n","import { Token, TokenType } from '../lexer';\nimport {\n ArrayAstNode,\n FormulaAstNode,\n FunctionAstNode,\n GroupAstNode,\n NotAstNode,\n ObjectAstNode,\n OperatorAstNode,\n ReferenceAstNode,\n TernaryAstNode,\n ValueAstNode,\n} from '../node';\n\nexport class Parser {\n private tokens: Token[] = [];\n private tokenIndex = 0;\n private allowIncomplete = false;\n private readonly atomParsers: Record<string, () => FormulaAstNode> = {\n identifier: () => (this.peekToken()?.type == 'leftParen' ? this.parseFunction() : this.parseReference()),\n leftParen: () => this.parseGroup(),\n value: () => this.parseLiteral(),\n leftBracket: () => this.parseArray(),\n leftBrace: () => this.parseObject(),\n invert: () => this.parseUnaryNot(),\n };\n\n parse(tokens: Token[], allowIncomplete = false): FormulaAstNode {\n this.tokens = tokens;\n this.tokenIndex = 0;\n this.allowIncomplete = allowIncomplete;\n\n return this.parseFormula();\n }\n\n private getCurrentToken(): Token {\n if (this.tokenIndex >= this.tokens.length) {\n throw new SyntaxError('Unexpected end of input');\n }\n return this.tokens[this.tokenIndex];\n }\n\n private peekToken(offset = 1): Token | undefined {\n const nextIndex = this.tokenIndex + offset;\n return nextIndex < this.tokens.length ? this.tokens[nextIndex] : undefined;\n }\n\n private throwExpectedButFound(expected: TokenType): never {\n throw new SyntaxError(\n `Expected a \"${expected}\" token but found: \"${this.getCurrentToken().value}\"\\n` +\n `formula ${this.getCurrentToken().line}\\n` +\n ` ${' '.repeat(this.getCurrentToken().column)}^`,\n );\n }\n\n private throwUnexpectedToken(): never {\n throw new SyntaxError(\n `Unexpected \"${this.getCurrentToken().value}\"\\n` +\n `formula ${this.getCurrentToken().line}\\n` +\n ` ${' '.repeat(this.getCurrentToken().column)}^`,\n );\n }\n\n private consume(type: TokenType): void {\n if (this.getCurrentToken().type === type) {\n this.tokenIndex += 1;\n } else {\n this.throwExpectedButFound(type);\n }\n }\n\n private consumeIfPresent(type: TokenType): boolean {\n if (this.allowIncomplete) {\n try {\n this.consume(type);\n return true;\n } catch {\n return false;\n }\n } else {\n this.consume(type);\n return true;\n }\n }\n\n private parseFormula(): FormulaAstNode {\n const entity = this.parseTernary();\n this.consume('endOfFile');\n return entity;\n }\n\n private parseFunction(): FunctionAstNode {\n const functionName = this.getCurrentToken().value as string;\n\n this.consume('identifier');\n this.consume('leftParen');\n\n const args: FormulaAstNode[] = [];\n do {\n if (this.getCurrentToken().type === 'comma') {\n this.consume('comma');\n }\n if (this.allowIncomplete && this.getCurrentToken().type === 'endOfFile') {\n break;\n }\n if (this.getCurrentToken().type === 'rightParen') {\n break;\n }\n args.push(this.parseTernary());\n } while (this.getCurrentToken().type === 'comma');\n\n const closed: boolean = this.consumeIfPresent('rightParen');\n\n return { type: 'function', name: functionName, args, closed };\n }\n\n private parseExpression(): FormulaAstNode {\n let result: FormulaAstNode = this.parseTerm();\n while (['plus', 'minus'].includes(this.getCurrentToken().type)) {\n const operator = this.getCurrentToken().type as 'plus' | 'minus';\n result = this.parseAdditionOperator(result, operator);\n }\n if (result == null) {\n this.throwUnexpectedToken();\n }\n return result;\n }\n\n private parseTerm(): FormulaAstNode {\n let result: FormulaAstNode = this.parseAtom();\n while (['multiply', 'divide'].includes(this.getCurrentToken().type)) {\n const operator = this.getCurrentToken().type as 'multiply' | 'divide';\n result = this.parseMultiplicationOperator(result, operator);\n }\n if (result == null) {\n this.throwUnexpectedToken();\n }\n return result;\n }\n\n private parseAtom(): FormulaAstNode {\n const tokenType = this.getCurrentToken().type;\n const parser = this.atomParsers[tokenType];\n if (!parser) {\n this.throwUnexpectedToken();\n }\n return parser();\n }\n\n private parseTernary(): TernaryAstNode | FormulaAstNode {\n const condition = this.parseComparison();\n if (this.getCurrentToken().type !== 'questionMark') {\n return condition;\n }\n\n this.consume('questionMark');\n const result: TernaryAstNode = {\n type: 'ternary',\n condition,\n thenBranch: null,\n elseBranch: null,\n closed: false,\n };\n\n if (this.getCurrentToken().type === 'endOfFile') {\n return result;\n }\n\n result.thenBranch = this.parseTernary();\n if (this.getCurrentToken().type === 'endOfFile') {\n return result;\n }\n\n this.consume('colon');\n if (this.getCurrentToken().type === 'endOfFile') {\n return result;\n }\n\n result.elseBranch = this.parseTernary();\n result.closed = true;\n return result;\n }\n\n private parseGroup(): GroupAstNode {\n this.consume('leftParen');\n const entity = this.parseTernary();\n const closed = this.consumeIfPresent('rightParen');\n return { type: 'group', item: entity, closed };\n }\n\n private parseUnaryNot(): NotAstNode {\n this.consume('invert');\n const result = { type: 'not', operand: null, closed: false } as NotAstNode;\n if (this.getCurrentToken().type === 'endOfFile') {\n return result;\n }\n result.operand = this.parseAtom();\n result.closed = true;\n return result;\n }\n\n private parseAdditionOperator(left: FormulaAstNode, operator: 'plus' | 'minus'): OperatorAstNode {\n this.consume(operator);\n const isEOF = this.getCurrentToken().type === 'endOfFile';\n return {\n type: operator,\n left,\n right: isEOF ? null : this.parseTerm(),\n closed: !isEOF,\n };\n }\n\n private parseMultiplicationOperator(left: FormulaAstNode, operator: 'divide' | 'multiply'): OperatorAstNode {\n this.consume(operator);\n const isEOF = this.getCurrentToken().type === 'endOfFile';\n return {\n type: operator,\n left,\n right: isEOF ? null : this.parseAtom(),\n closed: !isEOF,\n };\n }\n\n private parseComparison(): FormulaAstNode {\n const left = this.parseExpression();\n const comparisonTypes = ['eq', 'neq', 'gt', 'lt', 'gte', 'lte'];\n if (comparisonTypes.includes(this.getCurrentToken().type)) {\n return this.parseComparisonOperator(left);\n }\n return left;\n }\n\n private parseComparisonOperator(left: FormulaAstNode): OperatorAstNode {\n const operator = this.getCurrentToken().type as 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte';\n this.consume(operator);\n const isEOF = this.getCurrentToken().type === 'endOfFile';\n return {\n type: operator,\n left,\n right: isEOF ? null : this.parseExpression(),\n closed: !isEOF,\n };\n }\n\n private parseReference(): ReferenceAstNode {\n const variable = this.getCurrentToken().value as string;\n this.consume('identifier');\n return { type: 'reference', name: variable };\n }\n\n private parseLiteral(): ValueAstNode {\n const value = this.getCurrentToken().value;\n this.consume('value');\n return { type: 'value', value };\n }\n\n private parseArray(): ArrayAstNode {\n this.consume('leftBracket');\n\n const items: FormulaAstNode[] = [];\n do {\n if (this.getCurrentToken().type === 'comma') {\n this.consume('comma');\n }\n if (this.allowIncomplete && this.getCurrentToken().type === 'endOfFile') {\n break;\n }\n if (this.getCurrentToken().type === 'rightBracket') {\n break;\n }\n items.push(this.parseTernary());\n } while (this.getCurrentToken().type === 'comma');\n\n const closed = this.consumeIfPresent('rightBracket');\n\n return { type: 'array', items, closed };\n }\n\n private parseObjectKey(): FormulaAstNode {\n const currentToken = this.getCurrentToken();\n\n // Unquoted identifier → IdentifierAstNode (literal key)\n if (currentToken.type === 'identifier') {\n const name = currentToken.value as string;\n this.consume('identifier');\n return { type: 'identifier', name };\n }\n\n // Anything else (quoted strings, numbers, expressions) → parse normally\n return this.parseAtom();\n }\n\n private parseObject(): ObjectAstNode {\n this.consume('leftBrace');\n\n const properties: { key: FormulaAstNode; value: FormulaAstNode }[] = [];\n do {\n if (this.getCurrentToken().type === 'rightBrace') {\n break;\n }\n\n if (this.getCurrentToken().type === 'comma') {\n this.consume('comma');\n }\n if (this.allowIncomplete && this.getCurrentToken().type === 'endOfFile') {\n break;\n }\n if (this.getCurrentToken().type === 'rightBracket') {\n break;\n }\n const key = this.parseObjectKey();\n this.consume('colon');\n const value = this.parseTernary();\n properties.push({ key, value });\n } while (this.getCurrentToken().type === 'comma');\n\n const closed = this.consumeIfPresent('rightBrace');\n\n return { type: 'object', properties, closed };\n }\n}\n","import * as he from 'he';\n\nimport { tokenConfig, TokenType } from '../lexer';\nimport {\n ArrayAstNode,\n FormulaAstNode,\n FunctionAstNode,\n GroupAstNode,\n IdentifierAstNode,\n NotAstNode,\n ObjectAstNode,\n OperatorAstNode,\n ReferenceAstNode,\n TernaryAstNode,\n ValueAstNode,\n} from '../node';\n\nexport abstract class Stringifier {\n private readonly nodeVisitors: Record<string, (node: FormulaAstNode) => string> = {\n function: (node) => this.visitFunctionNode(node as FunctionAstNode),\n reference: (node) => this.visitVariableNode(node as ReferenceAstNode),\n identifier: (node) => this.visitIdentifierNode(node as IdentifierAstNode),\n value: (node) => this.visitValueNode(node as ValueAstNode),\n array: (node) => this.visitArrayNode(node as ArrayAstNode),\n object: (node) => this.visitObjectNode(node as ObjectAstNode),\n not: (node) => this.visitInvertNode(node as NotAstNode),\n plus: (node) => this.visitOperatorNode(node as OperatorAstNode),\n minus: (node) => this.visitOperatorNode(node as OperatorAstNode),\n multiply: (node) => this.visitOperatorNode(node as OperatorAstNode),\n divide: (node) => this.visitOperatorNode(node as OperatorAstNode),\n eq: (node) => this.visitOperatorNode(node as OperatorAstNode),\n neq: (node) => this.visitOperatorNode(node as OperatorAstNode),\n gt: (node) => this.visitOperatorNode(node as OperatorAstNode),\n lt: (node) => this.visitOperatorNode(node as OperatorAstNode),\n gte: (node) => this.visitOperatorNode(node as OperatorAstNode),\n lte: (node) => this.visitOperatorNode(node as OperatorAstNode),\n group: (node) => this.visitGroup(node as GroupAstNode),\n ternary: (node) => this.visitTernaryNode(node as TernaryAstNode),\n };\n\n protected visitNode(node: FormulaAstNode): string {\n const visitor = this.nodeVisitors[node.type];\n if (!visitor) {\n throw new Error(`Unrecognised AST node type: ${node.type}`);\n }\n return visitor(node);\n }\n\n protected visitValueNode(node: ValueAstNode): string {\n if (node.value && typeof node.value === 'object') {\n return this.processObjectValue(node.value);\n }\n\n return this.processStringValue(node.value);\n }\n\n protected processObjectValue(item: object) {\n const object = Object.entries(item);\n const key_values = object.map(([key, value]) => {\n let result_value: string;\n if (typeof value === 'object') {\n result_value = this.processObjectValue(value);\n } else {\n result_value = this.processStringValue(value);\n }\n return `${key}: ${result_value}`;\n });\n return `{ ${key_values.join(', ')} }`;\n }\n\n protected processStringValue(item: unknown): string {\n if (typeof item === 'string') {\n const escaped: string = he.escape(item.toString());\n return `'${String(escaped)}'`;\n }\n\n return String(item);\n }\n\n protected visitOperatorNode(node: OperatorAstNode): string {\n const operatorToken = tokenConfig[node.type as TokenType];\n if (!operatorToken || !('literal' in operatorToken)) {\n throw new Error(`Unrecognised operator type: ${node.type}`);\n }\n\n const operator = ` ${operatorToken.literal} `;\n const left = this.visitNode(node.left);\n const right = node.closed && node.right ? this.visitNode(node.right) : '';\n return `${left}${operator}${right}`;\n }\n\n protected visitTernaryNode(node: TernaryAstNode): string {\n let result: string = this.visitNode(node.condition) + ' ? ';\n if (node.thenBranch == null) {\n return result;\n }\n result += this.visitNode(node.thenBranch) + ' : ';\n if (node.elseBranch == null) {\n return result;\n }\n result += this.visitNode(node.elseBranch);\n return result;\n }\n\n protected abstract visitFunctionNode(node: FunctionAstNode): string;\n\n protected abstract visitVariableNode(node: ReferenceAstNode): string;\n\n protected abstract visitIdentifierNode(node: IdentifierAstNode): string;\n\n protected abstract visitArrayNode(node: ArrayAstNode): string;\n\n protected abstract visitObjectNode(node: ObjectAstNode): string;\n\n protected abstract visitInvertNode(node: NotAstNode): string;\n\n protected abstract visitGroup(node: GroupAstNode): string;\n}\n","import {\n ArrayAstNode,\n FormulaAstNode,\n FunctionAstNode,\n GroupAstNode,\n IdentifierAstNode,\n NotAstNode,\n ObjectAstNode,\n ReferenceAstNode,\n} from '../node';\nimport { Stringifier } from './stringifier';\n\nexport class DefaultStringifier extends Stringifier {\n stringify(tree: FormulaAstNode): string {\n return this.visitNode(tree);\n }\n\n protected visitFunctionNode(node: FunctionAstNode): string {\n return `${node.name}(${node.args.map((node) => this.visitNode(node)).join(', ')})`;\n }\n\n protected visitVariableNode(node: ReferenceAstNode): string {\n return node.name;\n }\n\n protected visitIdentifierNode(node: IdentifierAstNode): string {\n return node.name;\n }\n\n protected visitArrayNode(node: ArrayAstNode): string {\n return '[' + node.items.map((node) => this.visitNode(node)).join(', ') + ']';\n }\n\n protected visitObjectNode(node: ObjectAstNode): string {\n let result = '';\n\n result += '{';\n result += node.properties\n .map((prop) => {\n const key = this.visitNode(prop.key);\n const value = this.visitNode(prop.value);\n return `${key}: ${value}`;\n })\n .join(', ');\n result += '}';\n\n return result;\n }\n\n protected visitInvertNode(node: NotAstNode): string {\n let result = '!';\n\n if (node.operand == null) {\n return result;\n }\n result += this.visitNode(node.operand);\n\n return result;\n }\n\n protected visitGroup(node: GroupAstNode): string {\n let result = '';\n result += `(`;\n result += this.visitNode(node.item);\n result += node.closed ? ')' : '';\n return result;\n }\n}\n","import {\n ArrayAstNode,\n FormulaAstNode,\n FunctionAstNode,\n GroupAstNode,\n IdentifierAstNode,\n NotAstNode,\n ObjectAstNode,\n ReferenceAstNode,\n} from '../node';\nimport { Stringifier } from './stringifier';\n\nexport class HtmlStringifier extends Stringifier {\n private parenStyleCycle: number;\n private currentDeep = 1;\n\n constructor(parenStyleCycle = 3) {\n super();\n this.parenStyleCycle = parenStyleCycle;\n }\n\n stringify(tree: FormulaAstNode): string {\n this.currentDeep = 1;\n return `<div>${this.visitNode(tree)}</div>`;\n }\n\n setParenStyleCycle(newParenStyleCycle: number): void {\n this.parenStyleCycle = newParenStyleCycle;\n }\n\n protected visitFunctionNode(node: FunctionAstNode): string {\n let result = '';\n\n const paren = `paren-deep-${this.currentDeep}`;\n this.incrementParenDeep();\n\n result += this.createHtmlSpan('function', node.name);\n result += this.createHtmlSpan(paren, '(');\n result += node.args.map((arg) => this.visitNode(arg)).join(', ');\n result += node.closed ? this.createHtmlSpan(paren, ')') : ``;\n\n return result;\n }\n\n protected incrementParenDeep(): void {\n if (this.currentDeep < this.parenStyleCycle) {\n this.currentDeep += 1;\n } else {\n this.currentDeep = 1;\n }\n }\n\n protected visitVariableNode(node: ReferenceAstNode): string {\n return this.createHtmlSpan('variable', node.name);\n }\n\n protected visitIdentifierNode(node: IdentifierAstNode): string {\n return this.createHtmlSpan('identifier', node.name);\n }\n\n protected override processStringValue(value: unknown): string {\n return this.createHtmlSpan('value', super.processStringValue(value));\n }\n\n protected visitArrayNode(node: ArrayAstNode): string {\n let result = '';\n\n const paren = `paren-deep-${this.currentDeep}`;\n this.incrementParenDeep();\n\n result += this.createHtmlSpan(paren, '[');\n result += node.items\n .map((node) => {\n const deepStored = this.currentDeep;\n const result = this.visitNode(node);\n this.currentDeep = deepStored;\n return result;\n })\n .join(', ');\n result += node.closed ? this.createHtmlSpan(paren, ']') : ``;\n\n return result;\n }\n\n protected visitObjectNode(node: ObjectAstNode): string {\n let result = '';\n\n const paren = `paren-deep-${this.currentDeep}`;\n this.incrementParenDeep();\n\n result += this.createHtmlSpan(paren, '{');\n result += node.properties\n .map((prop) => {\n const deepStored = this.currentDeep;\n const key = this.visitNode(prop.key);\n const value = this.visitNode(prop.value);\n this.currentDeep = deepStored;\n return `${key}: ${value}`;\n })\n .join(', ');\n result += node.closed ? this.createHtmlSpan(paren, '}') : ``;\n\n return result;\n }\n\n protected visitInvertNode(node: NotAstNode): string {\n const paren = `paren-deep-${this.currentDeep}`;\n\n let result: string = this.createHtmlSpan(paren, '!');\n if (node.operand == null) {\n return result;\n }\n result += this.visitNode(node.operand);\n\n return result;\n }\n\n protected visitGroup(node: GroupAstNode): string {\n let result = '';\n\n const paren = `paren-deep-${this.currentDeep}`;\n this.incrementParenDeep();\n\n result += this.createHtmlSpan(paren, '(');\n result += this.visitNode(node.item);\n result += node.closed ? this.createHtmlSpan(paren, ')') : ``;\n\n return result;\n }\n\n private createHtmlSpan(class_attr: string, value: string): string {\n return `<span class=\"${class_attr}\">${value}</span>`;\n }\n}\n","import { Lexer } from './lexer';\nimport { FormulaAstNode } from './node';\nimport { Parser } from './parser';\nimport { DefaultStringifier, HtmlStringifier } from './stringifier';\n\n/**\n * Parses a formula string into an Abstract Syntax Tree (AST)\n *\n * @param formula - The formula string to parse\n * @returns The parsed AST representation that can be traversed or evaluated\n *\n * @example Basic expressions\n * ```typescript\n * parseFormula('42'); // Literal number\n * parseFormula('\"hello\"'); // Literal string\n * parseFormula('myVariable'); // Variable reference\n * ```\n *\n * @example Function calls\n * ```typescript\n * parseFormula('sum(1, 2, 3)'); // Function with arguments\n * parseFormula('getValue()'); // Function without arguments\n * parseFormula('calc(sum(1, 2), multiply(3, 4))'); // Nested functions\n * ```\n *\n * @example Operators and arithmetic\n * ```typescript\n * parseFormula('price * quantity'); // Multiplication\n * parseFormula('total - discount'); // Subtraction\n * parseFormula('(base + bonus) * multiplier'); // Grouped expressions\n * ```\n *\n * @example Complex structures\n * ```typescript\n * parseFormula('[1, 2, 3]'); // Arrays\n * parseFormula('{name: \"John\", age: 30}'); // Objects\n * parseFormula('isValid ? \"yes\" : \"no\"'); // Ternary conditionals\n * parseFormula('!isDisabled'); // Logical NOT\n * ```\n *\n * @throws {SyntaxError} When the formula contains invalid syntax\n * - Invalid characters (e.g., '@', '#', etc.)\n * - Unclosed parentheses, brackets, or braces\n * - Invalid token sequences\n *\n * @remarks\n * Supported syntax elements:\n * - **Literals**: numbers, strings (single/double quoted), booleans\n * - **Variables**: identifiers starting with letters, $, &, or %\n * - **Functions**: identifier followed by parentheses with optional arguments\n * - **Arrays**: square brackets with comma-separated values\n * - **Objects**: curly braces with key-value pairs\n * - **Operators**: +, -, *, / (following standard precedence)\n * - **Comparison**: ==, !=, >, <, >=, <= (lower precedence than arithmetic)\n * - **Logical**: ! (NOT operator)\n * - **Ternary**: condition ? trueBranch : falseBranch\n * - **Grouping**: parentheses for overriding precedence\n */\nexport function parseFormula(formula: string): FormulaAstNode {\n const lexer = new Lexer();\n const parser = new Parser();\n const tokenized = lexer.tokenize(formula);\n return parser.parse(tokenized);\n}\n\n/**\n * Converts a formula AST back into a formula string\n *\n * @param ast - The AST to stringify (as returned by parseFormula)\n * @returns The formula string representation\n *\n * @example Basic usage\n * ```typescript\n * const ast = parseFormula('sum(1, 2, 3)');\n * const formula = stringifyFormulaAst(ast); // \"sum(1, 2, 3)\"\n * ```\n *\n * @example Round-trip parsing\n * ```typescript\n * const original = 'price * quantity + tax';\n * const ast = parseFormula(original);\n * const reconstructed = stringifyFormulaAst(ast); // \"price * quantity + tax\"\n * ```\n *\n * @remarks\n * - The output may differ slightly from the original in spacing\n * - Parentheses may be added or removed based on operator precedence\n * - String quotes will be normalized to the stringifier's preference\n */\nexport function stringifyFormulaAst(ast: FormulaAstNode): string {\n const stringifier = new DefaultStringifier();\n return stringifier.stringify(ast);\n}\n\n/**\n * Formats a formula string as HTML with syntax highlighting\n *\n * @param formula - The formula string to format\n * @param allowIncomplete - Whether to allow incomplete formulas (useful for live editing). Default: false\n * @param parenStyleCycle - Number of parenthesis depth styles to cycle through. Default: 3\n * @returns HTML string with syntax highlighting using span elements with CSS classes\n *\n * @example Basic usage\n * ```typescript\n * const html = formatFormulaAsHtml('sum(1, 2, 3)');\n * // Returns: '<span class=\"function\">sum</span><span class=\"paren-0\">(</span>...'\n * ```\n *\n * @example Live editor with incomplete formulas\n * ```typescript\n * // Allow incomplete formulas for real-time syntax highlighting as user types\n * const html = formatFormulaAsHtml('sum(1, 2', true);\n * // Won't throw error even though parenthesis is unclosed\n * ```\n *\n * @example Custom parenthesis depth cycling\n * ```typescript\n * // Use 5 different colors for nested parentheses\n * const html = formatFormulaAsHtml('f(g(h(i(j(k())))))', false, 5);\n * ```\n *\n * @remarks\n * CSS classes used in the output:\n * - `function` - Function names\n * - `variable` - Variable identifiers\n * - `value` - Literal values (numbers, strings, booleans)\n * - `operator` - Arithmetic operators (+, -, *, /)\n * - `paren-N` - Parentheses at depth N (cycles based on parenStyleCycle)\n * - `bracket` - Square brackets for arrays\n * - `brace` - Curly braces for objects\n * - `punctuation` - Commas, colons, etc.\n *\n * @throws {SyntaxError} When formula has invalid syntax (unless allowIncomplete is true)\n */\nexport function formatFormulaAsHtml(formula: string, allowIncomplete = false, parenStyleCycle = 3): string {\n const lexer = new Lexer();\n const parser = new Parser();\n const stringifier = new HtmlStringifier(parenStyleCycle);\n const tokenized = lexer.tokenize(formula, allowIncomplete);\n const node = parser.parse(tokenized, allowIncomplete);\n return stringifier.stringify(node);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;AAAM,SAAU,QAAQ,CAAC,GAAW,EAAA;AAClC,IAAA,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE;IAE1B,IAAI,CAAC,OAAO,EAAE;AACZ,QAAA,OAAO,KAAK;;AAGd,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;AAC3B,IAAA,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;AACnD;;ACTO,MAAM,WAAW,GAAG;IACzB,SAAS,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE;IAClD,UAAU,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE;IACnD,WAAW,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE;IACpD,YAAY,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE;IACrD,SAAS,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE;IAClD,UAAU,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE;IACnD,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE;IAC5C,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE;IAC7C,QAAQ,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE;IAChD,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE;IAC9C,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE;IAC9C,YAAY,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE;IACpD,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE;IAC3C,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE;IAC5C,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE;IAC1C,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,EAAE;IAC1C,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE;IAC5C,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE;IAC5C,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE;IAChD,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE;AAChD,IAAA,UAAU,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE;AAClC,IAAA,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAC7B,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE;;AAe1C,MAAM,gBAAgB,GAAG,CAAC,IAAe,KAAY;AAC1D,IAAA,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ;AACnC;;MCnCa,KAAK,CAAA;AACA,IAAA,IAAI;AACJ,IAAA,KAAK;AACL,IAAA,MAAM;AACN,IAAA,IAAI;IAEpB,WAAA,CAAY,IAAO,EAAE,KAAa,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,EAAE,EAAA;AACxD,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAChB,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;QAEhB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAoB;;IAGtD,UAAU,CAAC,IAAO,EAAE,KAAa,EAAA;AACvC,QAAA,IAAI,IAAI,KAAK,WAAW,EAAE;AACxB,YAAA,OAAO,KAAmB;;AAG5B,QAAA,IAAI,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE;AACpC,YAAA,OAAO,KAAmB;;AAG5B,QAAA,IAAI,IAAI,KAAK,OAAO,EAAE;AACpB,YAAA,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;;AAGpC,QAAA,IAAI,IAAI,KAAK,YAAY,EAAE;AACzB,YAAA,OAAO,KAAK;;AAGd,QAAA,OAAO,KAAK;;AAGN,IAAA,qBAAqB,CAAC,IAAO,EAAA;AACnC,QAAA,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC;QACvC,OAAO,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,UAAU,IAAI,QAAQ,KAAK,aAAa;;AAGlF,IAAA,eAAe,CAAC,KAAa,EAAA;AACnC,QAAA,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,EAAE;AAE3C,QAAA,IAAI,eAAe,KAAK,MAAM,EAAE;AAC9B,YAAA,OAAO,IAAI;;AAGb,QAAA,IAAI,eAAe,KAAK,MAAM,EAAE;AAC9B,YAAA,OAAO,IAAI;;AAGb,QAAA,IAAI,eAAe,KAAK,OAAO,EAAE;AAC/B,YAAA,OAAO,KAAK;;AAGd,QAAA,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE;AACnB,YAAA,OAAO,MAAM,CAAC,KAAK,CAAC;;QAGtB,OAAO,KAAK,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC;;AAEnD;;AC9DD,MAAM,aAAa,GAAG,+CAA+C;AACrE;AACA;AACA,MAAM,gBAAgB,GAAG,0BAA0B;AACnD,MAAM,YAAY,GAAG,YAAY;AACjC,MAAM,eAAe,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC;AAE9D,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAqB;AACxD,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAqB;AACzD,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;IAC7D,IAAI,SAAS,IAAI,MAAM,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,EAAE;QACnD,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7B,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,SAAsB,CAAC;;aAC1D;YACL,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,SAAsB,CAAC;;;AAGtE;MAEa,KAAK,CAAA;IACR,IAAI,GAAG,EAAE;IACT,KAAK,GAAG,CAAC;IACT,eAAe,GAAG,KAAK;IACvB,kBAAkB,GAAoB,IAAI;AAElD,IAAA,QAAQ,CAAC,IAAY,EAAE,eAAe,GAAG,KAAK,EAAA;AAC5C,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAChB,QAAA,IAAI,CAAC,KAAK,GAAG,CAAC;AACd,QAAA,IAAI,CAAC,eAAe,GAAG,eAAe;QAEtC,MAAM,MAAM,GAAiB,EAAE;AAC/B,QAAA,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACxC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;;AAGlC,QAAA,OAAO,MAAM;;IAGP,OAAO,CAAC,IAAI,GAAG,CAAC,EAAA;AACtB,QAAA,IAAI,CAAC,KAAK,IAAI,IAAI;;IAGZ,cAAc,GAAA;QACpB,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;;IAGrE,YAAY,GAAA;AAClB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,EAAE;AACvC,QAAA,IAAI,SAAS,KAAK,EAAE,EAAE;YACpB,IAAI,CAAC,OAAO,EAAE;AACd,YAAA,OAAO,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;;QAG7D,IAAI,UAAU,GAAG,CAAC;AAClB,QAAA,OAAO,UAAU,GAAG,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,UAAU,CAAC,KAAK,GAAG,EAAE;AACrE,YAAA,UAAU,EAAE;;AAEd,QAAA,IAAI,UAAU,GAAG,CAAC,EAAE;AAClB,YAAA,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;AACxB,YAAA,OAAO,IAAI,CAAC,YAAY,EAAE;;QAG5B,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,aAAa,CAAC;QAC9C,IAAI,OAAO,EAAE;YACX,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/B,YAAA,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;;;;QAK9D,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,gBAAgB,CAAC;QACpD,IAAI,UAAU,EAAE;YACd,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAClC,YAAA,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;;QAGtE,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,mBAAmB,EAAE;AACjD,YAAA,IAAI,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;AACjC,gBAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;AAC5B,gBAAA,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;;;AAI1D,QAAA,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC;QAC9B,MAAM,SAAS,GAAG,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC;QACrD,IAAI,SAAS,EAAE;AACb,YAAA,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;AACf,YAAA,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;;AAG/D,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACxC,QAAA,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;YAC9B,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;YACtC,IAAI,KAAK,EAAE;gBACT,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AAC7B,gBAAA,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC;;;QAI9D,MAAM,IAAI,WAAW,CACnB,CAAA,2BAAA,EAA8B,IAAI,CAAC,KAAK,CAAA,EAAA,CAAI,GAAG,CAAA,SAAA,EAAY,IAAI,CAAC,IAAI,IAAI,GAAG,CAAA,SAAA,EAAY,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA,CAAA,CAAG,CACjH;;IAGK,gBAAgB,GAAA;AACtB,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE;AACxB,YAAA,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;gBAC5B,IAAI,CAAC,kBAAkB,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CACjG,YAAY,CACb;;YAEH,OAAO,IAAI,CAAC,kBAAkB;;AAEhC,QAAA,OAAO,CAAC,GAAG,eAAe,EAAE,YAAY,CAAC;;AAE5C;;MCxGY,MAAM,CAAA;IACT,MAAM,GAAY,EAAE;IACpB,UAAU,GAAG,CAAC;IACd,eAAe,GAAG,KAAK;AACd,IAAA,WAAW,GAAyC;QACnE,UAAU,EAAE,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,IAAI,WAAW,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;AACxG,QAAA,SAAS,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE;AAClC,QAAA,KAAK,EAAE,MAAM,IAAI,CAAC,YAAY,EAAE;AAChC,QAAA,WAAW,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE;AACpC,QAAA,SAAS,EAAE,MAAM,IAAI,CAAC,WAAW,EAAE;AACnC,QAAA,MAAM,EAAE,MAAM,IAAI,CAAC,aAAa,EAAE;KACnC;AAED,IAAA,KAAK,CAAC,MAAe,EAAE,eAAe,GAAG,KAAK,EAAA;AAC5C,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,IAAI,CAAC,UAAU,GAAG,CAAC;AACnB,QAAA,IAAI,CAAC,eAAe,GAAG,eAAe;AAEtC,QAAA,OAAO,IAAI,CAAC,YAAY,EAAE;;IAGpB,eAAe,GAAA;QACrB,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;AACzC,YAAA,MAAM,IAAI,WAAW,CAAC,yBAAyB,CAAC;;QAElD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;;IAG7B,SAAS,CAAC,MAAM,GAAG,CAAC,EAAA;AAC1B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,GAAG,MAAM;QAC1C,OAAO,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,SAAS;;AAGpE,IAAA,qBAAqB,CAAC,QAAmB,EAAA;AAC/C,QAAA,MAAM,IAAI,WAAW,CACnB,CAAA,YAAA,EAAe,QAAQ,CAAA,oBAAA,EAAuB,IAAI,CAAC,eAAe,EAAE,CAAC,KAAK,CAAA,GAAA,CAAK;AAC7E,YAAA,CAAA,QAAA,EAAW,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAA,EAAA,CAAI;AAC1C,YAAA,CAAA,OAAA,EAAU,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC,CAAA,CAAA,CAAG,CACzD;;IAGK,oBAAoB,GAAA;QAC1B,MAAM,IAAI,WAAW,CACnB,CAAA,YAAA,EAAe,IAAI,CAAC,eAAe,EAAE,CAAC,KAAK,CAAA,GAAA,CAAK;AAC9C,YAAA,CAAA,QAAA,EAAW,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAA,EAAA,CAAI;AAC1C,YAAA,CAAA,OAAA,EAAU,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC,CAAA,CAAA,CAAG,CACzD;;AAGK,IAAA,OAAO,CAAC,IAAe,EAAA;QAC7B,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,IAAI,EAAE;AACxC,YAAA,IAAI,CAAC,UAAU,IAAI,CAAC;;aACf;AACL,YAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC;;;AAI5B,IAAA,gBAAgB,CAAC,IAAe,EAAA;AACtC,QAAA,IAAI,IAAI,CAAC,eAAe,EAAE;AACxB,YAAA,IAAI;AACF,gBAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;AAClB,gBAAA,OAAO,IAAI;;AACX,YAAA,MAAM;AACN,gBAAA,OAAO,KAAK;;;aAET;AACL,YAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;AAClB,YAAA,OAAO,IAAI;;;IAIP,YAAY,GAAA;AAClB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE;AAClC,QAAA,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;AACzB,QAAA,OAAO,MAAM;;IAGP,aAAa,GAAA;QACnB,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,KAAe;AAE3D,QAAA,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;AAC1B,QAAA,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QAEzB,MAAM,IAAI,GAAqB,EAAE;AACjC,QAAA,GAAG;YACD,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE;AAC3C,gBAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;;AAEvB,YAAA,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,WAAW,EAAE;gBACvE;;YAEF,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,YAAY,EAAE;gBAChD;;YAEF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;SAC/B,QAAQ,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,OAAO;QAEhD,MAAM,MAAM,GAAY,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC;AAE3D,QAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE;;IAGvD,eAAe,GAAA;AACrB,QAAA,IAAI,MAAM,GAAmB,IAAI,CAAC,SAAS,EAAE;AAC7C,QAAA,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,EAAE;YAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,IAAwB;YAChE,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC;;AAEvD,QAAA,IAAI,MAAM,IAAI,IAAI,EAAE;YAClB,IAAI,CAAC,oBAAoB,EAAE;;AAE7B,QAAA,OAAO,MAAM;;IAGP,SAAS,GAAA;AACf,QAAA,IAAI,MAAM,GAAmB,IAAI,CAAC,SAAS,EAAE;AAC7C,QAAA,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,EAAE;YACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,IAA6B;YACrE,MAAM,GAAG,IAAI,CAAC,2BAA2B,CAAC,MAAM,EAAE,QAAQ,CAAC;;AAE7D,QAAA,IAAI,MAAM,IAAI,IAAI,EAAE;YAClB,IAAI,CAAC,oBAAoB,EAAE;;AAE7B,QAAA,OAAO,MAAM;;IAGP,SAAS,GAAA;QACf,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE;YACX,IAAI,CAAC,oBAAoB,EAAE;;QAE7B,OAAO,MAAM,EAAE;;IAGT,YAAY,GAAA;AAClB,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE;QACxC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,cAAc,EAAE;AAClD,YAAA,OAAO,SAAS;;AAGlB,QAAA,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;AAC5B,QAAA,MAAM,MAAM,GAAmB;AAC7B,YAAA,IAAI,EAAE,SAAS;YACf,SAAS;AACT,YAAA,UAAU,EAAE,IAAI;AAChB,YAAA,UAAU,EAAE,IAAI;AAChB,YAAA,MAAM,EAAE,KAAK;SACd;QAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,WAAW,EAAE;AAC/C,YAAA,OAAO,MAAM;;AAGf,QAAA,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE;QACvC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,WAAW,EAAE;AAC/C,YAAA,OAAO,MAAM;;AAGf,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QACrB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,WAAW,EAAE;AAC/C,YAAA,OAAO,MAAM;;AAGf,QAAA,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE;AACvC,QAAA,MAAM,CAAC,MAAM,GAAG,IAAI;AACpB,QAAA,OAAO,MAAM;;IAGP,UAAU,GAAA;AAChB,QAAA,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;AACzB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC;QAClD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE;;IAGxC,aAAa,GAAA;AACnB,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;AACtB,QAAA,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAgB;QAC1E,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,WAAW,EAAE;AAC/C,YAAA,OAAO,MAAM;;AAEf,QAAA,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE;AACjC,QAAA,MAAM,CAAC,MAAM,GAAG,IAAI;AACpB,QAAA,OAAO,MAAM;;IAGP,qBAAqB,CAAC,IAAoB,EAAE,QAA0B,EAAA;AAC5E,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,WAAW;QACzD,OAAO;AACL,YAAA,IAAI,EAAE,QAAQ;YACd,IAAI;AACJ,YAAA,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE;YACtC,MAAM,EAAE,CAAC,KAAK;SACf;;IAGK,2BAA2B,CAAC,IAAoB,EAAE,QAA+B,EAAA;AACvF,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,WAAW;QACzD,OAAO;AACL,YAAA,IAAI,EAAE,QAAQ;YACd,IAAI;AACJ,YAAA,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE;YACtC,MAAM,EAAE,CAAC,KAAK;SACf;;IAGK,eAAe,GAAA;AACrB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE;AACnC,QAAA,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC;AAC/D,QAAA,IAAI,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,EAAE;AACzD,YAAA,OAAO,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC;;AAE3C,QAAA,OAAO,IAAI;;AAGL,IAAA,uBAAuB,CAAC,IAAoB,EAAA;QAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,IAAkD;AAC1F,QAAA,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,WAAW;QACzD,OAAO;AACL,YAAA,IAAI,EAAE,QAAQ;YACd,IAAI;AACJ,YAAA,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE;YAC5C,MAAM,EAAE,CAAC,KAAK;SACf;;IAGK,cAAc,GAAA;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,KAAe;AACvD,QAAA,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE;;IAGtC,YAAY,GAAA;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,KAAK;AAC1C,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AACrB,QAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE;;IAGzB,UAAU,GAAA;AAChB,QAAA,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;QAE3B,MAAM,KAAK,GAAqB,EAAE;AAClC,QAAA,GAAG;YACD,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE;AAC3C,gBAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;;AAEvB,YAAA,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,WAAW,EAAE;gBACvE;;YAEF,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,cAAc,EAAE;gBAClD;;YAEF,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;SAChC,QAAQ,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,OAAO;QAEhD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC;QAEpD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE;;IAGjC,cAAc,GAAA;AACpB,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE;;AAG3C,QAAA,IAAI,YAAY,CAAC,IAAI,KAAK,YAAY,EAAE;AACtC,YAAA,MAAM,IAAI,GAAG,YAAY,CAAC,KAAe;AACzC,YAAA,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;AAC1B,YAAA,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE;;;AAIrC,QAAA,OAAO,IAAI,CAAC,SAAS,EAAE;;IAGjB,WAAW,GAAA;AACjB,QAAA,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QAEzB,MAAM,UAAU,GAAqD,EAAE;AACvE,QAAA,GAAG;YACD,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,YAAY,EAAE;gBAChD;;YAGF,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,OAAO,EAAE;AAC3C,gBAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;;AAEvB,YAAA,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,WAAW,EAAE;gBACvE;;YAEF,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,cAAc,EAAE;gBAClD;;AAEF,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,EAAE;AACjC,YAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;AACrB,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE;YACjC,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;SAChC,QAAQ,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,KAAK,OAAO;QAEhD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC;QAElD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE;;AAEhD;;MC/SqB,WAAW,CAAA;AACd,IAAA,YAAY,GAAqD;QAChF,QAAQ,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QACnE,SAAS,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAwB,CAAC;QACrE,UAAU,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,mBAAmB,CAAC,IAAyB,CAAC;QACzE,KAAK,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,cAAc,CAAC,IAAoB,CAAC;QAC1D,KAAK,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,cAAc,CAAC,IAAoB,CAAC;QAC1D,MAAM,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,eAAe,CAAC,IAAqB,CAAC;QAC7D,GAAG,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,eAAe,CAAC,IAAkB,CAAC;QACvD,IAAI,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QAC/D,KAAK,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QAChE,QAAQ,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QACnE,MAAM,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QACjE,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QAC7D,GAAG,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QAC9D,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QAC7D,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QAC7D,GAAG,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QAC9D,GAAG,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,iBAAiB,CAAC,IAAuB,CAAC;QAC9D,KAAK,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,CAAC,IAAoB,CAAC;QACtD,OAAO,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,gBAAgB,CAAC,IAAsB,CAAC;KACjE;AAES,IAAA,SAAS,CAAC,IAAoB,EAAA;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE;YACZ,MAAM,IAAI,KAAK,CAAC,CAAA,4BAAA,EAA+B,IAAI,CAAC,IAAI,CAAA,CAAE,CAAC;;AAE7D,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC;;AAGZ,IAAA,cAAc,CAAC,IAAkB,EAAA;QACzC,IAAI,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE;YAChD,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC;;QAG5C,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC;;AAGlC,IAAA,kBAAkB,CAAC,IAAY,EAAA;QACvC,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;AACnC,QAAA,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;AAC7C,YAAA,IAAI,YAAoB;AACxB,YAAA,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AAC7B,gBAAA,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC;;iBACxC;AACL,gBAAA,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC;;AAE/C,YAAA,OAAO,CAAA,EAAG,GAAG,CAAA,EAAA,EAAK,YAAY,EAAE;AAClC,SAAC,CAAC;QACF,OAAO,CAAA,EAAA,EAAK,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;;AAG7B,IAAA,kBAAkB,CAAC,IAAa,EAAA;AACxC,QAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;YAC5B,MAAM,OAAO,GAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;AAClD,YAAA,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG;;AAG/B,QAAA,OAAO,MAAM,CAAC,IAAI,CAAC;;AAGX,IAAA,iBAAiB,CAAC,IAAqB,EAAA;QAC/C,MAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,IAAiB,CAAC;QACzD,IAAI,CAAC,aAAa,IAAI,EAAE,SAAS,IAAI,aAAa,CAAC,EAAE;YACnD,MAAM,IAAI,KAAK,CAAC,CAAA,4BAAA,EAA+B,IAAI,CAAC,IAAI,CAAA,CAAE,CAAC;;AAG7D,QAAA,MAAM,QAAQ,GAAG,CAAA,CAAA,EAAI,aAAa,CAAC,OAAO,GAAG;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;AACzE,QAAA,OAAO,GAAG,IAAI,CAAA,EAAG,QAAQ,CAAA,EAAG,KAAK,EAAE;;AAG3B,IAAA,gBAAgB,CAAC,IAAoB,EAAA;AAC7C,QAAA,IAAI,MAAM,GAAW,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,KAAK;AAC3D,QAAA,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE;AAC3B,YAAA,OAAO,MAAM;;QAEf,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK;AACjD,QAAA,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE;AAC3B,YAAA,OAAO,MAAM;;QAEf,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC;AACzC,QAAA,OAAO,MAAM;;AAgBhB;;ACzGK,MAAO,kBAAmB,SAAQ,WAAW,CAAA;AACjD,IAAA,SAAS,CAAC,IAAoB,EAAA;AAC5B,QAAA,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;;AAGnB,IAAA,iBAAiB,CAAC,IAAqB,EAAA;AAC/C,QAAA,OAAO,CAAA,EAAG,IAAI,CAAC,IAAI,CAAA,CAAA,EAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;;AAG1E,IAAA,iBAAiB,CAAC,IAAsB,EAAA;QAChD,OAAO,IAAI,CAAC,IAAI;;AAGR,IAAA,mBAAmB,CAAC,IAAuB,EAAA;QACnD,OAAO,IAAI,CAAC,IAAI;;AAGR,IAAA,cAAc,CAAC,IAAkB,EAAA;QACzC,OAAO,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG;;AAGpE,IAAA,eAAe,CAAC,IAAmB,EAAA;QAC3C,IAAI,MAAM,GAAG,EAAE;QAEf,MAAM,IAAI,GAAG;QACb,MAAM,IAAI,IAAI,CAAC;AACZ,aAAA,GAAG,CAAC,CAAC,IAAI,KAAI;YACZ,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;YACpC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;AACxC,YAAA,OAAO,CAAA,EAAG,GAAG,CAAA,EAAA,EAAK,KAAK,EAAE;AAC3B,SAAC;aACA,IAAI,CAAC,IAAI,CAAC;QACb,MAAM,IAAI,GAAG;AAEb,QAAA,OAAO,MAAM;;AAGL,IAAA,eAAe,CAAC,IAAgB,EAAA;QACxC,IAAI,MAAM,GAAG,GAAG;AAEhB,QAAA,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE;AACxB,YAAA,OAAO,MAAM;;QAEf,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;AAEtC,QAAA,OAAO,MAAM;;AAGL,IAAA,UAAU,CAAC,IAAkB,EAAA;QACrC,IAAI,MAAM,GAAG,EAAE;QACf,MAAM,IAAI,GAAG;QACb,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;AACnC,QAAA,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,GAAG,EAAE;AAChC,QAAA,OAAO,MAAM;;AAEhB;;ACvDK,MAAO,eAAgB,SAAQ,WAAW,CAAA;AACtC,IAAA,eAAe;IACf,WAAW,GAAG,CAAC;IAEvB,WAAA,CAAY,eAAe,GAAG,CAAC,EAAA;AAC7B,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,eAAe,GAAG,eAAe;;AAGxC,IAAA,SAAS,CAAC,IAAoB,EAAA;AAC5B,QAAA,IAAI,CAAC,WAAW,GAAG,CAAC;QACpB,OAAO,CAAA,KAAA,EAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ;;AAG7C,IAAA,kBAAkB,CAAC,kBAA0B,EAAA;AAC3C,QAAA,IAAI,CAAC,eAAe,GAAG,kBAAkB;;AAGjC,IAAA,iBAAiB,CAAC,IAAqB,EAAA;QAC/C,IAAI,MAAM,GAAG,EAAE;AAEf,QAAA,MAAM,KAAK,GAAG,CAAA,WAAA,EAAc,IAAI,CAAC,WAAW,EAAE;QAC9C,IAAI,CAAC,kBAAkB,EAAE;QAEzB,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC;QACpD,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC;QACzC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;AAChE,QAAA,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE;AAE5D,QAAA,OAAO,MAAM;;IAGL,kBAAkB,GAAA;QAC1B,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE;AAC3C,YAAA,IAAI,CAAC,WAAW,IAAI,CAAC;;aAChB;AACL,YAAA,IAAI,CAAC,WAAW,GAAG,CAAC;;;AAId,IAAA,iBAAiB,CAAC,IAAsB,EAAA;QAChD,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC;;AAGzC,IAAA,mBAAmB,CAAC,IAAuB,EAAA;QACnD,OAAO,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC;;AAGlC,IAAA,kBAAkB,CAAC,KAAc,EAAA;AAClD,QAAA,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;;AAG5D,IAAA,cAAc,CAAC,IAAkB,EAAA;QACzC,IAAI,MAAM,GAAG,EAAE;AAEf,QAAA,MAAM,KAAK,GAAG,CAAA,WAAA,EAAc,IAAI,CAAC,WAAW,EAAE;QAC9C,IAAI,CAAC,kBAAkB,EAAE;QAEzB,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC;QACzC,MAAM,IAAI,IAAI,CAAC;AACZ,aAAA,GAAG,CAAC,CAAC,IAAI,KAAI;AACZ,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW;YACnC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;AACnC,YAAA,IAAI,CAAC,WAAW,GAAG,UAAU;AAC7B,YAAA,OAAO,MAAM;AACf,SAAC;aACA,IAAI,CAAC,IAAI,CAAC;AACb,QAAA,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE;AAE5D,QAAA,OAAO,MAAM;;AAGL,IAAA,eAAe,CAAC,IAAmB,EAAA;QAC3C,IAAI,MAAM,GAAG,EAAE;AAEf,QAAA,MAAM,KAAK,GAAG,CAAA,WAAA,EAAc,IAAI,CAAC,WAAW,EAAE;QAC9C,IAAI,CAAC,kBAAkB,EAAE;QAEzB,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC;QACzC,MAAM,IAAI,IAAI,CAAC;AACZ,aAAA,GAAG,CAAC,CAAC,IAAI,KAAI;AACZ,YAAA,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;YACpC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;AACxC,YAAA,IAAI,CAAC,WAAW,GAAG,UAAU;AAC7B,YAAA,OAAO,CAAA,EAAG,GAAG,CAAA,EAAA,EAAK,KAAK,EAAE;AAC3B,SAAC;aACA,IAAI,CAAC,IAAI,CAAC;AACb,QAAA,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE;AAE5D,QAAA,OAAO,MAAM;;AAGL,IAAA,eAAe,CAAC,IAAgB,EAAA;AACxC,QAAA,MAAM,KAAK,GAAG,CAAA,WAAA,EAAc,IAAI,CAAC,WAAW,EAAE;QAE9C,IAAI,MAAM,GAAW,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC;AACpD,QAAA,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE;AACxB,YAAA,OAAO,MAAM;;QAEf,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;AAEtC,QAAA,OAAO,MAAM;;AAGL,IAAA,UAAU,CAAC,IAAkB,EAAA;QACrC,IAAI,MAAM,GAAG,EAAE;AAEf,QAAA,MAAM,KAAK,GAAG,CAAA,WAAA,EAAc,IAAI,CAAC,WAAW,EAAE;QAC9C,IAAI,CAAC,kBAAkB,EAAE;QAEzB,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC;QACzC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;AACnC,QAAA,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE;AAE5D,QAAA,OAAO,MAAM;;IAGP,cAAc,CAAC,UAAkB,EAAE,KAAa,EAAA;AACtD,QAAA,OAAO,CAAA,aAAA,EAAgB,UAAU,CAAA,EAAA,EAAK,KAAK,SAAS;;AAEvD;;AChID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDG;AACG,SAAU,YAAY,CAAC,OAAe,EAAA;AAC1C,IAAA,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE;AACzB,IAAA,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE;IAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;AACzC,IAAA,OAAO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;AAChC;AAEA;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACG,SAAU,mBAAmB,CAAC,GAAmB,EAAA;AACrD,IAAA,MAAM,WAAW,GAAG,IAAI,kBAAkB,EAAE;AAC5C,IAAA,OAAO,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC;AACnC;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCG;AACG,SAAU,mBAAmB,CAAC,OAAe,EAAE,eAAe,GAAG,KAAK,EAAE,eAAe,GAAG,CAAC,EAAA;AAC/F,IAAA,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE;AACzB,IAAA,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE;AAC3B,IAAA,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC,eAAe,CAAC;IACxD,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,eAAe,CAAC;AACrD,IAAA,OAAO,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC;AACpC;;AC7IA;;AAEG;;;;"}
1
+ {"version":3,"file":"kaskad-formula-parser.mjs","sources":["../../../../libs/formula-parser/src/lib/utils.ts","../../../../libs/formula-parser/src/lib/lexer/token-config.ts","../../../../libs/formula-parser/src/lib/lexer/token.ts","../../../../libs/formula-parser/src/lib/lexer/lexer.ts","../../../../libs/formula-parser/src/lib/parser/parser.ts","../../../../libs/formula-parser/src/lib/stringifier/stringifier.ts","../../../../libs/formula-parser/src/lib/stringifier/default-stringifier.ts","../../../../libs/formula-parser/src/lib/stringifier/html-stringifier.ts","../../../../libs/formula-parser/src/lib/formula-parser.ts","../../../../libs/formula-parser/src/kaskad-formula-parser.ts"],"sourcesContent":["export function isNumber(str: string): boolean {\n const trimmed = str.trim();\n\n if (!trimmed) {\n return false;\n }\n\n const num = Number(trimmed);\n return !Number.isNaN(num) && Number.isFinite(num);\n}\n","export const tokenConfig = {\n leftParen: { literal: '(', category: 'delimiter' },\n rightParen: { literal: ')', category: 'delimiter' },\n leftBracket: { literal: '[', category: 'delimiter' },\n rightBracket: { literal: ']', category: 'delimiter' },\n leftBrace: { literal: '{', category: 'delimiter' },\n rightBrace: { literal: '}', category: 'delimiter' },\n plus: { literal: '+', category: 'operator' },\n minus: { literal: '-', category: 'operator' },\n multiply: { literal: '*', category: 'operator' },\n divide: { literal: '/', category: 'operator' },\n modulo: { literal: '%', category: 'operator' },\n invert: { literal: '!', category: 'operator' },\n questionMark: { literal: '?', category: 'operator' },\n eq: { literal: '==', category: 'operator' },\n neq: { literal: '!=', category: 'operator' },\n gt: { literal: '>', category: 'operator' },\n lt: { literal: '<', category: 'operator' },\n gte: { literal: '>=', category: 'operator' },\n lte: { literal: '<=', category: 'operator' },\n and: { literal: '&&', category: 'operator' },\n or: { literal: '||', category: 'operator' },\n nullCoalesce: { literal: '??', category: 'operator' },\n comma: { literal: ',', category: 'punctuation' },\n colon: { literal: ':', category: 'punctuation' },\n identifier: { category: 'entity' },\n value: { category: 'entity' },\n endOfFile: { literal: 'EOF', category: 'misc' },\n} as const;\n\nexport type TokenType = keyof typeof tokenConfig;\n\nexport type TokenTypeMap = {\n [K in keyof typeof tokenConfig]: K extends 'identifier'\n ? string\n : K extends 'value'\n ? string | boolean | number\n : (typeof tokenConfig)[K] extends { literal: infer L }\n ? L\n : never;\n};\n\nexport const getTokenCategory = (type: TokenType): string => {\n return tokenConfig[type].category;\n};\n","import { isNumber } from '../utils';\nimport { getTokenCategory, TokenType, TokenTypeMap } from './token-config';\n\nexport type TokenValue = string | boolean | number | null;\n\nexport class Token<T extends TokenType = TokenType> {\n public readonly type: T;\n public readonly value: TokenTypeMap[T];\n public readonly column: number;\n public readonly line: string;\n\n constructor(type: T, value: string, column = -1, line = '') {\n this.type = type;\n this.column = column;\n this.line = line;\n\n this.value = this.parseValue(type, value) as TokenTypeMap[T];\n }\n\n private parseValue(type: T, value: string): TokenValue {\n if (type === 'endOfFile') {\n return 'EOF' as TokenValue;\n }\n\n if (this.isDelimiterOrOperator(type)) {\n return value as TokenValue;\n }\n\n if (type === 'value') {\n return this.parseValueToken(value);\n }\n\n if (type === 'identifier') {\n return value;\n }\n\n return value;\n }\n\n private isDelimiterOrOperator(type: T): boolean {\n const category = getTokenCategory(type);\n return category === 'delimiter' || category === 'operator' || category === 'punctuation';\n }\n\n private parseValueToken(value: string): TokenValue {\n const normalizedValue = value.toLowerCase();\n\n if (normalizedValue === 'null') {\n return null;\n }\n\n if (normalizedValue === 'true') {\n return true;\n }\n\n if (normalizedValue === 'false') {\n return false;\n }\n\n if (isNumber(value)) {\n return Number(value);\n }\n\n return value.replace(/((^'|'$)|(?:^\"|\"$))/g, '').replace(/\\\\(.)/g, (_, ch) => {\n switch (ch) {\n case 'n':\n return '\\n';\n case 't':\n return '\\t';\n default:\n return ch;\n }\n });\n }\n}\n","import { Token } from './token';\nimport { tokenConfig, TokenType } from './token-config';\n\nconst LITERAL_REGEX = /^(null|NULL|true|TRUE|false|FALSE)(?=[^\\w]|$)/;\n// Matches identifiers including those with -> for component property access\n// Allows $ at start and after -> (e.g., $value, &ref->$value)\nconst IDENTIFIER_REGEX = /^[a-zA-Z$&](?:[\\w\\-_.>$]|\\?[-.>])*/;\nconst NUMBER_REGEX = /^\\d+\\.?\\d*/;\nconst STRING_PATTERNS = [/^'(?:[^'\\\\]|\\\\.)*'/, /^\"(?:[^\"\\\\]|\\\\.)*\"/, /^''/, /^\"\"/];\n\nconst MULTI_CHAR_LITERALS = new Map<string, TokenType>();\nconst SINGLE_CHAR_LITERALS = new Map<string, TokenType>();\nfor (const [tokenType, config] of Object.entries(tokenConfig)) {\n if ('literal' in config && config.literal !== 'EOF') {\n if (config.literal.length > 1) {\n MULTI_CHAR_LITERALS.set(config.literal, tokenType as TokenType);\n } else {\n SINGLE_CHAR_LITERALS.set(config.literal, tokenType as TokenType);\n }\n }\n}\n\nexport class Lexer {\n private text = '';\n private index = 0;\n private allowIncomplete = false;\n private incompletePatterns: RegExp[] | null = null;\n\n tokenize(text: string, allowIncomplete = false): Array<Token> {\n this.text = text;\n this.index = 0;\n this.allowIncomplete = allowIncomplete;\n\n const result: Array<Token> = [];\n while (this.index < this.text.length + 1) {\n result.push(this.getNextToken());\n }\n\n return result;\n }\n\n private advance(step = 1): void {\n this.index += step;\n }\n\n private getCurrentLine(): string {\n return this.index < this.text.length ? this.text.substring(this.index) : '';\n }\n\n private getNextToken(): Token {\n const remaining = this.getCurrentLine();\n if (remaining === '') {\n this.advance();\n return new Token('endOfFile', 'EOF', this.index, this.text);\n }\n\n let skipSpaces = 0;\n while (skipSpaces < remaining.length && /\\s/.test(remaining[skipSpaces])) {\n skipSpaces++;\n }\n if (skipSpaces > 0) {\n this.advance(skipSpaces);\n return this.getNextToken();\n }\n\n const literal = remaining.match(LITERAL_REGEX);\n if (literal) {\n this.advance(literal[0].length);\n return new Token('value', literal[0], this.index, this.text);\n }\n\n // Check multi-char literals (&&, ||, ==, etc.) before identifiers\n // so that & followed by & is parsed as && rather than two & identifiers\n for (const [literal, type] of MULTI_CHAR_LITERALS) {\n if (remaining.startsWith(literal)) {\n this.advance(literal.length);\n return new Token(type, literal, this.index, this.text);\n }\n }\n\n // Check for identifier BEFORE single-character tokens\n // This allows ?-> to be part of identifiers (e.g., &ref?->value)\n const identifier = remaining.match(IDENTIFIER_REGEX);\n if (identifier) {\n this.advance(identifier[0].length);\n return new Token('identifier', identifier[0], this.index, this.text);\n }\n\n const firstChar = remaining[0];\n const tokenType = SINGLE_CHAR_LITERALS.get(firstChar);\n if (tokenType) {\n this.advance(1);\n return new Token(tokenType, firstChar, this.index, this.text);\n }\n\n const patterns = this.getValuePatterns();\n for (const pattern of patterns) {\n const value = remaining.match(pattern);\n if (value) {\n this.advance(value[0].length);\n return new Token('value', value[0], this.index, this.text);\n }\n }\n\n throw new SyntaxError(\n `Invalid syntax at position ${this.index}\\n` + `Formula: ${this.text}\\n` + ` ${' '.repeat(this.index)}^`,\n );\n }\n\n private getValuePatterns(): RegExp[] {\n if (this.allowIncomplete) {\n if (!this.incompletePatterns) {\n this.incompletePatterns = STRING_PATTERNS.map((pattern) => new RegExp(pattern.source + '?')).concat(\n NUMBER_REGEX,\n );\n }\n return this.incompletePatterns;\n }\n return [...STRING_PATTERNS, NUMBER_REGEX];\n }\n}\n","import { Token, TokenType } from '../lexer';\nimport {\n ArrayAstNode,\n FormulaAstNode,\n FunctionAstNode,\n GroupAstNode,\n NegateAstNode,\n NotAstNode,\n ObjectAstNode,\n OperatorAstNode,\n ReferenceAstNode,\n TernaryAstNode,\n ValueAstNode,\n} from '../node';\n\nexport class Parser {\n private tokens: Token[] = [];\n private tokenIndex = 0;\n private allowIncomplete = false;\n private readonly atomParsers: Record<string, () => FormulaAstNode> = {\n identifier: () => (this.peekToken()?.type == 'leftParen' ? this.parseFunction() : this.parseReference()),\n leftParen: () => this.parseGroup(),\n value: () => this.parseLiteral(),\n leftBracket: () => this.parseArray(),\n leftBrace: () => this.parseObject(),\n invert: () => this.parseUnaryNot(),\n minus: () => this.parseUnaryMinus(),\n };\n\n parse(tokens: Token[], allowIncomplete = false): FormulaAstNode {\n this.tokens = tokens;\n this.tokenIndex = 0;\n this.allowIncomplete = allowIncomplete;\n\n return this.parseFormula();\n }\n\n private getCurrentToken(): Token {\n if (this.tokenIndex >= this.tokens.length) {\n throw new SyntaxError('Unexpected end of input');\n }\n return this.tokens[this.tokenIndex];\n }\n\n private peekToken(offset = 1): Token | undefined {\n const nextIndex = this.tokenIndex + offset;\n return nextIndex < this.tokens.length ? this.tokens[nextIndex] : undefined;\n }\n\n private throwExpectedButFound(expected: TokenType): never {\n throw new SyntaxError(\n `Expected a \"${expected}\" token but found: \"${this.getCurrentToken().value}\"\\n` +\n `formula ${this.getCurrentToken().line}\\n` +\n ` ${' '.repeat(this.getCurrentToken().column)}^`,\n );\n }\n\n private throwUnexpectedToken(): never {\n throw new SyntaxError(\n `Unexpected \"${this.getCurrentToken().value}\"\\n` +\n `formula ${this.getCurrentToken().line}\\n` +\n ` ${' '.repeat(this.getCurrentToken().column)}^`,\n );\n }\n\n private consume(type: TokenType): void {\n if (this.getCurrentToken().type === type) {\n this.tokenIndex += 1;\n } else {\n this.throwExpectedButFound(type);\n }\n }\n\n private consumeIfPresent(type: TokenType): boolean {\n if (this.allowIncomplete) {\n try {\n this.consume(type);\n return true;\n } catch {\n return false;\n }\n } else {\n this.consume(type);\n return true;\n }\n }\n\n private parseFormula(): FormulaAstNode {\n const entity = this.parseTernary();\n this.consume('endOfFile');\n return entity;\n }\n\n private parseFunction(): FunctionAstNode {\n const functionName = this.getCurrentToken().value as string;\n\n this.consume('identifier');\n this.consume('leftParen');\n\n const args: FormulaAstNode[] = [];\n do {\n if (this.getCurrentToken().type === 'comma') {\n this.consume('comma');\n }\n if (this.allowIncomplete && this.getCurrentToken().type === 'endOfFile') {\n break;\n }\n if (this.getCurrentToken().type === 'rightParen') {\n break;\n }\n args.push(this.parseTernary());\n } while (this.getCurrentToken().type === 'comma');\n\n const closed: boolean = this.consumeIfPresent('rightParen');\n\n return { type: 'function', name: functionName, args, closed };\n }\n\n private parseExpression(): FormulaAstNode {\n let result: FormulaAstNode = this.parseTerm();\n while (['plus', 'minus'].includes(this.getCurrentToken().type)) {\n const operator = this.getCurrentToken().type as 'plus' | 'minus';\n result = this.parseAdditionOperator(result, operator);\n }\n if (result == null) {\n this.throwUnexpectedToken();\n }\n return result;\n }\n\n private parseTerm(): FormulaAstNode {\n let result: FormulaAstNode = this.parseAtom();\n while (['multiply', 'divide', 'modulo'].includes(this.getCurrentToken().type)) {\n const operator = this.getCurrentToken().type as 'multiply' | 'divide' | 'modulo';\n result = this.parseMultiplicationOperator(result, operator);\n }\n if (result == null) {\n this.throwUnexpectedToken();\n }\n return result;\n }\n\n private parseAtom(): FormulaAstNode {\n const tokenType = this.getCurrentToken().type;\n const parser = this.atomParsers[tokenType];\n if (!parser) {\n this.throwUnexpectedToken();\n }\n return parser();\n }\n\n private parseTernary(): TernaryAstNode | FormulaAstNode {\n const condition = this.parseNullCoalesce();\n if (this.getCurrentToken().type !== 'questionMark') {\n return condition;\n }\n\n this.consume('questionMark');\n const result: TernaryAstNode = {\n type: 'ternary',\n condition,\n thenBranch: null,\n elseBranch: null,\n closed: false,\n };\n\n if (this.getCurrentToken().type === 'endOfFile') {\n return result;\n }\n\n result.thenBranch = this.parseTernary();\n if (this.getCurrentToken().type === 'endOfFile') {\n return result;\n }\n\n this.consume('colon');\n if (this.getCurrentToken().type === 'endOfFile') {\n return result;\n }\n\n result.elseBranch = this.parseTernary();\n result.closed = true;\n return result;\n }\n\n private parseGroup(): GroupAstNode {\n this.consume('leftParen');\n const entity = this.parseTernary();\n const closed = this.consumeIfPresent('rightParen');\n return { type: 'group', item: entity, closed };\n }\n\n private parseUnaryNot(): NotAstNode {\n this.consume('invert');\n const result = { type: 'not', operand: null, closed: false } as NotAstNode;\n if (this.getCurrentToken().type === 'endOfFile') {\n return result;\n }\n result.operand = this.parseAtom();\n result.closed = true;\n return result;\n }\n\n private parseUnaryMinus(): NegateAstNode {\n this.consume('minus');\n const result = { type: 'negate', operand: null, closed: false } as NegateAstNode;\n if (this.getCurrentToken().type === 'endOfFile') {\n return result;\n }\n result.operand = this.parseAtom();\n result.closed = true;\n return result;\n }\n\n private parseAdditionOperator(left: FormulaAstNode, operator: 'plus' | 'minus'): OperatorAstNode {\n this.consume(operator);\n const isEOF = this.getCurrentToken().type === 'endOfFile';\n return {\n type: operator,\n left,\n right: isEOF ? null : this.parseTerm(),\n closed: !isEOF,\n };\n }\n\n private parseMultiplicationOperator(\n left: FormulaAstNode,\n operator: 'divide' | 'multiply' | 'modulo',\n ): OperatorAstNode {\n this.consume(operator);\n const isEOF = this.getCurrentToken().type === 'endOfFile';\n return {\n type: operator,\n left,\n right: isEOF ? null : this.parseAtom(),\n closed: !isEOF,\n };\n }\n\n private parseComparison(): FormulaAstNode {\n const left = this.parseExpression();\n const comparisonTypes = ['eq', 'neq', 'gt', 'lt', 'gte', 'lte'];\n if (comparisonTypes.includes(this.getCurrentToken().type)) {\n return this.parseComparisonOperator(left);\n }\n return left;\n }\n\n private parseNullCoalesce(): FormulaAstNode {\n let result: FormulaAstNode = this.parseLogicalOr();\n while (this.getCurrentToken().type === 'nullCoalesce') {\n result = this.parseLogicalOperator(result, 'nullCoalesce', () => this.parseLogicalOr());\n }\n return result;\n }\n\n private parseLogicalOr(): FormulaAstNode {\n let result: FormulaAstNode = this.parseLogicalAnd();\n while (this.getCurrentToken().type === 'or') {\n result = this.parseLogicalOperator(result, 'or', () => this.parseLogicalAnd());\n }\n return result;\n }\n\n private parseLogicalAnd(): FormulaAstNode {\n let result: FormulaAstNode = this.parseComparison();\n while (this.getCurrentToken().type === 'and') {\n result = this.parseLogicalOperator(result, 'and', () => this.parseComparison());\n }\n return result;\n }\n\n private parseLogicalOperator(\n left: FormulaAstNode,\n operator: 'and' | 'or' | 'nullCoalesce',\n parseOperand: () => FormulaAstNode,\n ): OperatorAstNode {\n this.consume(operator);\n const isEOF = this.getCurrentToken().type === 'endOfFile';\n return {\n type: operator,\n left,\n right: isEOF ? null : parseOperand(),\n closed: !isEOF,\n };\n }\n\n private parseComparisonOperator(left: FormulaAstNode): OperatorAstNode {\n const operator = this.getCurrentToken().type as 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte';\n this.consume(operator);\n const isEOF = this.getCurrentToken().type === 'endOfFile';\n return {\n type: operator,\n left,\n right: isEOF ? null : this.parseExpression(),\n closed: !isEOF,\n };\n }\n\n private parseReference(): ReferenceAstNode {\n const variable = this.getCurrentToken().value as string;\n this.consume('identifier');\n return { type: 'reference', name: variable };\n }\n\n private parseLiteral(): ValueAstNode {\n const value = this.getCurrentToken().value;\n this.consume('value');\n return { type: 'value', value };\n }\n\n private parseArray(): ArrayAstNode {\n this.consume('leftBracket');\n\n const items: FormulaAstNode[] = [];\n do {\n if (this.getCurrentToken().type === 'comma') {\n this.consume('comma');\n }\n if (this.allowIncomplete && this.getCurrentToken().type === 'endOfFile') {\n break;\n }\n if (this.getCurrentToken().type === 'rightBracket') {\n break;\n }\n items.push(this.parseTernary());\n } while (this.getCurrentToken().type === 'comma');\n\n const closed = this.consumeIfPresent('rightBracket');\n\n return { type: 'array', items, closed };\n }\n\n private parseObjectKey(): FormulaAstNode {\n const currentToken = this.getCurrentToken();\n\n // Unquoted identifier → IdentifierAstNode (literal key)\n if (currentToken.type === 'identifier') {\n const name = currentToken.value as string;\n this.consume('identifier');\n return { type: 'identifier', name };\n }\n\n // Anything else (quoted strings, numbers, expressions) → parse normally\n return this.parseAtom();\n }\n\n private parseObject(): ObjectAstNode {\n this.consume('leftBrace');\n\n const properties: { key: FormulaAstNode; value: FormulaAstNode }[] = [];\n do {\n if (this.getCurrentToken().type === 'rightBrace') {\n break;\n }\n\n if (this.getCurrentToken().type === 'comma') {\n this.consume('comma');\n }\n if (this.allowIncomplete && this.getCurrentToken().type === 'endOfFile') {\n break;\n }\n if (this.getCurrentToken().type === 'rightBracket') {\n break;\n }\n const key = this.parseObjectKey();\n this.consume('colon');\n const value = this.parseTernary();\n properties.push({ key, value });\n } while (this.getCurrentToken().type === 'comma');\n\n const closed = this.consumeIfPresent('rightBrace');\n\n return { type: 'object', properties, closed };\n }\n}\n","import { tokenConfig, TokenType } from '../lexer';\nimport {\n ArrayAstNode,\n FormulaAstNode,\n FunctionAstNode,\n GroupAstNode,\n IdentifierAstNode,\n NegateAstNode,\n NotAstNode,\n ObjectAstNode,\n OperatorAstNode,\n ReferenceAstNode,\n TernaryAstNode,\n ValueAstNode,\n} from '../node';\n\nexport abstract class Stringifier {\n private readonly nodeVisitors: Record<string, (node: FormulaAstNode) => string> = {\n function: (node) => this.visitFunctionNode(node as FunctionAstNode),\n reference: (node) => this.visitVariableNode(node as ReferenceAstNode),\n identifier: (node) => this.visitIdentifierNode(node as IdentifierAstNode),\n value: (node) => this.visitValueNode(node as ValueAstNode),\n array: (node) => this.visitArrayNode(node as ArrayAstNode),\n object: (node) => this.visitObjectNode(node as ObjectAstNode),\n not: (node) => this.visitInvertNode(node as NotAstNode),\n negate: (node) => this.visitNegateNode(node as NegateAstNode),\n plus: (node) => this.visitOperatorNode(node as OperatorAstNode),\n minus: (node) => this.visitOperatorNode(node as OperatorAstNode),\n multiply: (node) => this.visitOperatorNode(node as OperatorAstNode),\n divide: (node) => this.visitOperatorNode(node as OperatorAstNode),\n modulo: (node) => this.visitOperatorNode(node as OperatorAstNode),\n eq: (node) => this.visitOperatorNode(node as OperatorAstNode),\n neq: (node) => this.visitOperatorNode(node as OperatorAstNode),\n gt: (node) => this.visitOperatorNode(node as OperatorAstNode),\n lt: (node) => this.visitOperatorNode(node as OperatorAstNode),\n gte: (node) => this.visitOperatorNode(node as OperatorAstNode),\n lte: (node) => this.visitOperatorNode(node as OperatorAstNode),\n and: (node) => this.visitOperatorNode(node as OperatorAstNode),\n or: (node) => this.visitOperatorNode(node as OperatorAstNode),\n nullCoalesce: (node) => this.visitOperatorNode(node as OperatorAstNode),\n group: (node) => this.visitGroup(node as GroupAstNode),\n ternary: (node) => this.visitTernaryNode(node as TernaryAstNode),\n };\n\n protected visitNode(node: FormulaAstNode): string {\n const visitor = this.nodeVisitors[node.type];\n if (!visitor) {\n throw new Error(`Unrecognised AST node type: ${node.type}`);\n }\n return visitor(node);\n }\n\n protected visitValueNode(node: ValueAstNode): string {\n if (node.value && typeof node.value === 'object') {\n return this.processObjectValue(node.value);\n }\n\n return this.processStringValue(node.value);\n }\n\n protected processObjectValue(item: object) {\n const object = Object.entries(item);\n const key_values = object.map(([key, value]) => {\n let result_value: string;\n if (typeof value === 'object') {\n result_value = this.processObjectValue(value);\n } else {\n result_value = this.processStringValue(value);\n }\n return `${key}: ${result_value}`;\n });\n return `{ ${key_values.join(', ')} }`;\n }\n\n protected processStringValue(item: unknown): string {\n if (typeof item === 'string') {\n const escaped = item.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n return `'${escaped}'`;\n }\n\n return String(item);\n }\n\n protected visitOperatorNode(node: OperatorAstNode): string {\n const operatorToken = tokenConfig[node.type as TokenType];\n if (!operatorToken || !('literal' in operatorToken)) {\n throw new Error(`Unrecognised operator type: ${node.type}`);\n }\n\n const operator = ` ${operatorToken.literal} `;\n const left = this.visitNode(node.left);\n const right = node.closed && node.right ? this.visitNode(node.right) : '';\n return `${left}${operator}${right}`;\n }\n\n protected visitTernaryNode(node: TernaryAstNode): string {\n let result: string = this.visitNode(node.condition) + ' ? ';\n if (node.thenBranch == null) {\n return result;\n }\n result += this.visitNode(node.thenBranch) + ' : ';\n if (node.elseBranch == null) {\n return result;\n }\n result += this.visitNode(node.elseBranch);\n return result;\n }\n\n protected abstract visitFunctionNode(node: FunctionAstNode): string;\n\n protected abstract visitVariableNode(node: ReferenceAstNode): string;\n\n protected abstract visitIdentifierNode(node: IdentifierAstNode): string;\n\n protected abstract visitArrayNode(node: ArrayAstNode): string;\n\n protected abstract visitObjectNode(node: ObjectAstNode): string;\n\n protected abstract visitInvertNode(node: NotAstNode): string;\n\n protected abstract visitNegateNode(node: NegateAstNode): string;\n\n protected abstract visitGroup(node: GroupAstNode): string;\n}\n","import {\n ArrayAstNode,\n FormulaAstNode,\n FunctionAstNode,\n GroupAstNode,\n IdentifierAstNode,\n NegateAstNode,\n NotAstNode,\n ObjectAstNode,\n ReferenceAstNode,\n} from '../node';\nimport { Stringifier } from './stringifier';\n\nexport class DefaultStringifier extends Stringifier {\n stringify(tree: FormulaAstNode): string {\n return this.visitNode(tree);\n }\n\n protected visitFunctionNode(node: FunctionAstNode): string {\n return `${node.name}(${node.args.map((node) => this.visitNode(node)).join(', ')})`;\n }\n\n protected visitVariableNode(node: ReferenceAstNode): string {\n return node.name;\n }\n\n protected visitIdentifierNode(node: IdentifierAstNode): string {\n return node.name;\n }\n\n protected visitArrayNode(node: ArrayAstNode): string {\n return '[' + node.items.map((node) => this.visitNode(node)).join(', ') + ']';\n }\n\n protected visitObjectNode(node: ObjectAstNode): string {\n let result = '';\n\n result += '{';\n result += node.properties\n .map((prop) => {\n const key = this.visitNode(prop.key);\n const value = this.visitNode(prop.value);\n return `${key}: ${value}`;\n })\n .join(', ');\n result += '}';\n\n return result;\n }\n\n protected visitInvertNode(node: NotAstNode): string {\n let result = '!';\n\n if (node.operand == null) {\n return result;\n }\n result += this.visitNode(node.operand);\n\n return result;\n }\n\n protected visitNegateNode(node: NegateAstNode): string {\n let result = '-';\n\n if (node.operand == null) {\n return result;\n }\n result += this.visitNode(node.operand);\n\n return result;\n }\n\n protected visitGroup(node: GroupAstNode): string {\n let result = '';\n result += `(`;\n result += this.visitNode(node.item);\n result += node.closed ? ')' : '';\n return result;\n }\n}\n","import * as he from 'he';\n\nimport {\n ArrayAstNode,\n FormulaAstNode,\n FunctionAstNode,\n GroupAstNode,\n IdentifierAstNode,\n NegateAstNode,\n NotAstNode,\n ObjectAstNode,\n ReferenceAstNode,\n} from '../node';\nimport { Stringifier } from './stringifier';\n\nexport class HtmlStringifier extends Stringifier {\n private parenStyleCycle: number;\n private currentDeep = 1;\n\n constructor(parenStyleCycle = 3) {\n super();\n this.parenStyleCycle = parenStyleCycle;\n }\n\n stringify(tree: FormulaAstNode): string {\n this.currentDeep = 1;\n return `<div>${this.visitNode(tree)}</div>`;\n }\n\n setParenStyleCycle(newParenStyleCycle: number): void {\n this.parenStyleCycle = newParenStyleCycle;\n }\n\n protected visitFunctionNode(node: FunctionAstNode): string {\n let result = '';\n\n const paren = `paren-deep-${this.currentDeep}`;\n this.incrementParenDeep();\n\n result += this.createHtmlSpan('function', node.name);\n result += this.createHtmlSpan(paren, '(');\n result += node.args.map((arg) => this.visitNode(arg)).join(', ');\n result += node.closed ? this.createHtmlSpan(paren, ')') : ``;\n\n return result;\n }\n\n protected incrementParenDeep(): void {\n if (this.currentDeep < this.parenStyleCycle) {\n this.currentDeep += 1;\n } else {\n this.currentDeep = 1;\n }\n }\n\n protected visitVariableNode(node: ReferenceAstNode): string {\n return this.createHtmlSpan('variable', node.name);\n }\n\n protected visitIdentifierNode(node: IdentifierAstNode): string {\n return this.createHtmlSpan('identifier', node.name);\n }\n\n protected override processStringValue(value: unknown): string {\n if (typeof value === 'string') {\n const formulaEscaped = value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n const htmlEscaped: string = he.escape(formulaEscaped);\n return this.createHtmlSpan('value', `'${htmlEscaped}'`);\n }\n return this.createHtmlSpan('value', String(value));\n }\n\n protected visitArrayNode(node: ArrayAstNode): string {\n let result = '';\n\n const paren = `paren-deep-${this.currentDeep}`;\n this.incrementParenDeep();\n\n result += this.createHtmlSpan(paren, '[');\n result += node.items\n .map((node) => {\n const deepStored = this.currentDeep;\n const result = this.visitNode(node);\n this.currentDeep = deepStored;\n return result;\n })\n .join(', ');\n result += node.closed ? this.createHtmlSpan(paren, ']') : ``;\n\n return result;\n }\n\n protected visitObjectNode(node: ObjectAstNode): string {\n let result = '';\n\n const paren = `paren-deep-${this.currentDeep}`;\n this.incrementParenDeep();\n\n result += this.createHtmlSpan(paren, '{');\n result += node.properties\n .map((prop) => {\n const deepStored = this.currentDeep;\n const key = this.visitNode(prop.key);\n const value = this.visitNode(prop.value);\n this.currentDeep = deepStored;\n return `${key}: ${value}`;\n })\n .join(', ');\n result += node.closed ? this.createHtmlSpan(paren, '}') : ``;\n\n return result;\n }\n\n protected visitInvertNode(node: NotAstNode): string {\n const paren = `paren-deep-${this.currentDeep}`;\n\n let result: string = this.createHtmlSpan(paren, '!');\n if (node.operand == null) {\n return result;\n }\n result += this.visitNode(node.operand);\n\n return result;\n }\n\n protected visitNegateNode(node: NegateAstNode): string {\n const paren = `paren-deep-${this.currentDeep}`;\n\n let result: string = this.createHtmlSpan(paren, '-');\n if (node.operand == null) {\n return result;\n }\n result += this.visitNode(node.operand);\n\n return result;\n }\n\n protected visitGroup(node: GroupAstNode): string {\n let result = '';\n\n const paren = `paren-deep-${this.currentDeep}`;\n this.incrementParenDeep();\n\n result += this.createHtmlSpan(paren, '(');\n result += this.visitNode(node.item);\n result += node.closed ? this.createHtmlSpan(paren, ')') : ``;\n\n return result;\n }\n\n private createHtmlSpan(class_attr: string, value: string): string {\n return `<span class=\"${class_attr}\">${value}</span>`;\n }\n}\n","import { Lexer } from './lexer';\nimport { FormulaAstNode } from './node';\nimport { Parser } from './parser';\nimport { DefaultStringifier, HtmlStringifier } from './stringifier';\n\n/**\n * Parses a formula string into an Abstract Syntax Tree (AST)\n *\n * @param formula - The formula string to parse\n * @returns The parsed AST representation that can be traversed or evaluated\n *\n * @example Basic expressions\n * ```typescript\n * parseFormula('42'); // Literal number\n * parseFormula('\"hello\"'); // Literal string\n * parseFormula('myVariable'); // Variable reference\n * ```\n *\n * @example Function calls\n * ```typescript\n * parseFormula('sum(1, 2, 3)'); // Function with arguments\n * parseFormula('getValue()'); // Function without arguments\n * parseFormula('calc(sum(1, 2), multiply(3, 4))'); // Nested functions\n * ```\n *\n * @example Operators and arithmetic\n * ```typescript\n * parseFormula('price * quantity'); // Multiplication\n * parseFormula('total - discount'); // Subtraction\n * parseFormula('(base + bonus) * multiplier'); // Grouped expressions\n * ```\n *\n * @example Complex structures\n * ```typescript\n * parseFormula('[1, 2, 3]'); // Arrays\n * parseFormula('{name: \"John\", age: 30}'); // Objects\n * parseFormula('isValid ? \"yes\" : \"no\"'); // Ternary conditionals\n * parseFormula('!isDisabled'); // Logical NOT\n * ```\n *\n * @throws {SyntaxError} When the formula contains invalid syntax\n * - Invalid characters (e.g., '@', '#', etc.)\n * - Unclosed parentheses, brackets, or braces\n * - Invalid token sequences\n *\n * @remarks\n * Supported syntax elements:\n * - **Literals**: numbers, strings (single/double quoted), booleans\n * - **Variables**: identifiers starting with letters, $, &, or %\n * - **Functions**: identifier followed by parentheses with optional arguments\n * - **Arrays**: square brackets with comma-separated values\n * - **Objects**: curly braces with key-value pairs\n * - **Operators**: +, -, *, / (following standard precedence)\n * - **Comparison**: ==, !=, >, <, >=, <= (lower precedence than arithmetic)\n * - **Logical**: ! (NOT operator)\n * - **Ternary**: condition ? trueBranch : falseBranch\n * - **Grouping**: parentheses for overriding precedence\n */\nexport function parseFormula(formula: string): FormulaAstNode {\n const lexer = new Lexer();\n const parser = new Parser();\n const tokenized = lexer.tokenize(formula);\n return parser.parse(tokenized);\n}\n\n/**\n * Converts a formula AST back into a formula string\n *\n * @param ast - The AST to stringify (as returned by parseFormula)\n * @returns The formula string representation\n *\n * @example Basic usage\n * ```typescript\n * const ast = parseFormula('sum(1, 2, 3)');\n * const formula = stringifyFormulaAst(ast); // \"sum(1, 2, 3)\"\n * ```\n *\n * @example Round-trip parsing\n * ```typescript\n * const original = 'price * quantity + tax';\n * const ast = parseFormula(original);\n * const reconstructed = stringifyFormulaAst(ast); // \"price * quantity + tax\"\n * ```\n *\n * @remarks\n * - The output may differ slightly from the original in spacing\n * - Parentheses may be added or removed based on operator precedence\n * - String quotes will be normalized to the stringifier's preference\n */\nexport function stringifyFormulaAst(ast: FormulaAstNode): string {\n const stringifier = new DefaultStringifier();\n return stringifier.stringify(ast);\n}\n\n/**\n * Formats a formula string as HTML with syntax highlighting\n *\n * @param formula - The formula string to format\n * @param allowIncomplete - Whether to allow incomplete formulas (useful for live editing). Default: false\n * @param parenStyleCycle - Number of parenthesis depth styles to cycle through. Default: 3\n * @returns HTML string with syntax highlighting using span elements with CSS classes\n *\n * @example Basic usage\n * ```typescript\n * const html = formatFormulaAsHtml('sum(1, 2, 3)');\n * // Returns: '<span class=\"function\">sum</span><span class=\"paren-0\">(</span>...'\n * ```\n *\n * @example Live editor with incomplete formulas\n * ```typescript\n * // Allow incomplete formulas for real-time syntax highlighting as user types\n * const html = formatFormulaAsHtml('sum(1, 2', true);\n * // Won't throw error even though parenthesis is unclosed\n * ```\n *\n * @example Custom parenthesis depth cycling\n * ```typescript\n * // Use 5 different colors for nested parentheses\n * const html = formatFormulaAsHtml('f(g(h(i(j(k())))))', false, 5);\n * ```\n *\n * @remarks\n * CSS classes used in the output:\n * - `function` - Function names\n * - `variable` - Variable identifiers\n * - `value` - Literal values (numbers, strings, booleans)\n * - `operator` - Arithmetic operators (+, -, *, /)\n * - `paren-N` - Parentheses at depth N (cycles based on parenStyleCycle)\n * - `bracket` - Square brackets for arrays\n * - `brace` - Curly braces for objects\n * - `punctuation` - Commas, colons, etc.\n *\n * @throws {SyntaxError} When formula has invalid syntax (unless allowIncomplete is true)\n */\nexport function formatFormulaAsHtml(formula: string, allowIncomplete = false, parenStyleCycle = 3): string {\n const lexer = new Lexer();\n const parser = new Parser();\n const stringifier = new HtmlStringifier(parenStyleCycle);\n const tokenized = lexer.tokenize(formula, allowIncomplete);\n const node = parser.parse(tokenized, allowIncomplete);\n return stringifier.stringify(node);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaskad/formula-parser",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "dependencies": {
5
5
  "he": "^1.2.0",
6
6
  "tslib": "^2.3.0"
@@ -14,7 +14,7 @@ interface ArrayAstNode extends ClosableAstNode {
14
14
  items: FormulaAstNode[];
15
15
  }
16
16
  interface OperatorAstNode extends ClosableAstNode {
17
- type: 'plus' | 'minus' | 'multiply' | 'divide' | 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte';
17
+ type: 'plus' | 'minus' | 'multiply' | 'divide' | 'modulo' | 'eq' | 'neq' | 'gt' | 'lt' | 'gte' | 'lte' | 'and' | 'or' | 'nullCoalesce';
18
18
  left: FormulaAstNode;
19
19
  right: FormulaAstNode | null;
20
20
  }
@@ -43,6 +43,10 @@ interface NotAstNode extends ClosableAstNode {
43
43
  type: 'not';
44
44
  operand: FormulaAstNode | null;
45
45
  }
46
+ interface NegateAstNode extends ClosableAstNode {
47
+ type: 'negate';
48
+ operand: FormulaAstNode | null;
49
+ }
46
50
  interface GroupAstNode extends ClosableAstNode {
47
51
  type: 'group';
48
52
  item: FormulaAstNode;
@@ -53,7 +57,7 @@ interface TernaryAstNode extends ClosableAstNode {
53
57
  thenBranch: FormulaAstNode | null;
54
58
  elseBranch: FormulaAstNode | null;
55
59
  }
56
- type FormulaAstNode = FunctionAstNode | ReferenceAstNode | IdentifierAstNode | ValueAstNode | ArrayAstNode | ObjectAstNode | NotAstNode | OperatorAstNode | GroupAstNode | TernaryAstNode;
60
+ type FormulaAstNode = FunctionAstNode | ReferenceAstNode | IdentifierAstNode | ValueAstNode | ArrayAstNode | ObjectAstNode | NotAstNode | NegateAstNode | OperatorAstNode | GroupAstNode | TernaryAstNode;
57
61
 
58
62
  /**
59
63
  * Parses a formula string into an Abstract Syntax Tree (AST)
@@ -217,6 +221,10 @@ declare const tokenConfig: {
217
221
  readonly literal: "/";
218
222
  readonly category: "operator";
219
223
  };
224
+ readonly modulo: {
225
+ readonly literal: "%";
226
+ readonly category: "operator";
227
+ };
220
228
  readonly invert: {
221
229
  readonly literal: "!";
222
230
  readonly category: "operator";
@@ -249,6 +257,18 @@ declare const tokenConfig: {
249
257
  readonly literal: "<=";
250
258
  readonly category: "operator";
251
259
  };
260
+ readonly and: {
261
+ readonly literal: "&&";
262
+ readonly category: "operator";
263
+ };
264
+ readonly or: {
265
+ readonly literal: "||";
266
+ readonly category: "operator";
267
+ };
268
+ readonly nullCoalesce: {
269
+ readonly literal: "??";
270
+ readonly category: "operator";
271
+ };
252
272
  readonly comma: {
253
273
  readonly literal: ",";
254
274
  readonly category: "punctuation";
@@ -320,9 +340,14 @@ declare class Parser {
320
340
  private parseTernary;
321
341
  private parseGroup;
322
342
  private parseUnaryNot;
343
+ private parseUnaryMinus;
323
344
  private parseAdditionOperator;
324
345
  private parseMultiplicationOperator;
325
346
  private parseComparison;
347
+ private parseNullCoalesce;
348
+ private parseLogicalOr;
349
+ private parseLogicalAnd;
350
+ private parseLogicalOperator;
326
351
  private parseComparisonOperator;
327
352
  private parseReference;
328
353
  private parseLiteral;
@@ -345,6 +370,7 @@ declare abstract class Stringifier {
345
370
  protected abstract visitArrayNode(node: ArrayAstNode): string;
346
371
  protected abstract visitObjectNode(node: ObjectAstNode): string;
347
372
  protected abstract visitInvertNode(node: NotAstNode): string;
373
+ protected abstract visitNegateNode(node: NegateAstNode): string;
348
374
  protected abstract visitGroup(node: GroupAstNode): string;
349
375
  }
350
376
 
@@ -356,6 +382,7 @@ declare class DefaultStringifier extends Stringifier {
356
382
  protected visitArrayNode(node: ArrayAstNode): string;
357
383
  protected visitObjectNode(node: ObjectAstNode): string;
358
384
  protected visitInvertNode(node: NotAstNode): string;
385
+ protected visitNegateNode(node: NegateAstNode): string;
359
386
  protected visitGroup(node: GroupAstNode): string;
360
387
  }
361
388
 
@@ -373,9 +400,10 @@ declare class HtmlStringifier extends Stringifier {
373
400
  protected visitArrayNode(node: ArrayAstNode): string;
374
401
  protected visitObjectNode(node: ObjectAstNode): string;
375
402
  protected visitInvertNode(node: NotAstNode): string;
403
+ protected visitNegateNode(node: NegateAstNode): string;
376
404
  protected visitGroup(node: GroupAstNode): string;
377
405
  private createHtmlSpan;
378
406
  }
379
407
 
380
408
  export { DefaultStringifier, HtmlStringifier, Lexer, Parser, Stringifier, Token, formatFormulaAsHtml, getTokenCategory, parseFormula, stringifyFormulaAst, tokenConfig };
381
- export type { AbstractAstNode, ArrayAstNode, ClosableAstNode, CompositeValue, FormulaAstNode, FunctionAstNode, GroupAstNode, IdentifierAstNode, NotAstNode, ObjectAstNode, OperatorAstNode, PrimitiveValue, ReferenceAstNode, TernaryAstNode, TokenType, TokenTypeMap, TokenValue, ValueAstNode };
409
+ export type { AbstractAstNode, ArrayAstNode, ClosableAstNode, CompositeValue, FormulaAstNode, FunctionAstNode, GroupAstNode, IdentifierAstNode, NegateAstNode, NotAstNode, ObjectAstNode, OperatorAstNode, PrimitiveValue, ReferenceAstNode, TernaryAstNode, TokenType, TokenTypeMap, TokenValue, ValueAstNode };