@bilig/formula 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +16 -0
  3. package/dist/addressing.d.ts +66 -0
  4. package/dist/addressing.js +179 -0
  5. package/dist/addressing.js.map +1 -0
  6. package/dist/ast.d.ts +74 -0
  7. package/dist/ast.js +2 -0
  8. package/dist/ast.js.map +1 -0
  9. package/dist/binder.d.ts +13 -0
  10. package/dist/binder.js +1700 -0
  11. package/dist/binder.js.map +1 -0
  12. package/dist/builtin-capabilities.d.ts +19 -0
  13. package/dist/builtin-capabilities.js +861 -0
  14. package/dist/builtin-capabilities.js.map +1 -0
  15. package/dist/builtins/complex.d.ts +10 -0
  16. package/dist/builtins/complex.js +407 -0
  17. package/dist/builtins/complex.js.map +1 -0
  18. package/dist/builtins/convert.d.ts +3 -0
  19. package/dist/builtins/convert.js +362 -0
  20. package/dist/builtins/convert.js.map +1 -0
  21. package/dist/builtins/datetime.d.ts +23 -0
  22. package/dist/builtins/datetime.js +1096 -0
  23. package/dist/builtins/datetime.js.map +1 -0
  24. package/dist/builtins/distribution-builtins.d.ts +16 -0
  25. package/dist/builtins/distribution-builtins.js +517 -0
  26. package/dist/builtins/distribution-builtins.js.map +1 -0
  27. package/dist/builtins/distributions.d.ts +34 -0
  28. package/dist/builtins/distributions.js +722 -0
  29. package/dist/builtins/distributions.js.map +1 -0
  30. package/dist/builtins/financial-builtins.d.ts +16 -0
  31. package/dist/builtins/financial-builtins.js +324 -0
  32. package/dist/builtins/financial-builtins.js.map +1 -0
  33. package/dist/builtins/financial.d.ts +11 -0
  34. package/dist/builtins/financial.js +241 -0
  35. package/dist/builtins/financial.js.map +1 -0
  36. package/dist/builtins/fixed-income-builtins.d.ts +14 -0
  37. package/dist/builtins/fixed-income-builtins.js +598 -0
  38. package/dist/builtins/fixed-income-builtins.js.map +1 -0
  39. package/dist/builtins/fixed-income.d.ts +42 -0
  40. package/dist/builtins/fixed-income.js +668 -0
  41. package/dist/builtins/fixed-income.js.map +1 -0
  42. package/dist/builtins/formatting.d.ts +8 -0
  43. package/dist/builtins/formatting.js +53 -0
  44. package/dist/builtins/formatting.js.map +1 -0
  45. package/dist/builtins/logical.d.ts +4 -0
  46. package/dist/builtins/logical.js +258 -0
  47. package/dist/builtins/logical.js.map +1 -0
  48. package/dist/builtins/lookup-array-shape-builtins.d.ts +21 -0
  49. package/dist/builtins/lookup-array-shape-builtins.js +517 -0
  50. package/dist/builtins/lookup-array-shape-builtins.js.map +1 -0
  51. package/dist/builtins/lookup-criteria-builtins.d.ts +16 -0
  52. package/dist/builtins/lookup-criteria-builtins.js +216 -0
  53. package/dist/builtins/lookup-criteria-builtins.js.map +1 -0
  54. package/dist/builtins/lookup-database-builtins.d.ts +17 -0
  55. package/dist/builtins/lookup-database-builtins.js +294 -0
  56. package/dist/builtins/lookup-database-builtins.js.map +1 -0
  57. package/dist/builtins/lookup-financial-builtins.d.ts +11 -0
  58. package/dist/builtins/lookup-financial-builtins.js +291 -0
  59. package/dist/builtins/lookup-financial-builtins.js.map +1 -0
  60. package/dist/builtins/lookup-hypothesis-builtins.d.ts +11 -0
  61. package/dist/builtins/lookup-hypothesis-builtins.js +57 -0
  62. package/dist/builtins/lookup-hypothesis-builtins.js.map +1 -0
  63. package/dist/builtins/lookup-matrix-builtins.d.ts +17 -0
  64. package/dist/builtins/lookup-matrix-builtins.js +218 -0
  65. package/dist/builtins/lookup-matrix-builtins.js.map +1 -0
  66. package/dist/builtins/lookup-order-statistics-builtins.d.ts +18 -0
  67. package/dist/builtins/lookup-order-statistics-builtins.js +575 -0
  68. package/dist/builtins/lookup-order-statistics-builtins.js.map +1 -0
  69. package/dist/builtins/lookup-reference-builtins.d.ts +18 -0
  70. package/dist/builtins/lookup-reference-builtins.js +300 -0
  71. package/dist/builtins/lookup-reference-builtins.js.map +1 -0
  72. package/dist/builtins/lookup-regression-builtins.d.ts +12 -0
  73. package/dist/builtins/lookup-regression-builtins.js +511 -0
  74. package/dist/builtins/lookup-regression-builtins.js.map +1 -0
  75. package/dist/builtins/lookup-sort-filter-builtins.d.ts +20 -0
  76. package/dist/builtins/lookup-sort-filter-builtins.js +382 -0
  77. package/dist/builtins/lookup-sort-filter-builtins.js.map +1 -0
  78. package/dist/builtins/lookup.d.ts +13 -0
  79. package/dist/builtins/lookup.js +867 -0
  80. package/dist/builtins/lookup.js.map +1 -0
  81. package/dist/builtins/math-builtins.d.ts +31 -0
  82. package/dist/builtins/math-builtins.js +420 -0
  83. package/dist/builtins/math-builtins.js.map +1 -0
  84. package/dist/builtins/numeric.d.ts +30 -0
  85. package/dist/builtins/numeric.js +150 -0
  86. package/dist/builtins/numeric.js.map +1 -0
  87. package/dist/builtins/placeholder.d.ts +9 -0
  88. package/dist/builtins/placeholder.js +540 -0
  89. package/dist/builtins/placeholder.js.map +1 -0
  90. package/dist/builtins/radix.d.ts +12 -0
  91. package/dist/builtins/radix.js +220 -0
  92. package/dist/builtins/radix.js.map +1 -0
  93. package/dist/builtins/statistical-builtins.d.ts +13 -0
  94. package/dist/builtins/statistical-builtins.js +240 -0
  95. package/dist/builtins/statistical-builtins.js.map +1 -0
  96. package/dist/builtins/statistics.d.ts +8 -0
  97. package/dist/builtins/statistics.js +74 -0
  98. package/dist/builtins/statistics.js.map +1 -0
  99. package/dist/builtins/text.d.ts +5 -0
  100. package/dist/builtins/text.js +1879 -0
  101. package/dist/builtins/text.js.map +1 -0
  102. package/dist/builtins.d.ts +8 -0
  103. package/dist/builtins.js +695 -0
  104. package/dist/builtins.js.map +1 -0
  105. package/dist/compatibility.d.ts +25 -0
  106. package/dist/compatibility.js +498 -0
  107. package/dist/compatibility.js.map +1 -0
  108. package/dist/compiler.d.ts +29 -0
  109. package/dist/compiler.js +474 -0
  110. package/dist/compiler.js.map +1 -0
  111. package/dist/external-function-adapter.d.ts +32 -0
  112. package/dist/external-function-adapter.js +42 -0
  113. package/dist/external-function-adapter.js.map +1 -0
  114. package/dist/generated/formula-inventory.d.ts +6839 -0
  115. package/dist/generated/formula-inventory.js +7368 -0
  116. package/dist/generated/formula-inventory.js.map +1 -0
  117. package/dist/group-pivot-evaluator.d.ts +28 -0
  118. package/dist/group-pivot-evaluator.js +435 -0
  119. package/dist/group-pivot-evaluator.js.map +1 -0
  120. package/dist/index.d.ts +16 -0
  121. package/dist/index.js +17 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/js-evaluator.d.ts +107 -0
  124. package/dist/js-evaluator.js +1651 -0
  125. package/dist/js-evaluator.js.map +1 -0
  126. package/dist/lexer.d.ts +6 -0
  127. package/dist/lexer.js +115 -0
  128. package/dist/lexer.js.map +1 -0
  129. package/dist/optimizer.d.ts +2 -0
  130. package/dist/optimizer.js +353 -0
  131. package/dist/optimizer.js.map +1 -0
  132. package/dist/parser.d.ts +2 -0
  133. package/dist/parser.js +352 -0
  134. package/dist/parser.js.map +1 -0
  135. package/dist/program-arena.d.ts +22 -0
  136. package/dist/program-arena.js +67 -0
  137. package/dist/program-arena.js.map +1 -0
  138. package/dist/runtime-values.d.ts +17 -0
  139. package/dist/runtime-values.js +11 -0
  140. package/dist/runtime-values.js.map +1 -0
  141. package/dist/special-call-rewrites.d.ts +2 -0
  142. package/dist/special-call-rewrites.js +74 -0
  143. package/dist/special-call-rewrites.js.map +1 -0
  144. package/dist/translation.d.ts +28 -0
  145. package/dist/translation.js +569 -0
  146. package/dist/translation.js.map +1 -0
  147. package/package.json +53 -0
@@ -0,0 +1,867 @@
1
+ import { ErrorCode, ValueTag } from "@bilig/protocol";
2
+ import { getExternalLookupFunction } from "../external-function-adapter.js";
3
+ import { createLookupArrayShapeBuiltins } from "./lookup-array-shape-builtins.js";
4
+ import { createLookupCriteriaBuiltins } from "./lookup-criteria-builtins.js";
5
+ import { createLookupDatabaseBuiltins } from "./lookup-database-builtins.js";
6
+ import { createLookupFinancialBuiltins } from "./lookup-financial-builtins.js";
7
+ import { createLookupHypothesisBuiltins } from "./lookup-hypothesis-builtins.js";
8
+ import { createLookupMatrixBuiltins } from "./lookup-matrix-builtins.js";
9
+ import { createLookupOrderStatisticsBuiltins } from "./lookup-order-statistics-builtins.js";
10
+ import { createLookupReferenceBuiltins } from "./lookup-reference-builtins.js";
11
+ import { createLookupRegressionBuiltins } from "./lookup-regression-builtins.js";
12
+ import { createLookupSortFilterBuiltins } from "./lookup-sort-filter-builtins.js";
13
+ function errorValue(code) {
14
+ return { tag: ValueTag.Error, code };
15
+ }
16
+ function numberResult(value) {
17
+ return { tag: ValueTag.Number, value };
18
+ }
19
+ function isError(value) {
20
+ return value !== undefined && !isRangeArg(value) && value.tag === ValueTag.Error;
21
+ }
22
+ function isRangeArg(value) {
23
+ return typeof value === "object" && value !== null && "kind" in value && value.kind === "range";
24
+ }
25
+ function isCriteriaOperator(value) {
26
+ return (value === "=" ||
27
+ value === "<>" ||
28
+ value === ">" ||
29
+ value === ">=" ||
30
+ value === "<" ||
31
+ value === "<=");
32
+ }
33
+ function findFirstNonRange(values) {
34
+ for (const value of values) {
35
+ if (!isRangeArg(value)) {
36
+ return value;
37
+ }
38
+ }
39
+ return undefined;
40
+ }
41
+ function areRangeArgs(values) {
42
+ return values.every((value) => isRangeArg(value));
43
+ }
44
+ function toNumber(value) {
45
+ switch (value.tag) {
46
+ case ValueTag.Number:
47
+ return value.value;
48
+ case ValueTag.Boolean:
49
+ return value.value ? 1 : 0;
50
+ case ValueTag.Empty:
51
+ return 0;
52
+ case ValueTag.String:
53
+ case ValueTag.Error:
54
+ return undefined;
55
+ default:
56
+ return undefined;
57
+ }
58
+ }
59
+ function toInteger(value) {
60
+ const numeric = toNumber(value);
61
+ if (numeric === undefined || !Number.isFinite(numeric)) {
62
+ return undefined;
63
+ }
64
+ return Math.trunc(numeric);
65
+ }
66
+ function toBoolean(value) {
67
+ switch (value.tag) {
68
+ case ValueTag.Boolean:
69
+ return value.value;
70
+ case ValueTag.Number:
71
+ return value.value !== 0;
72
+ case ValueTag.Empty:
73
+ return false;
74
+ case ValueTag.String:
75
+ case ValueTag.Error:
76
+ return undefined;
77
+ default:
78
+ return undefined;
79
+ }
80
+ }
81
+ function toStringValue(value) {
82
+ switch (value.tag) {
83
+ case ValueTag.Empty:
84
+ return "";
85
+ case ValueTag.Number:
86
+ return String(value.value);
87
+ case ValueTag.Boolean:
88
+ return value.value ? "TRUE" : "FALSE";
89
+ case ValueTag.String:
90
+ return value.value;
91
+ case ValueTag.Error:
92
+ return "";
93
+ }
94
+ }
95
+ function compareScalars(left, right) {
96
+ if ((left.tag === ValueTag.String || left.tag === ValueTag.Empty) &&
97
+ (right.tag === ValueTag.String || right.tag === ValueTag.Empty)) {
98
+ const normalizedLeft = toStringValue(left).toUpperCase();
99
+ const normalizedRight = toStringValue(right).toUpperCase();
100
+ if (normalizedLeft === normalizedRight) {
101
+ return 0;
102
+ }
103
+ return normalizedLeft < normalizedRight ? -1 : 1;
104
+ }
105
+ const leftNum = toNumber(left);
106
+ const rightNum = toNumber(right);
107
+ if (leftNum === undefined || rightNum === undefined) {
108
+ return undefined;
109
+ }
110
+ if (leftNum === rightNum) {
111
+ return 0;
112
+ }
113
+ return leftNum < rightNum ? -1 : 1;
114
+ }
115
+ function requireCellVector(arg) {
116
+ if (!isRangeArg(arg)) {
117
+ return errorValue(ErrorCode.Value);
118
+ }
119
+ if (arg.refKind !== "cells") {
120
+ return errorValue(ErrorCode.Value);
121
+ }
122
+ if (arg.rows !== 1 && arg.cols !== 1) {
123
+ return errorValue(ErrorCode.NA);
124
+ }
125
+ return arg;
126
+ }
127
+ function requireCellRange(arg) {
128
+ if (!isRangeArg(arg) || arg.refKind !== "cells") {
129
+ return errorValue(ErrorCode.Value);
130
+ }
131
+ return arg;
132
+ }
133
+ function getRangeValue(range, row, col) {
134
+ const index = row * range.cols + col;
135
+ return range.values[index] ?? { tag: ValueTag.Empty };
136
+ }
137
+ function arrayResult(values, rows, cols) {
138
+ return { kind: "array", values, rows, cols };
139
+ }
140
+ function collectNumericSeries(arg, mode) {
141
+ const values = [];
142
+ const cells = isRangeArg(arg) ? arg.values : [arg];
143
+ if (isRangeArg(arg) && arg.refKind !== "cells") {
144
+ return errorValue(ErrorCode.Value);
145
+ }
146
+ for (const cell of cells) {
147
+ if (cell.tag === ValueTag.Error) {
148
+ return cell;
149
+ }
150
+ if (cell.tag === ValueTag.Number) {
151
+ values.push(cell.value);
152
+ continue;
153
+ }
154
+ if (mode === "strict") {
155
+ return errorValue(ErrorCode.Value);
156
+ }
157
+ }
158
+ return values;
159
+ }
160
+ function numericAggregateCandidate(value) {
161
+ return value.tag === ValueTag.Number ? value.value : undefined;
162
+ }
163
+ function toCellRange(arg) {
164
+ if (!isRangeArg(arg)) {
165
+ return { kind: "range", values: [arg], refKind: "cells", rows: 1, cols: 1 };
166
+ }
167
+ if (arg.refKind !== "cells") {
168
+ return errorValue(ErrorCode.Value);
169
+ }
170
+ return arg;
171
+ }
172
+ function toNumericMatrix(arg) {
173
+ const range = toCellRange(arg);
174
+ if (!isRangeArg(range)) {
175
+ return range;
176
+ }
177
+ const matrix = [];
178
+ for (let row = 0; row < range.rows; row += 1) {
179
+ const rowValues = [];
180
+ for (let col = 0; col < range.cols; col += 1) {
181
+ const numeric = toNumber(getRangeValue(range, row, col));
182
+ if (numeric === undefined) {
183
+ return errorValue(ErrorCode.Value);
184
+ }
185
+ rowValues.push(numeric);
186
+ }
187
+ matrix.push(rowValues);
188
+ }
189
+ return matrix;
190
+ }
191
+ const LANCZOS_G = 7;
192
+ const LANCZOS_COEFFICIENTS = [
193
+ 676.5203681218851, -1259.1392167224028, 771.3234287776531, -176.6150291621406, 12.507343278686905,
194
+ -0.13857109526572012, 9.984369578019572e-6, 1.5056327351493116e-7,
195
+ ];
196
+ function logGamma(value) {
197
+ if (!Number.isFinite(value) || value <= 0) {
198
+ return Number.NaN;
199
+ }
200
+ let sum = 0.9999999999998099;
201
+ const shifted = value - 1;
202
+ LANCZOS_COEFFICIENTS.forEach((coefficient, index) => {
203
+ sum += coefficient / (shifted + index + 1);
204
+ });
205
+ const t = shifted + LANCZOS_G + 0.5;
206
+ return 0.5 * Math.log(2 * Math.PI) + (shifted + 0.5) * Math.log(t) - t + Math.log(sum);
207
+ }
208
+ function regularizedLowerGamma(shape, x) {
209
+ if (!Number.isFinite(shape) || !Number.isFinite(x) || shape <= 0 || x < 0) {
210
+ return Number.NaN;
211
+ }
212
+ if (x === 0) {
213
+ return 0;
214
+ }
215
+ const logGammaShape = logGamma(shape);
216
+ if (!Number.isFinite(logGammaShape)) {
217
+ return Number.NaN;
218
+ }
219
+ if (x < shape + 1) {
220
+ let term = 1 / shape;
221
+ let sum = term;
222
+ for (let iteration = 1; iteration < 1000; iteration += 1) {
223
+ term *= x / (shape + iteration);
224
+ sum += term;
225
+ if (Math.abs(term) <= Math.abs(sum) * 1e-14) {
226
+ break;
227
+ }
228
+ }
229
+ return sum * Math.exp(-x + shape * Math.log(x) - logGammaShape);
230
+ }
231
+ let b = x + 1 - shape;
232
+ let c = 1 / 1e-300;
233
+ let d = 1 / b;
234
+ let h = d;
235
+ for (let iteration = 1; iteration < 1000; iteration += 1) {
236
+ const factor = -iteration * (iteration - shape);
237
+ b += 2;
238
+ d = factor * d + b;
239
+ if (Math.abs(d) < 1e-300) {
240
+ d = 1e-300;
241
+ }
242
+ c = b + factor / c;
243
+ if (Math.abs(c) < 1e-300) {
244
+ c = 1e-300;
245
+ }
246
+ d = 1 / d;
247
+ const delta = d * c;
248
+ h *= delta;
249
+ if (Math.abs(delta - 1) <= 1e-14) {
250
+ break;
251
+ }
252
+ }
253
+ return 1 - Math.exp(-x + shape * Math.log(x) - logGammaShape) * h;
254
+ }
255
+ function regularizedUpperGamma(shape, x) {
256
+ const lower = regularizedLowerGamma(shape, x);
257
+ return Number.isFinite(lower) ? 1 - lower : Number.NaN;
258
+ }
259
+ function erfApprox(value) {
260
+ const sign = value < 0 ? -1 : 1;
261
+ const absolute = Math.abs(value);
262
+ const t = 1 / (1 + 0.3275911 * absolute);
263
+ const y = 1 -
264
+ ((((1.061405429 * t - 1.453152027) * t + 1.421413741) * t - 0.284496736) * t + 0.254829592) *
265
+ t *
266
+ Math.exp(-absolute * absolute);
267
+ return sign * y;
268
+ }
269
+ function standardNormalCdf(value) {
270
+ return 0.5 * (1 + erfApprox(value / Math.sqrt(2)));
271
+ }
272
+ function logBeta(alpha, beta) {
273
+ return logGamma(alpha) + logGamma(beta) - logGamma(alpha + beta);
274
+ }
275
+ function betaContinuedFraction(x, alpha, beta) {
276
+ const maxIterations = 200;
277
+ const epsilon = 1e-14;
278
+ const tiny = 1e-300;
279
+ const qab = alpha + beta;
280
+ const qap = alpha + 1;
281
+ const qam = alpha - 1;
282
+ let c = 1;
283
+ let d = 1 - (qab * x) / qap;
284
+ if (Math.abs(d) < tiny) {
285
+ d = tiny;
286
+ }
287
+ d = 1 / d;
288
+ let h = d;
289
+ for (let iteration = 1; iteration <= maxIterations; iteration += 1) {
290
+ const step = iteration * 2;
291
+ let factor = (iteration * (beta - iteration) * x) / ((qam + step) * (alpha + step));
292
+ d = 1 + factor * d;
293
+ if (Math.abs(d) < tiny) {
294
+ d = tiny;
295
+ }
296
+ c = 1 + factor / c;
297
+ if (Math.abs(c) < tiny) {
298
+ c = tiny;
299
+ }
300
+ d = 1 / d;
301
+ h *= d * c;
302
+ factor = (-(alpha + iteration) * (qab + iteration) * x) / ((alpha + step) * (qap + step));
303
+ d = 1 + factor * d;
304
+ if (Math.abs(d) < tiny) {
305
+ d = tiny;
306
+ }
307
+ c = 1 + factor / c;
308
+ if (Math.abs(c) < tiny) {
309
+ c = tiny;
310
+ }
311
+ d = 1 / d;
312
+ const delta = d * c;
313
+ h *= delta;
314
+ if (Math.abs(delta - 1) <= epsilon) {
315
+ break;
316
+ }
317
+ }
318
+ return h;
319
+ }
320
+ function regularizedBeta(x, alpha, beta) {
321
+ if (!Number.isFinite(x) ||
322
+ !Number.isFinite(alpha) ||
323
+ !Number.isFinite(beta) ||
324
+ x < 0 ||
325
+ x > 1 ||
326
+ alpha <= 0 ||
327
+ beta <= 0) {
328
+ return Number.NaN;
329
+ }
330
+ if (x === 0) {
331
+ return 0;
332
+ }
333
+ if (x === 1) {
334
+ return 1;
335
+ }
336
+ const logTerm = alpha * Math.log(x) + beta * Math.log(1 - x) - logBeta(alpha, beta);
337
+ if (!Number.isFinite(logTerm)) {
338
+ return Number.NaN;
339
+ }
340
+ const front = Math.exp(logTerm);
341
+ if (x < (alpha + 1) / (alpha + beta + 2)) {
342
+ return (front * betaContinuedFraction(x, alpha, beta)) / alpha;
343
+ }
344
+ return 1 - (front * betaContinuedFraction(1 - x, beta, alpha)) / beta;
345
+ }
346
+ function fDistributionCdf(x, degreesFreedom1, degreesFreedom2) {
347
+ if (!Number.isFinite(x) ||
348
+ !Number.isFinite(degreesFreedom1) ||
349
+ !Number.isFinite(degreesFreedom2) ||
350
+ x < 0 ||
351
+ degreesFreedom1 < 1 ||
352
+ degreesFreedom2 < 1) {
353
+ return Number.NaN;
354
+ }
355
+ const alpha = degreesFreedom1 / 2;
356
+ const beta = degreesFreedom2 / 2;
357
+ const transformed = (degreesFreedom1 * x) / (degreesFreedom1 * x + degreesFreedom2);
358
+ return regularizedBeta(transformed, alpha, beta);
359
+ }
360
+ function studentTCdf(x, degreesFreedom) {
361
+ if (!Number.isFinite(x) || !Number.isFinite(degreesFreedom) || degreesFreedom < 1) {
362
+ return Number.NaN;
363
+ }
364
+ if (x === 0) {
365
+ return 0.5;
366
+ }
367
+ const transformed = degreesFreedom / (degreesFreedom + x * x);
368
+ const tail = regularizedBeta(transformed, degreesFreedom / 2, 0.5);
369
+ if (!Number.isFinite(tail)) {
370
+ return Number.NaN;
371
+ }
372
+ return x > 0 ? 1 - tail / 2 : tail / 2;
373
+ }
374
+ function collectSampleNumbers(arg) {
375
+ if (!isRangeArg(arg)) {
376
+ if (isError(arg)) {
377
+ return arg;
378
+ }
379
+ return arg.tag === ValueTag.Number ? [arg.value] : errorValue(ErrorCode.Value);
380
+ }
381
+ const values = [];
382
+ for (const value of arg.values) {
383
+ if (value.tag === ValueTag.Error) {
384
+ return value;
385
+ }
386
+ if (value.tag === ValueTag.Number) {
387
+ values.push(value.value);
388
+ }
389
+ }
390
+ return values;
391
+ }
392
+ function chiSquareTestResult(actualArg, expectedArg) {
393
+ const actual = toNumericMatrix(actualArg);
394
+ if (!Array.isArray(actual)) {
395
+ return actual;
396
+ }
397
+ const expected = toNumericMatrix(expectedArg);
398
+ if (!Array.isArray(expected)) {
399
+ return expected;
400
+ }
401
+ const rows = actual.length;
402
+ const cols = actual[0]?.length ?? 0;
403
+ if (rows !== expected.length || cols !== (expected[0]?.length ?? 0)) {
404
+ return errorValue(ErrorCode.NA);
405
+ }
406
+ if ((rows === 1 && cols === 1) || rows === 0 || cols === 0) {
407
+ return errorValue(ErrorCode.NA);
408
+ }
409
+ let statistic = 0;
410
+ for (let row = 0; row < rows; row += 1) {
411
+ const actualRow = actual[row];
412
+ const expectedRow = expected[row];
413
+ if (actualRow.length !== cols || expectedRow.length !== cols) {
414
+ return errorValue(ErrorCode.NA);
415
+ }
416
+ for (let col = 0; col < cols; col += 1) {
417
+ const actualValue = actualRow[col];
418
+ const expectedValue = expectedRow[col];
419
+ if (actualValue < 0 || expectedValue < 0) {
420
+ return errorValue(ErrorCode.Value);
421
+ }
422
+ if (expectedValue === 0) {
423
+ return errorValue(ErrorCode.Div0);
424
+ }
425
+ const delta = actualValue - expectedValue;
426
+ statistic += (delta * delta) / expectedValue;
427
+ }
428
+ }
429
+ const degrees = rows > 1 && cols > 1 ? (rows - 1) * (cols - 1) : rows > 1 ? rows - 1 : cols - 1;
430
+ if (degrees <= 0) {
431
+ return errorValue(ErrorCode.NA);
432
+ }
433
+ const probability = regularizedUpperGamma(degrees / 2, statistic / 2);
434
+ return Number.isFinite(probability)
435
+ ? { tag: ValueTag.Number, value: probability }
436
+ : errorValue(ErrorCode.Value);
437
+ }
438
+ function fTestResult(firstArg, secondArg) {
439
+ const first = collectSampleNumbers(firstArg);
440
+ if (!Array.isArray(first)) {
441
+ return first;
442
+ }
443
+ const second = collectSampleNumbers(secondArg);
444
+ if (!Array.isArray(second)) {
445
+ return second;
446
+ }
447
+ if (first.length < 2 || second.length < 2) {
448
+ return errorValue(ErrorCode.Div0);
449
+ }
450
+ const firstMean = first.reduce((sum, value) => sum + value, 0) / first.length;
451
+ const secondMean = second.reduce((sum, value) => sum + value, 0) / second.length;
452
+ const firstVariance = first.reduce((sum, value) => sum + (value - firstMean) ** 2, 0) / (first.length - 1);
453
+ const secondVariance = second.reduce((sum, value) => sum + (value - secondMean) ** 2, 0) / (second.length - 1);
454
+ if (!(firstVariance > 0) || !(secondVariance > 0)) {
455
+ return errorValue(ErrorCode.Div0);
456
+ }
457
+ const firstLeads = firstVariance >= secondVariance;
458
+ const numeratorVariance = firstLeads ? firstVariance : secondVariance;
459
+ const denominatorVariance = firstLeads ? secondVariance : firstVariance;
460
+ const numeratorDf = firstLeads ? first.length - 1 : second.length - 1;
461
+ const denominatorDf = firstLeads ? second.length - 1 : first.length - 1;
462
+ const upperTail = 1 - fDistributionCdf(numeratorVariance / denominatorVariance, numeratorDf, denominatorDf);
463
+ const probability = Math.min(1, upperTail * 2);
464
+ return Number.isFinite(probability)
465
+ ? { tag: ValueTag.Number, value: probability }
466
+ : errorValue(ErrorCode.Value);
467
+ }
468
+ function zTestResult(arrayArg, xArg, sigmaArg) {
469
+ const sample = collectSampleNumbers(arrayArg);
470
+ if (!Array.isArray(sample)) {
471
+ return sample;
472
+ }
473
+ const x = !isRangeArg(xArg) ? toNumber(xArg) : undefined;
474
+ if (x === undefined || sample.length === 0) {
475
+ return errorValue(ErrorCode.Value);
476
+ }
477
+ let sigma;
478
+ if (sigmaArg !== undefined) {
479
+ sigma = !isRangeArg(sigmaArg) ? toNumber(sigmaArg) : undefined;
480
+ }
481
+ else if (sample.length >= 2) {
482
+ const mean = sample.reduce((sum, value) => sum + value, 0) / sample.length;
483
+ const variance = sample.reduce((sum, value) => sum + (value - mean) ** 2, 0) / (sample.length - 1);
484
+ sigma = variance > 0 ? Math.sqrt(variance) : undefined;
485
+ }
486
+ if (sigma === undefined || !(sigma > 0)) {
487
+ return errorValue(ErrorCode.Div0);
488
+ }
489
+ const mean = sample.reduce((sum, value) => sum + value, 0) / sample.length;
490
+ const zScore = (mean - x) / (sigma / Math.sqrt(sample.length));
491
+ const probability = 1 - standardNormalCdf(zScore);
492
+ return Number.isFinite(probability)
493
+ ? { tag: ValueTag.Number, value: probability }
494
+ : errorValue(ErrorCode.Value);
495
+ }
496
+ function tTestResult(firstArg, secondArg, tailsArg, typeArg) {
497
+ const first = collectSampleNumbers(firstArg);
498
+ if (!Array.isArray(first)) {
499
+ return first;
500
+ }
501
+ const second = collectSampleNumbers(secondArg);
502
+ if (!Array.isArray(second)) {
503
+ return second;
504
+ }
505
+ const tails = !isRangeArg(tailsArg) ? toNumber(tailsArg) : undefined;
506
+ const type = !isRangeArg(typeArg) ? toNumber(typeArg) : undefined;
507
+ if (tails === undefined ||
508
+ type === undefined ||
509
+ !Number.isInteger(tails) ||
510
+ !Number.isInteger(type) ||
511
+ ![1, 2].includes(tails) ||
512
+ ![1, 2, 3].includes(type)) {
513
+ return errorValue(ErrorCode.Value);
514
+ }
515
+ let statistic;
516
+ let degreesFreedom;
517
+ if (type === 1) {
518
+ if (first.length !== second.length) {
519
+ return errorValue(ErrorCode.NA);
520
+ }
521
+ if (first.length < 2) {
522
+ return errorValue(ErrorCode.Div0);
523
+ }
524
+ const deltas = first.map((value, index) => value - second[index]);
525
+ const mean = deltas.reduce((sum, value) => sum + value, 0) / deltas.length;
526
+ const variance = deltas.reduce((sum, value) => sum + (value - mean) ** 2, 0) / (deltas.length - 1);
527
+ if (!(variance > 0)) {
528
+ return errorValue(ErrorCode.Div0);
529
+ }
530
+ statistic = mean / Math.sqrt(variance / deltas.length);
531
+ degreesFreedom = deltas.length - 1;
532
+ }
533
+ else {
534
+ if (first.length < 2 || second.length < 2) {
535
+ return errorValue(ErrorCode.Div0);
536
+ }
537
+ const firstMean = first.reduce((sum, value) => sum + value, 0) / first.length;
538
+ const secondMean = second.reduce((sum, value) => sum + value, 0) / second.length;
539
+ const firstVariance = first.reduce((sum, value) => sum + (value - firstMean) ** 2, 0) / (first.length - 1);
540
+ const secondVariance = second.reduce((sum, value) => sum + (value - secondMean) ** 2, 0) / (second.length - 1);
541
+ if (!(firstVariance > 0) || !(secondVariance > 0)) {
542
+ return errorValue(ErrorCode.Div0);
543
+ }
544
+ if (type === 2) {
545
+ const pooledVariance = ((first.length - 1) * firstVariance + (second.length - 1) * secondVariance) /
546
+ (first.length + second.length - 2);
547
+ if (!(pooledVariance > 0)) {
548
+ return errorValue(ErrorCode.Div0);
549
+ }
550
+ statistic =
551
+ (firstMean - secondMean) /
552
+ Math.sqrt(pooledVariance * (1 / first.length + 1 / second.length));
553
+ degreesFreedom = first.length + second.length - 2;
554
+ }
555
+ else {
556
+ const firstTerm = firstVariance / first.length;
557
+ const secondTerm = secondVariance / second.length;
558
+ const denominator = Math.sqrt(firstTerm + secondTerm);
559
+ const welchDenominator = (firstTerm * firstTerm) / (first.length - 1) +
560
+ (secondTerm * secondTerm) / (second.length - 1);
561
+ if (!(denominator > 0) || !(welchDenominator > 0)) {
562
+ return errorValue(ErrorCode.Div0);
563
+ }
564
+ statistic = (firstMean - secondMean) / denominator;
565
+ degreesFreedom = (firstTerm + secondTerm) ** 2 / welchDenominator;
566
+ }
567
+ }
568
+ const upperTail = 1 - studentTCdf(Math.abs(statistic), degreesFreedom);
569
+ const probability = tails === 1 ? upperTail : Math.min(1, upperTail * 2);
570
+ return Number.isFinite(probability)
571
+ ? { tag: ValueTag.Number, value: probability }
572
+ : errorValue(ErrorCode.Value);
573
+ }
574
+ function flattenNumbers(arg) {
575
+ if (!isRangeArg(arg)) {
576
+ const numeric = toNumber(arg);
577
+ return numeric === undefined ? errorValue(ErrorCode.Value) : [numeric];
578
+ }
579
+ const values = [];
580
+ for (const value of arg.values) {
581
+ const numeric = toNumber(value);
582
+ if (numeric === undefined) {
583
+ return errorValue(ErrorCode.Value);
584
+ }
585
+ values.push(numeric);
586
+ }
587
+ return values;
588
+ }
589
+ function pickRangeRow(range, row) {
590
+ const values = [];
591
+ for (let col = 0; col < range.cols; col += 1) {
592
+ values.push(getRangeValue(range, row, col));
593
+ }
594
+ return values;
595
+ }
596
+ function hasWildcardPattern(pattern) {
597
+ for (let index = 0; index < pattern.length; index += 1) {
598
+ const char = pattern[index];
599
+ if (char === "~") {
600
+ index += 1;
601
+ continue;
602
+ }
603
+ if (char === "*" || char === "?") {
604
+ return true;
605
+ }
606
+ }
607
+ return false;
608
+ }
609
+ function wildcardPatternToRegExp(pattern) {
610
+ let source = "^";
611
+ for (let index = 0; index < pattern.length; index += 1) {
612
+ const char = pattern[index];
613
+ if (char === undefined) {
614
+ continue;
615
+ }
616
+ if (char === "~") {
617
+ const escaped = pattern[index + 1];
618
+ if (escaped !== undefined) {
619
+ source += escapeRegexFragment(escaped);
620
+ index += 1;
621
+ continue;
622
+ }
623
+ source += escapeRegexFragment(char);
624
+ continue;
625
+ }
626
+ if (char === "*") {
627
+ source += ".*";
628
+ continue;
629
+ }
630
+ if (char === "?") {
631
+ source += ".";
632
+ continue;
633
+ }
634
+ source += escapeRegexFragment(char);
635
+ }
636
+ source += "$";
637
+ return new RegExp(source, "i");
638
+ }
639
+ function escapeRegexFragment(value) {
640
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
641
+ }
642
+ function unescapeCriteriaPattern(pattern) {
643
+ let unescaped = "";
644
+ for (let index = 0; index < pattern.length; index += 1) {
645
+ const char = pattern[index];
646
+ if (char === undefined) {
647
+ continue;
648
+ }
649
+ if (char === "~") {
650
+ const escaped = pattern[index + 1];
651
+ if (escaped !== undefined) {
652
+ unescaped += escaped;
653
+ index += 1;
654
+ continue;
655
+ }
656
+ }
657
+ unescaped += char;
658
+ }
659
+ return unescaped;
660
+ }
661
+ function firstLookupError(args) {
662
+ return args.find((arg) => isError(arg));
663
+ }
664
+ const externalLookupBuiltinNames = ["FILTERXML", "STOCKHISTORY"];
665
+ function createExternalLookupBuiltin(name) {
666
+ return (...args) => {
667
+ const existingError = firstLookupError(args);
668
+ if (existingError) {
669
+ return existingError;
670
+ }
671
+ const external = getExternalLookupFunction(name);
672
+ return external ? external(...args) : errorValue(ErrorCode.Blocked);
673
+ };
674
+ }
675
+ const externalLookupBuiltins = Object.fromEntries(externalLookupBuiltinNames.map((name) => [name, createExternalLookupBuiltin(name)]));
676
+ const lookupRegressionBuiltins = createLookupRegressionBuiltins({
677
+ errorValue,
678
+ numberResult,
679
+ isRangeArg,
680
+ toNumber,
681
+ toBoolean,
682
+ flattenNumbers,
683
+ });
684
+ const lookupOrderStatisticsBuiltins = createLookupOrderStatisticsBuiltins({
685
+ errorValue,
686
+ numberResult,
687
+ arrayResult,
688
+ requireCellRange,
689
+ isError,
690
+ isRangeArg,
691
+ toNumber,
692
+ toInteger,
693
+ flattenNumbers,
694
+ });
695
+ const lookupFinancialBuiltins = createLookupFinancialBuiltins({
696
+ errorValue,
697
+ numberResult,
698
+ isRangeArg,
699
+ toNumber,
700
+ collectNumericSeries,
701
+ });
702
+ const lookupHypothesisBuiltins = createLookupHypothesisBuiltins({
703
+ errorValue,
704
+ chiSquareTestResult,
705
+ fTestResult,
706
+ zTestResult,
707
+ tTestResult,
708
+ });
709
+ const lookupMatrixBuiltins = createLookupMatrixBuiltins({
710
+ errorValue,
711
+ numberResult,
712
+ arrayResult,
713
+ isRangeArg,
714
+ requireCellRange,
715
+ findFirstNonRange,
716
+ areRangeArgs,
717
+ toNumber,
718
+ toNumericMatrix,
719
+ flattenNumbers,
720
+ });
721
+ const lookupSortFilterBuiltins = createLookupSortFilterBuiltins({
722
+ errorValue,
723
+ arrayResult,
724
+ isError,
725
+ isRangeArg,
726
+ toBoolean,
727
+ toInteger,
728
+ requireCellRange,
729
+ toCellRange,
730
+ compareScalars,
731
+ getRangeValue,
732
+ pickRangeRow,
733
+ });
734
+ const lookupDatabaseBuiltins = createLookupDatabaseBuiltins({
735
+ errorValue,
736
+ numberResult,
737
+ isError,
738
+ isRangeArg,
739
+ toNumber,
740
+ toStringValue,
741
+ requireCellRange,
742
+ getRangeValue,
743
+ matchesCriteria,
744
+ });
745
+ const lookupCriteriaBuiltins = createLookupCriteriaBuiltins({
746
+ errorValue,
747
+ numberResult,
748
+ isError,
749
+ isRangeArg,
750
+ toNumber,
751
+ requireCellRange,
752
+ matchesCriteria,
753
+ numericAggregateCandidate,
754
+ });
755
+ const lookupReferenceBuiltins = createLookupReferenceBuiltins({
756
+ errorValue,
757
+ numberResult,
758
+ isError,
759
+ isRangeArg,
760
+ toBoolean,
761
+ toInteger,
762
+ requireCellVector,
763
+ toCellRange,
764
+ compareScalars,
765
+ getRangeValue,
766
+ });
767
+ const lookupArrayShapeBuiltins = createLookupArrayShapeBuiltins({
768
+ errorValue,
769
+ arrayResult,
770
+ isError,
771
+ isRangeArg,
772
+ toBoolean,
773
+ toInteger,
774
+ requireCellRange,
775
+ toCellRange,
776
+ getRangeValue,
777
+ findFirstNonRange,
778
+ areRangeArgs,
779
+ pickRangeRow,
780
+ });
781
+ export const lookupBuiltins = {
782
+ ...lookupArrayShapeBuiltins,
783
+ ...lookupReferenceBuiltins,
784
+ ...lookupCriteriaBuiltins,
785
+ ...lookupDatabaseBuiltins,
786
+ ...lookupFinancialBuiltins,
787
+ ...lookupHypothesisBuiltins,
788
+ ...lookupRegressionBuiltins,
789
+ ...lookupOrderStatisticsBuiltins,
790
+ ...lookupMatrixBuiltins,
791
+ ...lookupSortFilterBuiltins,
792
+ ...externalLookupBuiltins,
793
+ };
794
+ function matchesCriteria(value, criteria) {
795
+ if (isError(value)) {
796
+ return false;
797
+ }
798
+ let { operator, operand } = parseCriteria(criteria);
799
+ if (operand.tag === ValueTag.String &&
800
+ (operator === "=" || operator === "<>") &&
801
+ hasWildcardPattern(operand.value)) {
802
+ const matches = wildcardPatternToRegExp(operand.value).test(toStringValue(value));
803
+ return operator === "=" ? matches : !matches;
804
+ }
805
+ if (operand.tag === ValueTag.String && operand.value.includes("~")) {
806
+ operand = {
807
+ tag: ValueTag.String,
808
+ value: unescapeCriteriaPattern(operand.value),
809
+ stringId: operand.stringId,
810
+ };
811
+ }
812
+ const comparison = compareScalars(value, operand);
813
+ if (comparison === undefined) {
814
+ return false;
815
+ }
816
+ switch (operator) {
817
+ case "=":
818
+ return comparison === 0;
819
+ case "<>":
820
+ return comparison !== 0;
821
+ case ">":
822
+ return comparison > 0;
823
+ case ">=":
824
+ return comparison >= 0;
825
+ case "<":
826
+ return comparison < 0;
827
+ case "<=":
828
+ return comparison <= 0;
829
+ }
830
+ }
831
+ function parseCriteria(criteria) {
832
+ if (criteria.tag !== ValueTag.String) {
833
+ return { operator: "=", operand: criteria };
834
+ }
835
+ const match = /^(<=|>=|<>|=|<|>)(.*)$/.exec(criteria.value);
836
+ if (!match) {
837
+ return { operator: "=", operand: criteria };
838
+ }
839
+ const operator = match[1] ?? "=";
840
+ return {
841
+ operator: isCriteriaOperator(operator) ? operator : "=",
842
+ operand: parseCriteriaOperand(match[2] ?? ""),
843
+ };
844
+ }
845
+ function parseCriteriaOperand(raw) {
846
+ const trimmed = raw.trim();
847
+ if (trimmed === "") {
848
+ return { tag: ValueTag.String, value: "", stringId: 0 };
849
+ }
850
+ const upper = trimmed.toUpperCase();
851
+ if (upper === "TRUE" || upper === "FALSE") {
852
+ return { tag: ValueTag.Boolean, value: upper === "TRUE" };
853
+ }
854
+ const numeric = Number(trimmed);
855
+ if (Number.isFinite(numeric)) {
856
+ return { tag: ValueTag.Number, value: numeric };
857
+ }
858
+ return { tag: ValueTag.String, value: trimmed, stringId: 0 };
859
+ }
860
+ export function getLookupBuiltin(name) {
861
+ const upper = name.toUpperCase();
862
+ if (upper === "USE.THE.COUNTIF") {
863
+ return lookupBuiltins["COUNTIF"];
864
+ }
865
+ return lookupBuiltins[upper] ?? getExternalLookupFunction(name);
866
+ }
867
+ //# sourceMappingURL=lookup.js.map