@ricsam/formula-engine 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/core/engine.cjs +12 -8
- package/dist/cjs/core/engine.cjs.map +3 -3
- package/dist/cjs/core/managers/dependency-manager.cjs +8 -8
- package/dist/cjs/core/managers/dependency-manager.cjs.map +3 -3
- package/dist/cjs/core/managers/evaluation-manager.cjs +10 -10
- package/dist/cjs/core/managers/evaluation-manager.cjs.map +2 -2
- package/dist/cjs/core/managers/frontier-dependency-manager.cjs.map +1 -1
- package/dist/cjs/core/managers/isDependencyNode.cjs +6 -6
- package/dist/cjs/core/managers/isDependencyNode.cjs.map +2 -2
- package/dist/cjs/core/managers/named-expression-manager.cjs.map +1 -1
- package/dist/cjs/core/managers/range-eval-order-builder.cjs +2 -2
- package/dist/cjs/core/managers/range-eval-order-builder.cjs.map +3 -3
- package/dist/cjs/core/managers/workbook-manager.cjs +3 -3
- package/dist/cjs/core/managers/workbook-manager.cjs.map +2 -2
- package/dist/cjs/core/types.cjs.map +2 -2
- package/dist/cjs/core/utils.cjs +2 -2
- package/dist/cjs/core/utils.cjs.map +2 -2
- package/dist/cjs/evaluator/arithmetic/add/add.cjs +2 -2
- package/dist/cjs/evaluator/arithmetic/add/add.cjs.map +2 -2
- package/dist/cjs/evaluator/arithmetic/divide/divide.cjs +2 -2
- package/dist/cjs/evaluator/arithmetic/divide/divide.cjs.map +2 -2
- package/dist/cjs/evaluator/arithmetic/multiply/multiply.cjs +2 -2
- package/dist/cjs/evaluator/arithmetic/multiply/multiply.cjs.map +2 -2
- package/dist/cjs/evaluator/arithmetic/power/power.cjs +2 -2
- package/dist/cjs/evaluator/arithmetic/power/power.cjs.map +2 -2
- package/dist/cjs/evaluator/arithmetic/subtract/subtract.cjs +2 -2
- package/dist/cjs/evaluator/arithmetic/subtract/subtract.cjs.map +2 -2
- package/dist/cjs/evaluator/comparison/equals.cjs.map +1 -1
- package/dist/cjs/evaluator/comparison/greater-than-or-equal.cjs +2 -2
- package/dist/cjs/evaluator/comparison/greater-than-or-equal.cjs.map +2 -2
- package/dist/cjs/evaluator/comparison/greater-than.cjs +2 -2
- package/dist/cjs/evaluator/comparison/greater-than.cjs.map +2 -2
- package/dist/cjs/evaluator/comparison/less-than-or-equal.cjs +2 -2
- package/dist/cjs/evaluator/comparison/less-than-or-equal.cjs.map +2 -2
- package/dist/cjs/evaluator/comparison/less-than.cjs +2 -2
- package/dist/cjs/evaluator/comparison/less-than.cjs.map +2 -2
- package/dist/cjs/evaluator/comparison/not-equals.cjs +2 -2
- package/dist/cjs/evaluator/comparison/not-equals.cjs.map +2 -2
- package/dist/cjs/evaluator/concatenation/concatenate.cjs +2 -2
- package/dist/cjs/evaluator/concatenation/concatenate.cjs.map +2 -2
- package/dist/cjs/evaluator/dependency-nodes/ast-evaluation-node.cjs +2 -2
- package/dist/cjs/evaluator/dependency-nodes/ast-evaluation-node.cjs.map +2 -2
- package/dist/cjs/evaluator/dependency-nodes/base-eval-node.cjs.map +2 -2
- package/dist/cjs/evaluator/dependency-nodes/cell-value-node.cjs +2 -2
- package/dist/cjs/evaluator/dependency-nodes/cell-value-node.cjs.map +2 -2
- package/dist/cjs/evaluator/dependency-nodes/empty-cell-evaluation-node.cjs +3 -3
- package/dist/cjs/evaluator/dependency-nodes/empty-cell-evaluation-node.cjs.map +2 -2
- package/dist/cjs/evaluator/dependency-nodes/spill-meta-node.cjs +2 -2
- package/dist/cjs/evaluator/dependency-nodes/spill-meta-node.cjs.map +2 -2
- package/dist/cjs/evaluator/evaluate-scalar-operator.cjs.map +1 -1
- package/dist/cjs/evaluator/evaluation-context.cjs.map +2 -2
- package/dist/cjs/evaluator/evaluation-error.cjs.map +1 -1
- package/dist/cjs/evaluator/formula-evaluator.cjs +6 -6
- package/dist/cjs/evaluator/formula-evaluator.cjs.map +3 -3
- package/dist/cjs/evaluator/range-evaluation-node.cjs +3 -3
- package/dist/cjs/evaluator/range-evaluation-node.cjs.map +2 -2
- package/dist/cjs/functions/_template/template.cjs.map +1 -1
- package/dist/cjs/functions/array/sequence/sequence.cjs +4 -4
- package/dist/cjs/functions/array/sequence/sequence.cjs.map +2 -2
- package/dist/cjs/functions/criteria-parser.cjs.map +1 -1
- package/dist/cjs/functions/criteria-utils.cjs +4 -4
- package/dist/cjs/functions/criteria-utils.cjs.map +3 -3
- package/dist/cjs/functions/{index.cjs → function-registry.cjs} +5 -5
- package/dist/cjs/functions/function-registry.cjs.map +10 -0
- package/dist/cjs/functions/function-utils.cjs.map +1 -1
- package/dist/cjs/functions/information/cell/cell.cjs +3 -3
- package/dist/cjs/functions/information/cell/cell.cjs.map +2 -2
- package/dist/cjs/functions/information/column/column.cjs +4 -4
- package/dist/cjs/functions/information/column/column.cjs.map +2 -2
- package/dist/cjs/functions/information/row/row.cjs +4 -4
- package/dist/cjs/functions/information/row/row.cjs.map +2 -2
- package/dist/cjs/functions/logical/and/and.cjs +2 -2
- package/dist/cjs/functions/logical/and/and.cjs.map +2 -2
- package/dist/cjs/functions/logical/if/if.cjs +2 -2
- package/dist/cjs/functions/logical/if/if.cjs.map +3 -3
- package/dist/cjs/functions/logical/iferror/iferror.cjs +3 -3
- package/dist/cjs/functions/logical/iferror/iferror.cjs.map +2 -2
- package/dist/cjs/functions/logical/or/or.cjs +2 -2
- package/dist/cjs/functions/logical/or/or.cjs.map +2 -2
- package/dist/cjs/functions/lookup/count/count-utils.cjs.map +1 -1
- package/dist/cjs/functions/lookup/count/count.cjs +2 -2
- package/dist/cjs/functions/lookup/count/count.cjs.map +2 -2
- package/dist/cjs/functions/lookup/count/countif.cjs +2 -2
- package/dist/cjs/functions/lookup/count/countif.cjs.map +2 -2
- package/dist/cjs/functions/lookup/count/countifs.cjs.map +1 -1
- package/dist/cjs/functions/lookup/index-lookup/index-lookup.cjs +2 -2
- package/dist/cjs/functions/lookup/index-lookup/index-lookup.cjs.map +2 -2
- package/dist/cjs/functions/lookup/match/match.cjs +2 -2
- package/dist/cjs/functions/lookup/match/match.cjs.map +2 -2
- package/dist/cjs/functions/lookup/xlookup/xlookup.cjs +2 -2
- package/dist/cjs/functions/lookup/xlookup/xlookup.cjs.map +2 -2
- package/dist/cjs/functions/math/average/average-utils.cjs +2 -2
- package/dist/cjs/functions/math/average/average-utils.cjs.map +2 -2
- package/dist/cjs/functions/math/average/average.cjs +2 -2
- package/dist/cjs/functions/math/average/average.cjs.map +2 -2
- package/dist/cjs/functions/math/average/averageif.cjs +3 -3
- package/dist/cjs/functions/math/average/averageif.cjs.map +3 -3
- package/dist/cjs/functions/math/average/averageifs.cjs.map +2 -2
- package/dist/cjs/functions/math/ceiling/ceiling.cjs +2 -2
- package/dist/cjs/functions/math/ceiling/ceiling.cjs.map +3 -3
- package/dist/cjs/functions/math/max/max-utils.cjs +2 -2
- package/dist/cjs/functions/math/max/max-utils.cjs.map +2 -2
- package/dist/cjs/functions/math/max/max.cjs +2 -2
- package/dist/cjs/functions/math/max/max.cjs.map +2 -2
- package/dist/cjs/functions/math/max/maxif.cjs +2 -2
- package/dist/cjs/functions/math/max/maxif.cjs.map +2 -2
- package/dist/cjs/functions/math/max/maxifs.cjs.map +2 -2
- package/dist/cjs/functions/math/min/min-utils.cjs +2 -2
- package/dist/cjs/functions/math/min/min-utils.cjs.map +2 -2
- package/dist/cjs/functions/math/min/min.cjs +2 -2
- package/dist/cjs/functions/math/min/min.cjs.map +3 -3
- package/dist/cjs/functions/math/min/minif.cjs +2 -2
- package/dist/cjs/functions/math/min/minif.cjs.map +2 -2
- package/dist/cjs/functions/math/min/minifs.cjs.map +2 -2
- package/dist/cjs/functions/math/sum/sum.cjs +2 -2
- package/dist/cjs/functions/math/sum/sum.cjs.map +2 -2
- package/dist/cjs/functions/math/sum/sumif.cjs +2 -2
- package/dist/cjs/functions/math/sum/sumif.cjs.map +2 -2
- package/dist/cjs/functions/math/sum/sumifs.cjs.map +2 -2
- package/dist/cjs/functions/math/sum/summation-utils.cjs.map +1 -1
- package/dist/cjs/functions/reference/address/address.cjs +2 -2
- package/dist/cjs/functions/reference/address/address.cjs.map +2 -2
- package/dist/cjs/functions/reference/indirect/indirect.cjs +3 -3
- package/dist/cjs/functions/reference/indirect/indirect.cjs.map +3 -3
- package/dist/cjs/functions/reference/offset/offset.cjs +3 -3
- package/dist/cjs/functions/reference/offset/offset.cjs.map +2 -2
- package/dist/cjs/functions/text/concatenate/concatenate.cjs +2 -2
- package/dist/cjs/functions/text/concatenate/concatenate.cjs.map +2 -2
- package/dist/cjs/functions/text/exact/exact.cjs +2 -2
- package/dist/cjs/functions/text/exact/exact.cjs.map +2 -2
- package/dist/cjs/functions/text/find/find.cjs +2 -2
- package/dist/cjs/functions/text/find/find.cjs.map +3 -3
- package/dist/cjs/functions/text/left/left.cjs +2 -2
- package/dist/cjs/functions/text/left/left.cjs.map +2 -2
- package/dist/cjs/functions/text/len/len.cjs +2 -2
- package/dist/cjs/functions/text/len/len.cjs.map +3 -3
- package/dist/cjs/functions/text/mid/mid.cjs +2 -2
- package/dist/cjs/functions/text/mid/mid.cjs.map +2 -2
- package/dist/cjs/functions/text/right/right.cjs +2 -2
- package/dist/cjs/functions/text/right/right.cjs.map +3 -3
- package/dist/cjs/functions/text/text-helpers.cjs +2 -2
- package/dist/cjs/functions/text/text-helpers.cjs.map +2 -2
- package/dist/cjs/functions/text/textjoin/textjoin.cjs +2 -2
- package/dist/cjs/functions/text/textjoin/textjoin.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/parser/formatter.cjs +2 -2
- package/dist/cjs/parser/formatter.cjs.map +2 -2
- package/dist/mjs/core/engine.mjs +7 -9
- package/dist/mjs/core/engine.mjs.map +3 -3
- package/dist/mjs/core/managers/dependency-manager.mjs +8 -8
- package/dist/mjs/core/managers/dependency-manager.mjs.map +3 -3
- package/dist/mjs/core/managers/evaluation-manager.mjs +10 -10
- package/dist/mjs/core/managers/evaluation-manager.mjs.map +2 -2
- package/dist/mjs/core/managers/frontier-dependency-manager.mjs.map +1 -1
- package/dist/mjs/core/managers/isDependencyNode.mjs +6 -6
- package/dist/mjs/core/managers/isDependencyNode.mjs.map +2 -2
- package/dist/mjs/core/managers/named-expression-manager.mjs.map +1 -1
- package/dist/mjs/core/managers/range-eval-order-builder.mjs +2 -2
- package/dist/mjs/core/managers/range-eval-order-builder.mjs.map +3 -3
- package/dist/mjs/core/managers/workbook-manager.mjs +3 -3
- package/dist/mjs/core/managers/workbook-manager.mjs.map +2 -2
- package/dist/mjs/core/types.mjs.map +2 -2
- package/dist/mjs/core/utils.mjs +2 -2
- package/dist/mjs/core/utils.mjs.map +2 -2
- package/dist/mjs/evaluator/arithmetic/add/add.mjs +2 -2
- package/dist/mjs/evaluator/arithmetic/add/add.mjs.map +2 -2
- package/dist/mjs/evaluator/arithmetic/divide/divide.mjs +2 -2
- package/dist/mjs/evaluator/arithmetic/divide/divide.mjs.map +2 -2
- package/dist/mjs/evaluator/arithmetic/multiply/multiply.mjs +2 -2
- package/dist/mjs/evaluator/arithmetic/multiply/multiply.mjs.map +2 -2
- package/dist/mjs/evaluator/arithmetic/power/power.mjs +2 -2
- package/dist/mjs/evaluator/arithmetic/power/power.mjs.map +2 -2
- package/dist/mjs/evaluator/arithmetic/subtract/subtract.mjs +2 -2
- package/dist/mjs/evaluator/arithmetic/subtract/subtract.mjs.map +2 -2
- package/dist/mjs/evaluator/comparison/equals.mjs.map +1 -1
- package/dist/mjs/evaluator/comparison/greater-than-or-equal.mjs +2 -2
- package/dist/mjs/evaluator/comparison/greater-than-or-equal.mjs.map +2 -2
- package/dist/mjs/evaluator/comparison/greater-than.mjs +2 -2
- package/dist/mjs/evaluator/comparison/greater-than.mjs.map +2 -2
- package/dist/mjs/evaluator/comparison/less-than-or-equal.mjs +2 -2
- package/dist/mjs/evaluator/comparison/less-than-or-equal.mjs.map +2 -2
- package/dist/mjs/evaluator/comparison/less-than.mjs +2 -2
- package/dist/mjs/evaluator/comparison/less-than.mjs.map +2 -2
- package/dist/mjs/evaluator/comparison/not-equals.mjs +2 -2
- package/dist/mjs/evaluator/comparison/not-equals.mjs.map +2 -2
- package/dist/mjs/evaluator/concatenation/concatenate.mjs +2 -2
- package/dist/mjs/evaluator/concatenation/concatenate.mjs.map +2 -2
- package/dist/mjs/evaluator/dependency-nodes/ast-evaluation-node.mjs +2 -2
- package/dist/mjs/evaluator/dependency-nodes/ast-evaluation-node.mjs.map +2 -2
- package/dist/mjs/evaluator/dependency-nodes/base-eval-node.mjs.map +2 -2
- package/dist/mjs/evaluator/dependency-nodes/cell-value-node.mjs +2 -2
- package/dist/mjs/evaluator/dependency-nodes/cell-value-node.mjs.map +2 -2
- package/dist/mjs/evaluator/dependency-nodes/empty-cell-evaluation-node.mjs +3 -3
- package/dist/mjs/evaluator/dependency-nodes/empty-cell-evaluation-node.mjs.map +2 -2
- package/dist/mjs/evaluator/dependency-nodes/spill-meta-node.mjs +2 -2
- package/dist/mjs/evaluator/dependency-nodes/spill-meta-node.mjs.map +2 -2
- package/dist/mjs/evaluator/evaluate-scalar-operator.mjs.map +1 -1
- package/dist/mjs/evaluator/evaluation-context.mjs.map +2 -2
- package/dist/mjs/evaluator/evaluation-error.mjs.map +1 -1
- package/dist/mjs/evaluator/formula-evaluator.mjs +7 -7
- package/dist/mjs/evaluator/formula-evaluator.mjs.map +3 -3
- package/dist/mjs/evaluator/range-evaluation-node.mjs +3 -3
- package/dist/mjs/evaluator/range-evaluation-node.mjs.map +2 -2
- package/dist/mjs/functions/_template/template.mjs.map +1 -1
- package/dist/mjs/functions/array/sequence/sequence.mjs +4 -4
- package/dist/mjs/functions/array/sequence/sequence.mjs.map +2 -2
- package/dist/mjs/functions/criteria-parser.mjs.map +1 -1
- package/dist/mjs/functions/criteria-utils.mjs +8 -8
- package/dist/mjs/functions/criteria-utils.mjs.map +3 -3
- package/dist/mjs/functions/{index.mjs → function-registry.mjs} +2 -2
- package/dist/mjs/functions/function-registry.mjs.map +10 -0
- package/dist/mjs/functions/function-utils.mjs.map +1 -1
- package/dist/mjs/functions/information/cell/cell.mjs +3 -3
- package/dist/mjs/functions/information/cell/cell.mjs.map +2 -2
- package/dist/mjs/functions/information/column/column.mjs +4 -4
- package/dist/mjs/functions/information/column/column.mjs.map +2 -2
- package/dist/mjs/functions/information/row/row.mjs +4 -4
- package/dist/mjs/functions/information/row/row.mjs.map +2 -2
- package/dist/mjs/functions/logical/and/and.mjs +2 -2
- package/dist/mjs/functions/logical/and/and.mjs.map +2 -2
- package/dist/mjs/functions/logical/if/if.mjs +2 -2
- package/dist/mjs/functions/logical/if/if.mjs.map +3 -3
- package/dist/mjs/functions/logical/iferror/iferror.mjs +3 -3
- package/dist/mjs/functions/logical/iferror/iferror.mjs.map +2 -2
- package/dist/mjs/functions/logical/or/or.mjs +2 -2
- package/dist/mjs/functions/logical/or/or.mjs.map +2 -2
- package/dist/mjs/functions/lookup/count/count-utils.mjs.map +1 -1
- package/dist/mjs/functions/lookup/count/count.mjs +2 -2
- package/dist/mjs/functions/lookup/count/count.mjs.map +2 -2
- package/dist/mjs/functions/lookup/count/countif.mjs +2 -2
- package/dist/mjs/functions/lookup/count/countif.mjs.map +2 -2
- package/dist/mjs/functions/lookup/count/countifs.mjs.map +1 -1
- package/dist/mjs/functions/lookup/index-lookup/index-lookup.mjs +2 -2
- package/dist/mjs/functions/lookup/index-lookup/index-lookup.mjs.map +2 -2
- package/dist/mjs/functions/lookup/match/match.mjs +2 -2
- package/dist/mjs/functions/lookup/match/match.mjs.map +2 -2
- package/dist/mjs/functions/lookup/xlookup/xlookup.mjs +2 -2
- package/dist/mjs/functions/lookup/xlookup/xlookup.mjs.map +2 -2
- package/dist/mjs/functions/math/average/average-utils.mjs +2 -2
- package/dist/mjs/functions/math/average/average-utils.mjs.map +2 -2
- package/dist/mjs/functions/math/average/average.mjs +2 -2
- package/dist/mjs/functions/math/average/average.mjs.map +2 -2
- package/dist/mjs/functions/math/average/averageif.mjs +3 -3
- package/dist/mjs/functions/math/average/averageif.mjs.map +3 -3
- package/dist/mjs/functions/math/average/averageifs.mjs.map +2 -2
- package/dist/mjs/functions/math/ceiling/ceiling.mjs +2 -2
- package/dist/mjs/functions/math/ceiling/ceiling.mjs.map +3 -3
- package/dist/mjs/functions/math/max/max-utils.mjs +2 -2
- package/dist/mjs/functions/math/max/max-utils.mjs.map +2 -2
- package/dist/mjs/functions/math/max/max.mjs +2 -2
- package/dist/mjs/functions/math/max/max.mjs.map +2 -2
- package/dist/mjs/functions/math/max/maxif.mjs +2 -2
- package/dist/mjs/functions/math/max/maxif.mjs.map +2 -2
- package/dist/mjs/functions/math/max/maxifs.mjs.map +2 -2
- package/dist/mjs/functions/math/min/min-utils.mjs +2 -2
- package/dist/mjs/functions/math/min/min-utils.mjs.map +2 -2
- package/dist/mjs/functions/math/min/min.mjs +2 -2
- package/dist/mjs/functions/math/min/min.mjs.map +2 -2
- package/dist/mjs/functions/math/min/minif.mjs +2 -2
- package/dist/mjs/functions/math/min/minif.mjs.map +2 -2
- package/dist/mjs/functions/math/min/minifs.mjs.map +2 -2
- package/dist/mjs/functions/math/sum/sum.mjs +2 -2
- package/dist/mjs/functions/math/sum/sum.mjs.map +2 -2
- package/dist/mjs/functions/math/sum/sumif.mjs +2 -2
- package/dist/mjs/functions/math/sum/sumif.mjs.map +2 -2
- package/dist/mjs/functions/math/sum/sumifs.mjs.map +2 -2
- package/dist/mjs/functions/math/sum/summation-utils.mjs.map +1 -1
- package/dist/mjs/functions/reference/address/address.mjs +2 -2
- package/dist/mjs/functions/reference/address/address.mjs.map +2 -2
- package/dist/mjs/functions/reference/indirect/indirect.mjs +3 -3
- package/dist/mjs/functions/reference/indirect/indirect.mjs.map +3 -3
- package/dist/mjs/functions/reference/offset/offset.mjs +3 -3
- package/dist/mjs/functions/reference/offset/offset.mjs.map +2 -2
- package/dist/mjs/functions/text/concatenate/concatenate.mjs +2 -2
- package/dist/mjs/functions/text/concatenate/concatenate.mjs.map +2 -2
- package/dist/mjs/functions/text/exact/exact.mjs +2 -2
- package/dist/mjs/functions/text/exact/exact.mjs.map +2 -2
- package/dist/mjs/functions/text/find/find.mjs +2 -2
- package/dist/mjs/functions/text/find/find.mjs.map +3 -3
- package/dist/mjs/functions/text/left/left.mjs +3 -3
- package/dist/mjs/functions/text/left/left.mjs.map +2 -2
- package/dist/mjs/functions/text/len/len.mjs +2 -2
- package/dist/mjs/functions/text/len/len.mjs.map +3 -3
- package/dist/mjs/functions/text/mid/mid.mjs +3 -3
- package/dist/mjs/functions/text/mid/mid.mjs.map +2 -2
- package/dist/mjs/functions/text/right/right.mjs +4 -4
- package/dist/mjs/functions/text/right/right.mjs.map +3 -3
- package/dist/mjs/functions/text/text-helpers.mjs +2 -2
- package/dist/mjs/functions/text/text-helpers.mjs.map +2 -2
- package/dist/mjs/functions/text/textjoin/textjoin.mjs +2 -2
- package/dist/mjs/functions/text/textjoin/textjoin.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/parser/formatter.mjs +2 -2
- package/dist/mjs/parser/formatter.mjs.map +2 -2
- package/dist/types/core/engine.d.ts +5 -1
- package/dist/types/core/managers/dependency-manager.d.ts +7 -7
- package/dist/types/core/managers/dependency-node.d.ts +5 -5
- package/dist/types/core/managers/evaluation-manager.d.ts +4 -4
- package/dist/types/core/managers/frontier-dependency-manager.d.ts +2 -2
- package/dist/types/core/managers/named-expression-manager.d.ts +2 -2
- package/dist/types/core/managers/workbook-manager.d.ts +1 -1
- package/dist/types/core/types.d.ts +3 -3
- package/dist/types/evaluator/arithmetic/add/add.d.ts +1 -1
- package/dist/types/evaluator/arithmetic/divide/divide.d.ts +1 -1
- package/dist/types/evaluator/arithmetic/multiply/multiply.d.ts +1 -1
- package/dist/types/evaluator/arithmetic/power/power.d.ts +1 -1
- package/dist/types/evaluator/arithmetic/subtract/subtract.d.ts +1 -1
- package/dist/types/evaluator/comparison/equals.d.ts +1 -1
- package/dist/types/evaluator/comparison/greater-than-or-equal.d.ts +1 -1
- package/dist/types/evaluator/comparison/greater-than.d.ts +1 -1
- package/dist/types/evaluator/comparison/less-than-or-equal.d.ts +1 -1
- package/dist/types/evaluator/comparison/less-than.d.ts +1 -1
- package/dist/types/evaluator/comparison/not-equals.d.ts +1 -1
- package/dist/types/evaluator/concatenation/concatenate.d.ts +1 -1
- package/dist/types/evaluator/dependency-nodes/ast-evaluation-node.d.ts +2 -2
- package/dist/types/evaluator/dependency-nodes/base-eval-node.d.ts +1 -1
- package/dist/types/evaluator/dependency-nodes/cell-value-node.d.ts +1 -1
- package/dist/types/evaluator/dependency-nodes/empty-cell-evaluation-node.d.ts +4 -4
- package/dist/types/evaluator/dependency-nodes/spill-meta-node.d.ts +1 -1
- package/dist/types/evaluator/evaluate-scalar-operator.d.ts +1 -1
- package/dist/types/evaluator/evaluation-context.d.ts +3 -3
- package/dist/types/evaluator/evaluation-error.d.ts +2 -2
- package/dist/types/evaluator/formula-evaluator.d.ts +5 -5
- package/dist/types/evaluator/range-evaluation-node.d.ts +4 -4
- package/dist/types/functions/_template/template.d.ts +1 -1
- package/dist/types/functions/array/sequence/sequence.d.ts +1 -1
- package/dist/types/functions/criteria-parser.d.ts +1 -1
- package/dist/types/functions/criteria-utils.d.ts +5 -5
- package/dist/types/functions/{index.d.ts → function-registry.d.ts} +1 -1
- package/dist/types/functions/function-utils.d.ts +5 -5
- package/dist/types/functions/information/cell/cell.d.ts +1 -1
- package/dist/types/functions/information/column/column.d.ts +1 -1
- package/dist/types/functions/information/row/row.d.ts +1 -1
- package/dist/types/functions/logical/and/and.d.ts +1 -1
- package/dist/types/functions/logical/if/if.d.ts +1 -1
- package/dist/types/functions/logical/iferror/iferror.d.ts +1 -1
- package/dist/types/functions/logical/or/or.d.ts +1 -1
- package/dist/types/functions/lookup/count/count-utils.d.ts +2 -2
- package/dist/types/functions/lookup/count/count.d.ts +1 -1
- package/dist/types/functions/lookup/count/countif.d.ts +1 -1
- package/dist/types/functions/lookup/count/countifs.d.ts +1 -1
- package/dist/types/functions/lookup/index-lookup/index-lookup.d.ts +1 -1
- package/dist/types/functions/lookup/match/match.d.ts +1 -1
- package/dist/types/functions/lookup/xlookup/xlookup.d.ts +1 -1
- package/dist/types/functions/math/average/average-utils.d.ts +2 -2
- package/dist/types/functions/math/average/average.d.ts +1 -1
- package/dist/types/functions/math/average/averageif.d.ts +1 -1
- package/dist/types/functions/math/average/averageifs.d.ts +1 -1
- package/dist/types/functions/math/ceiling/ceiling.d.ts +1 -1
- package/dist/types/functions/math/max/max-utils.d.ts +2 -2
- package/dist/types/functions/math/max/max.d.ts +1 -1
- package/dist/types/functions/math/max/maxif.d.ts +1 -1
- package/dist/types/functions/math/max/maxifs.d.ts +1 -1
- package/dist/types/functions/math/min/min-utils.d.ts +2 -2
- package/dist/types/functions/math/min/min.d.ts +1 -1
- package/dist/types/functions/math/min/minif.d.ts +1 -1
- package/dist/types/functions/math/min/minifs.d.ts +1 -1
- package/dist/types/functions/math/sum/sum.d.ts +1 -1
- package/dist/types/functions/math/sum/sumif.d.ts +1 -1
- package/dist/types/functions/math/sum/sumifs.d.ts +1 -1
- package/dist/types/functions/math/sum/summation-utils.d.ts +1 -1
- package/dist/types/functions/reference/address/address.d.ts +1 -1
- package/dist/types/functions/reference/indirect/indirect.d.ts +1 -1
- package/dist/types/functions/reference/offset/offset.d.ts +1 -1
- package/dist/types/functions/text/concatenate/concatenate.d.ts +1 -1
- package/dist/types/functions/text/exact/exact.d.ts +1 -1
- package/dist/types/functions/text/find/find.d.ts +1 -1
- package/dist/types/functions/text/left/left.d.ts +1 -1
- package/dist/types/functions/text/len/len.d.ts +1 -1
- package/dist/types/functions/text/mid/mid.d.ts +1 -1
- package/dist/types/functions/text/right/right.d.ts +1 -1
- package/dist/types/functions/text/text-helpers.d.ts +3 -3
- package/dist/types/functions/text/textjoin/textjoin.d.ts +1 -1
- package/package.json +1 -1
- package/dist/cjs/core/managers/index.cjs +0 -49
- package/dist/cjs/core/managers/index.cjs.map +0 -10
- package/dist/cjs/functions/index.cjs.map +0 -10
- package/dist/mjs/core/managers/index.mjs +0 -21
- package/dist/mjs/core/managers/index.mjs.map +0 -10
- package/dist/mjs/functions/index.mjs.map +0 -10
- package/dist/types/core/managers/index.d.ts +0 -7
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/information/row/row.ts"],
|
|
4
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} from \"
|
|
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} from \"../../../core/types.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\nimport type { ReferenceNode, RangeNode } from \"../../../parser/ast.mjs\";\nimport { EvaluationError } from \"../../../evaluator/evaluation-error.mjs\";\nimport {\n getRangeIntersection,\n isCellAddress,\n isRangeAddress,\n} from \"../../../core/utils.mjs\";\n\n/**\n * ROW function - Returns the row number of a reference\n *\n * Usage: ROW([reference])\n *\n * If reference is omitted, returns the row number of the cell in which the formula appears.\n *\n * Examples:\n * - ROW() returns the row number of the current cell\n * - ROW(A5) returns 5\n * - ROW(A5:A10) returns an array of row numbers {5;6;7;8;9;10}\n */\nexport const ROW: FunctionDefinition = {\n name: \"ROW\",\n evaluate: function (node, context): FunctionEvaluationResult {\n // If no arguments, return the row of the current cell (1-based)\n if (node.args.length === 0) {\n context.addContextDependency(\"row\");\n return {\n type: \"value\",\n result: {\n type: \"number\",\n value: context.cellAddress.rowIndex + 1,\n },\n };\n }\n\n if (node.args.length > 1) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"ROW function takes at most 1 argument\",\n errAddress: context.dependencyNode,\n };\n }\n\n const argNode = node.args[0]!;\n\n // Evaluate the argument\n const argResult = this.evaluateNode(argNode, context);\n\n // Handle errors and awaiting evaluation\n if (\n argResult.type === \"error\" ||\n argResult.type === \"awaiting-evaluation\"\n ) {\n return argResult;\n }\n\n // Check if we have a cell or range reference\n const cellOrRange =\n argResult.type === \"spilled-values\"\n ? (argResult.sourceCell ?? argResult.sourceRange)\n : argResult.sourceCell;\n\n // If we don't have a sourceCell or sourceRange, the argument is invalid\n if (!cellOrRange) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"ROW function requires a cell or range reference\",\n errAddress: context.dependencyNode,\n };\n }\n\n // If we have a sourceCell (single cell reference), return its row\n if (isCellAddress(cellOrRange)) {\n return {\n type: \"value\",\n result: { type: \"number\", value: cellOrRange.rowIndex + 1 },\n };\n }\n\n // If we have a sourceRange, return spilled row numbers\n if (isRangeAddress(cellOrRange) && argResult.type === \"spilled-values\") {\n const sourceRange = cellOrRange.range;\n\n // Return as spilled values - evaluate returns row numbers based on position\n return {\n type: \"spilled-values\",\n spillArea: (origin) => argResult.spillArea(origin),\n sourceRange: cellOrRange,\n source: \"ROW with range/array argument\",\n evaluate: (spillOffset, evalContext) => {\n // If we have a sourceRange, use it to get the actual row number\n if (sourceRange) {\n const actualRow = sourceRange.start.row + spillOffset.y;\n return {\n type: \"value\",\n result: { type: \"number\", value: actualRow + 1 }, // 1-based\n };\n }\n\n // Otherwise, use spillArea to get the row number relative to where it appears\n const spillArea = argResult.spillArea(evalContext.cellAddress);\n const actualRow = spillArea.start.row + spillOffset.y;\n return {\n type: \"value\",\n result: { type: \"number\", value: actualRow + 1 }, // 1-based\n };\n },\n evaluateAllCells: ({ evaluate, intersection, context, origin }) => {\n // Determine the actual range to evaluate\n let rangeToEvaluate = cellOrRange.range;\n\n // Apply intersection if provided\n if (intersection) {\n // Use the intersection range\n const newRange = getRangeIntersection(\n rangeToEvaluate,\n intersection\n );\n if (!newRange) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Intersection range is not valid\",\n errAddress: context.dependencyNode,\n };\n }\n rangeToEvaluate = newRange;\n }\n\n // Check if the range is infinite\n if (\n rangeToEvaluate.end.row.type === \"infinity\" ||\n rangeToEvaluate.end.col.type === \"infinity\"\n ) {\n throw new EvaluationError(\n FormulaError.VALUE,\n \"ROW function cannot evaluate all cells over an infinite range\"\n );\n }\n\n // Extract unique row numbers from the range\n const startRow = rangeToEvaluate.start.row;\n const endRow = rangeToEvaluate.end.row.value;\n\n const rowSet = new Set<number>();\n for (let row = startRow; row <= endRow; row++) {\n rowSet.add(row + 1); // 1-based\n }\n const rows = Array.from(rowSet).sort((a, b) => a - b);\n\n const results: CellInRangeResult[] = [];\n for (let i = 0; i < rows.length; i++) {\n const relativePos = { x: 0, y: i };\n const evaled = evaluate(relativePos, context);\n results.push({\n result: evaled,\n relativePos,\n });\n }\n return {\n type: \"values\",\n values: results,\n };\n },\n };\n }\n\n // If we reach here, cellOrRange type is unknown\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"ROW function requires a cell or range reference\",\n errAddress: context.dependencyNode,\n };\n },\n};\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "06BB67FD2627AC3D64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/functions/logical/and/and.ts
|
|
2
2
|
import {
|
|
3
3
|
FormulaError
|
|
4
|
-
} from "
|
|
4
|
+
} from "../../../core/types.mjs";
|
|
5
5
|
function isTruthy(value) {
|
|
6
6
|
switch (value.type) {
|
|
7
7
|
case "boolean":
|
|
@@ -81,4 +81,4 @@ export {
|
|
|
81
81
|
AND
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
//# debugId=
|
|
84
|
+
//# debugId=D0FB4FD00CC5D74964756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/logical/and/and.ts"],
|
|
4
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 ErrorEvaluationResult,\n} from \"
|
|
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 ErrorEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport type { FormulaEvaluator } from \"../../../evaluator/formula-evaluator.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\n\n/**\n * AND function - Returns TRUE if all arguments are TRUE, FALSE otherwise\n *\n * Usage: AND(logical1, [logical2], ...)\n *\n * logical1, logical2, ...: Logical values or expressions to evaluate\n *\n * Examples:\n * AND(TRUE, TRUE) - returns TRUE\n * AND(TRUE, FALSE) - returns FALSE\n * AND(A1>10, B1<20) - returns TRUE if both conditions are met\n * AND(A1:A3) - returns TRUE if all values in A1:A3 are truthy\n *\n * Note:\n * - Supports spilled values (dynamic arrays) for arguments\n * - Logical evaluation: 0 and empty string are FALSE, everything else is TRUE\n * - If any argument is spilled, returns spilled results\n * - Short-circuit evaluation: stops at first FALSE value\n */\n\n/**\n * Convert a cell value to boolean for logical evaluation\n */\nfunction isTruthy(value: CellValue): boolean {\n switch (value.type) {\n case \"boolean\":\n return value.value;\n case \"number\":\n return value.value !== 0;\n case \"string\":\n return value.value !== \"\";\n case \"infinity\":\n return true; // Infinity is truthy\n default:\n return false;\n }\n}\n\n// AND function does not create spilled results - it processes all values in ranges\n// as individual logical tests and returns a single boolean result\n\n/**\n * AND function implementation\n */\nexport const AND: FunctionDefinition = {\n name: \"AND\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length === 0) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"AND function requires at least one argument\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Process arguments one by one (like SUM function)\n for (const arg of node.args) {\n const argResult = this.evaluateNode(arg, context);\n\n if (argResult.type === \"error\" || argResult.type === \"awaiting-evaluation\") {\n return argResult;\n }\n\n if (argResult.type === \"value\") {\n // Single value - check if truthy\n if (!isTruthy(argResult.result)) {\n return {\n type: \"value\",\n result: { type: \"boolean\", value: false },\n };\n }\n } else if (argResult.type === \"spilled-values\") {\n // Range - check all values in the range\n const cellValues = argResult.evaluateAllCells.call(this, {\n context,\n origin: context.cellAddress,\n evaluate: argResult.evaluate,\n lookupOrder: \"col-major\",\n });\n\n if (cellValues.type === \"error\" || cellValues.type === \"awaiting-evaluation\") {\n return cellValues;\n }\n\n for (const cellValue of cellValues.values) {\n if (cellValue.result.type === \"error\") {\n return cellValue.result;\n }\n if (cellValue.result.type === \"value\") {\n if (!isTruthy(cellValue.result.result)) {\n return {\n type: \"value\",\n result: { type: \"boolean\", value: false },\n };\n }\n }\n }\n } else {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Invalid argument type for AND function\",\n errAddress: context.dependencyNode,\n };\n }\n }\n\n // All arguments are truthy\n return {\n type: \"value\",\n result: { type: \"boolean\", value: true },\n };\n },\n};\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";AAAA;AAAA;AAAA;AAuCA,SAAS,QAAQ,CAAC,OAA2B;AAAA,EAC3C,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO,MAAM;AAAA,SACV;AAAA,MACH,OAAO,MAAM,UAAU;AAAA,SACpB;AAAA,MACH,OAAO,MAAM,UAAU;AAAA,SACpB;AAAA,MACH,OAAO;AAAA;AAAA,MAEP,OAAO;AAAA;AAAA;AAUN,IAAM,MAA0B;AAAA,EACrC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAC3D,IAAI,KAAK,KAAK,WAAW,GAAG;AAAA,MAC1B,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,WAAW,OAAO,KAAK,MAAM;AAAA,MAC3B,MAAM,YAAY,KAAK,aAAa,KAAK,OAAO;AAAA,MAEhD,IAAI,UAAU,SAAS,WAAW,UAAU,SAAS,uBAAuB;AAAA,QAC1E,OAAO;AAAA,MACT;AAAA,MAEA,IAAI,UAAU,SAAS,SAAS;AAAA,QAE9B,IAAI,CAAC,SAAS,UAAU,MAAM,GAAG;AAAA,UAC/B,OAAO;AAAA,YACL,MAAM;AAAA,YACN,QAAQ,EAAE,MAAM,WAAW,OAAO,MAAM;AAAA,UAC1C;AAAA,QACF;AAAA,MACF,EAAO,SAAI,UAAU,SAAS,kBAAkB;AAAA,QAE9C,MAAM,aAAa,UAAU,iBAAiB,KAAK,MAAM;AAAA,UACvD;AAAA,UACA,QAAQ,QAAQ;AAAA,UAChB,UAAU,UAAU;AAAA,UACpB,aAAa;AAAA,QACf,CAAC;AAAA,QAED,IAAI,WAAW,SAAS,WAAW,WAAW,SAAS,uBAAuB;AAAA,UAC5E,OAAO;AAAA,QACT;AAAA,QAEA,WAAW,aAAa,WAAW,QAAQ;AAAA,UACzC,IAAI,UAAU,OAAO,SAAS,SAAS;AAAA,YACrC,OAAO,UAAU;AAAA,UACnB;AAAA,UACA,IAAI,UAAU,OAAO,SAAS,SAAS;AAAA,YACrC,IAAI,CAAC,SAAS,UAAU,OAAO,MAAM,GAAG;AAAA,cACtC,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,QAAQ,EAAE,MAAM,WAAW,OAAO,MAAM;AAAA,cAC1C;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,EAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA;AAAA,IAEJ;AAAA,IAGA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,WAAW,OAAO,KAAK;AAAA,IACzC;AAAA;AAEJ;",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "D0FB4FD00CC5D74964756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/functions/logical/if/if.ts
|
|
2
2
|
import {
|
|
3
3
|
FormulaError
|
|
4
|
-
} from "
|
|
4
|
+
} from "../../../core/types.mjs";
|
|
5
5
|
function isTruthy(value) {
|
|
6
6
|
switch (value.type) {
|
|
7
7
|
case "boolean":
|
|
@@ -164,4 +164,4 @@ export {
|
|
|
164
164
|
IF
|
|
165
165
|
};
|
|
166
166
|
|
|
167
|
-
//# debugId=
|
|
167
|
+
//# debugId=8082D7E46D5CD04064756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/logical/if/if.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n FormulaError,\n type
|
|
5
|
+
"import {\n FormulaError,\n type CellAddress,\n type CellValue,\n type ErrorEvaluationResult,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n type SingleEvaluationResult,\n type SpilledValuesEvaluationResult,\n type SpreadsheetRange\n} from \"../../../core/types.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\nimport type { FormulaEvaluator } from \"../../../evaluator/formula-evaluator.mjs\";\n\n/**\n * IF function - Returns one value if a condition is true and another value if it's false\n *\n * Usage: IF(logical_test, value_if_true, [value_if_false])\n *\n * logical_test: The condition to evaluate (required)\n * value_if_true: The value to return if the condition is true (required)\n * value_if_false: The value to return if the condition is false (optional, defaults to FALSE)\n *\n * Examples:\n * IF(A1>10, \"High\", \"Low\") - returns \"High\" if A1>10, otherwise \"Low\"\n * IF(B1=\"\", \"Empty\", B1) - returns \"Empty\" if B1 is empty, otherwise B1's value\n * IF(C1<0, \"Negative\") - returns \"Negative\" if C1<0, otherwise FALSE\n *\n * Note:\n * - Supports spilled values (dynamic arrays) for all arguments\n * - Logical test evaluation: 0 and empty string are FALSE, everything else is TRUE\n * - If logical_test is spilled, returns spilled results\n */\n\n/**\n * Convert a cell value to boolean for logical evaluation\n */\nfunction isTruthy(value: CellValue): boolean {\n switch (value.type) {\n case \"boolean\":\n return value.value;\n case \"number\":\n return value.value !== 0;\n case \"string\":\n return value.value !== \"\";\n case \"infinity\":\n return true; // Infinity is truthy\n default:\n return false;\n }\n}\n\n/**\n * Helper for creating spilled-values result for IF function\n */\nfunction createIfSpilledResult(\n this: FormulaEvaluator,\n {\n logicalTestResult,\n valueIfTrueResult,\n valueIfFalseResult,\n context,\n }: {\n logicalTestResult: FunctionEvaluationResult;\n valueIfTrueResult: FunctionEvaluationResult;\n valueIfFalseResult: FunctionEvaluationResult;\n context: EvaluationContext;\n }\n): SpilledValuesEvaluationResult | ErrorEvaluationResult {\n const hasSpilledTest = logicalTestResult.type === \"spilled-values\";\n const hasSpilledTrue = valueIfTrueResult.type === \"spilled-values\";\n const hasSpilledFalse = valueIfFalseResult.type === \"spilled-values\";\n\n if (!hasSpilledTest && !hasSpilledTrue && !hasSpilledFalse) {\n throw new Error(\"createIfSpilledResult called without spilled values\");\n }\n\n return {\n type: \"spilled-values\",\n spillArea: (origin: CellAddress): SpreadsheetRange => {\n // Calculate spill area (union of all spilled ranges)\n let spillArea: SpreadsheetRange | undefined;\n\n const spilledResults = [\n hasSpilledTest ? logicalTestResult : null,\n hasSpilledTrue ? valueIfTrueResult : null,\n hasSpilledFalse ? valueIfFalseResult : null,\n ].filter(Boolean) as SpilledValuesEvaluationResult[];\n\n for (const result of spilledResults) {\n const currentSpillArea = result.spillArea(origin);\n if (!spillArea) {\n spillArea = currentSpillArea;\n } else {\n spillArea = this.unionRanges(\n this.projectRange(spillArea, origin),\n this.projectRange(currentSpillArea, origin)\n );\n }\n }\n\n if (!spillArea) {\n throw new Error(\"No spilled values found\");\n }\n return spillArea;\n },\n source: \"IF with spilled values\",\n evaluate: (spilledCell: any, evalContext: any): SingleEvaluationResult => {\n // Evaluate all arguments at this spilled position\n const spillLogicalResult = hasSpilledTest\n ? logicalTestResult.evaluate(spilledCell, evalContext)\n : logicalTestResult;\n const spillTrueResult = hasSpilledTrue\n ? valueIfTrueResult.evaluate(spilledCell, evalContext)\n : valueIfTrueResult;\n const spillFalseResult = hasSpilledFalse\n ? valueIfFalseResult.evaluate(spilledCell, evalContext)\n : valueIfFalseResult;\n\n // Check for errors\n if (spillLogicalResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled logical test has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n if (spillLogicalResult.type === \"error\" || spillLogicalResult.type === \"awaiting-evaluation\") {\n return spillLogicalResult;\n }\n\n if (spillTrueResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled true value has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n if (spillTrueResult.type === \"error\" || spillTrueResult.type === \"awaiting-evaluation\") {\n return spillTrueResult;\n }\n\n if (spillFalseResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled false value has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n if (spillFalseResult.type === \"error\" || spillFalseResult.type === \"awaiting-evaluation\") {\n return spillFalseResult;\n }\n\n // Perform IF logic\n if (spillLogicalResult.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Invalid logical test result\",\n errAddress: context.dependencyNode,\n };\n }\n\n const isTrue = isTruthy(spillLogicalResult.result);\n return isTrue ? spillTrueResult : spillFalseResult;\n },\n evaluateAllCells: (intersectingRange: any) => {\n throw new Error(\"WIP: evaluateAllCells for IF is not implemented\");\n },\n };\n}\n\n/**\n * IF function implementation\n */\nexport const IF: FunctionDefinition = {\n name: \"IF\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length < 2 || node.args.length > 3) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"IF function takes 2 or 3 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate logical test\n const logicalTestResult = this.evaluateNode(node.args[0]!, context);\n if (\n logicalTestResult.type === \"awaiting-evaluation\" ||\n logicalTestResult.type === \"error\"\n ) {\n return logicalTestResult;\n }\n\n // Handle spilled values - we need to evaluate both branches\n // because different cells might take different paths\n if (logicalTestResult.type === \"spilled-values\") {\n // Evaluate value_if_true\n const valueIfTrueResult = this.evaluateNode(node.args[1]!, context);\n if (valueIfTrueResult.type === \"error\" || valueIfTrueResult.type === \"awaiting-evaluation\") {\n return valueIfTrueResult;\n }\n\n // Evaluate value_if_false (optional, defaults to FALSE)\n let valueIfFalseResult: FunctionEvaluationResult;\n if (node.args.length > 2) {\n valueIfFalseResult = this.evaluateNode(node.args[2]!, context);\n if (valueIfFalseResult.type === \"error\" || valueIfFalseResult.type === \"awaiting-evaluation\") {\n return valueIfFalseResult;\n }\n } else {\n valueIfFalseResult = {\n type: \"value\",\n result: { type: \"boolean\", value: false },\n };\n }\n\n return createIfSpilledResult.call(this, {\n logicalTestResult,\n valueIfTrueResult,\n valueIfFalseResult,\n context,\n });\n }\n\n // Evaluate the logical test\n const isTrue = isTruthy(logicalTestResult.result);\n\n // LAZY EVALUATION: Only evaluate the branch we need\n if (isTrue) {\n // Evaluate value_if_true\n const valueIfTrueResult = this.evaluateNode(node.args[1]!, context);\n return valueIfTrueResult;\n } else {\n // Evaluate value_if_false (optional, defaults to FALSE)\n if (node.args.length > 2) {\n const valueIfFalseResult = this.evaluateNode(node.args[2]!, context);\n return valueIfFalseResult;\n } else {\n return {\n type: \"value\",\n result: { type: \"boolean\", value: false },\n };\n }\n }\n },\n};\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";AAAA;AAAA;AAAA;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "8082D7E46D5CD04064756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/functions/logical/iferror/iferror.ts
|
|
2
2
|
import {
|
|
3
3
|
FormulaError
|
|
4
|
-
} from "
|
|
5
|
-
import { captureEvaluationErrors } from "
|
|
4
|
+
} from "../../../core/types.mjs";
|
|
5
|
+
import { captureEvaluationErrors } from "../../../core/utils.mjs";
|
|
6
6
|
function createIfErrorSpilledResult({
|
|
7
7
|
valueResult,
|
|
8
8
|
valueIfErrorResult,
|
|
@@ -95,4 +95,4 @@ export {
|
|
|
95
95
|
IFERROR
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
//# debugId=
|
|
98
|
+
//# debugId=1EE09B201DE1DE6264756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/logical/iferror/iferror.ts"],
|
|
4
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 ErrorEvaluationResult,\n} from \"
|
|
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 ErrorEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport { captureEvaluationErrors } from \"../../../core/utils.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\nimport type { FormulaEvaluator } from \"../../../evaluator/formula-evaluator.mjs\";\n\n/**\n * IFERROR function - Returns a value you specify if a formula evaluates to an error\n *\n * Usage: IFERROR(value, value_if_error)\n *\n * value: The expression to check for errors (required)\n * value_if_error: The value to return if the expression is an error (required)\n *\n * Examples:\n * IFERROR(A1/B1, \"Division error\") - returns \"Division error\" if B1 is 0\n * IFERROR(VLOOKUP(A1, table, 2), \"Not found\") - returns \"Not found\" if lookup fails\n * IFERROR(1/0, 0) - returns 0 instead of #DIV/0! error\n *\n * Note:\n * - If value is not an error, returns the value unchanged\n * - If value is an error, returns value_if_error\n * - Supports spilled values (dynamic arrays) for both arguments\n * - Any error type (#VALUE!, #DIV/0!, #N/A, etc.) triggers the error handling\n */\n\n/**\n * Helper for creating spilled-values result for IFERROR function\n */\nfunction createIfErrorSpilledResult(\n this: FormulaEvaluator,\n {\n valueResult,\n valueIfErrorResult,\n context,\n }: {\n valueResult: FunctionEvaluationResult;\n valueIfErrorResult: FunctionEvaluationResult;\n context: EvaluationContext;\n }\n): SpilledValuesEvaluationResult | ErrorEvaluationResult {\n const hasSpilledValue = valueResult.type === \"spilled-values\";\n const hasSpilledError = valueIfErrorResult.type === \"spilled-values\";\n\n if (!hasSpilledValue && !hasSpilledError) {\n throw new Error(\"createIfErrorSpilledResult called without spilled values\");\n }\n\n return {\n type: \"spilled-values\",\n spillArea: (origin: CellAddress): SpreadsheetRange => {\n // Calculate spill area (union of spilled ranges)\n if (hasSpilledValue && valueResult.type === \"spilled-values\") {\n const spillArea = valueResult.spillArea(origin);\n if (hasSpilledError && valueIfErrorResult.type === \"spilled-values\") {\n return this.unionRanges(\n this.projectRange(spillArea, origin),\n this.projectRange(valueIfErrorResult.spillArea(origin), origin)\n );\n }\n return spillArea;\n } else if (\n hasSpilledError &&\n valueIfErrorResult.type === \"spilled-values\"\n ) {\n return valueIfErrorResult.spillArea(origin);\n } else {\n throw new Error(\"No spilled values found\");\n }\n },\n source: \"IFERROR with spilled values\",\n evaluate: (spilledCell: any, evalContext: any): SingleEvaluationResult => {\n // Evaluate arguments at this spilled position\n const spillValueResult = hasSpilledValue\n ? valueResult.evaluate(spilledCell, evalContext)\n : valueResult;\n const spillErrorResult = hasSpilledError\n ? valueIfErrorResult.evaluate(spilledCell, evalContext)\n : valueIfErrorResult;\n\n if (spillValueResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled value has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n\n if (spillErrorResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled error value has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n\n // IFERROR logic: if first argument is error, return second argument\n if (\n spillValueResult.type === \"error\" ||\n spillValueResult.type === \"awaiting-evaluation\"\n ) {\n return spillErrorResult;\n }\n\n // If first argument is not an error, return it\n return spillValueResult;\n },\n evaluateAllCells: (intersectingRange: any) => {\n throw new Error(\"WIP: evaluateAllCells for IFERROR is not implemented\");\n },\n };\n}\n\n/**\n * IFERROR function implementation\n */\nexport const IFERROR: FunctionDefinition = {\n name: \"IFERROR\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length !== 2) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"IFERROR function takes exactly 2 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate the value argument (the expression to check for errors)\n const valueResult = captureEvaluationErrors(\n context.dependencyNode,\n () => this.evaluateNode(node.args[0]!, context)\n );\n\n if (valueResult.type === \"awaiting-evaluation\") {\n return valueResult;\n }\n\n // Handle spilled values - we need to evaluate both branches\n // because different cells might have errors or not\n if (valueResult.type === \"spilled-values\") {\n // Evaluate the value_if_error argument\n const valueIfErrorResult = this.evaluateNode(node.args[1]!, context);\n if (\n valueIfErrorResult.type === \"error\" ||\n valueIfErrorResult.type === \"awaiting-evaluation\"\n ) {\n return valueIfErrorResult; // Error in the error handler itself\n }\n\n return createIfErrorSpilledResult.call(this, {\n valueResult,\n valueIfErrorResult,\n context,\n });\n }\n\n // LAZY EVALUATION: Only evaluate error handler if we have an error\n // IFERROR logic: if first argument is error, return second argument\n if (valueResult.type === \"error\") {\n const valueIfErrorResult = this.evaluateNode(node.args[1]!, context);\n return valueIfErrorResult;\n }\n\n // If first argument is not an error, return it unchanged\n // WITHOUT evaluating the error handler\n return valueResult;\n },\n};\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "1EE09B201DE1DE6264756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/functions/logical/or/or.ts
|
|
2
2
|
import {
|
|
3
3
|
FormulaError
|
|
4
|
-
} from "
|
|
4
|
+
} from "../../../core/types.mjs";
|
|
5
5
|
function isTruthy(value) {
|
|
6
6
|
switch (value.type) {
|
|
7
7
|
case "boolean":
|
|
@@ -81,4 +81,4 @@ export {
|
|
|
81
81
|
OR
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
//# debugId=
|
|
84
|
+
//# debugId=4301A45DE683310964756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/logical/or/or.ts"],
|
|
4
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 ErrorEvaluationResult,\n} from \"
|
|
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 ErrorEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport type { FormulaEvaluator } from \"../../../evaluator/formula-evaluator.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\n\n/**\n * OR function - Returns TRUE if any argument is TRUE, FALSE otherwise\n *\n * Usage: OR(logical1, [logical2], ...)\n *\n * logical1, logical2, ...: Logical values or expressions to evaluate\n *\n * Examples:\n * OR(TRUE, FALSE) - returns TRUE\n * OR(FALSE, FALSE) - returns FALSE\n * OR(A1>10, B1<20) - returns TRUE if either condition is met\n * OR(A1:A3) - returns TRUE if any value in A1:A3 is truthy\n *\n * Note:\n * - Supports spilled values (dynamic arrays) for arguments\n * - Logical evaluation: 0 and empty string are FALSE, everything else is TRUE\n * - If any argument is spilled, processes all values in the range\n * - Short-circuit evaluation: stops at first TRUE value\n */\n\n/**\n * Convert a cell value to boolean for logical evaluation\n */\nfunction isTruthy(value: CellValue): boolean {\n switch (value.type) {\n case \"boolean\":\n return value.value;\n case \"number\":\n return value.value !== 0;\n case \"string\":\n return value.value !== \"\";\n case \"infinity\":\n return true; // Infinity is truthy\n default:\n return false;\n }\n}\n\n// OR function does not create spilled results - it processes all values in ranges\n// as individual logical tests and returns a single boolean result\n\n/**\n * OR function implementation\n */\nexport const OR: FunctionDefinition = {\n name: \"OR\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length === 0) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OR function requires at least one argument\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Process arguments one by one (like AND function)\n for (const arg of node.args) {\n const argResult = this.evaluateNode(arg, context);\n\n if (argResult.type === \"error\" || argResult.type === \"awaiting-evaluation\") {\n return argResult;\n }\n\n if (argResult.type === \"value\") {\n // Single value - check if truthy\n if (isTruthy(argResult.result)) {\n // Short-circuit: return TRUE on first truthy value\n return {\n type: \"value\",\n result: { type: \"boolean\", value: true },\n };\n }\n } else if (argResult.type === \"spilled-values\") {\n // Range - check all values in the range\n const cellValues = argResult.evaluateAllCells.call(this, {\n context,\n origin: context.cellAddress,\n evaluate: argResult.evaluate,\n lookupOrder: \"col-major\",\n });\n if (cellValues.type === \"error\" || cellValues.type === \"awaiting-evaluation\") {\n return cellValues;\n }\n for (const cellValue of cellValues.values) {\n if (cellValue.result.type === \"error\" || cellValue.result.type === \"awaiting-evaluation\") {\n return cellValue.result;\n }\n if (cellValue.result.type === \"value\") {\n if (isTruthy(cellValue.result.result)) {\n // Short-circuit: return TRUE on first truthy value\n return {\n type: \"value\",\n result: { type: \"boolean\", value: true },\n };\n }\n }\n }\n } else {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Invalid argument type for OR function\",\n errAddress: context.dependencyNode,\n };\n }\n }\n\n // All arguments are falsy\n return {\n type: \"value\",\n result: { type: \"boolean\", value: false },\n };\n },\n};\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";AAAA;AAAA;AAAA;AAuCA,SAAS,QAAQ,CAAC,OAA2B;AAAA,EAC3C,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO,MAAM;AAAA,SACV;AAAA,MACH,OAAO,MAAM,UAAU;AAAA,SACpB;AAAA,MACH,OAAO,MAAM,UAAU;AAAA,SACpB;AAAA,MACH,OAAO;AAAA;AAAA,MAEP,OAAO;AAAA;AAAA;AAUN,IAAM,KAAyB;AAAA,EACpC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAC3D,IAAI,KAAK,KAAK,WAAW,GAAG;AAAA,MAC1B,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,WAAW,OAAO,KAAK,MAAM;AAAA,MAC3B,MAAM,YAAY,KAAK,aAAa,KAAK,OAAO;AAAA,MAEhD,IAAI,UAAU,SAAS,WAAW,UAAU,SAAS,uBAAuB;AAAA,QAC1E,OAAO;AAAA,MACT;AAAA,MAEA,IAAI,UAAU,SAAS,SAAS;AAAA,QAE9B,IAAI,SAAS,UAAU,MAAM,GAAG;AAAA,UAE9B,OAAO;AAAA,YACL,MAAM;AAAA,YACN,QAAQ,EAAE,MAAM,WAAW,OAAO,KAAK;AAAA,UACzC;AAAA,QACF;AAAA,MACF,EAAO,SAAI,UAAU,SAAS,kBAAkB;AAAA,QAE9C,MAAM,aAAa,UAAU,iBAAiB,KAAK,MAAM;AAAA,UACvD;AAAA,UACA,QAAQ,QAAQ;AAAA,UAChB,UAAU,UAAU;AAAA,UACpB,aAAa;AAAA,QACf,CAAC;AAAA,QACD,IAAI,WAAW,SAAS,WAAW,WAAW,SAAS,uBAAuB;AAAA,UAC5E,OAAO;AAAA,QACT;AAAA,QACA,WAAW,aAAa,WAAW,QAAQ;AAAA,UACzC,IAAI,UAAU,OAAO,SAAS,WAAW,UAAU,OAAO,SAAS,uBAAuB;AAAA,YACxF,OAAO,UAAU;AAAA,UACnB;AAAA,UACA,IAAI,UAAU,OAAO,SAAS,SAAS;AAAA,YACrC,IAAI,SAAS,UAAU,OAAO,MAAM,GAAG;AAAA,cAErC,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,QAAQ,EAAE,MAAM,WAAW,OAAO,KAAK;AAAA,cACzC;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF,EAAO;AAAA,QACL,OAAO;AAAA,UACL,MAAM;AAAA,UACN,KAAK,aAAa;AAAA,UAClB,SAAS;AAAA,UACT,YAAY,QAAQ;AAAA,QACtB;AAAA;AAAA,IAEJ;AAAA,IAGA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,WAAW,OAAO,MAAM;AAAA,IAC1C;AAAA;AAEJ;",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "4301A45DE683310964756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/lookup/count/count-utils.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n type CellAddress,\n type FunctionEvaluationResult,\n type SingleEvaluationResult,\n} from \"
|
|
5
|
+
"import {\n type CellAddress,\n type FunctionEvaluationResult,\n type SingleEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport type { ParsedCriteria } from \"../../criteria-parser.mjs\";\n\n/**\n * Performs counting of numeric values from an iterable of SingleEvaluationResult values\n * Handles numbers and infinities according to Excel's COUNT behavior\n * - Propagates errors immediately\n * - Only counts numeric values (numbers and infinities)\n * - Ignores non-numeric values (strings, booleans, empty cells)\n *\n * @param results - Iterable of SingleEvaluationResult to count\n * @returns FunctionEvaluationResult with the count\n */\nexport function performCount(\n results: Iterable<SingleEvaluationResult>\n): FunctionEvaluationResult {\n let count = 0;\n\n for (const result of results) {\n if (result.type === \"error\" || result.type === \"awaiting-evaluation\") {\n // Propagate errors immediately\n return result;\n }\n\n if (result.type === \"value\") {\n if (\n result.result.type === \"number\" ||\n result.result.type === \"infinity\"\n ) {\n count++;\n }\n // Non-numeric values (strings, booleans) are ignored\n }\n }\n\n return {\n type: \"value\",\n result: { type: \"number\", value: count },\n };\n}\n\nexport function countEmptyCells(\n criteriaRangeResult: FunctionEvaluationResult,\n parsedCriteria: ParsedCriteria,\n currentCell: CellAddress\n): FunctionEvaluationResult | undefined {\n // Special case: counting empty cells over infinite ranges\n if (\n criteriaRangeResult.type === \"spilled-values\" &&\n parsedCriteria.type === \"exact\" &&\n parsedCriteria.value.type === \"string\" &&\n parsedCriteria.value.value === \"\"\n ) {\n const spillArea = criteriaRangeResult.spillArea(currentCell);\n\n // Check if this is an infinite range\n if (\n spillArea.end.col.type === \"infinity\" ||\n spillArea.end.row.type === \"infinity\"\n ) {\n // Return infinity for infinite empty cell count\n return {\n type: \"value\",\n result: { type: \"infinity\", sign: \"positive\" },\n };\n }\n }\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";AAiBO,SAAS,YAAY,CAC1B,SAC0B;AAAA,EAC1B,IAAI,QAAQ;AAAA,EAEZ,WAAW,UAAU,SAAS;AAAA,IAC5B,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,uBAAuB;AAAA,MAEpE,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,OAAO,SAAS,SAAS;AAAA,MAC3B,IACE,OAAO,OAAO,SAAS,YACvB,OAAO,OAAO,SAAS,YACvB;AAAA,QACA;AAAA,MACF;AAAA,IAEF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ,EAAE,MAAM,UAAU,OAAO,MAAM;AAAA,EACzC;AAAA;AAGK,SAAS,eAAe,CAC7B,qBACA,gBACA,aACsC;AAAA,EAEtC,IACE,oBAAoB,SAAS,oBAC7B,eAAe,SAAS,WACxB,eAAe,MAAM,SAAS,YAC9B,eAAe,MAAM,UAAU,IAC/B;AAAA,IACA,MAAM,YAAY,oBAAoB,UAAU,WAAW;AAAA,IAG3D,IACE,UAAU,IAAI,IAAI,SAAS,cAC3B,UAAU,IAAI,IAAI,SAAS,YAC3B;AAAA,MAEA,OAAO;AAAA,QACL,MAAM;AAAA,QACN,QAAQ,EAAE,MAAM,YAAY,MAAM,WAAW;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAAA;",
|
|
8
8
|
"debugId": "27BAB068756EB60864756E2164756E21",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/functions/lookup/count/count.ts
|
|
2
|
-
import { createArgumentIterator } from "
|
|
2
|
+
import { createArgumentIterator } from "../../../functions/function-utils.mjs";
|
|
3
3
|
import { performCount } from "./count-utils.mjs";
|
|
4
4
|
var COUNT = {
|
|
5
5
|
name: "COUNT",
|
|
@@ -15,4 +15,4 @@ export {
|
|
|
15
15
|
COUNT
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
//# debugId=
|
|
18
|
+
//# debugId=9BE1648CD1E3933E64756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/lookup/count/count.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"
|
|
5
|
+
"import {\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport { createArgumentIterator } from \"../../../functions/function-utils.mjs\";\nimport { performCount } from \"./count-utils.mjs\";\n\n/**\n * COUNT function - Counts the number of cells that contain numbers\n * \n * Usage: COUNT(value1, [value2], ...)\n * \n * Examples:\n * COUNT(1, 2, 3) - returns 3\n * COUNT(A1:A10) - counts numeric values in the range A1:A10\n * COUNT(A1:A5, B1:B5) - counts numeric values in both ranges\n * \n * Note:\n * - Only numeric values are counted (numbers and infinities)\n * - Text, logical values, and empty cells are ignored\n * - Errors propagate immediately\n * \n * From Excel documentation:\n * \"The COUNT function counts the number of cells that contain numbers, \n * and counts numbers within the list of arguments.\"\n */\nexport const COUNT: FunctionDefinition = {\n name: \"COUNT\",\n evaluate: function (node, context): FunctionEvaluationResult {\n // Create iterator over all argument values\n const argumentValues = createArgumentIterator(this, node, context, \"col-major\");\n\n if (argumentValues.type !== \"values\") {\n return argumentValues;\n }\n // Use shared counting utility\n return performCount(argumentValues.values);\n },\n};\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";AAIA;AACA;AAqBO,IAAM,QAA4B;AAAA,EACvC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAE3D,MAAM,iBAAiB,uBAAuB,MAAM,MAAM,SAAS,WAAW;AAAA,IAE9E,IAAI,eAAe,SAAS,UAAU;AAAA,MACpC,OAAO;AAAA,IACT;AAAA,IAEA,OAAO,aAAa,eAAe,MAAM;AAAA;AAE7C;",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "9BE1648CD1E3933E64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/functions/lookup/count/countif.ts
|
|
2
2
|
import {
|
|
3
3
|
FormulaError
|
|
4
|
-
} from "
|
|
4
|
+
} from "../../../core/types.mjs";
|
|
5
5
|
import {
|
|
6
6
|
processMultiCriteriaValues
|
|
7
7
|
} from "../../criteria-utils.mjs";
|
|
@@ -65,4 +65,4 @@ export {
|
|
|
65
65
|
COUNTIF
|
|
66
66
|
};
|
|
67
67
|
|
|
68
|
-
//# debugId=
|
|
68
|
+
//# debugId=407C64A3E189C5E664756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/lookup/count/countif.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n FormulaError,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"
|
|
5
|
+
"import {\n FormulaError,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\nimport {\n processMultiCriteriaValues,\n validateSingleCriteriaArgs,\n} from \"../../criteria-utils.mjs\";\nimport { parseCriteria, matchesParsedCriteria } from \"../../criteria-parser.mjs\";\nimport { countEmptyCells } from \"./count-utils.mjs\";\n\n/**\n * COUNTIF function - Counts cells in a range that meet a criteria\n *\n * Usage: COUNTIF(range, criteria)\n *\n * range: The range of cells to evaluate\n * criteria: The criteria to match against. Can be:\n * - Exact value: \"Apple\", 42\n * - Comparison: \">10\", \"<=5\", \"<>0\"\n * - Wildcards: \"App*\", \"?ruit\"\n *\n * Examples:\n * COUNTIF(A1:A10, \"Apple\") - counts cells containing \"Apple\"\n * COUNTIF(B1:B10, \">10\") - counts cells with values greater than 10\n * COUNTIF(C1:C10, \"App*\") - counts cells starting with \"App\"\n *\n * Note:\n * - Supports type coercion for comparisons\n * - Case-sensitive string matching\n * - Wildcards: * matches any sequence, ? matches any single character\n */\n\n/**\n * COUNTIF function implementation\n */\nexport const COUNTIF: FunctionDefinition = {\n name: \"COUNTIF\",\n evaluate: function (node, context): FunctionEvaluationResult {\n // Validate arguments - COUNTIF takes exactly 2 arguments\n if (node.args.length !== 2) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"COUNTIF function takes exactly 2 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate criteria range (first argument)\n const criteriaRangeResult = this.evaluateNode(node.args[0]!, context);\n if (criteriaRangeResult.type === \"error\" || criteriaRangeResult.type === \"awaiting-evaluation\") {\n return criteriaRangeResult;\n }\n\n // Evaluate criteria (second argument)\n const criteriaResult = this.evaluateNode(node.args[1]!, context);\n if (criteriaResult.type === \"error\" || criteriaResult.type === \"awaiting-evaluation\") {\n return criteriaResult;\n }\n\n if (criteriaResult.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"COUNTIF 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 // Special case: counting empty cells over infinite ranges\n const countingEmptyCells = countEmptyCells(\n criteriaRangeResult,\n parsedCriteria,\n context.cellAddress\n );\n if (countingEmptyCells) {\n return countingEmptyCells;\n }\n\n // Use shared criteria processing - count all matching values (including non-numeric)\n let count = 0;\n\n const results = processMultiCriteriaValues(\n this,\n criteriaRangeResult,\n [{ rangeResult: criteriaRangeResult, parsedCriteria }],\n context,\n \"col-major\"\n );\n\n if (results.type === \"error\" || results.type === \"awaiting-evaluation\") {\n return results;\n }\n\n for (const result of results.values) {\n // COUNTIF counts all matching cells, including errors and non-numeric values\n count++;\n }\n\n return {\n type: \"value\",\n result: { type: \"number\", value: count },\n };\n },\n};\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";AAAA;AAAA;AAAA;AAMA;AAAA;AAAA;AAIA;AACA;AA2BO,IAAM,UAA8B;AAAA,EACzC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAE3D,IAAI,KAAK,KAAK,WAAW,GAAG;AAAA,MAC1B,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,MAAM,sBAAsB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IACpE,IAAI,oBAAoB,SAAS,WAAW,oBAAoB,SAAS,uBAAuB;AAAA,MAC9F,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,iBAAiB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IAC/D,IAAI,eAAe,SAAS,WAAW,eAAe,SAAS,uBAAuB;AAAA,MACpF,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,gBACzB,qBACA,gBACA,QAAQ,WACV;AAAA,IACA,IAAI,oBAAoB;AAAA,MACtB,OAAO;AAAA,IACT;AAAA,IAGA,IAAI,QAAQ;AAAA,IAEZ,MAAM,UAAU,2BACd,MACA,qBACA,CAAC,EAAE,aAAa,qBAAqB,eAAe,CAAC,GACrD,SACA,WACF;AAAA,IAEA,IAAI,QAAQ,SAAS,WAAW,QAAQ,SAAS,uBAAuB;AAAA,MACtE,OAAO;AAAA,IACT;AAAA,IAEA,WAAW,UAAU,QAAQ,QAAQ;AAAA,MAEnC;AAAA,IACF;AAAA,IAEA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,UAAU,OAAO,MAAM;AAAA,IACzC;AAAA;AAEJ;",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "407C64A3E189C5E664756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/lookup/count/countifs.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n FormulaError,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"
|
|
5
|
+
"import {\n FormulaError,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\nimport { \n parseCriteriaPairs, \n processMultiCriteriaValues, \n validateCountifsArgs \n} from \"../../criteria-utils.mjs\";\n\n/**\n * COUNTIFS function - Counts cells that meet multiple criteria\n * \n * Usage: COUNTIFS(criteria_range1, criteria1, [criteria_range2, criteria2], ...)\n * \n * criteria_range1: The first range to evaluate against criteria1\n * criteria1: The first criteria to match against\n * criteria_range2, criteria2: Optional additional criteria pairs\n * \n * Examples:\n * COUNTIFS(A1:A10, \"Apple\") - counts cells in A1:A10 that equal \"Apple\"\n * COUNTIFS(A1:A10, \"Apple\", B1:B10, \">10\") - counts where A1:A10 = \"Apple\" AND B1:B10 > 10\n * \n * Note:\n * - All criteria must be satisfied for a cell to be counted\n * - Counts all matching cells, not just numeric ones\n * - Returns 0 if no cells match all criteria\n * - Unlike other IFS functions, COUNTIFS counts the first criteria range itself\n */\nexport const COUNTIFS: FunctionDefinition = {\n name: \"COUNTIFS\",\n evaluate: function (node, context): FunctionEvaluationResult {\n // Validate arguments\n const argError = validateCountifsArgs(node.args.length, context);\n if (argError) {\n return argError;\n }\n\n // Parse criteria pairs starting from argument 0 (COUNTIFS has different syntax)\n const criteriaPairsResult = parseCriteriaPairs.call(this, node, context, this.evaluateNode, 0);\n if ('type' in criteriaPairsResult) {\n return criteriaPairsResult;\n }\n\n // The first criteria range is what we count\n const countRangeResult = criteriaPairsResult[0]!.rangeResult;\n\n // Process values with criteria using generator - count all matching cells (including non-numeric)\n let count = 0;\n\n const matchingValues = processMultiCriteriaValues(\n this,\n countRangeResult,\n criteriaPairsResult,\n context,\n \"col-major\"\n );\n \n if (matchingValues.type === \"error\" || matchingValues.type === \"awaiting-evaluation\") {\n return matchingValues;\n }\n\n for (const result of matchingValues.values) {\n // COUNTIFS counts all matching cells, including errors and non-numeric values\n count++;\n }\n\n return {\n type: \"value\",\n result: { type: \"number\", value: count },\n };\n },\n};\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";AAMA;AAAA;AAAA;AAAA;AAAA;AAyBO,IAAM,WAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAE3D,MAAM,WAAW,qBAAqB,KAAK,KAAK,QAAQ,OAAO;AAAA,IAC/D,IAAI,UAAU;AAAA,MACZ,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,sBAAsB,mBAAmB,KAAK,MAAM,MAAM,SAAS,KAAK,cAAc,CAAC;AAAA,IAC7F,IAAI,UAAU,qBAAqB;AAAA,MACjC,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,mBAAmB,oBAAoB,GAAI;AAAA,IAGjD,IAAI,QAAQ;AAAA,IAEZ,MAAM,iBAAiB,2BACrB,MACA,kBACA,qBACA,SACA,WACF;AAAA,IAEA,IAAI,eAAe,SAAS,WAAW,eAAe,SAAS,uBAAuB;AAAA,MACpF,OAAO;AAAA,IACT;AAAA,IAEA,WAAW,UAAU,eAAe,QAAQ;AAAA,MAE1C;AAAA,IACF;AAAA,IAEA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,UAAU,OAAO,MAAM;AAAA,IACzC;AAAA;AAEJ;",
|
|
8
8
|
"debugId": "F0EF47E92080589364756E2164756E21",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/functions/lookup/index-lookup/index-lookup.ts
|
|
2
2
|
import {
|
|
3
3
|
FormulaError
|
|
4
|
-
} from "
|
|
4
|
+
} from "../../../core/types.mjs";
|
|
5
5
|
function getValueFromArray(arrayResult, row, col, context) {
|
|
6
6
|
const dims = arrayResult.spillArea(context.cellAddress);
|
|
7
7
|
const rowIndex = row - 1;
|
|
@@ -156,4 +156,4 @@ export {
|
|
|
156
156
|
INDEX
|
|
157
157
|
};
|
|
158
158
|
|
|
159
|
-
//# debugId=
|
|
159
|
+
//# debugId=055E9DA396CC498064756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/lookup/index-lookup/index-lookup.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n FormulaError,\n type CellValue,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n type ValueEvaluationResult,\n type SpilledValuesEvaluationResult,\n type CellAddress,\n type SpreadsheetRange,\n type ErrorEvaluationResult,\n} from \"
|
|
5
|
+
"import {\n FormulaError,\n type CellValue,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n type ValueEvaluationResult,\n type SpilledValuesEvaluationResult,\n type CellAddress,\n type SpreadsheetRange,\n type ErrorEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport type { FormulaEngine } from \"../../../core/engine.mjs\";\nimport type { FormulaEvaluator } from \"../../../evaluator/formula-evaluator.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\n\n/**\n * INDEX function - Returns a value from a table or array\n * INDEX(array, row_num, [column_num])\n *\n * STRICT TYPE CHECKING:\n * - array: range/array only\n * - row_num: number only (integer, 1-based)\n * - column_num: number only (integer, 1-based, optional)\n *\n * If array is 1-dimensional (single row or column):\n * - Only row_num is used (treats as a linear array)\n * - column_num is ignored if provided\n *\n * If array is 2-dimensional:\n * - Both row_num and column_num can be used\n * - If column_num is omitted, returns entire row\n */\n\n// Helper function to get value from array at specific position\nfunction getValueFromArray(\n this: FormulaEvaluator,\n arrayResult: SpilledValuesEvaluationResult,\n row: number,\n col: number,\n context: EvaluationContext\n): CellValue | ErrorEvaluationResult {\n const dims = arrayResult.spillArea(context.cellAddress);\n\n // Convert 1-based indices to 0-based\n const rowIndex = row - 1;\n const colIndex = col - 1;\n\n // Calculate actual cell position\n const actualRow = dims.start.row + rowIndex;\n const actualCol = dims.start.col + colIndex;\n\n // Check bounds\n if (\n actualRow < 0 ||\n (dims.end.row.type === \"number\" && actualRow > dims.end.row.value)\n ) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: `INDEX: row_num ${row} is out of range`,\n errAddress: context.dependencyNode,\n };\n }\n\n if (\n actualCol < 0 ||\n (dims.end.col.type === \"number\" && actualCol > dims.end.col.value)\n ) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: `INDEX: column_num ${col} is out of range`,\n errAddress: context.dependencyNode,\n };\n }\n\n const spilledAddress: CellAddress = {\n colIndex: actualCol,\n rowIndex: actualRow,\n sheetName: context.cellAddress.sheetName,\n workbookName: context.cellAddress.workbookName,\n };\n\n const spill = {\n address: spilledAddress,\n spillOffset: {\n x: actualCol - dims.start.col,\n y: actualRow - dims.start.row,\n },\n };\n\n const spillResult = arrayResult.evaluate(spill.spillOffset, context);\n\n if (!spillResult) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"INDEX: Unable to retrieve value from array\",\n errAddress: context.dependencyNode,\n };\n }\n\n if (\n spillResult.type === \"error\" ||\n spillResult.type === \"awaiting-evaluation\"\n ) {\n return spillResult;\n }\n\n return spillResult.result;\n}\n\nexport const INDEX: FunctionDefinition = {\n name: \"INDEX\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length < 2 || node.args.length > 3) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"INDEX function takes 2 or 3 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate array argument\n const arrayResult = this.evaluateNode(node.args[0]!, context);\n if (\n arrayResult.type === \"error\" ||\n arrayResult.type === \"awaiting-evaluation\"\n ) {\n return arrayResult;\n }\n\n // Evaluate row_num argument\n const rowNumResult = this.evaluateNode(node.args[1]!, context);\n if (\n rowNumResult.type === \"error\" ||\n rowNumResult.type === \"awaiting-evaluation\"\n ) {\n return rowNumResult;\n }\n\n // Evaluate column_num argument (optional)\n let colNumResult: FunctionEvaluationResult | null = null;\n if (node.args[2]) {\n colNumResult = this.evaluateNode(node.args[2], context);\n if (\n colNumResult.type === \"error\" ||\n colNumResult.type === \"awaiting-evaluation\"\n ) {\n return colNumResult;\n }\n }\n\n // Handle spilled arrays for row_num and col_num (not array which is expected to be a range)\n if (\n rowNumResult.type === \"spilled-values\" ||\n (colNumResult && colNumResult.type === \"spilled-values\")\n ) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message:\n \"INDEX: Spilled row_num/column_num arguments not yet implemented\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Strict type checking for row_num\n if (rowNumResult.result.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: `INDEX row_num must be number, got ${rowNumResult.result.type}`,\n errAddress: context.dependencyNode,\n };\n }\n\n const colNumValue = colNumResult?.result;\n\n // Strict type checking for column_num if provided\n if (colNumValue && colNumValue.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: `INDEX column_num must be number, got ${colNumValue.type}`,\n errAddress: context.dependencyNode,\n };\n }\n\n // Extract row and column numbers (convert to integers)\n const rowNum = Math.floor(rowNumResult.result.value);\n const colNum = colNumValue ? Math.floor(colNumValue.value) : 1;\n\n // Validate that indices are positive\n if (rowNum < 1) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: `INDEX row_num must be >= 1, got ${rowNum}`,\n errAddress: context.dependencyNode,\n };\n }\n\n if (colNum < 1) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: `INDEX column_num must be >= 1, got ${colNum}`,\n errAddress: context.dependencyNode,\n };\n }\n\n // Handle different array result types\n if (arrayResult.type === \"value\") {\n // Single value case - can only access [1,1]\n if (rowNum !== 1 || colNum !== 1) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: `INDEX: Single value can only be accessed at [1,1], got [${rowNum},${colNum}]`,\n errAddress: context.dependencyNode,\n };\n }\n return {\n type: \"value\",\n result: arrayResult.result,\n } satisfies ValueEvaluationResult;\n } else if (arrayResult.type === \"spilled-values\") {\n // Array case - use helper function to get value\n const result = getValueFromArray.call(\n this,\n arrayResult,\n rowNum,\n colNum,\n context\n );\n\n if (result.type === \"error\" || result.type === \"awaiting-evaluation\") {\n return result;\n }\n\n return {\n type: \"value\",\n result,\n } satisfies ValueEvaluationResult;\n } else {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"INDEX: Invalid array argument type\",\n errAddress: context.dependencyNode,\n };\n }\n },\n};\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "055E9DA396CC498064756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/functions/lookup/match/match.ts
|
|
2
2
|
import {
|
|
3
3
|
FormulaError
|
|
4
|
-
} from "
|
|
4
|
+
} from "../../../core/types.mjs";
|
|
5
5
|
function matchOperation(lookupValue, lookupArray, matchType, context, isHorizontal) {
|
|
6
6
|
if (lookupValue.type !== "string" && lookupValue.type !== "number") {
|
|
7
7
|
return {
|
|
@@ -137,4 +137,4 @@ export {
|
|
|
137
137
|
MATCH
|
|
138
138
|
};
|
|
139
139
|
|
|
140
|
-
//# debugId=
|
|
140
|
+
//# debugId=BA7EA11C6CC1796964756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/functions/lookup/match/match.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n FormulaError,\n type CellValue,\n type EvaluateAllCellsResult,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"
|
|
5
|
+
"import {\n FormulaError,\n type CellValue,\n type EvaluateAllCellsResult,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"../../../core/types.mjs\";\nimport type { EvaluationContext } from \"../../../evaluator/evaluation-context.mjs\";\n\n/**\n * MATCH function - Returns the position of a value in an array\n * MATCH(lookup_value, lookup_array, [match_type])\n * match_type: 1 = less than or equal (default), 0 = exact match, -1 = greater than or equal\n *\n * STRICT TYPE CHECKING:\n * - lookup_value: string or number only\n * - lookup_array: array of strings or numbers only\n * - match_type: number only (must be -1, 0, or 1)\n */\n\n// Helper function to perform MATCH operation\nfunction matchOperation(\n lookupValue: CellValue,\n lookupArray: EvaluateAllCellsResult,\n matchType: number,\n context: EvaluationContext,\n isHorizontal: boolean\n): FunctionEvaluationResult {\n // Strict type checking for lookup_value\n if (lookupValue.type !== \"string\" && lookupValue.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: `MATCH lookup_value must be string or number, got ${lookupValue.type}`,\n errAddress: context.dependencyNode,\n };\n }\n\n // Validate match_type\n if (matchType !== -1 && matchType !== 0 && matchType !== 1) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: `MATCH match_type must be -1, 0, or 1, got ${matchType}`,\n errAddress: context.dependencyNode,\n };\n }\n if (\n lookupArray.type === \"awaiting-evaluation\" ||\n lookupArray.type === \"error\"\n ) {\n return lookupArray;\n }\n\n for (const value of lookupArray.values) {\n if (value.result.type === \"value\") {\n if (matchType === 0) {\n // Exact match\n const arrayValue = value.result.result;\n\n if (\n arrayValue.type === lookupValue.type &&\n arrayValue.value === lookupValue.value\n ) {\n // For horizontal arrays (single row), use x position (column index)\n // For vertical arrays (single/multiple columns), use y position (row index)\n const position = isHorizontal\n ? value.relativePos.x + 1\n : value.relativePos.y + 1;\n\n return {\n type: \"value\",\n result: { type: \"number\", value: position },\n }; // 1-based index\n }\n } else {\n // Approximate match (1 or -1) - requires sorted array\n // For now, throw an error until we add sorting validation\n // TODO: Add proper approximate match logic with sorted array validation\n throw new Error(\"MATCH: approximate match not fully implemented\");\n }\n }\n }\n\n return {\n type: \"error\",\n err: FormulaError.NA,\n message: \"MATCH: lookup_value not found in lookup_array\",\n errAddress: context.dependencyNode,\n };\n}\n\nexport const MATCH: FunctionDefinition = {\n name: \"MATCH\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length < 2 || node.args.length > 3) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"MATCH function takes 2 or 3 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate lookup_value\n const lookupValueResult = this.evaluateNode(node.args[0]!, context);\n if (\n lookupValueResult.type === \"error\" ||\n lookupValueResult.type === \"awaiting-evaluation\"\n ) {\n return lookupValueResult;\n }\n\n // Evaluate lookup_array\n const lookupArrayResult = this.evaluateNode(node.args[1]!, context);\n if (\n lookupArrayResult.type === \"error\" ||\n lookupArrayResult.type === \"awaiting-evaluation\"\n ) {\n return lookupArrayResult;\n }\n\n // Evaluate match_type (optional, defaults to 1)\n let matchTypeResult: FunctionEvaluationResult = {\n type: \"value\",\n result: { type: \"number\", value: 1 },\n };\n\n if (node.args[2]) {\n matchTypeResult = this.evaluateNode(node.args[2], context);\n if (\n matchTypeResult.type === \"error\" ||\n matchTypeResult.type === \"awaiting-evaluation\"\n ) {\n return matchTypeResult;\n }\n }\n\n // Handle spilled arrays for lookup_value and match_type (not lookup_array which is expected to be a range)\n if (\n lookupValueResult.type === \"spilled-values\" ||\n matchTypeResult.type === \"spilled-values\"\n ) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"MATCH: Spilled array arguments not yet implemented\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Strict type checking for match_type\n if (matchTypeResult.result.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: `MATCH match_type must be number, got ${matchTypeResult.result.type}`,\n errAddress: context.dependencyNode,\n };\n }\n\n // Extract lookup_array values\n let lookupArray: EvaluateAllCellsResult = {\n type: \"awaiting-evaluation\",\n waitingFor: context.dependencyNode,\n errAddress: context.dependencyNode,\n };\n let isHorizontal = false;\n\n // Handle direct range arguments (like A:A) before extracting lookup_array values\n\n // Extract lookup_array values for non-infinite ranges\n if (lookupArrayResult.type === \"value\") {\n // Single value case - treat as array with one element\n lookupArray = {\n type: \"values\",\n values: [{ result: lookupArrayResult, relativePos: { x: 0, y: 0 } }],\n };\n isHorizontal = false; // Single value, treat as vertical\n } else if (lookupArrayResult.type === \"spilled-values\") {\n // Validate that lookup_array is 1D (either single row OR single column)\n const spillArea = lookupArrayResult.spillArea(context.cellAddress);\n const startRow = spillArea.start.row;\n const endRow = spillArea.end.row;\n const startCol = spillArea.start.col;\n const endCol = spillArea.end.col;\n\n // Check if it's a single row (horizontal)\n const isSingleRow = endRow.type === \"number\" && startRow === endRow.value;\n\n // Check if it's a single column (vertical)\n const isSingleCol = endCol.type === \"number\" && startCol === endCol.value;\n\n // MATCH requires a 1D array - either single row OR single column, not both or neither\n if (!isSingleRow && !isSingleCol) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message:\n \"MATCH lookup_array must be a single row or single column (1D array)\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Cannot be both single row AND single column (that would be a single cell, which is handled)\n if (isSingleRow && isSingleCol) {\n // This is actually a single cell, which is fine\n isHorizontal = false; // Treat single cell as vertical\n } else {\n // Horizontal if it's a single row\n isHorizontal = isSingleRow;\n }\n\n // Extract values from spilled array\n lookupArray = lookupArrayResult.evaluateAllCells.call(this, {\n context,\n evaluate: lookupArrayResult.evaluate,\n origin: context.cellAddress,\n lookupOrder: \"col-major\",\n });\n }\n\n // Perform MATCH operation\n return matchOperation(\n lookupValueResult.result,\n lookupArray,\n Math.floor(matchTypeResult.result.value), // Floor to handle decimal inputs\n context,\n isHorizontal\n );\n },\n};\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
8
|
+
"debugId": "BA7EA11C6CC1796964756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/functions/lookup/xlookup/xlookup.ts
|
|
2
2
|
import {
|
|
3
3
|
FormulaError
|
|
4
|
-
} from "
|
|
4
|
+
} from "../../../core/types.mjs";
|
|
5
5
|
function compareValues(a, b) {
|
|
6
6
|
if (a.type !== b.type) {
|
|
7
7
|
const typeOrder = { number: 0, string: 1, boolean: 2, infinity: 0 };
|
|
@@ -379,4 +379,4 @@ export {
|
|
|
379
379
|
XLOOKUP
|
|
380
380
|
};
|
|
381
381
|
|
|
382
|
-
//# debugId=
|
|
382
|
+
//# debugId=8677AE929CDF067464756E2164756E21
|