@ricsam/formula-engine 0.0.1
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.
- package/README.md +100 -0
- package/dist/cjs/core/ast-traverser.cjs +124 -0
- package/dist/cjs/core/ast-traverser.cjs.map +10 -0
- package/dist/cjs/core/autofill-utils.cjs +304 -0
- package/dist/cjs/core/autofill-utils.cjs.map +10 -0
- package/dist/cjs/core/engine.cjs +390 -0
- package/dist/cjs/core/engine.cjs.map +10 -0
- package/dist/cjs/core/managers/cache-manager.cjs +58 -0
- package/dist/cjs/core/managers/cache-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/dependency-manager.cjs +620 -0
- package/dist/cjs/core/managers/dependency-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/dependency-node.cjs +24 -0
- package/dist/cjs/core/managers/dependency-node.cjs.map +9 -0
- package/dist/cjs/core/managers/evaluation-manager.cjs +433 -0
- package/dist/cjs/core/managers/evaluation-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/event-manager.cjs +49 -0
- package/dist/cjs/core/managers/event-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/frontier-dependency-manager.cjs +181 -0
- package/dist/cjs/core/managers/frontier-dependency-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/index.cjs +49 -0
- package/dist/cjs/core/managers/index.cjs.map +10 -0
- package/dist/cjs/core/managers/isDependencyNode.cjs +44 -0
- package/dist/cjs/core/managers/isDependencyNode.cjs.map +10 -0
- package/dist/cjs/core/managers/named-expression-manager.cjs +379 -0
- package/dist/cjs/core/managers/named-expression-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/range-eval-order-builder.cjs +644 -0
- package/dist/cjs/core/managers/range-eval-order-builder.cjs.map +10 -0
- package/dist/cjs/core/managers/table-manager.cjs +254 -0
- package/dist/cjs/core/managers/table-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/workbook-manager.cjs +474 -0
- package/dist/cjs/core/managers/workbook-manager.cjs.map +10 -0
- package/dist/cjs/core/map-serializer.cjs +69 -0
- package/dist/cjs/core/map-serializer.cjs.map +10 -0
- package/dist/cjs/core/named-expression-renamer.cjs +88 -0
- package/dist/cjs/core/named-expression-renamer.cjs.map +10 -0
- package/dist/cjs/core/sheet-renamer.cjs +89 -0
- package/dist/cjs/core/sheet-renamer.cjs.map +10 -0
- package/dist/cjs/core/sheet-utils.cjs +39 -0
- package/dist/cjs/core/sheet-utils.cjs.map +10 -0
- package/dist/cjs/core/table-renamer.cjs +88 -0
- package/dist/cjs/core/table-renamer.cjs.map +10 -0
- package/dist/cjs/core/types.cjs +48 -0
- package/dist/cjs/core/types.cjs.map +10 -0
- package/dist/cjs/core/utils/range-serializer.cjs +65 -0
- package/dist/cjs/core/utils/range-serializer.cjs.map +10 -0
- package/dist/cjs/core/utils/spreadsheet-visualizer.cjs +142 -0
- package/dist/cjs/core/utils/spreadsheet-visualizer.cjs.map +10 -0
- package/dist/cjs/core/utils.cjs +434 -0
- package/dist/cjs/core/utils.cjs.map +10 -0
- package/dist/cjs/core/workbook-renamer.cjs +106 -0
- package/dist/cjs/core/workbook-renamer.cjs.map +10 -0
- package/dist/cjs/debug/flags.cjs +47 -0
- package/dist/cjs/debug/flags.cjs.map +10 -0
- package/dist/cjs/evaluator/arithmetic/add/add.cjs +82 -0
- package/dist/cjs/evaluator/arithmetic/add/add.cjs.map +10 -0
- package/dist/cjs/evaluator/arithmetic/divide/divide.cjs +107 -0
- package/dist/cjs/evaluator/arithmetic/divide/divide.cjs.map +10 -0
- package/dist/cjs/evaluator/arithmetic/multiply/multiply.cjs +93 -0
- package/dist/cjs/evaluator/arithmetic/multiply/multiply.cjs.map +10 -0
- package/dist/cjs/evaluator/arithmetic/power/power.cjs +125 -0
- package/dist/cjs/evaluator/arithmetic/power/power.cjs.map +10 -0
- package/dist/cjs/evaluator/arithmetic/subtract/subtract.cjs +84 -0
- package/dist/cjs/evaluator/arithmetic/subtract/subtract.cjs.map +10 -0
- package/dist/cjs/evaluator/comparison/equals.cjs +64 -0
- package/dist/cjs/evaluator/comparison/equals.cjs.map +10 -0
- package/dist/cjs/evaluator/comparison/greater-than-or-equal.cjs +61 -0
- package/dist/cjs/evaluator/comparison/greater-than-or-equal.cjs.map +10 -0
- package/dist/cjs/evaluator/comparison/greater-than.cjs +61 -0
- package/dist/cjs/evaluator/comparison/greater-than.cjs.map +10 -0
- package/dist/cjs/evaluator/comparison/less-than-or-equal.cjs +69 -0
- package/dist/cjs/evaluator/comparison/less-than-or-equal.cjs.map +10 -0
- package/dist/cjs/evaluator/comparison/less-than.cjs +68 -0
- package/dist/cjs/evaluator/comparison/less-than.cjs.map +10 -0
- package/dist/cjs/evaluator/comparison/not-equals.cjs +53 -0
- package/dist/cjs/evaluator/comparison/not-equals.cjs.map +10 -0
- package/dist/cjs/evaluator/concatenation/concatenate.cjs +72 -0
- package/dist/cjs/evaluator/concatenation/concatenate.cjs.map +10 -0
- package/dist/cjs/evaluator/dependency-nodes/ast-evaluation-node.cjs +58 -0
- package/dist/cjs/evaluator/dependency-nodes/ast-evaluation-node.cjs.map +10 -0
- package/dist/cjs/evaluator/dependency-nodes/base-eval-node.cjs +112 -0
- package/dist/cjs/evaluator/dependency-nodes/base-eval-node.cjs.map +10 -0
- package/dist/cjs/evaluator/dependency-nodes/cell-value-node.cjs +54 -0
- package/dist/cjs/evaluator/dependency-nodes/cell-value-node.cjs.map +10 -0
- package/dist/cjs/evaluator/dependency-nodes/empty-cell-evaluation-node.cjs +108 -0
- package/dist/cjs/evaluator/dependency-nodes/empty-cell-evaluation-node.cjs.map +10 -0
- package/dist/cjs/evaluator/dependency-nodes/spill-meta-node.cjs +50 -0
- package/dist/cjs/evaluator/dependency-nodes/spill-meta-node.cjs.map +10 -0
- package/dist/cjs/evaluator/evaluate-scalar-operator.cjs +254 -0
- package/dist/cjs/evaluator/evaluate-scalar-operator.cjs.map +10 -0
- package/dist/cjs/evaluator/evaluation-context.cjs +154 -0
- package/dist/cjs/evaluator/evaluation-context.cjs.map +10 -0
- package/dist/cjs/evaluator/evaluation-error.cjs +75 -0
- package/dist/cjs/evaluator/evaluation-error.cjs.map +10 -0
- package/dist/cjs/evaluator/formula-evaluator.cjs +797 -0
- package/dist/cjs/evaluator/formula-evaluator.cjs.map +10 -0
- package/dist/cjs/evaluator/range-evaluation-node.cjs +88 -0
- package/dist/cjs/evaluator/range-evaluation-node.cjs.map +10 -0
- package/dist/cjs/functions/_template/template.cjs +42 -0
- package/dist/cjs/functions/_template/template.cjs.map +10 -0
- package/dist/cjs/functions/array/sequence/sequence.cjs +315 -0
- package/dist/cjs/functions/array/sequence/sequence.cjs.map +10 -0
- package/dist/cjs/functions/criteria-parser.cjs +217 -0
- package/dist/cjs/functions/criteria-parser.cjs.map +10 -0
- package/dist/cjs/functions/criteria-utils.cjs +291 -0
- package/dist/cjs/functions/criteria-utils.cjs.map +10 -0
- package/dist/cjs/functions/function-utils.cjs +63 -0
- package/dist/cjs/functions/function-utils.cjs.map +10 -0
- package/dist/cjs/functions/index.cjs +125 -0
- package/dist/cjs/functions/index.cjs.map +10 -0
- package/dist/cjs/functions/information/cell/cell.cjs +196 -0
- package/dist/cjs/functions/information/cell/cell.cjs.map +10 -0
- package/dist/cjs/functions/information/column/column.cjs +144 -0
- package/dist/cjs/functions/information/column/column.cjs.map +10 -0
- package/dist/cjs/functions/information/row/row.cjs +150 -0
- package/dist/cjs/functions/information/row/row.cjs.map +10 -0
- package/dist/cjs/functions/logical/and/and.cjs +112 -0
- package/dist/cjs/functions/logical/and/and.cjs.map +10 -0
- package/dist/cjs/functions/logical/if/if.cjs +195 -0
- package/dist/cjs/functions/logical/if/if.cjs.map +10 -0
- package/dist/cjs/functions/logical/iferror/iferror.cjs +126 -0
- package/dist/cjs/functions/logical/iferror/iferror.cjs.map +10 -0
- package/dist/cjs/functions/logical/or/or.cjs +112 -0
- package/dist/cjs/functions/logical/or/or.cjs.map +10 -0
- package/dist/cjs/functions/lookup/count/count-utils.cjs +65 -0
- package/dist/cjs/functions/lookup/count/count-utils.cjs.map +10 -0
- package/dist/cjs/functions/lookup/count/count.cjs +48 -0
- package/dist/cjs/functions/lookup/count/count.cjs.map +10 -0
- package/dist/cjs/functions/lookup/count/countif.cjs +94 -0
- package/dist/cjs/functions/lookup/count/countif.cjs.map +10 -0
- package/dist/cjs/functions/lookup/count/countifs.cjs +63 -0
- package/dist/cjs/functions/lookup/count/countifs.cjs.map +10 -0
- package/dist/cjs/functions/lookup/index-lookup/index-lookup.cjs +187 -0
- package/dist/cjs/functions/lookup/index-lookup/index-lookup.cjs.map +10 -0
- package/dist/cjs/functions/lookup/match/match.cjs +168 -0
- package/dist/cjs/functions/lookup/match/match.cjs.map +10 -0
- package/dist/cjs/functions/lookup/xlookup/xlookup.cjs +410 -0
- package/dist/cjs/functions/lookup/xlookup/xlookup.cjs.map +10 -0
- package/dist/cjs/functions/math/average/average-utils.cjs +72 -0
- package/dist/cjs/functions/math/average/average-utils.cjs.map +10 -0
- package/dist/cjs/functions/math/average/average.cjs +48 -0
- package/dist/cjs/functions/math/average/average.cjs.map +10 -0
- package/dist/cjs/functions/math/average/averageif.cjs +83 -0
- package/dist/cjs/functions/math/average/averageif.cjs.map +10 -0
- package/dist/cjs/functions/math/average/averageifs.cjs +61 -0
- package/dist/cjs/functions/math/average/averageifs.cjs.map +10 -0
- package/dist/cjs/functions/math/ceiling/ceiling.cjs +219 -0
- package/dist/cjs/functions/math/ceiling/ceiling.cjs.map +10 -0
- package/dist/cjs/functions/math/max/max-utils.cjs +71 -0
- package/dist/cjs/functions/math/max/max-utils.cjs.map +10 -0
- package/dist/cjs/functions/math/max/max.cjs +48 -0
- package/dist/cjs/functions/math/max/max.cjs.map +10 -0
- package/dist/cjs/functions/math/max/maxif.cjs +83 -0
- package/dist/cjs/functions/math/max/maxif.cjs.map +10 -0
- package/dist/cjs/functions/math/max/maxifs.cjs +61 -0
- package/dist/cjs/functions/math/max/maxifs.cjs.map +10 -0
- package/dist/cjs/functions/math/min/min-utils.cjs +71 -0
- package/dist/cjs/functions/math/min/min-utils.cjs.map +10 -0
- package/dist/cjs/functions/math/min/min.cjs +48 -0
- package/dist/cjs/functions/math/min/min.cjs.map +10 -0
- package/dist/cjs/functions/math/min/minif.cjs +83 -0
- package/dist/cjs/functions/math/min/minif.cjs.map +10 -0
- package/dist/cjs/functions/math/min/minifs.cjs +61 -0
- package/dist/cjs/functions/math/min/minifs.cjs.map +10 -0
- package/dist/cjs/functions/math/sum/sum.cjs +48 -0
- package/dist/cjs/functions/math/sum/sum.cjs.map +10 -0
- package/dist/cjs/functions/math/sum/sumif.cjs +83 -0
- package/dist/cjs/functions/math/sum/sumif.cjs.map +10 -0
- package/dist/cjs/functions/math/sum/sumifs.cjs +60 -0
- package/dist/cjs/functions/math/sum/sumifs.cjs.map +10 -0
- package/dist/cjs/functions/math/sum/summation-utils.cjs +57 -0
- package/dist/cjs/functions/math/sum/summation-utils.cjs.map +10 -0
- package/dist/cjs/functions/reference/address/address.cjs +163 -0
- package/dist/cjs/functions/reference/address/address.cjs.map +10 -0
- package/dist/cjs/functions/reference/indirect/indirect.cjs +102 -0
- package/dist/cjs/functions/reference/indirect/indirect.cjs.map +10 -0
- package/dist/cjs/functions/reference/offset/offset.cjs +233 -0
- package/dist/cjs/functions/reference/offset/offset.cjs.map +10 -0
- package/dist/cjs/functions/text/concatenate/concatenate.cjs +167 -0
- package/dist/cjs/functions/text/concatenate/concatenate.cjs.map +10 -0
- package/dist/cjs/functions/text/exact/exact.cjs +171 -0
- package/dist/cjs/functions/text/exact/exact.cjs.map +10 -0
- package/dist/cjs/functions/text/find/find.cjs +397 -0
- package/dist/cjs/functions/text/find/find.cjs.map +10 -0
- package/dist/cjs/functions/text/left/left.cjs +109 -0
- package/dist/cjs/functions/text/left/left.cjs.map +10 -0
- package/dist/cjs/functions/text/len/len.cjs +119 -0
- package/dist/cjs/functions/text/len/len.cjs.map +10 -0
- package/dist/cjs/functions/text/mid/mid.cjs +103 -0
- package/dist/cjs/functions/text/mid/mid.cjs.map +10 -0
- package/dist/cjs/functions/text/right/right.cjs +167 -0
- package/dist/cjs/functions/text/right/right.cjs.map +10 -0
- package/dist/cjs/functions/text/text-helpers.cjs +179 -0
- package/dist/cjs/functions/text/text-helpers.cjs.map +10 -0
- package/dist/cjs/functions/text/textjoin/textjoin.cjs +173 -0
- package/dist/cjs/functions/text/textjoin/textjoin.cjs.map +10 -0
- package/dist/cjs/package.json +5 -0
- package/dist/cjs/parser/ast.cjs +175 -0
- package/dist/cjs/parser/ast.cjs.map +10 -0
- package/dist/cjs/parser/formatter.cjs +319 -0
- package/dist/cjs/parser/formatter.cjs.map +10 -0
- package/dist/cjs/parser/grammar.cjs +375 -0
- package/dist/cjs/parser/grammar.cjs.map +10 -0
- package/dist/cjs/parser/lexer.cjs +443 -0
- package/dist/cjs/parser/lexer.cjs.map +10 -0
- package/dist/cjs/parser/parser.cjs +1700 -0
- package/dist/cjs/parser/parser.cjs.map +10 -0
- package/dist/cjs/react/hooks.cjs +59 -0
- package/dist/cjs/react/hooks.cjs.map +10 -0
- package/dist/mjs/core/ast-traverser.mjs +94 -0
- package/dist/mjs/core/ast-traverser.mjs.map +10 -0
- package/dist/mjs/core/autofill-utils.mjs +274 -0
- package/dist/mjs/core/autofill-utils.mjs.map +10 -0
- package/dist/mjs/core/engine.mjs +366 -0
- package/dist/mjs/core/engine.mjs.map +10 -0
- package/dist/mjs/core/managers/cache-manager.mjs +27 -0
- package/dist/mjs/core/managers/cache-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/dependency-manager.mjs +593 -0
- package/dist/mjs/core/managers/dependency-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/dependency-node.mjs +2 -0
- package/dist/mjs/core/managers/dependency-node.mjs.map +9 -0
- package/dist/mjs/core/managers/evaluation-manager.mjs +415 -0
- package/dist/mjs/core/managers/evaluation-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/event-manager.mjs +18 -0
- package/dist/mjs/core/managers/event-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/frontier-dependency-manager.mjs +151 -0
- package/dist/mjs/core/managers/frontier-dependency-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/index.mjs +21 -0
- package/dist/mjs/core/managers/index.mjs.map +10 -0
- package/dist/mjs/core/managers/isDependencyNode.mjs +14 -0
- package/dist/mjs/core/managers/isDependencyNode.mjs.map +10 -0
- package/dist/mjs/core/managers/named-expression-manager.mjs +348 -0
- package/dist/mjs/core/managers/named-expression-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/range-eval-order-builder.mjs +618 -0
- package/dist/mjs/core/managers/range-eval-order-builder.mjs.map +10 -0
- package/dist/mjs/core/managers/table-manager.mjs +224 -0
- package/dist/mjs/core/managers/table-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/workbook-manager.mjs +447 -0
- package/dist/mjs/core/managers/workbook-manager.mjs.map +10 -0
- package/dist/mjs/core/map-serializer.mjs +39 -0
- package/dist/mjs/core/map-serializer.mjs.map +10 -0
- package/dist/mjs/core/named-expression-renamer.mjs +58 -0
- package/dist/mjs/core/named-expression-renamer.mjs.map +10 -0
- package/dist/mjs/core/sheet-renamer.mjs +59 -0
- package/dist/mjs/core/sheet-renamer.mjs.map +10 -0
- package/dist/mjs/core/sheet-utils.mjs +8 -0
- package/dist/mjs/core/sheet-utils.mjs.map +10 -0
- package/dist/mjs/core/table-renamer.mjs +58 -0
- package/dist/mjs/core/table-renamer.mjs.map +10 -0
- package/dist/mjs/core/types.mjs +18 -0
- package/dist/mjs/core/types.mjs.map +10 -0
- package/dist/mjs/core/utils/range-serializer.mjs +35 -0
- package/dist/mjs/core/utils/range-serializer.mjs.map +10 -0
- package/dist/mjs/core/utils/spreadsheet-visualizer.mjs +112 -0
- package/dist/mjs/core/utils/spreadsheet-visualizer.mjs.map +10 -0
- package/dist/mjs/core/utils.mjs +409 -0
- package/dist/mjs/core/utils.mjs.map +10 -0
- package/dist/mjs/core/workbook-renamer.mjs +76 -0
- package/dist/mjs/core/workbook-renamer.mjs.map +10 -0
- package/dist/mjs/debug/flags.mjs +17 -0
- package/dist/mjs/debug/flags.mjs.map +10 -0
- package/dist/mjs/evaluator/arithmetic/add/add.mjs +52 -0
- package/dist/mjs/evaluator/arithmetic/add/add.mjs.map +10 -0
- package/dist/mjs/evaluator/arithmetic/divide/divide.mjs +77 -0
- package/dist/mjs/evaluator/arithmetic/divide/divide.mjs.map +10 -0
- package/dist/mjs/evaluator/arithmetic/multiply/multiply.mjs +63 -0
- package/dist/mjs/evaluator/arithmetic/multiply/multiply.mjs.map +10 -0
- package/dist/mjs/evaluator/arithmetic/power/power.mjs +95 -0
- package/dist/mjs/evaluator/arithmetic/power/power.mjs.map +10 -0
- package/dist/mjs/evaluator/arithmetic/subtract/subtract.mjs +54 -0
- package/dist/mjs/evaluator/arithmetic/subtract/subtract.mjs.map +10 -0
- package/dist/mjs/evaluator/comparison/equals.mjs +34 -0
- package/dist/mjs/evaluator/comparison/equals.mjs.map +10 -0
- package/dist/mjs/evaluator/comparison/greater-than-or-equal.mjs +31 -0
- package/dist/mjs/evaluator/comparison/greater-than-or-equal.mjs.map +10 -0
- package/dist/mjs/evaluator/comparison/greater-than.mjs +31 -0
- package/dist/mjs/evaluator/comparison/greater-than.mjs.map +10 -0
- package/dist/mjs/evaluator/comparison/less-than-or-equal.mjs +39 -0
- package/dist/mjs/evaluator/comparison/less-than-or-equal.mjs.map +10 -0
- package/dist/mjs/evaluator/comparison/less-than.mjs +38 -0
- package/dist/mjs/evaluator/comparison/less-than.mjs.map +10 -0
- package/dist/mjs/evaluator/comparison/not-equals.mjs +23 -0
- package/dist/mjs/evaluator/comparison/not-equals.mjs.map +10 -0
- package/dist/mjs/evaluator/concatenation/concatenate.mjs +42 -0
- package/dist/mjs/evaluator/concatenation/concatenate.mjs.map +10 -0
- package/dist/mjs/evaluator/dependency-nodes/ast-evaluation-node.mjs +28 -0
- package/dist/mjs/evaluator/dependency-nodes/ast-evaluation-node.mjs.map +10 -0
- package/dist/mjs/evaluator/dependency-nodes/base-eval-node.mjs +81 -0
- package/dist/mjs/evaluator/dependency-nodes/base-eval-node.mjs.map +10 -0
- package/dist/mjs/evaluator/dependency-nodes/cell-value-node.mjs +24 -0
- package/dist/mjs/evaluator/dependency-nodes/cell-value-node.mjs.map +10 -0
- package/dist/mjs/evaluator/dependency-nodes/empty-cell-evaluation-node.mjs +78 -0
- package/dist/mjs/evaluator/dependency-nodes/empty-cell-evaluation-node.mjs.map +10 -0
- package/dist/mjs/evaluator/dependency-nodes/spill-meta-node.mjs +20 -0
- package/dist/mjs/evaluator/dependency-nodes/spill-meta-node.mjs.map +10 -0
- package/dist/mjs/evaluator/evaluate-scalar-operator.mjs +226 -0
- package/dist/mjs/evaluator/evaluate-scalar-operator.mjs.map +10 -0
- package/dist/mjs/evaluator/evaluation-context.mjs +123 -0
- package/dist/mjs/evaluator/evaluation-context.mjs.map +10 -0
- package/dist/mjs/evaluator/evaluation-error.mjs +44 -0
- package/dist/mjs/evaluator/evaluation-error.mjs.map +10 -0
- package/dist/mjs/evaluator/formula-evaluator.mjs +780 -0
- package/dist/mjs/evaluator/formula-evaluator.mjs.map +10 -0
- package/dist/mjs/evaluator/range-evaluation-node.mjs +58 -0
- package/dist/mjs/evaluator/range-evaluation-node.mjs.map +10 -0
- package/dist/mjs/functions/_template/template.mjs +12 -0
- package/dist/mjs/functions/_template/template.mjs.map +10 -0
- package/dist/mjs/functions/array/sequence/sequence.mjs +287 -0
- package/dist/mjs/functions/array/sequence/sequence.mjs.map +10 -0
- package/dist/mjs/functions/criteria-parser.mjs +187 -0
- package/dist/mjs/functions/criteria-parser.mjs.map +10 -0
- package/dist/mjs/functions/criteria-utils.mjs +268 -0
- package/dist/mjs/functions/criteria-utils.mjs.map +10 -0
- package/dist/mjs/functions/function-utils.mjs +33 -0
- package/dist/mjs/functions/function-utils.mjs.map +10 -0
- package/dist/mjs/functions/index.mjs +95 -0
- package/dist/mjs/functions/index.mjs.map +10 -0
- package/dist/mjs/functions/information/cell/cell.mjs +168 -0
- package/dist/mjs/functions/information/cell/cell.mjs.map +10 -0
- package/dist/mjs/functions/information/column/column.mjs +120 -0
- package/dist/mjs/functions/information/column/column.mjs.map +10 -0
- package/dist/mjs/functions/information/row/row.mjs +126 -0
- package/dist/mjs/functions/information/row/row.mjs.map +10 -0
- package/dist/mjs/functions/logical/and/and.mjs +84 -0
- package/dist/mjs/functions/logical/and/and.mjs.map +10 -0
- package/dist/mjs/functions/logical/if/if.mjs +167 -0
- package/dist/mjs/functions/logical/if/if.mjs.map +10 -0
- package/dist/mjs/functions/logical/iferror/iferror.mjs +98 -0
- package/dist/mjs/functions/logical/iferror/iferror.mjs.map +10 -0
- package/dist/mjs/functions/logical/or/or.mjs +84 -0
- package/dist/mjs/functions/logical/or/or.mjs.map +10 -0
- package/dist/mjs/functions/lookup/count/count-utils.mjs +35 -0
- package/dist/mjs/functions/lookup/count/count-utils.mjs.map +10 -0
- package/dist/mjs/functions/lookup/count/count.mjs +18 -0
- package/dist/mjs/functions/lookup/count/count.mjs.map +10 -0
- package/dist/mjs/functions/lookup/count/countif.mjs +68 -0
- package/dist/mjs/functions/lookup/count/countif.mjs.map +10 -0
- package/dist/mjs/functions/lookup/count/countifs.mjs +37 -0
- package/dist/mjs/functions/lookup/count/countifs.mjs.map +10 -0
- package/dist/mjs/functions/lookup/index-lookup/index-lookup.mjs +159 -0
- package/dist/mjs/functions/lookup/index-lookup/index-lookup.mjs.map +10 -0
- package/dist/mjs/functions/lookup/match/match.mjs +140 -0
- package/dist/mjs/functions/lookup/match/match.mjs.map +10 -0
- package/dist/mjs/functions/lookup/xlookup/xlookup.mjs +382 -0
- package/dist/mjs/functions/lookup/xlookup/xlookup.mjs.map +10 -0
- package/dist/mjs/functions/math/average/average-utils.mjs +44 -0
- package/dist/mjs/functions/math/average/average-utils.mjs.map +10 -0
- package/dist/mjs/functions/math/average/average.mjs +18 -0
- package/dist/mjs/functions/math/average/average.mjs.map +10 -0
- package/dist/mjs/functions/math/average/averageif.mjs +58 -0
- package/dist/mjs/functions/math/average/averageif.mjs.map +10 -0
- package/dist/mjs/functions/math/average/averageifs.mjs +35 -0
- package/dist/mjs/functions/math/average/averageifs.mjs.map +10 -0
- package/dist/mjs/functions/math/ceiling/ceiling.mjs +191 -0
- package/dist/mjs/functions/math/ceiling/ceiling.mjs.map +10 -0
- package/dist/mjs/functions/math/max/max-utils.mjs +43 -0
- package/dist/mjs/functions/math/max/max-utils.mjs.map +10 -0
- package/dist/mjs/functions/math/max/max.mjs +18 -0
- package/dist/mjs/functions/math/max/max.mjs.map +10 -0
- package/dist/mjs/functions/math/max/maxif.mjs +58 -0
- package/dist/mjs/functions/math/max/maxif.mjs.map +10 -0
- package/dist/mjs/functions/math/max/maxifs.mjs +35 -0
- package/dist/mjs/functions/math/max/maxifs.mjs.map +10 -0
- package/dist/mjs/functions/math/min/min-utils.mjs +43 -0
- package/dist/mjs/functions/math/min/min-utils.mjs.map +10 -0
- package/dist/mjs/functions/math/min/min.mjs +18 -0
- package/dist/mjs/functions/math/min/min.mjs.map +10 -0
- package/dist/mjs/functions/math/min/minif.mjs +58 -0
- package/dist/mjs/functions/math/min/minif.mjs.map +10 -0
- package/dist/mjs/functions/math/min/minifs.mjs +35 -0
- package/dist/mjs/functions/math/min/minifs.mjs.map +10 -0
- package/dist/mjs/functions/math/sum/sum.mjs +18 -0
- package/dist/mjs/functions/math/sum/sum.mjs.map +10 -0
- package/dist/mjs/functions/math/sum/sumif.mjs +58 -0
- package/dist/mjs/functions/math/sum/sumif.mjs.map +10 -0
- package/dist/mjs/functions/math/sum/sumifs.mjs +34 -0
- package/dist/mjs/functions/math/sum/sumifs.mjs.map +10 -0
- package/dist/mjs/functions/math/sum/summation-utils.mjs +27 -0
- package/dist/mjs/functions/math/sum/summation-utils.mjs.map +10 -0
- package/dist/mjs/functions/reference/address/address.mjs +135 -0
- package/dist/mjs/functions/reference/address/address.mjs.map +10 -0
- package/dist/mjs/functions/reference/indirect/indirect.mjs +74 -0
- package/dist/mjs/functions/reference/indirect/indirect.mjs.map +10 -0
- package/dist/mjs/functions/reference/offset/offset.mjs +205 -0
- package/dist/mjs/functions/reference/offset/offset.mjs.map +10 -0
- package/dist/mjs/functions/text/concatenate/concatenate.mjs +139 -0
- package/dist/mjs/functions/text/concatenate/concatenate.mjs.map +10 -0
- package/dist/mjs/functions/text/exact/exact.mjs +143 -0
- package/dist/mjs/functions/text/exact/exact.mjs.map +10 -0
- package/dist/mjs/functions/text/find/find.mjs +369 -0
- package/dist/mjs/functions/text/find/find.mjs.map +10 -0
- package/dist/mjs/functions/text/left/left.mjs +81 -0
- package/dist/mjs/functions/text/left/left.mjs.map +10 -0
- package/dist/mjs/functions/text/len/len.mjs +91 -0
- package/dist/mjs/functions/text/len/len.mjs.map +10 -0
- package/dist/mjs/functions/text/mid/mid.mjs +75 -0
- package/dist/mjs/functions/text/mid/mid.mjs.map +10 -0
- package/dist/mjs/functions/text/right/right.mjs +143 -0
- package/dist/mjs/functions/text/right/right.mjs.map +10 -0
- package/dist/mjs/functions/text/text-helpers.mjs +151 -0
- package/dist/mjs/functions/text/text-helpers.mjs.map +10 -0
- package/dist/mjs/functions/text/textjoin/textjoin.mjs +145 -0
- package/dist/mjs/functions/text/textjoin/textjoin.mjs.map +10 -0
- package/dist/mjs/package.json +5 -0
- package/dist/mjs/parser/ast.mjs +145 -0
- package/dist/mjs/parser/ast.mjs.map +10 -0
- package/dist/mjs/parser/formatter.mjs +289 -0
- package/dist/mjs/parser/formatter.mjs.map +10 -0
- package/dist/mjs/parser/grammar.mjs +345 -0
- package/dist/mjs/parser/grammar.mjs.map +10 -0
- package/dist/mjs/parser/lexer.mjs +412 -0
- package/dist/mjs/parser/lexer.mjs.map +10 -0
- package/dist/mjs/parser/parser.mjs +1692 -0
- package/dist/mjs/parser/parser.mjs.map +10 -0
- package/dist/mjs/react/hooks.mjs +16 -0
- package/dist/mjs/react/hooks.mjs.map +10 -0
- package/dist/types/core/ast-traverser.d.ts +28 -0
- package/dist/types/core/autofill-utils.d.ts +32 -0
- package/dist/types/core/engine.d.ts +184 -0
- package/dist/types/core/managers/cache-manager.d.ts +14 -0
- package/dist/types/core/managers/dependency-manager.d.ts +147 -0
- package/dist/types/core/managers/dependency-node.d.ts +13 -0
- package/dist/types/core/managers/evaluation-manager.d.ts +30 -0
- package/dist/types/core/managers/event-manager.d.ts +8 -0
- package/dist/types/core/managers/frontier-dependency-manager.d.ts +69 -0
- package/dist/types/core/managers/index.d.ts +7 -0
- package/dist/types/core/managers/isDependencyNode.d.ts +2 -0
- package/dist/types/core/managers/named-expression-manager.d.ts +101 -0
- package/dist/types/core/managers/range-eval-order-builder.d.ts +33 -0
- package/dist/types/core/managers/table-manager.d.ts +84 -0
- package/dist/types/core/managers/workbook-manager.d.ts +136 -0
- package/dist/types/core/map-serializer.d.ts +4 -0
- package/dist/types/core/named-expression-renamer.d.ts +21 -0
- package/dist/types/core/sheet-renamer.d.ts +28 -0
- package/dist/types/core/sheet-utils.d.ts +2 -0
- package/dist/types/core/table-renamer.d.ts +21 -0
- package/dist/types/core/types.d.ts +272 -0
- package/dist/types/core/utils/cell-address-parsing.test.d.ts +1 -0
- package/dist/types/core/utils/range-serializer.d.ts +22 -0
- package/dist/types/core/utils/range-serializer.test.d.ts +1 -0
- package/dist/types/core/utils/spreadsheet-visualizer.d.ts +30 -0
- package/dist/types/core/utils.d.ts +48 -0
- package/dist/types/core/workbook-renamer.d.ts +28 -0
- package/dist/types/debug/flags.d.ts +11 -0
- package/dist/types/evaluator/arithmetic/add/add.d.ts +2 -0
- package/dist/types/evaluator/arithmetic/add/add.test.d.ts +1 -0
- package/dist/types/evaluator/arithmetic/divide/divide.d.ts +2 -0
- package/dist/types/evaluator/arithmetic/divide/divide.test.d.ts +1 -0
- package/dist/types/evaluator/arithmetic/multiply/multiply.d.ts +2 -0
- package/dist/types/evaluator/arithmetic/multiply/multiply.test.d.ts +1 -0
- package/dist/types/evaluator/arithmetic/power/power.d.ts +2 -0
- package/dist/types/evaluator/arithmetic/power/power.test.d.ts +1 -0
- package/dist/types/evaluator/arithmetic/subtract/subtract.d.ts +2 -0
- package/dist/types/evaluator/arithmetic/subtract/subtract.test.d.ts +1 -0
- package/dist/types/evaluator/comparison/comparison-operators.test.d.ts +1 -0
- package/dist/types/evaluator/comparison/equals.d.ts +6 -0
- package/dist/types/evaluator/comparison/greater-than-or-equal.d.ts +6 -0
- package/dist/types/evaluator/comparison/greater-than.d.ts +6 -0
- package/dist/types/evaluator/comparison/less-than-or-equal.d.ts +6 -0
- package/dist/types/evaluator/comparison/less-than.d.ts +6 -0
- package/dist/types/evaluator/comparison/not-equals.d.ts +6 -0
- package/dist/types/evaluator/concatenation/concatenate.d.ts +6 -0
- package/dist/types/evaluator/concatenation/concatenate.test.d.ts +1 -0
- package/dist/types/evaluator/dependency-nodes/ast-evaluation-node.d.ts +12 -0
- package/dist/types/evaluator/dependency-nodes/base-eval-node.d.ts +31 -0
- package/dist/types/evaluator/dependency-nodes/cell-value-node.d.ts +10 -0
- package/dist/types/evaluator/dependency-nodes/empty-cell-evaluation-node.d.ts +17 -0
- package/dist/types/evaluator/dependency-nodes/spill-meta-node.d.ts +7 -0
- package/dist/types/evaluator/evaluate-scalar-operator.d.ts +12 -0
- package/dist/types/evaluator/evaluation-context.d.ts +66 -0
- package/dist/types/evaluator/evaluation-error.d.ts +20 -0
- package/dist/types/evaluator/formula-evaluator.d.ts +67 -0
- package/dist/types/evaluator/open-range-evaluator.test.d.ts +1 -0
- package/dist/types/evaluator/range-evaluation-node.d.ts +16 -0
- package/dist/types/functions/_template/template.d.ts +5 -0
- package/dist/types/functions/_template/template.test.d.ts +1 -0
- package/dist/types/functions/array/sequence/performance-test.d.ts +1 -0
- package/dist/types/functions/array/sequence/sequence.d.ts +14 -0
- package/dist/types/functions/array/sequence/sequence.test.d.ts +1 -0
- package/dist/types/functions/criteria-parser.d.ts +27 -0
- package/dist/types/functions/criteria-utils.d.ts +61 -0
- package/dist/types/functions/function-utils.d.ts +21 -0
- package/dist/types/functions/index.d.ts +2 -0
- package/dist/types/functions/information/cell/cell.d.ts +24 -0
- package/dist/types/functions/information/cell/cell.test.d.ts +1 -0
- package/dist/types/functions/information/column/column.d.ts +14 -0
- package/dist/types/functions/information/column/column.test.d.ts +1 -0
- package/dist/types/functions/information/row/row.d.ts +14 -0
- package/dist/types/functions/information/row/row.test.d.ts +1 -0
- package/dist/types/functions/logical/and/and.d.ts +5 -0
- package/dist/types/functions/logical/and/and.test.d.ts +1 -0
- package/dist/types/functions/logical/if/if.d.ts +5 -0
- package/dist/types/functions/logical/if/if.test.d.ts +1 -0
- package/dist/types/functions/logical/iferror/iferror.d.ts +5 -0
- package/dist/types/functions/logical/iferror/iferror.test.d.ts +1 -0
- package/dist/types/functions/logical/or/or.d.ts +5 -0
- package/dist/types/functions/logical/or/or.test.d.ts +1 -0
- package/dist/types/functions/lookup/count/count-utils.d.ts +14 -0
- package/dist/types/functions/lookup/count/count.d.ts +21 -0
- package/dist/types/functions/lookup/count/count.test.d.ts +1 -0
- package/dist/types/functions/lookup/count/countif.d.ts +26 -0
- package/dist/types/functions/lookup/count/countif.test.d.ts +1 -0
- package/dist/types/functions/lookup/count/countifs.d.ts +21 -0
- package/dist/types/functions/lookup/count/countifs.test.d.ts +1 -0
- package/dist/types/functions/lookup/index-lookup/index-lookup.d.ts +2 -0
- package/dist/types/functions/lookup/index-lookup/index-lookup.test.d.ts +1 -0
- package/dist/types/functions/lookup/match/match.d.ts +2 -0
- package/dist/types/functions/lookup/match/match.test.d.ts +1 -0
- package/dist/types/functions/lookup/xlookup/xlookup.d.ts +2 -0
- package/dist/types/functions/lookup/xlookup/xlookup.test.d.ts +1 -0
- package/dist/types/functions/math/average/average-utils.d.ts +10 -0
- package/dist/types/functions/math/average/average.d.ts +18 -0
- package/dist/types/functions/math/average/average.test.d.ts +1 -0
- package/dist/types/functions/math/average/averageif.d.ts +23 -0
- package/dist/types/functions/math/average/averageif.test.d.ts +1 -0
- package/dist/types/functions/math/average/averageifs.d.ts +21 -0
- package/dist/types/functions/math/average/averageifs.test.d.ts +1 -0
- package/dist/types/functions/math/ceiling/ceiling.d.ts +5 -0
- package/dist/types/functions/math/ceiling/ceiling.test.d.ts +1 -0
- package/dist/types/functions/math/max/max-utils.d.ts +20 -0
- package/dist/types/functions/math/max/max.d.ts +18 -0
- package/dist/types/functions/math/max/max.test.d.ts +1 -0
- package/dist/types/functions/math/max/maxif.d.ts +23 -0
- package/dist/types/functions/math/max/maxif.test.d.ts +1 -0
- package/dist/types/functions/math/max/maxifs.d.ts +21 -0
- package/dist/types/functions/math/max/maxifs.test.d.ts +1 -0
- package/dist/types/functions/math/min/min-utils.d.ts +20 -0
- package/dist/types/functions/math/min/min.d.ts +5 -0
- package/dist/types/functions/math/min/min.test.d.ts +1 -0
- package/dist/types/functions/math/min/minif.d.ts +23 -0
- package/dist/types/functions/math/min/minif.test.d.ts +1 -0
- package/dist/types/functions/math/min/minifs.d.ts +21 -0
- package/dist/types/functions/math/min/minifs.test.d.ts +1 -0
- package/dist/types/functions/math/sum/sum.d.ts +5 -0
- package/dist/types/functions/math/sum/sum.test.d.ts +1 -0
- package/dist/types/functions/math/sum/sumif.d.ts +23 -0
- package/dist/types/functions/math/sum/sumif.test.d.ts +1 -0
- package/dist/types/functions/math/sum/sumifs.d.ts +21 -0
- package/dist/types/functions/math/sum/sumifs.test.d.ts +1 -0
- package/dist/types/functions/math/sum/summation-utils.d.ts +19 -0
- package/dist/types/functions/reference/address/address.d.ts +18 -0
- package/dist/types/functions/reference/address/address.test.d.ts +1 -0
- package/dist/types/functions/reference/indirect/indirect.d.ts +20 -0
- package/dist/types/functions/reference/indirect/indirect.test.d.ts +1 -0
- package/dist/types/functions/reference/offset/offset.d.ts +23 -0
- package/dist/types/functions/reference/offset/offset.test.d.ts +1 -0
- package/dist/types/functions/text/concatenate/concatenate.d.ts +5 -0
- package/dist/types/functions/text/concatenate/concatenate.test.d.ts +1 -0
- package/dist/types/functions/text/exact/exact.d.ts +5 -0
- package/dist/types/functions/text/exact/exact.test.d.ts +1 -0
- package/dist/types/functions/text/find/find.d.ts +20 -0
- package/dist/types/functions/text/find/find.test.d.ts +1 -0
- package/dist/types/functions/text/left/left.d.ts +19 -0
- package/dist/types/functions/text/left/left.test.d.ts +1 -0
- package/dist/types/functions/text/len/len.d.ts +16 -0
- package/dist/types/functions/text/len/len.test.d.ts +1 -0
- package/dist/types/functions/text/mid/mid.d.ts +20 -0
- package/dist/types/functions/text/mid/mid.test.d.ts +1 -0
- package/dist/types/functions/text/right/right.d.ts +2 -0
- package/dist/types/functions/text/right/right.test.d.ts +1 -0
- package/dist/types/functions/text/text-helpers.d.ts +27 -0
- package/dist/types/functions/text/textjoin/textjoin.d.ts +5 -0
- package/dist/types/functions/text/textjoin/textjoin.test.d.ts +1 -0
- package/dist/types/parser/ast.d.ts +275 -0
- package/dist/types/parser/formatter.d.ts +6 -0
- package/dist/types/parser/grammar.d.ts +203 -0
- package/dist/types/parser/lexer.d.ts +144 -0
- package/dist/types/parser/parser.d.ts +159 -0
- package/dist/types/react/hooks.d.ts +5 -0
- package/package.json +41 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
// src/functions/lookup/xlookup/xlookup.ts
|
|
2
|
+
import {
|
|
3
|
+
FormulaError
|
|
4
|
+
} from "src/core/types";
|
|
5
|
+
function compareValues(a, b) {
|
|
6
|
+
if (a.type !== b.type) {
|
|
7
|
+
const typeOrder = { number: 0, string: 1, boolean: 2, infinity: 0 };
|
|
8
|
+
return (typeOrder[a.type] || 3) - (typeOrder[b.type] || 3);
|
|
9
|
+
}
|
|
10
|
+
if (a.type === "number" && b.type === "number") {
|
|
11
|
+
return a.value - b.value;
|
|
12
|
+
}
|
|
13
|
+
if (a.type === "string" && b.type === "string") {
|
|
14
|
+
return a.value.localeCompare(b.value);
|
|
15
|
+
}
|
|
16
|
+
if (a.type === "boolean" && b.type === "boolean") {
|
|
17
|
+
return (a.value ? 1 : 0) - (b.value ? 1 : 0);
|
|
18
|
+
}
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
function valuesMatch(a, b) {
|
|
22
|
+
if (a.type !== b.type)
|
|
23
|
+
return false;
|
|
24
|
+
if (a.type === "number" && b.type === "number") {
|
|
25
|
+
return a.value === b.value;
|
|
26
|
+
}
|
|
27
|
+
if (a.type === "string" && b.type === "string") {
|
|
28
|
+
return a.value === b.value;
|
|
29
|
+
}
|
|
30
|
+
if (a.type === "boolean" && b.type === "boolean") {
|
|
31
|
+
return a.value === b.value;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
function wildcardMatch(pattern, text) {
|
|
36
|
+
let regex = "";
|
|
37
|
+
let i = 0;
|
|
38
|
+
while (i < pattern.length) {
|
|
39
|
+
const char = pattern[i];
|
|
40
|
+
if (!char)
|
|
41
|
+
break;
|
|
42
|
+
if (char === "~" && i + 1 < pattern.length) {
|
|
43
|
+
const nextChar = pattern[i + 1];
|
|
44
|
+
if (nextChar) {
|
|
45
|
+
regex += nextChar.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
46
|
+
}
|
|
47
|
+
i += 2;
|
|
48
|
+
} else if (char === "*") {
|
|
49
|
+
regex += ".*";
|
|
50
|
+
i++;
|
|
51
|
+
} else if (char === "?") {
|
|
52
|
+
regex += ".";
|
|
53
|
+
i++;
|
|
54
|
+
} else {
|
|
55
|
+
regex += char.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
56
|
+
i++;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const re = new RegExp(`^${regex}$`, "i");
|
|
61
|
+
return re.test(text);
|
|
62
|
+
} catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function xlookupOperation(lookupValue, lookupArray, returnArray, ifNotFound, hasIfNotFound, matchMode, searchMode, context) {
|
|
67
|
+
if (![0, -1, 1, 2].includes(matchMode)) {
|
|
68
|
+
return {
|
|
69
|
+
type: "error",
|
|
70
|
+
err: FormulaError.VALUE,
|
|
71
|
+
errAddress: context.dependencyNode,
|
|
72
|
+
message: `XLOOKUP match_mode must be -1, 0, 1, or 2, got ${matchMode}`
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (![1, -1, 2, -2].includes(searchMode)) {
|
|
76
|
+
return {
|
|
77
|
+
type: "error",
|
|
78
|
+
err: FormulaError.VALUE,
|
|
79
|
+
errAddress: context.dependencyNode,
|
|
80
|
+
message: `XLOOKUP search_mode must be 1, -1, 2, or -2, got ${searchMode}`
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (lookupArray.type !== "values") {
|
|
84
|
+
return lookupArray;
|
|
85
|
+
}
|
|
86
|
+
if (returnArray.type !== "values") {
|
|
87
|
+
return returnArray;
|
|
88
|
+
}
|
|
89
|
+
if (lookupArray.values.length !== returnArray.values.length) {
|
|
90
|
+
return {
|
|
91
|
+
type: "error",
|
|
92
|
+
err: FormulaError.VALUE,
|
|
93
|
+
errAddress: context.dependencyNode,
|
|
94
|
+
message: "XLOOKUP lookup_array and return_array must have same dimensions"
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
if (lookupArray.values.length === 0) {
|
|
98
|
+
return {
|
|
99
|
+
type: "error",
|
|
100
|
+
err: FormulaError.VALUE,
|
|
101
|
+
errAddress: context.dependencyNode,
|
|
102
|
+
message: "XLOOKUP lookup_array cannot be empty"
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (searchMode === 2 || searchMode === -2) {
|
|
106
|
+
return {
|
|
107
|
+
type: "error",
|
|
108
|
+
err: FormulaError.VALUE,
|
|
109
|
+
errAddress: context.dependencyNode,
|
|
110
|
+
message: "XLOOKUP binary search mode not yet implemented"
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const searchArray = searchMode === -1 ? [...lookupArray.values].reverse() : lookupArray.values;
|
|
114
|
+
const searchReturnArray = searchMode === -1 ? [...returnArray.values].reverse() : returnArray.values;
|
|
115
|
+
let bestMatchIndex = -1;
|
|
116
|
+
let bestMatchValue = null;
|
|
117
|
+
for (let i = 0;i < searchArray.length; i++) {
|
|
118
|
+
const item = searchArray[i];
|
|
119
|
+
if (!item || item.result.type !== "value")
|
|
120
|
+
continue;
|
|
121
|
+
const arrayValue = item.result.result;
|
|
122
|
+
if (matchMode === 0) {
|
|
123
|
+
if (valuesMatch(lookupValue, arrayValue)) {
|
|
124
|
+
const returnItem = searchReturnArray[i];
|
|
125
|
+
if (!returnItem)
|
|
126
|
+
continue;
|
|
127
|
+
if (returnItem.result.type === "value") {
|
|
128
|
+
return {
|
|
129
|
+
type: "value",
|
|
130
|
+
result: returnItem.result.result
|
|
131
|
+
};
|
|
132
|
+
} else if (returnItem.result.type === "error") {
|
|
133
|
+
return returnItem.result;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
} else if (matchMode === 2) {
|
|
137
|
+
if (lookupValue.type === "string" && arrayValue.type === "string") {
|
|
138
|
+
if (wildcardMatch(lookupValue.value, arrayValue.value)) {
|
|
139
|
+
const returnItem = searchReturnArray[i];
|
|
140
|
+
if (!returnItem)
|
|
141
|
+
continue;
|
|
142
|
+
if (returnItem.result.type === "value") {
|
|
143
|
+
return {
|
|
144
|
+
type: "value",
|
|
145
|
+
result: returnItem.result.result
|
|
146
|
+
};
|
|
147
|
+
} else if (returnItem.result.type === "error") {
|
|
148
|
+
return returnItem.result;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
} else if (matchMode === -1) {
|
|
153
|
+
const cmp = compareValues(arrayValue, lookupValue);
|
|
154
|
+
if (cmp === 0) {
|
|
155
|
+
const returnItem = searchReturnArray[i];
|
|
156
|
+
if (!returnItem)
|
|
157
|
+
continue;
|
|
158
|
+
if (returnItem.result.type === "value") {
|
|
159
|
+
return {
|
|
160
|
+
type: "value",
|
|
161
|
+
result: returnItem.result.result
|
|
162
|
+
};
|
|
163
|
+
} else if (returnItem.result.type === "error") {
|
|
164
|
+
return returnItem.result;
|
|
165
|
+
}
|
|
166
|
+
} else if (cmp < 0) {
|
|
167
|
+
if (bestMatchValue === null || compareValues(arrayValue, bestMatchValue) > 0) {
|
|
168
|
+
bestMatchIndex = i;
|
|
169
|
+
bestMatchValue = arrayValue;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
} else if (matchMode === 1) {
|
|
173
|
+
const cmp = compareValues(arrayValue, lookupValue);
|
|
174
|
+
if (cmp === 0) {
|
|
175
|
+
const returnItem = searchReturnArray[i];
|
|
176
|
+
if (!returnItem)
|
|
177
|
+
continue;
|
|
178
|
+
if (returnItem.result.type === "value") {
|
|
179
|
+
return {
|
|
180
|
+
type: "value",
|
|
181
|
+
result: returnItem.result.result
|
|
182
|
+
};
|
|
183
|
+
} else if (returnItem.result.type === "error") {
|
|
184
|
+
return returnItem.result;
|
|
185
|
+
}
|
|
186
|
+
} else if (cmp > 0) {
|
|
187
|
+
if (bestMatchValue === null || compareValues(arrayValue, bestMatchValue) < 0) {
|
|
188
|
+
bestMatchIndex = i;
|
|
189
|
+
bestMatchValue = arrayValue;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (bestMatchIndex !== -1) {
|
|
195
|
+
const returnItem = searchReturnArray[bestMatchIndex];
|
|
196
|
+
if (returnItem && returnItem.result.type === "value") {
|
|
197
|
+
return {
|
|
198
|
+
type: "value",
|
|
199
|
+
result: returnItem.result.result
|
|
200
|
+
};
|
|
201
|
+
} else if (returnItem && returnItem.result.type === "error") {
|
|
202
|
+
return returnItem.result;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (hasIfNotFound && ifNotFound !== null) {
|
|
206
|
+
return {
|
|
207
|
+
type: "value",
|
|
208
|
+
result: ifNotFound
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
type: "error",
|
|
213
|
+
err: FormulaError.NA,
|
|
214
|
+
errAddress: context.dependencyNode,
|
|
215
|
+
message: "XLOOKUP: lookup_value not found"
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
var XLOOKUP = {
|
|
219
|
+
name: "XLOOKUP",
|
|
220
|
+
evaluate: function(node, context) {
|
|
221
|
+
if (node.args.length < 3 || node.args.length > 6) {
|
|
222
|
+
return {
|
|
223
|
+
type: "error",
|
|
224
|
+
err: FormulaError.VALUE,
|
|
225
|
+
errAddress: context.dependencyNode,
|
|
226
|
+
message: "XLOOKUP function takes 3 to 6 arguments"
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
const lookupValueResult = this.evaluateNode(node.args[0], context);
|
|
230
|
+
if (lookupValueResult.type === "error") {
|
|
231
|
+
return lookupValueResult;
|
|
232
|
+
}
|
|
233
|
+
const lookupArrayResult = this.evaluateNode(node.args[1], context);
|
|
234
|
+
if (lookupArrayResult.type === "error") {
|
|
235
|
+
return lookupArrayResult;
|
|
236
|
+
}
|
|
237
|
+
const returnArrayResult = this.evaluateNode(node.args[2], context);
|
|
238
|
+
if (returnArrayResult.type === "error") {
|
|
239
|
+
return returnArrayResult;
|
|
240
|
+
}
|
|
241
|
+
let ifNotFoundResult = null;
|
|
242
|
+
if (node.args[3]) {
|
|
243
|
+
ifNotFoundResult = this.evaluateNode(node.args[3], context);
|
|
244
|
+
if (ifNotFoundResult.type === "error") {
|
|
245
|
+
return ifNotFoundResult;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
let matchModeResult = {
|
|
249
|
+
type: "value",
|
|
250
|
+
result: { type: "number", value: 0 }
|
|
251
|
+
};
|
|
252
|
+
if (node.args[4]) {
|
|
253
|
+
matchModeResult = this.evaluateNode(node.args[4], context);
|
|
254
|
+
if (matchModeResult.type === "error") {
|
|
255
|
+
return matchModeResult;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
let searchModeResult = {
|
|
259
|
+
type: "value",
|
|
260
|
+
result: { type: "number", value: 1 }
|
|
261
|
+
};
|
|
262
|
+
if (node.args[5]) {
|
|
263
|
+
searchModeResult = this.evaluateNode(node.args[5], context);
|
|
264
|
+
if (searchModeResult.type === "error") {
|
|
265
|
+
return searchModeResult;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (lookupValueResult.type === "spilled-values" || ifNotFoundResult && ifNotFoundResult.type === "spilled-values" || matchModeResult.type === "spilled-values" || searchModeResult.type === "spilled-values") {
|
|
269
|
+
return {
|
|
270
|
+
type: "error",
|
|
271
|
+
err: FormulaError.VALUE,
|
|
272
|
+
errAddress: context.dependencyNode,
|
|
273
|
+
message: "XLOOKUP: Spilled array arguments not yet supported"
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
if (lookupValueResult.type !== "value") {
|
|
277
|
+
return {
|
|
278
|
+
type: "error",
|
|
279
|
+
err: FormulaError.VALUE,
|
|
280
|
+
errAddress: context.dependencyNode,
|
|
281
|
+
message: "XLOOKUP: Invalid lookup_value result type"
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
if (matchModeResult.type !== "value") {
|
|
285
|
+
return {
|
|
286
|
+
type: "error",
|
|
287
|
+
err: FormulaError.VALUE,
|
|
288
|
+
errAddress: context.dependencyNode,
|
|
289
|
+
message: "XLOOKUP: Invalid match_mode result type"
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
if (searchModeResult.type !== "value") {
|
|
293
|
+
return {
|
|
294
|
+
type: "error",
|
|
295
|
+
err: FormulaError.VALUE,
|
|
296
|
+
errAddress: context.dependencyNode,
|
|
297
|
+
message: "XLOOKUP: Invalid search_mode result type"
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
if (matchModeResult.result.type !== "number") {
|
|
301
|
+
return {
|
|
302
|
+
type: "error",
|
|
303
|
+
err: FormulaError.VALUE,
|
|
304
|
+
errAddress: context.dependencyNode,
|
|
305
|
+
message: `XLOOKUP match_mode must be number, got ${matchModeResult.result.type}`
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
if (searchModeResult.result.type !== "number") {
|
|
309
|
+
return {
|
|
310
|
+
type: "error",
|
|
311
|
+
err: FormulaError.VALUE,
|
|
312
|
+
errAddress: context.dependencyNode,
|
|
313
|
+
message: `XLOOKUP search_mode must be number, got ${searchModeResult.result.type}`
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
let ifNotFound = null;
|
|
317
|
+
const hasIfNotFound = !!ifNotFoundResult;
|
|
318
|
+
if (ifNotFoundResult && ifNotFoundResult.type === "value") {
|
|
319
|
+
ifNotFound = ifNotFoundResult.result;
|
|
320
|
+
}
|
|
321
|
+
const matchMode = Math.floor(matchModeResult.result.value);
|
|
322
|
+
const searchMode = Math.floor(searchModeResult.result.value);
|
|
323
|
+
let lookupArray = {
|
|
324
|
+
type: "error",
|
|
325
|
+
err: FormulaError.VALUE,
|
|
326
|
+
errAddress: context.dependencyNode,
|
|
327
|
+
message: "XLOOKUP: Invalid lookup_array type"
|
|
328
|
+
};
|
|
329
|
+
if (lookupArrayResult.type === "value") {
|
|
330
|
+
lookupArray = {
|
|
331
|
+
type: "values",
|
|
332
|
+
values: [{ result: lookupArrayResult, relativePos: { x: 0, y: 0 } }]
|
|
333
|
+
};
|
|
334
|
+
} else if (lookupArrayResult.type === "spilled-values") {
|
|
335
|
+
lookupArray = lookupArrayResult.evaluateAllCells.call(this, {
|
|
336
|
+
context,
|
|
337
|
+
evaluate: lookupArrayResult.evaluate,
|
|
338
|
+
origin: context.cellAddress,
|
|
339
|
+
lookupOrder: "col-major"
|
|
340
|
+
});
|
|
341
|
+
} else {
|
|
342
|
+
return {
|
|
343
|
+
type: "error",
|
|
344
|
+
err: FormulaError.VALUE,
|
|
345
|
+
errAddress: context.dependencyNode,
|
|
346
|
+
message: "XLOOKUP: Invalid lookup_array type"
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
let returnArray = {
|
|
350
|
+
type: "error",
|
|
351
|
+
err: FormulaError.VALUE,
|
|
352
|
+
errAddress: context.dependencyNode,
|
|
353
|
+
message: "XLOOKUP: Invalid return_array type"
|
|
354
|
+
};
|
|
355
|
+
if (returnArrayResult.type === "value") {
|
|
356
|
+
returnArray = {
|
|
357
|
+
type: "values",
|
|
358
|
+
values: [{ result: returnArrayResult, relativePos: { x: 0, y: 0 } }]
|
|
359
|
+
};
|
|
360
|
+
} else if (returnArrayResult.type === "spilled-values") {
|
|
361
|
+
returnArray = returnArrayResult.evaluateAllCells.call(this, {
|
|
362
|
+
context,
|
|
363
|
+
evaluate: returnArrayResult.evaluate,
|
|
364
|
+
origin: context.cellAddress,
|
|
365
|
+
lookupOrder: "col-major"
|
|
366
|
+
});
|
|
367
|
+
} else {
|
|
368
|
+
return {
|
|
369
|
+
type: "error",
|
|
370
|
+
err: FormulaError.VALUE,
|
|
371
|
+
errAddress: context.dependencyNode,
|
|
372
|
+
message: "XLOOKUP: Invalid return_array type"
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
return xlookupOperation.call(this, lookupValueResult.result, lookupArray, returnArray, ifNotFound, hasIfNotFound, matchMode, searchMode, context);
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
export {
|
|
379
|
+
XLOOKUP
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
//# debugId=F246D0507C9ABA1B64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/functions/lookup/xlookup/xlookup.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n FormulaError,\n type CellValue,\n type CellNumber,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n type ValueEvaluationResult,\n type CellAddress,\n type SpreadsheetRange,\n type SpilledValuesEvaluationResult,\n type SingleEvaluationResult,\n type CellInRangeResult,\n type EvaluateAllCellsResult,\n} from \"src/core/types\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\nimport type { FormulaEvaluator } from \"src/evaluator/formula-evaluator\";\n\n/**\n * XLOOKUP function - Searches for a value and returns a corresponding value from another array\n * XLOOKUP(lookup_value, lookup_array, return_array, [if_not_found], [match_mode], [search_mode])\n *\n * Parameters:\n * - lookup_value: The value to search for (any type)\n * - lookup_array: The array or range to search\n * - return_array: The array or range to return values from\n * - if_not_found: Optional value to return when no match is found (default: #N/A)\n * - match_mode: Optional integer specifying match type (default: 0)\n * - 0: Exact match; if none, return #N/A\n * - -1: Exact match; if none, return next smaller item\n * - 1: Exact match; if none, return next larger item\n * - 2: Wildcard match (*, ?, ~)\n * - search_mode: Optional integer specifying search direction (default: 1)\n * - 1: Search from first item (forward)\n * - -1: Search from last item (reverse)\n * - 2: Binary search (ascending order required)\n * - -2: Binary search (descending order required)\n */\n\n// Helper to compare values for XLOOKUP\nfunction compareValues(a: CellValue, b: CellValue): number {\n // Handle different type comparisons\n if (a.type !== b.type) {\n // Numbers < Strings < Booleans in Excel comparison order\n const typeOrder = { number: 0, string: 1, boolean: 2, infinity: 0 };\n return (typeOrder[a.type] || 3) - (typeOrder[b.type] || 3);\n }\n\n // Same type comparison\n if (a.type === \"number\" && b.type === \"number\") {\n return a.value - b.value;\n }\n if (a.type === \"string\" && b.type === \"string\") {\n return a.value.localeCompare(b.value);\n }\n if (a.type === \"boolean\" && b.type === \"boolean\") {\n return (a.value ? 1 : 0) - (b.value ? 1 : 0);\n }\n\n return 0;\n}\n\n// Helper to check if values match (exact match)\nfunction valuesMatch(a: CellValue, b: CellValue): boolean {\n if (a.type !== b.type) return false;\n if (a.type === \"number\" && b.type === \"number\") {\n return a.value === b.value;\n }\n if (a.type === \"string\" && b.type === \"string\") {\n return a.value === b.value;\n }\n if (a.type === \"boolean\" && b.type === \"boolean\") {\n return a.value === b.value;\n }\n return false;\n}\n\n// Helper to check wildcard match\nfunction wildcardMatch(pattern: string, text: string): boolean {\n // Convert wildcard pattern to regex\n // ~ is escape character, * matches any sequence, ? matches single char\n let regex = \"\";\n let i = 0;\n while (i < pattern.length) {\n const char = pattern[i];\n if (!char) break;\n\n if (char === \"~\" && i + 1 < pattern.length) {\n // Escape next character\n const nextChar = pattern[i + 1];\n if (nextChar) {\n regex += nextChar.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n }\n i += 2;\n } else if (char === \"*\") {\n regex += \".*\";\n i++;\n } else if (char === \"?\") {\n regex += \".\";\n i++;\n } else {\n regex += char.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n i++;\n }\n }\n\n try {\n const re = new RegExp(`^${regex}$`, \"i\"); // Case-insensitive\n return re.test(text);\n } catch {\n return false;\n }\n}\n\n// Helper function to perform XLOOKUP operation\nfunction xlookupOperation(\n this: FormulaEvaluator,\n lookupValue: CellValue,\n lookupArray: EvaluateAllCellsResult,\n returnArray: EvaluateAllCellsResult,\n ifNotFound: CellValue | null,\n hasIfNotFound: boolean,\n matchMode: number,\n searchMode: number,\n context: EvaluationContext\n): FunctionEvaluationResult {\n // Validate match_mode\n if (![0, -1, 1, 2].includes(matchMode)) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: `XLOOKUP match_mode must be -1, 0, 1, or 2, got ${matchMode}`,\n };\n }\n\n // Validate search_mode\n if (![1, -1, 2, -2].includes(searchMode)) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: `XLOOKUP search_mode must be 1, -1, 2, or -2, got ${searchMode}`,\n };\n }\n\n if (lookupArray.type !== \"values\") {\n return lookupArray;\n }\n if (returnArray.type !== \"values\") {\n return returnArray;\n }\n\n // Check arrays have same length\n if (lookupArray.values.length !== returnArray.values.length) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message:\n \"XLOOKUP lookup_array and return_array must have same dimensions\",\n };\n }\n\n if (lookupArray.values.length === 0) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP lookup_array cannot be empty\",\n };\n }\n\n // Binary search modes (not yet implemented)\n if (searchMode === 2 || searchMode === -2) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP binary search mode not yet implemented\",\n };\n }\n\n // Determine search order\n const searchArray =\n searchMode === -1 ? [...lookupArray.values].reverse() : lookupArray.values;\n const searchReturnArray =\n searchMode === -1 ? [...returnArray.values].reverse() : returnArray.values;\n\n let bestMatchIndex = -1;\n let bestMatchValue: CellValue | null = null;\n\n // Search through the array\n for (let i = 0; i < searchArray.length; i++) {\n const item = searchArray[i];\n if (!item || item.result.type !== \"value\") continue;\n\n const arrayValue = item.result.result;\n\n // Match mode 0: Exact match\n if (matchMode === 0) {\n if (valuesMatch(lookupValue, arrayValue)) {\n const returnItem = searchReturnArray[i];\n if (!returnItem) continue;\n\n if (returnItem.result.type === \"value\") {\n return {\n type: \"value\",\n result: returnItem.result.result,\n };\n } else if (returnItem.result.type === \"error\") {\n return returnItem.result;\n }\n }\n }\n // Match mode 2: Wildcard match\n else if (matchMode === 2) {\n if (lookupValue.type === \"string\" && arrayValue.type === \"string\") {\n if (wildcardMatch(lookupValue.value, arrayValue.value)) {\n const returnItem = searchReturnArray[i];\n if (!returnItem) continue;\n\n if (returnItem.result.type === \"value\") {\n return {\n type: \"value\",\n result: returnItem.result.result,\n };\n } else if (returnItem.result.type === \"error\") {\n return returnItem.result;\n }\n }\n }\n }\n // Match mode -1: Exact or next smaller\n else if (matchMode === -1) {\n const cmp = compareValues(arrayValue, lookupValue);\n if (cmp === 0) {\n // Exact match found\n const returnItem = searchReturnArray[i];\n if (!returnItem) continue;\n\n if (returnItem.result.type === \"value\") {\n return {\n type: \"value\",\n result: returnItem.result.result,\n };\n } else if (returnItem.result.type === \"error\") {\n return returnItem.result;\n }\n } else if (cmp < 0) {\n // arrayValue < lookupValue\n if (\n bestMatchValue === null ||\n compareValues(arrayValue, bestMatchValue) > 0\n ) {\n bestMatchIndex = i;\n bestMatchValue = arrayValue;\n }\n }\n }\n // Match mode 1: Exact or next larger\n else if (matchMode === 1) {\n const cmp = compareValues(arrayValue, lookupValue);\n if (cmp === 0) {\n // Exact match found\n const returnItem = searchReturnArray[i];\n if (!returnItem) continue;\n\n if (returnItem.result.type === \"value\") {\n return {\n type: \"value\",\n result: returnItem.result.result,\n };\n } else if (returnItem.result.type === \"error\") {\n return returnItem.result;\n }\n } else if (cmp > 0) {\n // arrayValue > lookupValue\n if (\n bestMatchValue === null ||\n compareValues(arrayValue, bestMatchValue) < 0\n ) {\n bestMatchIndex = i;\n bestMatchValue = arrayValue;\n }\n }\n }\n }\n\n // Check if we found an approximate match\n if (bestMatchIndex !== -1) {\n const returnItem = searchReturnArray[bestMatchIndex];\n if (returnItem && returnItem.result.type === \"value\") {\n return {\n type: \"value\",\n result: returnItem.result.result,\n };\n } else if (returnItem && returnItem.result.type === \"error\") {\n return returnItem.result;\n }\n }\n\n // No match found - return if_not_found or #N/A\n if (hasIfNotFound && ifNotFound !== null) {\n return {\n type: \"value\",\n result: ifNotFound,\n };\n }\n\n return {\n type: \"error\",\n err: FormulaError.NA,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP: lookup_value not found\",\n };\n}\n\nexport const XLOOKUP: FunctionDefinition = {\n name: \"XLOOKUP\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length < 3 || node.args.length > 6) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP function takes 3 to 6 arguments\",\n };\n }\n\n // Evaluate lookup_value\n const lookupValueResult = this.evaluateNode(node.args[0]!, context);\n if (lookupValueResult.type === \"error\") {\n return lookupValueResult;\n }\n\n // Evaluate lookup_array\n const lookupArrayResult = this.evaluateNode(node.args[1]!, context);\n if (lookupArrayResult.type === \"error\") {\n return lookupArrayResult;\n }\n\n // Evaluate return_array\n const returnArrayResult = this.evaluateNode(node.args[2]!, context);\n if (returnArrayResult.type === \"error\") {\n return returnArrayResult;\n }\n\n // Evaluate if_not_found (optional)\n let ifNotFoundResult: FunctionEvaluationResult | null = null;\n if (node.args[3]) {\n ifNotFoundResult = this.evaluateNode(node.args[3], context);\n if (ifNotFoundResult.type === \"error\") {\n return ifNotFoundResult;\n }\n }\n\n // Evaluate match_mode (optional, defaults to 0)\n let matchModeResult: FunctionEvaluationResult = {\n type: \"value\",\n result: { type: \"number\", value: 0 },\n };\n if (node.args[4]) {\n matchModeResult = this.evaluateNode(node.args[4], context);\n if (matchModeResult.type === \"error\") {\n return matchModeResult;\n }\n }\n\n // Evaluate search_mode (optional, defaults to 1)\n let searchModeResult: FunctionEvaluationResult = {\n type: \"value\",\n result: { type: \"number\", value: 1 },\n };\n if (node.args[5]) {\n searchModeResult = this.evaluateNode(node.args[5], context);\n if (searchModeResult.type === \"error\") {\n return searchModeResult;\n }\n }\n\n // Handle spilled arrays for simple arguments\n if (\n lookupValueResult.type === \"spilled-values\" ||\n (ifNotFoundResult && ifNotFoundResult.type === \"spilled-values\") ||\n matchModeResult.type === \"spilled-values\" ||\n searchModeResult.type === \"spilled-values\"\n ) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP: Spilled array arguments not yet supported\",\n };\n }\n\n // Validate result types\n if (lookupValueResult.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP: Invalid lookup_value result type\",\n };\n }\n\n if (matchModeResult.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP: Invalid match_mode result type\",\n };\n }\n\n if (searchModeResult.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP: Invalid search_mode result type\",\n };\n }\n\n // Type check match_mode\n if (matchModeResult.result.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: `XLOOKUP match_mode must be number, got ${matchModeResult.result.type}`,\n };\n }\n\n // Type check search_mode\n if (searchModeResult.result.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: `XLOOKUP search_mode must be number, got ${searchModeResult.result.type}`,\n };\n }\n\n // Extract if_not_found value\n let ifNotFound: CellValue | null = null;\n const hasIfNotFound = !!ifNotFoundResult;\n if (ifNotFoundResult && ifNotFoundResult.type === \"value\") {\n ifNotFound = ifNotFoundResult.result;\n }\n\n // Extract match_mode and search_mode as integers\n const matchMode = Math.floor(matchModeResult.result.value);\n const searchMode = Math.floor(searchModeResult.result.value);\n\n // Extract lookup_array values\n let lookupArray: EvaluateAllCellsResult = {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP: Invalid lookup_array type\",\n };\n if (lookupArrayResult.type === \"value\") {\n lookupArray = {\n type: \"values\",\n values: [{ result: lookupArrayResult, relativePos: { x: 0, y: 0 } }],\n };\n } else if (lookupArrayResult.type === \"spilled-values\") {\n lookupArray = lookupArrayResult.evaluateAllCells.call(this, {\n context,\n evaluate: lookupArrayResult.evaluate,\n origin: context.cellAddress,\n lookupOrder: \"col-major\",\n });\n } else {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP: Invalid lookup_array type\",\n };\n }\n\n // Extract return_array values\n let returnArray: EvaluateAllCellsResult = {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP: Invalid return_array type\",\n };\n if (returnArrayResult.type === \"value\") {\n returnArray = {\n type: \"values\",\n values: [{ result: returnArrayResult, relativePos: { x: 0, y: 0 } }],\n };\n } else if (returnArrayResult.type === \"spilled-values\") {\n returnArray = returnArrayResult.evaluateAllCells.call(this, {\n context,\n evaluate: returnArrayResult.evaluate,\n origin: context.cellAddress,\n lookupOrder: \"col-major\",\n });\n } else {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n errAddress: context.dependencyNode,\n message: \"XLOOKUP: Invalid return_array type\",\n };\n }\n\n // Perform XLOOKUP operation\n return xlookupOperation.call(\n this,\n lookupValueResult.result,\n lookupArray,\n returnArray,\n ifNotFound,\n hasIfNotFound,\n matchMode,\n searchMode,\n context\n );\n },\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "F246D0507C9ABA1B64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// src/functions/math/average/average-utils.ts
|
|
2
|
+
import {
|
|
3
|
+
FormulaError
|
|
4
|
+
} from "src/core/types";
|
|
5
|
+
function performAverage(results, context) {
|
|
6
|
+
let sum = 0;
|
|
7
|
+
let count = 0;
|
|
8
|
+
for (const result of results) {
|
|
9
|
+
if (result.type === "error") {
|
|
10
|
+
return result;
|
|
11
|
+
}
|
|
12
|
+
if (result.type === "awaiting-evaluation") {
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
if (result.type === "value") {
|
|
16
|
+
if (result.result.type === "number") {
|
|
17
|
+
sum += result.result.value;
|
|
18
|
+
count++;
|
|
19
|
+
} else if (result.result.type === "infinity") {
|
|
20
|
+
return {
|
|
21
|
+
type: "value",
|
|
22
|
+
result: result.result
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (count === 0) {
|
|
28
|
+
return {
|
|
29
|
+
type: "error",
|
|
30
|
+
err: FormulaError.DIV0,
|
|
31
|
+
message: "Cannot calculate average of empty range",
|
|
32
|
+
errAddress: context.dependencyNode
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
type: "value",
|
|
37
|
+
result: { type: "number", value: sum / count }
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
performAverage
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
//# debugId=A2F15D16FE74F8C164756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/functions/math/average/average-utils.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n FormulaError,\n type FunctionEvaluationResult,\n type SingleEvaluationResult,\n} from \"src/core/types\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\n\n/**\n * Performs averaging of an iterable of SingleEvaluationResult values\n * Handles numbers, infinities, and errors according to Excel's AVERAGE behavior\n *\n * @param results - Iterable of SingleEvaluationResult to average\n * @returns FunctionEvaluationResult with the average or appropriate error\n */\nexport function performAverage(\n results: SingleEvaluationResult[],\n context: EvaluationContext\n): FunctionEvaluationResult {\n let sum = 0;\n let count = 0;\n\n for (const result of results) {\n if (result.type === \"error\") {\n // Propagate errors immediately\n return result;\n }\n if (result.type === \"awaiting-evaluation\") {\n return result;\n }\n\n if (result.type === \"value\") {\n if (result.result.type === \"number\") {\n sum += result.result.value;\n count++;\n } else if (result.result.type === \"infinity\") {\n // Infinity dominates - return immediately\n return {\n type: \"value\",\n result: result.result,\n };\n }\n // Non-numeric values (strings, booleans) are ignored\n }\n }\n\n if (count === 0) {\n return {\n type: \"error\",\n err: FormulaError.DIV0,\n message: \"Cannot calculate average of empty range\",\n errAddress: context.dependencyNode,\n };\n }\n\n return {\n type: \"value\",\n result: { type: \"number\", value: sum / count },\n };\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAAA;AAAA;AAAA;AAcO,SAAS,cAAc,CAC5B,SACA,SAC0B;AAAA,EAC1B,IAAI,MAAM;AAAA,EACV,IAAI,QAAQ;AAAA,EAEZ,WAAW,UAAU,SAAS;AAAA,IAC5B,IAAI,OAAO,SAAS,SAAS;AAAA,MAE3B,OAAO;AAAA,IACT;AAAA,IACA,IAAI,OAAO,SAAS,uBAAuB;AAAA,MACzC,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,OAAO,SAAS,SAAS;AAAA,MAC3B,IAAI,OAAO,OAAO,SAAS,UAAU;AAAA,QACnC,OAAO,OAAO,OAAO;AAAA,QACrB;AAAA,MACF,EAAO,SAAI,OAAO,OAAO,SAAS,YAAY;AAAA,QAE5C,OAAO;AAAA,UACL,MAAM;AAAA,UACN,QAAQ,OAAO;AAAA,QACjB;AAAA,MACF;AAAA,IAEF;AAAA,EACF;AAAA,EAEA,IAAI,UAAU,GAAG;AAAA,IACf,OAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK,aAAa;AAAA,MAClB,SAAS;AAAA,MACT,YAAY,QAAQ;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,EAAE,MAAM,UAAU,OAAO,MAAM,MAAM;AAAA,EAC/C;AAAA;",
|
|
8
|
+
"debugId": "A2F15D16FE74F8C164756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// src/functions/math/average/average.ts
|
|
2
|
+
import { performAverage } from "./average-utils.mjs";
|
|
3
|
+
import { createArgumentIterator } from "src/functions/function-utils";
|
|
4
|
+
var AVERAGE = {
|
|
5
|
+
name: "AVERAGE",
|
|
6
|
+
evaluate: function(node, context) {
|
|
7
|
+
const argumentValues = createArgumentIterator(this, node, context, "col-major");
|
|
8
|
+
if (argumentValues.type !== "values") {
|
|
9
|
+
return argumentValues;
|
|
10
|
+
}
|
|
11
|
+
return performAverage(argumentValues.values, context);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
export {
|
|
15
|
+
AVERAGE
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//# debugId=C029FB3B43F4C5E164756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/functions/math/average/average.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"src/core/types\";\nimport { performAverage } from \"./average-utils.mjs\";\nimport { createArgumentIterator } from \"src/functions/function-utils\";\n\n/**\n * AVERAGE function - Calculates the arithmetic mean of all numbers in the arguments\n *\n * Usage: AVERAGE(value1, [value2], ...)\n *\n * Examples:\n * AVERAGE(1, 2, 3) - returns 2\n * AVERAGE(A1:A10) - averages all numbers in the range A1:A10\n * AVERAGE(A1:A5, B1:B5) - averages all numbers in both ranges\n *\n * Note:\n * - Only numeric values are included in the calculation\n * - Text, logical values, and empty cells are ignored in ranges\n * - Direct text/logical arguments cause errors\n * - Returns #DIV/0! if no numeric values are found\n */\nexport const AVERAGE: FunctionDefinition = {\n name: \"AVERAGE\",\n evaluate: function (node, context): FunctionEvaluationResult {\n // Create iterator over all argument values\n const argumentValues = createArgumentIterator(\n this,\n node,\n context,\n \"col-major\"\n );\n\n if (argumentValues.type !== \"values\") {\n return argumentValues;\n }\n\n // Use shared averaging utility (now with unified error propagation)\n return performAverage(argumentValues.values, context);\n },\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAIA;AACA;AAkBO,IAAM,UAA8B;AAAA,EACzC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAE3D,MAAM,iBAAiB,uBACrB,MACA,MACA,SACA,WACF;AAAA,IAEA,IAAI,eAAe,SAAS,UAAU;AAAA,MACpC,OAAO;AAAA,IACT;AAAA,IAGA,OAAO,eAAe,eAAe,QAAQ,OAAO;AAAA;AAExD;",
|
|
8
|
+
"debugId": "C029FB3B43F4C5E164756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// src/functions/math/average/averageif.ts
|
|
2
|
+
import {
|
|
3
|
+
FormulaError
|
|
4
|
+
} from "src/core/types";
|
|
5
|
+
import {
|
|
6
|
+
processMultiCriteriaValues,
|
|
7
|
+
validateSingleCriteriaArgs
|
|
8
|
+
} from "../../criteria-utils.mjs";
|
|
9
|
+
import { parseCriteria } from "../../criteria-parser.mjs";
|
|
10
|
+
import { performAverage } from "./average-utils.mjs";
|
|
11
|
+
var AVERAGEIF = {
|
|
12
|
+
name: "AVERAGEIF",
|
|
13
|
+
evaluate: function(node, context) {
|
|
14
|
+
const argError = validateSingleCriteriaArgs("AVERAGEIF", node.args.length, context);
|
|
15
|
+
if (argError) {
|
|
16
|
+
return argError;
|
|
17
|
+
}
|
|
18
|
+
const criteriaRangeResult = this.evaluateNode(node.args[0], context);
|
|
19
|
+
if (criteriaRangeResult.type === "error") {
|
|
20
|
+
return criteriaRangeResult;
|
|
21
|
+
}
|
|
22
|
+
const criteriaResult = this.evaluateNode(node.args[1], context);
|
|
23
|
+
if (criteriaResult.type === "error") {
|
|
24
|
+
return criteriaResult;
|
|
25
|
+
}
|
|
26
|
+
if (criteriaResult.type !== "value") {
|
|
27
|
+
return {
|
|
28
|
+
type: "error",
|
|
29
|
+
err: FormulaError.VALUE,
|
|
30
|
+
message: "AVERAGEIF criteria must be a single value",
|
|
31
|
+
errAddress: context.dependencyNode
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const parsedCriteria = parseCriteria(criteriaResult.result);
|
|
35
|
+
if (parsedCriteria.type === "error") {
|
|
36
|
+
return {
|
|
37
|
+
type: "error",
|
|
38
|
+
err: FormulaError.VALUE,
|
|
39
|
+
message: parsedCriteria.message,
|
|
40
|
+
errAddress: context.dependencyNode
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const averageRangeResult = node.args.length === 3 ? this.evaluateNode(node.args[2], context) : criteriaRangeResult;
|
|
44
|
+
if (averageRangeResult.type === "error") {
|
|
45
|
+
return averageRangeResult;
|
|
46
|
+
}
|
|
47
|
+
const matchingValues = processMultiCriteriaValues(this, averageRangeResult, [{ rangeResult: criteriaRangeResult, parsedCriteria }], context, "col-major");
|
|
48
|
+
if (matchingValues.type === "error" || matchingValues.type === "awaiting-evaluation") {
|
|
49
|
+
return matchingValues;
|
|
50
|
+
}
|
|
51
|
+
return performAverage(matchingValues.values, context);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
export {
|
|
55
|
+
AVERAGEIF
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
//# debugId=ECB1C9E28720AEEC64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/functions/math/average/averageif.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n FormulaError,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"src/core/types\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\nimport { \n processMultiCriteriaValues, \n validateSingleCriteriaArgs,\n} from \"../../criteria-utils.mjs\";\nimport { parseCriteria, matchesParsedCriteria } from \"../../criteria-parser.mjs\";\nimport { performAverage } from \"./average-utils.mjs\";\n\n/**\n * AVERAGEIF function - Calculates the average of cells in a range that meet a criteria\n * \n * Usage: AVERAGEIF(range, criteria, [average_range])\n * \n * range: The range of cells to evaluate against the criteria\n * criteria: The criteria to match against. Can be:\n * - Exact value: \"Apple\", 42\n * - Comparison: \">10\", \"<=5\", \"<>0\"\n * - Wildcards: \"App*\", \"?ruit\"\n * average_range: Optional. The range to average. If omitted, uses the range parameter\n * \n * Examples:\n * AVERAGEIF(A1:A10, \"Apple\") - averages cells in A1:A10 that contain \"Apple\"\n * AVERAGEIF(B1:B10, \">10\") - averages cells in B1:B10 with values greater than 10\n * AVERAGEIF(A1:A10, \"Apple\", B1:B10) - averages B1:B10 where A1:A10 contains \"Apple\"\n * \n * Note:\n * - Only numeric values are included in the average calculation\n * - Returns error if no values match the criteria\n */\nexport const AVERAGEIF: FunctionDefinition = {\n name: \"AVERAGEIF\",\n evaluate: function (node, context): FunctionEvaluationResult {\n // Validate arguments\n const argError = validateSingleCriteriaArgs(\"AVERAGEIF\", node.args.length, context);\n if (argError) {\n return argError;\n }\n\n // Evaluate criteria range (first argument)\n const criteriaRangeResult = this.evaluateNode(node.args[0]!, context);\n if (criteriaRangeResult.type === \"error\") {\n return criteriaRangeResult;\n }\n\n // Evaluate criteria (second argument)\n const criteriaResult = this.evaluateNode(node.args[1]!, context);\n if (criteriaResult.type === \"error\") {\n return criteriaResult;\n }\n\n if (criteriaResult.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"AVERAGEIF criteria must be a single value\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Parse criteria\n const parsedCriteria = parseCriteria(criteriaResult.result);\n if (parsedCriteria.type === \"error\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: parsedCriteria.message,\n errAddress: context.dependencyNode,\n };\n }\n\n // Determine average range (third argument if present, otherwise same as criteria range)\n const averageRangeResult = node.args.length === 3 \n ? this.evaluateNode(node.args[2]!, context)\n : criteriaRangeResult;\n \n if (averageRangeResult.type === \"error\") {\n return averageRangeResult;\n }\n\n // Use shared average utility for standard cases\n const matchingValues = processMultiCriteriaValues(\n this,\n averageRangeResult,\n [{ rangeResult: criteriaRangeResult, parsedCriteria }],\n context,\n \"col-major\"\n );\n\n if (matchingValues.type === \"error\" || matchingValues.type === \"awaiting-evaluation\") {\n return matchingValues;\n }\n\n return performAverage(matchingValues.values, context);\n },\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAAA;AAIA;AACA;AAuBO,IAAM,YAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAE3D,MAAM,WAAW,2BAA2B,aAAa,KAAK,KAAK,QAAQ,OAAO;AAAA,IAClF,IAAI,UAAU;AAAA,MACZ,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,sBAAsB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IACpE,IAAI,oBAAoB,SAAS,SAAS;AAAA,MACxC,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,iBAAiB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IAC/D,IAAI,eAAe,SAAS,SAAS;AAAA,MACnC,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,eAAe,SAAS,SAAS;AAAA,MACnC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,MAAM,iBAAiB,cAAc,eAAe,MAAM;AAAA,IAC1D,IAAI,eAAe,SAAS,SAAS;AAAA,MACnC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS,eAAe;AAAA,QACxB,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,MAAM,qBAAqB,KAAK,KAAK,WAAW,IAC5C,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO,IACxC;AAAA,IAEJ,IAAI,mBAAmB,SAAS,SAAS;AAAA,MACvC,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,iBAAiB,2BACrB,MACA,oBACA,CAAC,EAAE,aAAa,qBAAqB,eAAe,CAAC,GACrD,SACA,WACF;AAAA,IAEA,IAAI,eAAe,SAAS,WAAW,eAAe,SAAS,uBAAuB;AAAA,MACpF,OAAO;AAAA,IACT;AAAA,IAEA,OAAO,eAAe,eAAe,QAAQ,OAAO;AAAA;AAExD;",
|
|
8
|
+
"debugId": "ECB1C9E28720AEEC64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/functions/math/average/averageifs.ts
|
|
2
|
+
import {
|
|
3
|
+
parseCriteriaPairs,
|
|
4
|
+
processMultiCriteriaValues,
|
|
5
|
+
validateMultiCriteriaArgs
|
|
6
|
+
} from "../../criteria-utils.mjs";
|
|
7
|
+
import { performAverage } from "./average-utils.mjs";
|
|
8
|
+
var AVERAGEIFS = {
|
|
9
|
+
name: "AVERAGEIFS",
|
|
10
|
+
evaluate: function(node, context) {
|
|
11
|
+
const argError = validateMultiCriteriaArgs("AVERAGEIFS", node.args.length, context);
|
|
12
|
+
if (argError) {
|
|
13
|
+
return argError;
|
|
14
|
+
}
|
|
15
|
+
const averageRangeResult = this.evaluateNode(node.args[0], context);
|
|
16
|
+
if (averageRangeResult.type === "error") {
|
|
17
|
+
return averageRangeResult;
|
|
18
|
+
}
|
|
19
|
+
const criteriaPairsResult = parseCriteriaPairs.call(this, node, context, this.evaluateNode, 1);
|
|
20
|
+
if ("type" in criteriaPairsResult) {
|
|
21
|
+
return criteriaPairsResult;
|
|
22
|
+
}
|
|
23
|
+
const criteriaPairs = criteriaPairsResult;
|
|
24
|
+
const matchingValues = processMultiCriteriaValues(this, averageRangeResult, criteriaPairs, context, "col-major");
|
|
25
|
+
if (matchingValues.type === "error" || matchingValues.type === "awaiting-evaluation") {
|
|
26
|
+
return matchingValues;
|
|
27
|
+
}
|
|
28
|
+
return performAverage(matchingValues.values, context);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
AVERAGEIFS
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
//# debugId=81C16C1A4A35CECF64756E2164756E21
|