@rowsncolumns/toolkit 24.5.4 → 24.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/cjs/autofilter-condition.js +6 -2
  2. package/dist/cjs/excel-parser/helpers.d.ts +9 -1
  3. package/dist/cjs/excel-parser/helpers.d.ts.map +1 -1
  4. package/dist/cjs/excel-parser/helpers.js +70 -16
  5. package/dist/cjs/excel-parser/interface.d.ts +9 -1
  6. package/dist/cjs/excel-parser/interface.d.ts.map +1 -1
  7. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -1
  8. package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.js +61 -6
  9. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -1
  10. package/dist/cjs/excel-parser/plugins/xlsx/data-validations.js +13 -2
  11. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +8 -1
  12. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
  13. package/dist/cjs/excel-parser/plugins/xlsx/index.js +159 -26
  14. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts +17 -2
  15. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
  16. package/dist/cjs/excel-parser/plugins/xlsx/styles.js +25 -14
  17. package/dist/cjs/excel-parser/types.d.ts +5 -1
  18. package/dist/cjs/excel-parser/types.d.ts.map +1 -1
  19. package/dist/cjs/excel-parser/workbook.d.ts +1 -0
  20. package/dist/cjs/excel-parser/workbook.d.ts.map +1 -1
  21. package/dist/cjs/excel-parser/workbook.js +4 -0
  22. package/dist/cjs/excel-parser/worker.js +3 -0
  23. package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -1
  24. package/dist/cjs/exporter/xlsx/chart-builder.js +167 -53
  25. package/dist/cjs/exporter/xlsx/future-functions.d.ts +6 -7
  26. package/dist/cjs/exporter/xlsx/future-functions.d.ts.map +1 -1
  27. package/dist/cjs/exporter/xlsx/future-functions.js +5 -261
  28. package/dist/cjs/exporter/xlsx/style-builder.d.ts.map +1 -1
  29. package/dist/cjs/exporter/xlsx/style-builder.js +62 -19
  30. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts +10 -2
  31. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -1
  32. package/dist/cjs/exporter/xlsx/xlsx-export.js +404 -158
  33. package/dist/cjs/helpers/excel-formula-prefixes.d.ts +51 -0
  34. package/dist/cjs/helpers/excel-formula-prefixes.d.ts.map +1 -0
  35. package/dist/cjs/helpers/excel-formula-prefixes.js +548 -0
  36. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  37. package/dist/esm/autofilter-condition.js +6 -2
  38. package/dist/esm/excel-parser/helpers.d.ts +9 -1
  39. package/dist/esm/excel-parser/helpers.d.ts.map +1 -1
  40. package/dist/esm/excel-parser/helpers.js +65 -3
  41. package/dist/esm/excel-parser/interface.d.ts +9 -1
  42. package/dist/esm/excel-parser/interface.d.ts.map +1 -1
  43. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -1
  44. package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.js +42 -1
  45. package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -1
  46. package/dist/esm/excel-parser/plugins/xlsx/data-validations.js +11 -2
  47. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +8 -1
  48. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
  49. package/dist/esm/excel-parser/plugins/xlsx/index.js +109 -4
  50. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts +17 -2
  51. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
  52. package/dist/esm/excel-parser/plugins/xlsx/styles.js +20 -8
  53. package/dist/esm/excel-parser/types.d.ts +5 -1
  54. package/dist/esm/excel-parser/types.d.ts.map +1 -1
  55. package/dist/esm/excel-parser/workbook.d.ts +1 -0
  56. package/dist/esm/excel-parser/workbook.d.ts.map +1 -1
  57. package/dist/esm/excel-parser/workbook.js +3 -0
  58. package/dist/esm/excel-parser/worker.js +3 -0
  59. package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -1
  60. package/dist/esm/exporter/xlsx/chart-builder.js +80 -0
  61. package/dist/esm/exporter/xlsx/future-functions.d.ts +6 -7
  62. package/dist/esm/exporter/xlsx/future-functions.d.ts.map +1 -1
  63. package/dist/esm/exporter/xlsx/future-functions.js +5 -261
  64. package/dist/esm/exporter/xlsx/style-builder.d.ts.map +1 -1
  65. package/dist/esm/exporter/xlsx/style-builder.js +56 -18
  66. package/dist/esm/exporter/xlsx/xlsx-export.d.ts +10 -2
  67. package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -1
  68. package/dist/esm/exporter/xlsx/xlsx-export.js +338 -106
  69. package/dist/esm/helpers/excel-formula-prefixes.d.ts +51 -0
  70. package/dist/esm/helpers/excel-formula-prefixes.d.ts.map +1 -0
  71. package/dist/esm/helpers/excel-formula-prefixes.js +531 -0
  72. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  73. package/package.json +4 -4
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Every function Excel stores behind `_xlfn.` (uppercase). One list for both
3
+ * directions: the exporter qualifies exactly these; the importer strips any
4
+ * marker it finds, list or not, so a newer function still opens cleanly.
5
+ */
6
+ export declare const FUTURE_FUNCTION_NAMES: readonly string[];
7
+ /**
8
+ * Future functions that Excel writes behind the worksheet-scope prefix
9
+ * (`_xlfn._xlws.`) rather than plain `_xlfn.` — the dynamic-array functions
10
+ * that also exist as worksheet-only names, plus Python in Excel.
11
+ */
12
+ export declare const WORKSHEET_SCOPED_FUTURE_FUNCTIONS: ReadonlySet<string>;
13
+ /**
14
+ * Remove every `_xlfn.` / `_xlws.` / `_xlpm.` / `_xludf.` storage marker from
15
+ * `formula` (outside string literals and quoted sheet names). Idempotent.
16
+ */
17
+ export declare function stripExcelFormulaPrefixes(formula: string): string;
18
+ /**
19
+ * `_xlfn.ANCHORARRAY(A1)` / `ANCHORARRAY(Sheet1!A1)` → `A1#` / `Sheet1!A1#`
20
+ * — Excel's stored form of the spilled-range operator back to its UI form.
21
+ * A call whose argument is not exactly one cell reference is left as is.
22
+ */
23
+ export declare function decodeAnchorArray(formula: string): string;
24
+ /**
25
+ * `A1#` / `Sheet1!A1#` → `ANCHORARRAY(A1)` / `ANCHORARRAY(Sheet1!A1)` — the
26
+ * spilled-range operator in the form sheet XML accepts (future-function
27
+ * qualification then adds the `_xlfn.` prefix). `#REF!#` is left alone.
28
+ */
29
+ export declare function encodeSpilledRanges(formula: string): string;
30
+ /**
31
+ * Prefix every LET / LAMBDA parameter with `_xlpm.` — at its declaration and
32
+ * at every use inside the call (a use as a function, `double(5)` for a
33
+ * LET-bound lambda, included). Parameters are the odd-position LET arguments
34
+ * (all but the last argument, which is the calculation) and every LAMBDA
35
+ * argument but the last. Already-prefixed input comes out prefixed once.
36
+ */
37
+ export declare function qualifyLambdaParameters(formula: string): string;
38
+ /**
39
+ * Export direction. Strip the storage markers and re-add the correct one to
40
+ * every future-function call in `formula`, write `A1#` as `ANCHORARRAY(A1)`
41
+ * (qualified to `_xlfn.ANCHORARRAY`) and prefix LET / LAMBDA parameters with
42
+ * `_xlpm.`. Quoted spans keep their original text. Idempotent: already
43
+ * qualified input comes out qualified exactly once.
44
+ */
45
+ export declare function qualifyFutureFunctions(formula: string): string;
46
+ /**
47
+ * Import direction. The formula as Excel displays it: every storage marker
48
+ * removed, `_xlfn.ANCHORARRAY(A1)` shown as `A1#`, `_xlfn.SINGLE(x)` as `@x`.
49
+ */
50
+ export declare function normalizeImportedFormula(formula: string): string;
51
+ //# sourceMappingURL=excel-formula-prefixes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"excel-formula-prefixes.d.ts","sourceRoot":"","sources":["../../../helpers/excel-formula-prefixes.ts"],"names":[],"mappings":"AAoCA;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EA+KlD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,EAAE,WAAW,CAAC,MAAM,CAIhE,CAAC;AA4FH;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjE;AAuDD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA6BzD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkB3D;AA0CD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgD/D;AAID;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAM9D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIhE"}
@@ -0,0 +1,548 @@
1
+ import { __read, __spreadArray, __values } from "tslib";
2
+ /**
3
+ * Excel's file-format spelling of modern formulas, in both directions.
4
+ *
5
+ * The .xlsx grammar was frozen with Excel 2007, so every function added since
6
+ * is stored behind a namespace prefix the UI never shows:
7
+ *
8
+ * - `_xlfn.NAME(` — a "future function" (`_xlfn.XLOOKUP(`, `_xlfn.IFS(`);
9
+ * - `_xlfn._xlws.NAME(` — the worksheet-scoped dynamic-array functions
10
+ * (`_xlfn._xlws.FILTER(`, `_xlfn._xlws.SORT(`, `_xlfn._xlws.PY(`);
11
+ * - `_xlpm.name` — every LET / LAMBDA parameter, at its declaration
12
+ * and at every use (`_xlfn.LET(_xlpm.x,A1,_xlpm.x+1)`);
13
+ * - `_xlfn.ANCHORARRAY(A1)` — the spilled-range operator `A1#`;
14
+ * - `_xlfn.SINGLE(x)` — the implicit-intersection operator `@x`;
15
+ * - `_xludf.NAME(` — a user-defined (add-in) function.
16
+ *
17
+ * Written bare, Excel does not resolve a future function: it renders the call
18
+ * behind the implicit-intersection operator (`=@DAYS(...)`) and evaluates
19
+ * `#NAME?`. Kept prefixed in the engine, `SUM(_xlfn.ANCHORARRAY(A1))` is a
20
+ * `#NAME?` and the formula bar shows `=_xlfn.XLOOKUP(`. So the importer
21
+ * removes every marker ({@link normalizeImportedFormula}) and the exporter
22
+ * re-adds them from one list ({@link qualifyFutureFunctions}); a formula
23
+ * round-trips unchanged.
24
+ *
25
+ * The list follows Microsoft's documentation of `_xlfn.`-prefixed functions
26
+ * ("Issue: An _xlfn. prefix is displayed in front of a function in a
27
+ * formula", support.microsoft.com) plus the dynamic-array / LAMBDA-era, 2024
28
+ * and Python-in-Excel additions that ship with the same prefix convention.
29
+ */
30
+ import { lexify, tokenVocabulary } from "@rowsncolumns/calculator";
31
+ import { decodeImplicitIntersection } from "./implicit-intersection";
32
+ var T = tokenVocabulary;
33
+ /**
34
+ * Every function Excel stores behind `_xlfn.` (uppercase). One list for both
35
+ * directions: the exporter qualifies exactly these; the importer strips any
36
+ * marker it finds, list or not, so a newer function still opens cleanly.
37
+ */
38
+ export var FUTURE_FUNCTION_NAMES = [
39
+ "ACOT",
40
+ "ACOTH",
41
+ "AGGREGATE",
42
+ "ANCHORARRAY",
43
+ "ARABIC",
44
+ "ARRAYTOTEXT",
45
+ "BASE",
46
+ "BETA.DIST",
47
+ "BETA.INV",
48
+ "BINOM.DIST",
49
+ "BINOM.DIST.RANGE",
50
+ "BINOM.INV",
51
+ "BITAND",
52
+ "BITLSHIFT",
53
+ "BITOR",
54
+ "BITRSHIFT",
55
+ "BITXOR",
56
+ "BYCOL",
57
+ "BYROW",
58
+ "CEILING.MATH",
59
+ "CEILING.PRECISE",
60
+ "CHISQ.DIST",
61
+ "CHISQ.DIST.RT",
62
+ "CHISQ.INV",
63
+ "CHISQ.INV.RT",
64
+ "CHISQ.TEST",
65
+ "CHOOSECOLS",
66
+ "CHOOSEROWS",
67
+ "COMBINA",
68
+ "CONCAT",
69
+ "CONFIDENCE.NORM",
70
+ "CONFIDENCE.T",
71
+ "COT",
72
+ "COTH",
73
+ "COVARIANCE.P",
74
+ "COVARIANCE.S",
75
+ "CSC",
76
+ "CSCH",
77
+ "DAYS",
78
+ "DECIMAL",
79
+ "DETECTLANGUAGE",
80
+ "DROP",
81
+ "ENCODEURL",
82
+ "ERF.PRECISE",
83
+ "ERFC.PRECISE",
84
+ "EXPAND",
85
+ "EXPON.DIST",
86
+ "F.DIST",
87
+ "F.DIST.RT",
88
+ "F.INV",
89
+ "F.INV.RT",
90
+ "F.TEST",
91
+ "FIELDVALUE",
92
+ "FILTER",
93
+ "FILTERXML",
94
+ "FLOOR.MATH",
95
+ "FLOOR.PRECISE",
96
+ "FORECAST.ETS",
97
+ "FORECAST.ETS.CONFINT",
98
+ "FORECAST.ETS.SEASONALITY",
99
+ "FORECAST.ETS.STAT",
100
+ "FORECAST.LINEAR",
101
+ "FORMULATEXT",
102
+ "GAMMA",
103
+ "GAMMA.DIST",
104
+ "GAMMA.INV",
105
+ "GAMMALN.PRECISE",
106
+ "GAUSS",
107
+ "GROUPBY",
108
+ "HSTACK",
109
+ "HYPGEOM.DIST",
110
+ "IFNA",
111
+ "IFS",
112
+ "IMAGE",
113
+ "IMCOSH",
114
+ "IMCOT",
115
+ "IMCSC",
116
+ "IMCSCH",
117
+ "IMSEC",
118
+ "IMSECH",
119
+ "IMSINH",
120
+ "IMTAN",
121
+ "ISFORMULA",
122
+ "ISOMITTED",
123
+ "ISOWEEKNUM",
124
+ "LAMBDA",
125
+ "LET",
126
+ "LOGNORM.DIST",
127
+ "LOGNORM.INV",
128
+ "MAKEARRAY",
129
+ "MAP",
130
+ "MAXIFS",
131
+ "MINIFS",
132
+ "MODE.MULT",
133
+ "MODE.SNGL",
134
+ "MUNIT",
135
+ "NEGBINOM.DIST",
136
+ "NETWORKDAYS.INTL",
137
+ "NORM.DIST",
138
+ "NORM.INV",
139
+ "NORM.S.DIST",
140
+ "NORM.S.INV",
141
+ "NUMBERVALUE",
142
+ "PDURATION",
143
+ "PERCENTILE.EXC",
144
+ "PERCENTILE.INC",
145
+ "PERCENTOF",
146
+ "PERCENTRANK.EXC",
147
+ "PERCENTRANK.INC",
148
+ "PERMUTATIONA",
149
+ "PHI",
150
+ "PIVOTBY",
151
+ "POISSON.DIST",
152
+ "PQSOURCE",
153
+ "PY",
154
+ "PYTHON_STR",
155
+ "PYTHON_TYPE",
156
+ "PYTHON_TYPENAME",
157
+ "QUARTILE.EXC",
158
+ "QUARTILE.INC",
159
+ "QUERYSTRING",
160
+ "RANDARRAY",
161
+ "RANK.AVG",
162
+ "RANK.EQ",
163
+ "REDUCE",
164
+ "REGEXEXTRACT",
165
+ "REGEXREPLACE",
166
+ "REGEXTEST",
167
+ "RRI",
168
+ "SCAN",
169
+ "SEC",
170
+ "SECH",
171
+ "SEQUENCE",
172
+ "SHEET",
173
+ "SHEETS",
174
+ "SINGLE",
175
+ "SKEW.P",
176
+ "SORT",
177
+ "SORTBY",
178
+ "STDEV.P",
179
+ "STDEV.S",
180
+ "STOCKHISTORY",
181
+ "SWITCH",
182
+ "T.DIST",
183
+ "T.DIST.2T",
184
+ "T.DIST.RT",
185
+ "T.INV",
186
+ "T.INV.2T",
187
+ "T.TEST",
188
+ "TAKE",
189
+ "TEXTAFTER",
190
+ "TEXTBEFORE",
191
+ "TEXTJOIN",
192
+ "TEXTSPLIT",
193
+ "TOCOL",
194
+ "TOROW",
195
+ "TRANSLATE",
196
+ "TRIMRANGE",
197
+ "UNICHAR",
198
+ "UNICODE",
199
+ "UNIQUE",
200
+ "VALUETOTEXT",
201
+ "VAR.P",
202
+ "VAR.S",
203
+ "VSTACK",
204
+ "WEBSERVICE",
205
+ "WEIBULL.DIST",
206
+ "WORKDAY.INTL",
207
+ "WRAPCOLS",
208
+ "WRAPROWS",
209
+ "XLOOKUP",
210
+ "XMATCH",
211
+ "XOR",
212
+ "Z.TEST",
213
+ ];
214
+ /**
215
+ * Future functions that Excel writes behind the worksheet-scope prefix
216
+ * (`_xlfn._xlws.`) rather than plain `_xlfn.` — the dynamic-array functions
217
+ * that also exist as worksheet-only names, plus Python in Excel.
218
+ */
219
+ export var WORKSHEET_SCOPED_FUTURE_FUNCTIONS = new Set([
220
+ "FILTER",
221
+ "SORT",
222
+ "PY",
223
+ ]);
224
+ var QUALIFIED_BY_NAME = new Map(FUTURE_FUNCTION_NAMES.map(function (name) { return [
225
+ name,
226
+ WORKSHEET_SCOPED_FUTURE_FUNCTIONS.has(name)
227
+ ? "_xlfn._xlws.".concat(name)
228
+ : "_xlfn.".concat(name),
229
+ ]; }));
230
+ // Longest names first so `T.DIST.2T` wins over `T.DIST`. The match must be
231
+ // followed by `(` — a bare name (e.g. the defined name `DAYS`) is not a call.
232
+ var FUTURE_FUNCTION_REGEX = new RegExp("(" +
233
+ __spreadArray([], __read(FUTURE_FUNCTION_NAMES), false).sort(function (a, b) { return b.length - a.length; })
234
+ .map(function (name) { return name.replace(/\./g, "\\."); })
235
+ .join("|") +
236
+ ")(\\s*\\()", "gi");
237
+ // `\b` is not enough of a left boundary: it would match the `DAYS` in
238
+ // `_xlfn.DAYS` and in `MYDAYS`. The preceding character is checked by offset
239
+ // instead of being consumed by the pattern, so nested calls
240
+ // (`SORT(FILTER(...))`) still match after the enclosing one.
241
+ var FUTURE_FUNCTION_LEFT_BOUNDARY = /[A-Za-z0-9_.$]/;
242
+ // A storage marker starts an identifier: nothing identifier-like may precede
243
+ // it (`MY_xlfn.X` is one name). `_xlfn._xlws.FILTER` strips in two passes.
244
+ var STORAGE_PREFIX_REGEX = /(?<![A-Za-z0-9_])_xl(?:fn|ws|pm|udf)\./gi;
245
+ /**
246
+ * Run `transform` over every unquoted span of `formula`, copying string
247
+ * literals (`"…"`) and quoted sheet names (`'…'`) verbatim. A doubled quote
248
+ * inside a span is an escaped quote; an unterminated literal consumes the
249
+ * rest of the formula.
250
+ */
251
+ function mapUnquotedSegments(formula, transform) {
252
+ var result = "";
253
+ var segmentStart = 0;
254
+ var index = 0;
255
+ while (index < formula.length) {
256
+ var char = formula[index];
257
+ if (char !== '"' && char !== "'") {
258
+ index++;
259
+ continue;
260
+ }
261
+ result += transform(formula.slice(segmentStart, index));
262
+ var end = index + 1;
263
+ while (end < formula.length) {
264
+ if (formula[end] === char) {
265
+ if (formula[end + 1] === char) {
266
+ end += 2;
267
+ continue;
268
+ }
269
+ break;
270
+ }
271
+ end++;
272
+ }
273
+ var literalEnd = end < formula.length ? end + 1 : formula.length;
274
+ result += formula.slice(index, literalEnd);
275
+ index = literalEnd;
276
+ segmentStart = literalEnd;
277
+ }
278
+ return result + transform(formula.slice(segmentStart));
279
+ }
280
+ var stripSegment = function (segment) {
281
+ return segment.replace(STORAGE_PREFIX_REGEX, "");
282
+ };
283
+ function qualifySegment(segment) {
284
+ var stripped = stripSegment(segment);
285
+ return stripped.replace(FUTURE_FUNCTION_REGEX, function (match, name, open, offset) {
286
+ if (offset > 0 &&
287
+ FUTURE_FUNCTION_LEFT_BOUNDARY.test(stripped[offset - 1])) {
288
+ return match;
289
+ }
290
+ var qualified = QUALIFIED_BY_NAME.get(name.toUpperCase());
291
+ return qualified ? qualified + open : match;
292
+ });
293
+ }
294
+ /**
295
+ * Remove every `_xlfn.` / `_xlws.` / `_xlpm.` / `_xludf.` storage marker from
296
+ * `formula` (outside string literals and quoted sheet names). Idempotent.
297
+ */
298
+ export function stripExcelFormulaPrefixes(formula) {
299
+ return mapUnquotedSegments(formula, stripSegment);
300
+ }
301
+ // ---------------------------------------------------------------- token helpers
302
+ var tokenName = function (token) { var _a; return (_a = token === null || token === void 0 ? void 0 : token.tokenType) === null || _a === void 0 ? void 0 : _a.name; };
303
+ var tokenEnd = function (token) { var _a; return ((_a = token.endOffset) !== null && _a !== void 0 ? _a : token.startOffset) + 1; };
304
+ /** Index of the `)` closing the call / group that opens at `start`, or -1. */
305
+ var closeParenOf = function (tokens, start) {
306
+ var depth = 0;
307
+ for (var i = start; i < tokens.length; i++) {
308
+ var name_1 = tokenName(tokens[i]);
309
+ if (name_1 === T.Function.name || name_1 === T.OpenParen.name)
310
+ depth++;
311
+ else if (name_1 === T.CloseParen.name)
312
+ depth--;
313
+ if (depth === 0)
314
+ return i;
315
+ }
316
+ return -1;
317
+ };
318
+ var isSheetPrefix = function (token) {
319
+ var name = tokenName(token);
320
+ return (name === T.Sheet.name ||
321
+ name === T.SheetQuoted.name ||
322
+ name === T.SheetRange.name);
323
+ };
324
+ /** Apply non-overlapping `[start, end)` replacements to `source`. */
325
+ var applyReplacements = function (source, replacements) {
326
+ var e_1, _a;
327
+ var sorted = __spreadArray([], __read(replacements), false).sort(function (a, b) { return a.start - b.start; });
328
+ var out = "";
329
+ var cursor = 0;
330
+ try {
331
+ for (var sorted_1 = __values(sorted), sorted_1_1 = sorted_1.next(); !sorted_1_1.done; sorted_1_1 = sorted_1.next()) {
332
+ var r = sorted_1_1.value;
333
+ if (r.start < cursor)
334
+ continue;
335
+ out += source.slice(cursor, r.start) + r.text;
336
+ cursor = r.end;
337
+ }
338
+ }
339
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
340
+ finally {
341
+ try {
342
+ if (sorted_1_1 && !sorted_1_1.done && (_a = sorted_1.return)) _a.call(sorted_1);
343
+ }
344
+ finally { if (e_1) throw e_1.error; }
345
+ }
346
+ return out + source.slice(cursor);
347
+ };
348
+ var safeLexify = function (formula) {
349
+ try {
350
+ return lexify(formula).tokens;
351
+ }
352
+ catch (_a) {
353
+ return undefined;
354
+ }
355
+ };
356
+ // ---------------------------------------------------------------- spilled-range operator
357
+ var ANCHORARRAY_CALL = /^(?:_xlfn\.)?ANCHORARRAY\($/i;
358
+ /**
359
+ * `_xlfn.ANCHORARRAY(A1)` / `ANCHORARRAY(Sheet1!A1)` → `A1#` / `Sheet1!A1#`
360
+ * — Excel's stored form of the spilled-range operator back to its UI form.
361
+ * A call whose argument is not exactly one cell reference is left as is.
362
+ */
363
+ export function decodeAnchorArray(formula) {
364
+ var tokens = safeLexify(formula);
365
+ if (!tokens)
366
+ return formula;
367
+ var replacements = [];
368
+ for (var i = 0; i < tokens.length; i++) {
369
+ var token = tokens[i];
370
+ if (tokenName(token) !== T.Function.name ||
371
+ !ANCHORARRAY_CALL.test(token.image)) {
372
+ continue;
373
+ }
374
+ var close_1 = closeParenOf(tokens, i);
375
+ if (close_1 === -1)
376
+ continue;
377
+ var inner = tokens.slice(i + 1, close_1);
378
+ var cell = inner[inner.length - 1];
379
+ var isCell = cell !== undefined &&
380
+ tokenName(cell) === T.Cell.name &&
381
+ !cell.image.endsWith("#") &&
382
+ (inner.length === 1 || (inner.length === 2 && isSheetPrefix(inner[0])));
383
+ if (!isCell)
384
+ continue;
385
+ replacements.push({
386
+ start: token.startOffset,
387
+ end: tokenEnd(tokens[close_1]),
388
+ text: "".concat(formula.slice(inner[0].startOffset, tokenEnd(cell)), "#"),
389
+ });
390
+ }
391
+ return replacements.length ? applyReplacements(formula, replacements) : formula;
392
+ }
393
+ /**
394
+ * `A1#` / `Sheet1!A1#` → `ANCHORARRAY(A1)` / `ANCHORARRAY(Sheet1!A1)` — the
395
+ * spilled-range operator in the form sheet XML accepts (future-function
396
+ * qualification then adds the `_xlfn.` prefix). `#REF!#` is left alone.
397
+ */
398
+ export function encodeSpilledRanges(formula) {
399
+ var tokens = safeLexify(formula);
400
+ if (!tokens)
401
+ return formula;
402
+ var replacements = [];
403
+ for (var i = 0; i < tokens.length; i++) {
404
+ var token = tokens[i];
405
+ if (tokenName(token) !== T.Cell.name || !token.image.endsWith("#")) {
406
+ continue;
407
+ }
408
+ var first = isSheetPrefix(tokens[i - 1]) ? tokens[i - 1] : token;
409
+ var ref = formula.slice(first.startOffset, tokenEnd(token) - 1);
410
+ replacements.push({
411
+ start: first.startOffset,
412
+ end: tokenEnd(token),
413
+ text: "ANCHORARRAY(".concat(ref, ")"),
414
+ });
415
+ }
416
+ return replacements.length ? applyReplacements(formula, replacements) : formula;
417
+ }
418
+ // ---------------------------------------------------------------- LET / LAMBDA parameters
419
+ var LET_CALL = /^(?:_xlfn\.)?LET\($/i;
420
+ var LAMBDA_CALL = /^(?:_xlfn\.)?LAMBDA\($/i;
421
+ var PARAMETER_MARKER = /^_xlpm\./i;
422
+ /**
423
+ * A bare identifier at `index`: a `Name`, or a one-to-three-letter word the
424
+ * lexer reads as a whole-column reference (`x`, `acc`) when it is not part of
425
+ * an `A:A` column range.
426
+ */
427
+ var isIdentifier = function (tokens, index) {
428
+ var name = tokenName(tokens[index]);
429
+ if (name === T.Name.name)
430
+ return true;
431
+ if (name !== T.Column.name)
432
+ return false;
433
+ if (/[$\d]/.test(tokens[index].image))
434
+ return false;
435
+ return (tokenName(tokens[index - 1]) !== T.Colon.name &&
436
+ tokenName(tokens[index + 1]) !== T.Colon.name);
437
+ };
438
+ /** `a, b, c` → the token index ranges of the top-level arguments of a call. */
439
+ var topLevelArguments = function (tokens, open, close) {
440
+ var args = [];
441
+ var depth = 0;
442
+ var start = open + 1;
443
+ for (var i = open + 1; i < close; i++) {
444
+ var name_2 = tokenName(tokens[i]);
445
+ if (name_2 === T.Function.name || name_2 === T.OpenParen.name)
446
+ depth++;
447
+ else if (name_2 === T.CloseParen.name)
448
+ depth--;
449
+ else if (depth === 0 && (name_2 === T.Comma.name || name_2 === T.Semicolon.name)) {
450
+ args.push([start, i - 1]);
451
+ start = i + 1;
452
+ }
453
+ }
454
+ if (start <= close - 1)
455
+ args.push([start, close - 1]);
456
+ return args;
457
+ };
458
+ /**
459
+ * Prefix every LET / LAMBDA parameter with `_xlpm.` — at its declaration and
460
+ * at every use inside the call (a use as a function, `double(5)` for a
461
+ * LET-bound lambda, included). Parameters are the odd-position LET arguments
462
+ * (all but the last argument, which is the calculation) and every LAMBDA
463
+ * argument but the last. Already-prefixed input comes out prefixed once.
464
+ */
465
+ export function qualifyLambdaParameters(formula) {
466
+ var tokens = safeLexify(formula);
467
+ if (!tokens)
468
+ return formula;
469
+ var replacements = new Map();
470
+ var _loop_1 = function (i) {
471
+ var token = tokens[i];
472
+ if (tokenName(token) !== T.Function.name)
473
+ return "continue";
474
+ var isLet = LET_CALL.test(token.image);
475
+ var isLambda = !isLet && LAMBDA_CALL.test(token.image);
476
+ if (!isLet && !isLambda)
477
+ return "continue";
478
+ var close_2 = closeParenOf(tokens, i);
479
+ if (close_2 === -1)
480
+ return "continue";
481
+ var args = topLevelArguments(tokens, i, close_2);
482
+ var params = new Set();
483
+ args.forEach(function (_a, index) {
484
+ var _b = __read(_a, 2), start = _b[0], end = _b[1];
485
+ var isLast = index === args.length - 1;
486
+ var isParameter = isLambda ? !isLast : index % 2 === 0 && !isLast;
487
+ if (!isParameter || start !== end)
488
+ return;
489
+ var arg = tokens[start];
490
+ if (!isIdentifier(tokens, start))
491
+ return;
492
+ params.add(arg.image.replace(PARAMETER_MARKER, "").toUpperCase());
493
+ });
494
+ if (!params.size)
495
+ return "continue";
496
+ for (var j = i + 1; j < close_2; j++) {
497
+ var inner = tokens[j];
498
+ var bare = void 0;
499
+ if (isIdentifier(tokens, j)) {
500
+ bare = inner.image;
501
+ }
502
+ else if (tokenName(inner) === T.Function.name) {
503
+ bare = inner.image.slice(0, -1);
504
+ }
505
+ else {
506
+ continue;
507
+ }
508
+ var stripped = bare.replace(PARAMETER_MARKER, "");
509
+ if (!params.has(stripped.toUpperCase()))
510
+ continue;
511
+ // Structured-reference and sheet-prefixed names are never parameters.
512
+ var previous = tokens[j - 1];
513
+ if (isSheetPrefix(previous))
514
+ continue;
515
+ replacements.set(inner.startOffset, {
516
+ start: inner.startOffset,
517
+ end: inner.startOffset + bare.length,
518
+ text: "_xlpm.".concat(stripped),
519
+ });
520
+ }
521
+ };
522
+ for (var i = 0; i < tokens.length; i++) {
523
+ _loop_1(i);
524
+ }
525
+ return replacements.size
526
+ ? applyReplacements(formula, __spreadArray([], __read(replacements.values()), false))
527
+ : formula;
528
+ }
529
+ // ---------------------------------------------------------------- public directions
530
+ /**
531
+ * Export direction. Strip the storage markers and re-add the correct one to
532
+ * every future-function call in `formula`, write `A1#` as `ANCHORARRAY(A1)`
533
+ * (qualified to `_xlfn.ANCHORARRAY`) and prefix LET / LAMBDA parameters with
534
+ * `_xlpm.`. Quoted spans keep their original text. Idempotent: already
535
+ * qualified input comes out qualified exactly once.
536
+ */
537
+ export function qualifyFutureFunctions(formula) {
538
+ // The qualify pass strips every marker (including `_xlpm.`) before re-adding
539
+ // `_xlfn.`, so the parameter pass must run last.
540
+ return qualifyLambdaParameters(mapUnquotedSegments(encodeSpilledRanges(formula), qualifySegment));
541
+ }
542
+ /**
543
+ * Import direction. The formula as Excel displays it: every storage marker
544
+ * removed, `_xlfn.ANCHORARRAY(A1)` shown as `A1#`, `_xlfn.SINGLE(x)` as `@x`.
545
+ */
546
+ export function normalizeImportedFormula(formula) {
547
+ return decodeImplicitIntersection(decodeAnchorArray(stripExcelFormulaPrefixes(formula)));
548
+ }
@@ -1 +1 @@
1
- {"root":["../../autofilter-condition.ts","../../csv-export.ts","../../csv-import-worker.ts","../../csv-import.ts","../../excel-export.ts","../../excel-import-session.ts","../../excel-import-worker.ts","../../helpers.ts","../../index.ts","../../indexed-colors.ts","../../ods-export.ts","../../parse.ts","../../power-query.ts","../../print-settings.ts","../../server.ts","../../theme1.ts","../../types.ts","../../vitest.config.ts","../../xlsx.d.ts","../../csv-parser/helpers.ts","../../csv-parser/types.ts","../../csv-parser/worker.ts","../../excel-parser/builtin-numfmts.ts","../../excel-parser/cfb-decryptor.ts","../../excel-parser/cfb-encryptor.ts","../../excel-parser/dv-cell-stamp.ts","../../excel-parser/helpers.ts","../../excel-parser/interface.ts","../../excel-parser/registry.ts","../../excel-parser/style-registry.ts","../../excel-parser/theme-default.ts","../../excel-parser/types.ts","../../excel-parser/utils.ts","../../excel-parser/workbook.ts","../../excel-parser/worker.ts","../../excel-parser/zip-parser-streaming.ts","../../excel-parser/zip-parser.ts","../../excel-parser/plugins/base/index.ts","../../excel-parser/plugins/ods/conditional-formatting.ts","../../excel-parser/plugins/ods/data-validations.ts","../../excel-parser/plugins/ods/formula.ts","../../excel-parser/plugins/ods/index.ts","../../excel-parser/plugins/ods/sparklines.ts","../../excel-parser/plugins/ods/styles.ts","../../excel-parser/plugins/ods/types.ts","../../excel-parser/plugins/xls/index.ts","../../excel-parser/plugins/xlsb/biff-record-reader.ts","../../excel-parser/plugins/xlsb/index.ts","../../excel-parser/plugins/xlsb/rgce-parser.ts","../../excel-parser/plugins/xlsm/index.ts","../../excel-parser/plugins/xlsx/chartex.ts","../../excel-parser/plugins/xlsx/charts.ts","../../excel-parser/plugins/xlsx/conditional-formatting.ts","../../excel-parser/plugins/xlsx/data-validations.ts","../../excel-parser/plugins/xlsx/drawing.ts","../../excel-parser/plugins/xlsx/form-controls.ts","../../excel-parser/plugins/xlsx/index.ts","../../excel-parser/plugins/xlsx/numfmt.ts","../../excel-parser/plugins/xlsx/pivots.ts","../../excel-parser/plugins/xlsx/relationships.ts","../../excel-parser/plugins/xlsx/sheet-views.ts","../../excel-parser/plugins/xlsx/styles.ts","../../excel-parser/plugins/xlsx/theme.ts","../../excel-parser/plugins/xlsx/threaded-comments.ts","../../excel-parser/plugins/xlsx/value-type-detection.ts","../../exporter/invalid-data-validation.ts","../../exporter/ods/ods-export.ts","../../exporter/ods/sparkline-builder.ts","../../exporter/xlsx/chart-builder.ts","../../exporter/xlsx/chart-templates.ts","../../exporter/xlsx/chartex-builder.ts","../../exporter/xlsx/form-controls-builder.ts","../../exporter/xlsx/future-functions.ts","../../exporter/xlsx/pivot-builder.ts","../../exporter/xlsx/power-query-builder.ts","../../exporter/xlsx/slicer-builder.ts","../../exporter/xlsx/sparkline-builder.ts","../../exporter/xlsx/style-builder.ts","../../exporter/xlsx/threaded-comments-builder.ts","../../exporter/xlsx/xlsx-export.ts","../../helpers/implicit-intersection.ts","../../helpers/theme-xml-generator.ts"],"version":"5.8.3"}
1
+ {"root":["../../autofilter-condition.ts","../../csv-export.ts","../../csv-import-worker.ts","../../csv-import.ts","../../excel-export.ts","../../excel-import-session.ts","../../excel-import-worker.ts","../../helpers.ts","../../index.ts","../../indexed-colors.ts","../../ods-export.ts","../../parse.ts","../../power-query.ts","../../print-settings.ts","../../server.ts","../../theme1.ts","../../types.ts","../../vitest.config.ts","../../xlsx.d.ts","../../csv-parser/helpers.ts","../../csv-parser/types.ts","../../csv-parser/worker.ts","../../excel-parser/builtin-numfmts.ts","../../excel-parser/cfb-decryptor.ts","../../excel-parser/cfb-encryptor.ts","../../excel-parser/dv-cell-stamp.ts","../../excel-parser/helpers.ts","../../excel-parser/interface.ts","../../excel-parser/registry.ts","../../excel-parser/style-registry.ts","../../excel-parser/theme-default.ts","../../excel-parser/types.ts","../../excel-parser/utils.ts","../../excel-parser/workbook.ts","../../excel-parser/worker.ts","../../excel-parser/zip-parser-streaming.ts","../../excel-parser/zip-parser.ts","../../excel-parser/plugins/base/index.ts","../../excel-parser/plugins/ods/conditional-formatting.ts","../../excel-parser/plugins/ods/data-validations.ts","../../excel-parser/plugins/ods/formula.ts","../../excel-parser/plugins/ods/index.ts","../../excel-parser/plugins/ods/sparklines.ts","../../excel-parser/plugins/ods/styles.ts","../../excel-parser/plugins/ods/types.ts","../../excel-parser/plugins/xls/index.ts","../../excel-parser/plugins/xlsb/biff-record-reader.ts","../../excel-parser/plugins/xlsb/index.ts","../../excel-parser/plugins/xlsb/rgce-parser.ts","../../excel-parser/plugins/xlsm/index.ts","../../excel-parser/plugins/xlsx/chartex.ts","../../excel-parser/plugins/xlsx/charts.ts","../../excel-parser/plugins/xlsx/conditional-formatting.ts","../../excel-parser/plugins/xlsx/data-validations.ts","../../excel-parser/plugins/xlsx/drawing.ts","../../excel-parser/plugins/xlsx/form-controls.ts","../../excel-parser/plugins/xlsx/index.ts","../../excel-parser/plugins/xlsx/numfmt.ts","../../excel-parser/plugins/xlsx/pivots.ts","../../excel-parser/plugins/xlsx/relationships.ts","../../excel-parser/plugins/xlsx/sheet-views.ts","../../excel-parser/plugins/xlsx/styles.ts","../../excel-parser/plugins/xlsx/theme.ts","../../excel-parser/plugins/xlsx/threaded-comments.ts","../../excel-parser/plugins/xlsx/value-type-detection.ts","../../exporter/invalid-data-validation.ts","../../exporter/ods/ods-export.ts","../../exporter/ods/sparkline-builder.ts","../../exporter/xlsx/chart-builder.ts","../../exporter/xlsx/chart-templates.ts","../../exporter/xlsx/chartex-builder.ts","../../exporter/xlsx/form-controls-builder.ts","../../exporter/xlsx/future-functions.ts","../../exporter/xlsx/pivot-builder.ts","../../exporter/xlsx/power-query-builder.ts","../../exporter/xlsx/slicer-builder.ts","../../exporter/xlsx/sparkline-builder.ts","../../exporter/xlsx/style-builder.ts","../../exporter/xlsx/threaded-comments-builder.ts","../../exporter/xlsx/xlsx-export.ts","../../helpers/excel-formula-prefixes.ts","../../helpers/implicit-intersection.ts","../../helpers/theme-xml-generator.ts"],"version":"5.8.3"}
@@ -233,6 +233,10 @@ const singleCustomFilterToCondition = (filter) => {
233
233
  const operator = filter.operator ?? "equal";
234
234
  const val = String(filter.val ?? "");
235
235
  // Text wildcards: equal/notEqual carrying * map back to contains/starts/ends.
236
+ // A NEGATED begins-with / ends-with (`notEqual` + `x*` / `*x`, Excel's "does
237
+ // not begin / end with") has no condition type of its own — it falls through
238
+ // to TEXT_NOT_EQ with the wildcard value verbatim, so the export writes
239
+ // `notEqual` + `x*` back unchanged instead of flipping it to `equal`.
236
240
  if ((operator === "equal" || operator === "notEqual") && /[*?]/.test(val)) {
237
241
  const negated = operator === "notEqual";
238
242
  const lead = val.startsWith("*");
@@ -244,10 +248,10 @@ const singleCustomFilterToCondition = (filter) => {
244
248
  values: [{ userEnteredValue: core }],
245
249
  };
246
250
  }
247
- if (trail) {
251
+ if (trail && !negated) {
248
252
  return { type: "TEXT_STARTS_WITH", values: [{ userEnteredValue: core }] };
249
253
  }
250
- if (lead) {
254
+ if (lead && !negated) {
251
255
  return { type: "TEXT_ENDS_WITH", values: [{ userEnteredValue: core }] };
252
256
  }
253
257
  }
@@ -1,5 +1,7 @@
1
1
  import type { GridRange } from "@rowsncolumns/common-types";
2
- import type { Column, FilterSpec, SortSpecs, TableTotalsRowFunction } from "@rowsncolumns/spreadsheet";
2
+ import type { Column, DateGroupFilter, FilterSpec, SortSpecs, TableTotalsRowFunction } from "@rowsncolumns/spreadsheet";
3
+ /** The engine's "(Blanks)" checklist entry — Excel's `<filters blank="1">`. */
4
+ export declare const BLANK_LABEL = "(Blanks)";
3
5
  export declare const getRangeFromAddressRef: (ref: string) => GridRange | undefined;
4
6
  /**
5
7
  * OOXML `<col width>` (and `<sheetFormatPr defaultColWidth>`) → pixels.
@@ -24,6 +26,12 @@ export declare const isTableTotalsRowFunction: (value: unknown) => value is Tabl
24
26
  * present so columns without a totals row stay `{ name }`.
25
27
  */
26
28
  export declare const parseTableColumnTotals: (colDef: any) => Pick<Column, "totalsRowFunction" | "totalsRowLabel" | "totalsRowFormula">;
29
+ /**
30
+ * A `<dateGroupItem>`'s attributes → the criteria's date-group entry, or
31
+ * `undefined` without a year. `dateTimeGrouping` defaults to `day` like the
32
+ * schema.
33
+ */
34
+ export declare function dateGroupFilterFromAttributes(attrs: Record<string, unknown> | undefined): DateGroupFilter | undefined;
27
35
  export declare function createFilterSpecsFromAutoFilter(autoFilter: any,
28
36
  /**
29
37
  * Optional dxf resolver — called with (dxfId, cellColor) to return a
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../excel-parser/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAEV,MAAM,EACN,UAAU,EACV,SAAS,EACT,sBAAsB,EACvB,MAAM,2BAA2B,CAAC;AAUnC,eAAO,MAAM,sBAAsB,GAAI,KAAK,MAAM,KAAG,SAAS,GAAG,SAIhE,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,UAMrD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,UAMpC;AAmBD,eAAO,MAAM,wBAAwB,GACnC,OAAO,OAAO,KACb,KAAK,IAAI,sBACwD,CAAC;AAErE;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GACjC,QAAQ,GAAG,KACV,IAAI,CAAC,MAAM,EAAE,mBAAmB,GAAG,gBAAgB,GAAG,kBAAkB,CAmB1E,CAAC;AAqBF,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,GAAG;AACf;;;;GAIG;AACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,gBA0G5E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAgBtE;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,GAAG,EACd,KAAK,EAAE,SAAS,EAChB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,GAC1E,SAAS,EAAE,CA2Cb;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,wBAkB3D"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../excel-parser/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAEV,MAAM,EACN,eAAe,EACf,UAAU,EACV,SAAS,EACT,sBAAsB,EACvB,MAAM,2BAA2B,CAAC;AAUnC,+EAA+E;AAC/E,eAAO,MAAM,WAAW,aAAa,CAAC;AAEtC,eAAO,MAAM,sBAAsB,GAAI,KAAK,MAAM,KAAG,SAAS,GAAG,SAIhE,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,UAMrD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,UAMpC;AAmBD,eAAO,MAAM,wBAAwB,GACnC,OAAO,OAAO,KACb,KAAK,IAAI,sBACwD,CAAC;AAErE;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GACjC,QAAQ,GAAG,KACV,IAAI,CAAC,MAAM,EAAE,mBAAmB,GAAG,gBAAgB,GAAG,kBAAkB,CAmB1E,CAAC;AAqBF;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACzC,eAAe,GAAG,SAAS,CA8B7B;AAED,wBAAgB,+BAA+B,CAC7C,UAAU,EAAE,GAAG;AACf;;;;GAIG;AACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,gBAgI5E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAgBtE;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,GAAG,EACd,KAAK,EAAE,SAAS,EAChB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,GAC1E,SAAS,EAAE,CA2Cb;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,wBAkB3D"}