@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,205 @@
|
|
|
1
|
+
// src/functions/reference/offset/offset.ts
|
|
2
|
+
import {
|
|
3
|
+
FormulaError
|
|
4
|
+
} from "src/core/types";
|
|
5
|
+
import { isCellAddress, isRangeAddress } from "src/core/utils";
|
|
6
|
+
var OFFSET = {
|
|
7
|
+
name: "OFFSET",
|
|
8
|
+
evaluate: function(node, context) {
|
|
9
|
+
if (node.args.length < 3 || node.args.length > 5) {
|
|
10
|
+
return {
|
|
11
|
+
type: "error",
|
|
12
|
+
err: FormulaError.VALUE,
|
|
13
|
+
message: "OFFSET function requires 3 to 5 arguments",
|
|
14
|
+
errAddress: context.dependencyNode
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const refResult = this.evaluateNode(node.args[0], context);
|
|
18
|
+
if (refResult.type === "error" || refResult.type === "awaiting-evaluation") {
|
|
19
|
+
return refResult;
|
|
20
|
+
}
|
|
21
|
+
const rowsResult = this.evaluateNode(node.args[1], context);
|
|
22
|
+
if (rowsResult.type === "error" || rowsResult.type === "awaiting-evaluation") {
|
|
23
|
+
return rowsResult;
|
|
24
|
+
}
|
|
25
|
+
if (rowsResult.type !== "value" || rowsResult.result.type !== "number") {
|
|
26
|
+
return {
|
|
27
|
+
type: "error",
|
|
28
|
+
err: FormulaError.VALUE,
|
|
29
|
+
message: "OFFSET function rows must be a number",
|
|
30
|
+
errAddress: context.dependencyNode
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const colsResult = this.evaluateNode(node.args[2], context);
|
|
34
|
+
if (colsResult.type === "error" || colsResult.type === "awaiting-evaluation") {
|
|
35
|
+
return colsResult;
|
|
36
|
+
}
|
|
37
|
+
if (colsResult.type !== "value" || colsResult.result.type !== "number") {
|
|
38
|
+
return {
|
|
39
|
+
type: "error",
|
|
40
|
+
err: FormulaError.VALUE,
|
|
41
|
+
message: "OFFSET function cols must be a number",
|
|
42
|
+
errAddress: context.dependencyNode
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const rowsOffset = Math.floor(rowsResult.result.value);
|
|
46
|
+
const colsOffset = Math.floor(colsResult.result.value);
|
|
47
|
+
let height;
|
|
48
|
+
if (node.args.length >= 4) {
|
|
49
|
+
const heightResult = this.evaluateNode(node.args[3], context);
|
|
50
|
+
if (heightResult.type === "error" || heightResult.type === "awaiting-evaluation") {
|
|
51
|
+
return heightResult;
|
|
52
|
+
}
|
|
53
|
+
if (heightResult.type === "value" && heightResult.result.type === "number") {
|
|
54
|
+
height = Math.floor(heightResult.result.value);
|
|
55
|
+
if (height < 1) {
|
|
56
|
+
return {
|
|
57
|
+
type: "error",
|
|
58
|
+
err: FormulaError.VALUE,
|
|
59
|
+
message: "OFFSET function height must be positive",
|
|
60
|
+
errAddress: context.dependencyNode
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
let width;
|
|
66
|
+
if (node.args.length === 5) {
|
|
67
|
+
const widthResult = this.evaluateNode(node.args[4], context);
|
|
68
|
+
if (widthResult.type === "error" || widthResult.type === "awaiting-evaluation") {
|
|
69
|
+
return widthResult;
|
|
70
|
+
}
|
|
71
|
+
if (widthResult.type === "value" && widthResult.result.type === "number") {
|
|
72
|
+
width = Math.floor(widthResult.result.value);
|
|
73
|
+
if (width < 1) {
|
|
74
|
+
return {
|
|
75
|
+
type: "error",
|
|
76
|
+
err: FormulaError.VALUE,
|
|
77
|
+
message: "OFFSET function width must be positive",
|
|
78
|
+
errAddress: context.dependencyNode
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
let baseRange;
|
|
84
|
+
let baseSheetName = context.cellAddress.sheetName;
|
|
85
|
+
let baseWorkbookName = context.cellAddress.workbookName;
|
|
86
|
+
const cellOrRange = refResult.type === "spilled-values" ? refResult.sourceCell ?? refResult.sourceRange : refResult.sourceCell;
|
|
87
|
+
if (!cellOrRange) {
|
|
88
|
+
return {
|
|
89
|
+
type: "error",
|
|
90
|
+
err: FormulaError.VALUE,
|
|
91
|
+
message: "OFFSET function requires a cell or range reference",
|
|
92
|
+
errAddress: context.dependencyNode
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (isCellAddress(cellOrRange)) {
|
|
96
|
+
baseSheetName = cellOrRange.sheetName;
|
|
97
|
+
baseWorkbookName = cellOrRange.workbookName;
|
|
98
|
+
baseRange = {
|
|
99
|
+
start: {
|
|
100
|
+
col: cellOrRange.colIndex,
|
|
101
|
+
row: cellOrRange.rowIndex
|
|
102
|
+
},
|
|
103
|
+
end: {
|
|
104
|
+
col: { type: "number", value: cellOrRange.colIndex },
|
|
105
|
+
row: { type: "number", value: cellOrRange.rowIndex }
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
} else if (isRangeAddress(cellOrRange)) {
|
|
109
|
+
baseSheetName = cellOrRange.sheetName;
|
|
110
|
+
baseWorkbookName = cellOrRange.workbookName;
|
|
111
|
+
baseRange = cellOrRange.range;
|
|
112
|
+
} else {
|
|
113
|
+
return {
|
|
114
|
+
type: "error",
|
|
115
|
+
err: FormulaError.VALUE,
|
|
116
|
+
message: "OFFSET function requires a cell or range reference",
|
|
117
|
+
errAddress: context.dependencyNode
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
const offsetStartCol = baseRange.start.col + colsOffset;
|
|
121
|
+
const offsetStartRow = baseRange.start.row + rowsOffset;
|
|
122
|
+
if (offsetStartCol < 0 || offsetStartRow < 0) {
|
|
123
|
+
return {
|
|
124
|
+
type: "error",
|
|
125
|
+
err: FormulaError.REF,
|
|
126
|
+
message: "OFFSET function resulted in invalid cell reference",
|
|
127
|
+
errAddress: context.dependencyNode
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
let offsetEndCol;
|
|
131
|
+
let offsetEndRow;
|
|
132
|
+
if (width !== undefined) {
|
|
133
|
+
offsetEndCol = offsetStartCol + width - 1;
|
|
134
|
+
} else if (baseRange.end.col.type === "number") {
|
|
135
|
+
offsetEndCol = offsetStartCol + (baseRange.end.col.value - baseRange.start.col);
|
|
136
|
+
} else {
|
|
137
|
+
return {
|
|
138
|
+
type: "error",
|
|
139
|
+
err: FormulaError.VALUE,
|
|
140
|
+
message: "OFFSET function requires finite reference when width is omitted",
|
|
141
|
+
errAddress: context.dependencyNode
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (height !== undefined) {
|
|
145
|
+
offsetEndRow = offsetStartRow + height - 1;
|
|
146
|
+
} else if (baseRange.end.row.type === "number") {
|
|
147
|
+
offsetEndRow = offsetStartRow + (baseRange.end.row.value - baseRange.start.row);
|
|
148
|
+
} else {
|
|
149
|
+
return {
|
|
150
|
+
type: "error",
|
|
151
|
+
err: FormulaError.VALUE,
|
|
152
|
+
message: "OFFSET function requires finite reference when height is omitted",
|
|
153
|
+
errAddress: context.dependencyNode
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
if (offsetEndCol < 0 || offsetEndRow < 0) {
|
|
157
|
+
return {
|
|
158
|
+
type: "error",
|
|
159
|
+
err: FormulaError.REF,
|
|
160
|
+
message: "OFFSET function resulted in invalid cell reference",
|
|
161
|
+
errAddress: context.dependencyNode
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const offsetRange = {
|
|
165
|
+
start: {
|
|
166
|
+
col: offsetStartCol,
|
|
167
|
+
row: offsetStartRow
|
|
168
|
+
},
|
|
169
|
+
end: {
|
|
170
|
+
col: { type: "number", value: offsetEndCol },
|
|
171
|
+
row: { type: "number", value: offsetEndRow }
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
if (offsetStartCol === offsetEndCol && offsetStartRow === offsetEndRow) {
|
|
175
|
+
return this.evaluateReference({
|
|
176
|
+
type: "reference",
|
|
177
|
+
address: {
|
|
178
|
+
colIndex: offsetStartCol,
|
|
179
|
+
rowIndex: offsetStartRow
|
|
180
|
+
},
|
|
181
|
+
sheetName: baseSheetName,
|
|
182
|
+
workbookName: baseWorkbookName,
|
|
183
|
+
isAbsolute: {
|
|
184
|
+
col: true,
|
|
185
|
+
row: true
|
|
186
|
+
}
|
|
187
|
+
}, context);
|
|
188
|
+
}
|
|
189
|
+
return this.evaluateRange({
|
|
190
|
+
type: "range",
|
|
191
|
+
range: offsetRange,
|
|
192
|
+
sheetName: baseSheetName,
|
|
193
|
+
workbookName: baseWorkbookName,
|
|
194
|
+
isAbsolute: {
|
|
195
|
+
start: { col: true, row: true },
|
|
196
|
+
end: { col: true, row: true }
|
|
197
|
+
}
|
|
198
|
+
}, context);
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
export {
|
|
202
|
+
OFFSET
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
//# debugId=406F37BBAB304EEB64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/functions/reference/offset/offset.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 SpreadsheetRangeEnd,\n} from \"src/core/types\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\nimport type { ReferenceNode, RangeNode } from \"src/parser/ast\";\nimport { isCellAddress, isRangeAddress } from \"src/core/utils\";\n\n/**\n * OFFSET function - Returns a reference offset from a given reference\n * \n * Usage: OFFSET(reference, rows, cols, [height], [width])\n * \n * reference: The reference from which you want to base the offset\n * rows: The number of rows, up or down, that you want the upper-left cell to refer to\n * cols: The number of columns, left or right, that you want the upper-left cell to refer to\n * height: (optional) The height, in number of rows, that you want the returned reference to be\n * width: (optional) The width, in number of columns, that you want the returned reference to be\n * \n * Examples:\n * - OFFSET(A1, 2, 3) returns the value in cell D3 (2 rows down, 3 columns right from A1)\n * - OFFSET(A1, 0, 0, 3, 1) returns the range A1:A3\n * - OFFSET(A1, 1, 1, 2, 2) returns the range B2:C3\n * \n * Notes:\n * - If rows or cols offset reference from the edge of the worksheet, returns #REF! error\n * - Height and width must be positive\n * - If height or width is omitted, the same height or width as reference is used\n */\nexport const OFFSET: FunctionDefinition = {\n name: \"OFFSET\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length < 3 || node.args.length > 5) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OFFSET function requires 3 to 5 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate reference\n const refResult = this.evaluateNode(node.args[0]!, context);\n if (\n refResult.type === \"error\" ||\n refResult.type === \"awaiting-evaluation\"\n ) {\n return refResult;\n }\n\n // Evaluate rows offset\n const rowsResult = this.evaluateNode(node.args[1]!, context);\n if (\n rowsResult.type === \"error\" ||\n rowsResult.type === \"awaiting-evaluation\"\n ) {\n return rowsResult;\n }\n\n if (rowsResult.type !== \"value\" || rowsResult.result.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OFFSET function rows must be a number\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate cols offset\n const colsResult = this.evaluateNode(node.args[2]!, context);\n if (\n colsResult.type === \"error\" ||\n colsResult.type === \"awaiting-evaluation\"\n ) {\n return colsResult;\n }\n\n if (colsResult.type !== \"value\" || colsResult.result.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OFFSET function cols must be a number\",\n errAddress: context.dependencyNode,\n };\n }\n\n const rowsOffset = Math.floor(rowsResult.result.value);\n const colsOffset = Math.floor(colsResult.result.value);\n\n // Optional height parameter\n let height: number | undefined;\n if (node.args.length >= 4) {\n const heightResult = this.evaluateNode(node.args[3]!, context);\n if (\n heightResult.type === \"error\" ||\n heightResult.type === \"awaiting-evaluation\"\n ) {\n return heightResult;\n }\n\n if (heightResult.type === \"value\" && heightResult.result.type === \"number\") {\n height = Math.floor(heightResult.result.value);\n if (height < 1) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OFFSET function height must be positive\",\n errAddress: context.dependencyNode,\n };\n }\n }\n }\n\n // Optional width parameter\n let width: number | undefined;\n if (node.args.length === 5) {\n const widthResult = this.evaluateNode(node.args[4]!, context);\n if (\n widthResult.type === \"error\" ||\n widthResult.type === \"awaiting-evaluation\"\n ) {\n return widthResult;\n }\n\n if (widthResult.type === \"value\" && widthResult.result.type === \"number\") {\n width = Math.floor(widthResult.result.value);\n if (width < 1) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OFFSET function width must be positive\",\n errAddress: context.dependencyNode,\n };\n }\n }\n }\n\n // Get the base cell/range from the evaluated reference\n let baseRange: SpreadsheetRange;\n let baseSheetName: string = context.cellAddress.sheetName;\n let baseWorkbookName: string = context.cellAddress.workbookName;\n\n // Check if we have a cell or range reference\n const cellOrRange =\n refResult.type === \"spilled-values\"\n ? (refResult.sourceCell ?? refResult.sourceRange)\n : refResult.sourceCell;\n\n if (!cellOrRange) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OFFSET function requires a cell or range reference\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Extract the base range from sourceCell or sourceRange\n if (isCellAddress(cellOrRange)) {\n // It's a CellAddress\n baseSheetName = cellOrRange.sheetName;\n baseWorkbookName = cellOrRange.workbookName;\n baseRange = {\n start: {\n col: cellOrRange.colIndex,\n row: cellOrRange.rowIndex,\n },\n end: {\n col: { type: \"number\", value: cellOrRange.colIndex },\n row: { type: \"number\", value: cellOrRange.rowIndex },\n },\n };\n } else if (isRangeAddress(cellOrRange)) {\n // It's a RangeAddress\n baseSheetName = cellOrRange.sheetName;\n baseWorkbookName = cellOrRange.workbookName;\n baseRange = cellOrRange.range;\n } else {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OFFSET function requires a cell or range reference\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Calculate the offset range\n const offsetStartCol = baseRange.start.col + colsOffset;\n const offsetStartRow = baseRange.start.row + rowsOffset;\n\n // Validate bounds (assuming reasonable spreadsheet size)\n if (offsetStartCol < 0 || offsetStartRow < 0) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"OFFSET function resulted in invalid cell reference\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Calculate end position based on height/width or original range size\n let offsetEndCol: number;\n let offsetEndRow: number;\n\n if (width !== undefined) {\n offsetEndCol = offsetStartCol + width - 1;\n } else if (baseRange.end.col.type === \"number\") {\n offsetEndCol = offsetStartCol + (baseRange.end.col.value - baseRange.start.col);\n } else {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OFFSET function requires finite reference when width is omitted\",\n errAddress: context.dependencyNode,\n };\n }\n\n if (height !== undefined) {\n offsetEndRow = offsetStartRow + height - 1;\n } else if (baseRange.end.row.type === \"number\") {\n offsetEndRow = offsetStartRow + (baseRange.end.row.value - baseRange.start.row);\n } else {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"OFFSET function requires finite reference when height is omitted\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Validate the end bounds\n if (offsetEndCol < 0 || offsetEndRow < 0) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"OFFSET function resulted in invalid cell reference\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Create the offset range\n const offsetRange: SpreadsheetRange = {\n start: {\n col: offsetStartCol,\n row: offsetStartRow,\n },\n end: {\n col: { type: \"number\", value: offsetEndCol },\n row: { type: \"number\", value: offsetEndRow },\n },\n };\n\n // If it's a single cell, return its value\n if (offsetStartCol === offsetEndCol && offsetStartRow === offsetEndRow) {\n return this.evaluateReference(\n {\n type: \"reference\",\n address: {\n colIndex: offsetStartCol,\n rowIndex: offsetStartRow,\n },\n sheetName: baseSheetName,\n workbookName: baseWorkbookName,\n isAbsolute: {\n col: true,\n row: true,\n },\n },\n context\n );\n }\n\n // Otherwise, return a range reference (spilled values)\n return this.evaluateRange(\n {\n type: \"range\",\n range: offsetRange,\n sheetName: baseSheetName,\n workbookName: baseWorkbookName,\n isAbsolute: {\n start: { col: true, row: true },\n end: { col: true, row: true },\n },\n },\n context\n );\n },\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "406F37BBAB304EEB64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// src/functions/text/concatenate/concatenate.ts
|
|
2
|
+
import {
|
|
3
|
+
FormulaError
|
|
4
|
+
} from "src/core/types";
|
|
5
|
+
function coerceToString(result, context) {
|
|
6
|
+
if (result.type !== "value") {
|
|
7
|
+
return {
|
|
8
|
+
type: "error",
|
|
9
|
+
err: FormulaError.VALUE,
|
|
10
|
+
message: "Invalid argument type",
|
|
11
|
+
errAddress: context.dependencyNode
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
switch (result.result.type) {
|
|
15
|
+
case "string":
|
|
16
|
+
return result.result.value;
|
|
17
|
+
case "number":
|
|
18
|
+
if (result.result.value === Infinity) {
|
|
19
|
+
return "INFINITY";
|
|
20
|
+
} else if (result.result.value === -Infinity) {
|
|
21
|
+
return "-INFINITY";
|
|
22
|
+
} else if (isNaN(result.result.value)) {
|
|
23
|
+
return "NaN";
|
|
24
|
+
} else {
|
|
25
|
+
return result.result.value.toString();
|
|
26
|
+
}
|
|
27
|
+
case "boolean":
|
|
28
|
+
return result.result.value ? "TRUE" : "FALSE";
|
|
29
|
+
default:
|
|
30
|
+
return {
|
|
31
|
+
type: "error",
|
|
32
|
+
err: FormulaError.VALUE,
|
|
33
|
+
message: "Cannot convert argument to string",
|
|
34
|
+
errAddress: context.dependencyNode
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function concatenateOperation(textResults, context) {
|
|
39
|
+
let result = "";
|
|
40
|
+
for (const textResult of textResults) {
|
|
41
|
+
const stringValue = coerceToString(textResult, context);
|
|
42
|
+
if (typeof stringValue === "object" && stringValue.type === "error") {
|
|
43
|
+
return stringValue;
|
|
44
|
+
}
|
|
45
|
+
result += stringValue;
|
|
46
|
+
}
|
|
47
|
+
return { type: "value", result: { type: "string", value: result } };
|
|
48
|
+
}
|
|
49
|
+
function createConcatenateSpilledResult({
|
|
50
|
+
textResults,
|
|
51
|
+
context
|
|
52
|
+
}) {
|
|
53
|
+
const spilledResults = textResults.filter((result) => result.type === "spilled-values");
|
|
54
|
+
if (spilledResults.length === 0) {
|
|
55
|
+
throw new Error("createConcatenateSpilledResult called without spilled values");
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
type: "spilled-values",
|
|
59
|
+
spillArea: (origin) => {
|
|
60
|
+
let spillArea;
|
|
61
|
+
for (const result of textResults) {
|
|
62
|
+
if (result.type === "spilled-values") {
|
|
63
|
+
const currentSpillArea = result.spillArea(origin);
|
|
64
|
+
if (!spillArea) {
|
|
65
|
+
spillArea = currentSpillArea;
|
|
66
|
+
} else {
|
|
67
|
+
spillArea = this.unionRanges(this.projectRange(spillArea, origin), this.projectRange(currentSpillArea, origin));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!spillArea) {
|
|
72
|
+
throw new Error("No spilled values found");
|
|
73
|
+
}
|
|
74
|
+
return spillArea;
|
|
75
|
+
},
|
|
76
|
+
source: "CONCATENATE with spilled values",
|
|
77
|
+
evaluate: (spilledCell, evalContext) => {
|
|
78
|
+
const spilledTextResults = [];
|
|
79
|
+
for (const textResult of textResults) {
|
|
80
|
+
if (textResult.type === "spilled-values") {
|
|
81
|
+
const spillResult = textResult.evaluate(spilledCell, evalContext);
|
|
82
|
+
if (spillResult === undefined) {
|
|
83
|
+
return {
|
|
84
|
+
type: "error",
|
|
85
|
+
err: FormulaError.REF,
|
|
86
|
+
message: "The spilled results have not been evaluated",
|
|
87
|
+
errAddress: context.dependencyNode
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (spillResult.type === "error") {
|
|
91
|
+
return spillResult;
|
|
92
|
+
}
|
|
93
|
+
spilledTextResults.push(spillResult);
|
|
94
|
+
} else {
|
|
95
|
+
spilledTextResults.push(textResult);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return concatenateOperation(spilledTextResults, context);
|
|
99
|
+
},
|
|
100
|
+
evaluateAllCells: (intersectingRange) => {
|
|
101
|
+
throw new Error("WIP: evaluateAllCells for CONCATENATE is not implemented");
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
var CONCATENATE = {
|
|
106
|
+
name: "CONCATENATE",
|
|
107
|
+
evaluate: function(node, context) {
|
|
108
|
+
if (node.args.length < 1) {
|
|
109
|
+
return {
|
|
110
|
+
type: "error",
|
|
111
|
+
err: FormulaError.VALUE,
|
|
112
|
+
message: "CONCATENATE function requires at least 1 argument",
|
|
113
|
+
errAddress: context.dependencyNode
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const textResults = [];
|
|
117
|
+
for (const arg of node.args) {
|
|
118
|
+
const result = this.evaluateNode(arg, context);
|
|
119
|
+
if (result.type === "error" || result.type === "awaiting-evaluation") {
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
textResults.push(result);
|
|
123
|
+
}
|
|
124
|
+
const hasSpilledValues = textResults.some((result) => result.type === "spilled-values");
|
|
125
|
+
if (hasSpilledValues) {
|
|
126
|
+
return createConcatenateSpilledResult.call(this, {
|
|
127
|
+
textResults,
|
|
128
|
+
context
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return concatenateOperation(textResults, context);
|
|
132
|
+
},
|
|
133
|
+
aliases: ["CONCAT"]
|
|
134
|
+
};
|
|
135
|
+
export {
|
|
136
|
+
CONCATENATE
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
//# debugId=96483CED2199205664756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/functions/text/concatenate/concatenate.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import {\n FormulaError,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n type CellString,\n type CellAddress,\n type SpreadsheetRange,\n type SpilledValuesEvaluationResult,\n type ErrorEvaluationResult,\n type SingleEvaluationResult,\n} from \"src/core/types\";\nimport { FormulaEvaluator } from \"src/evaluator/formula-evaluator\";\nimport type { FunctionNode } from \"src/parser/ast\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\n\n/**\n * CONCATENATE function - Joins several text strings into one text string\n *\n * Usage: CONCATENATE(text1, text2, ...)\n *\n * text1, text2, ...: Text strings to be joined together.\n *\n * Example: CONCATENATE(\"Hello\", \" \", \"World\") returns \"Hello World\"\n *\n * Note:\n * - Takes 1 or more arguments\n * - Supports type coercion: strings, numbers, and booleans are converted to strings\n * - Numbers: converted to string representation (123 -> \"123\", Infinity -> \"INFINITY\")\n * - Booleans: TRUE -> \"TRUE\", FALSE -> \"FALSE\"\n * - Supports dynamic arrays (spilled values) for arguments\n * - If any argument is a spilled value, the result will be spilled\n */\n\n/**\n * Helper function to convert a cell value to string with type coercion\n */\nfunction coerceToString(\n result: FunctionEvaluationResult,\n context: EvaluationContext\n): string | ErrorEvaluationResult {\n if (result.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Invalid argument type\",\n errAddress: context.dependencyNode,\n };\n }\n\n switch (result.result.type) {\n case \"string\":\n return result.result.value;\n case \"number\":\n // Convert number to string\n if (result.result.value === Infinity) {\n return \"INFINITY\";\n } else if (result.result.value === -Infinity) {\n return \"-INFINITY\";\n } else if (isNaN(result.result.value)) {\n return \"NaN\";\n } else {\n return result.result.value.toString();\n }\n case \"boolean\":\n // Convert boolean to string\n return result.result.value ? \"TRUE\" : \"FALSE\";\n default:\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Cannot convert argument to string\",\n errAddress: context.dependencyNode,\n };\n }\n}\n\n/**\n * Helper function to perform CONCATENATE operation on evaluated arguments\n */\nfunction concatenateOperation(\n textResults: FunctionEvaluationResult[],\n context: EvaluationContext\n): { type: \"value\"; result: CellString } | ErrorEvaluationResult {\n let result = \"\";\n for (const textResult of textResults) {\n const stringValue = coerceToString(textResult, context);\n if (typeof stringValue === \"object\" && stringValue.type === \"error\") {\n return stringValue;\n }\n result += stringValue;\n }\n return { type: \"value\", result: { type: \"string\", value: result } };\n}\n\n/**\n * Helper for creating spilled-values result for CONCATENATE function\n */\nfunction createConcatenateSpilledResult(\n this: FormulaEvaluator,\n {\n textResults,\n context,\n }: {\n textResults: FunctionEvaluationResult[];\n context: EvaluationContext;\n }\n): SpilledValuesEvaluationResult | ErrorEvaluationResult {\n const spilledResults = textResults.filter(\n (result) => result.type === \"spilled-values\"\n );\n\n if (spilledResults.length === 0) {\n throw new Error(\n \"createConcatenateSpilledResult called without spilled values\"\n );\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 for (const result of textResults) {\n if (result.type === \"spilled-values\") {\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\n if (!spillArea) {\n throw new Error(\"No spilled values found\");\n }\n return spillArea;\n },\n source: \"CONCATENATE with spilled values\",\n evaluate: (spilledCell, evalContext): SingleEvaluationResult => {\n // Evaluate all arguments at this spilled position\n const spilledTextResults: FunctionEvaluationResult[] = [];\n\n for (const textResult of textResults) {\n if (textResult.type === \"spilled-values\") {\n const spillResult = textResult.evaluate(spilledCell, evalContext);\n if (spillResult === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled results have not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n if (spillResult.type === \"error\") {\n return spillResult;\n }\n spilledTextResults.push(spillResult);\n } else {\n spilledTextResults.push(textResult);\n }\n }\n\n return concatenateOperation(spilledTextResults, context);\n },\n evaluateAllCells: (intersectingRange) => {\n throw new Error(\n \"WIP: evaluateAllCells for CONCATENATE is not implemented\"\n );\n },\n };\n}\n\n/**\n * CONCATENATE function implementation\n */\nexport const CONCATENATE: FunctionDefinition = {\n name: \"CONCATENATE\",\n evaluate: function (\n node: FunctionNode,\n context: EvaluationContext\n ): FunctionEvaluationResult {\n if (node.args.length < 1) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"CONCATENATE function requires at least 1 argument\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate all arguments\n const textResults: FunctionEvaluationResult[] = [];\n for (const arg of node.args) {\n const result = this.evaluateNode(arg, context);\n if (result.type === \"error\" || result.type === \"awaiting-evaluation\") {\n return result;\n }\n textResults.push(result);\n }\n\n // Check if any arguments are spilled values\n const hasSpilledValues = textResults.some(\n (result) => result.type === \"spilled-values\"\n );\n\n if (hasSpilledValues) {\n return createConcatenateSpilledResult.call(this, {\n textResults,\n context,\n });\n }\n\n // All arguments are single values - type coercion will be handled in concatenateOperation\n\n // Perform concatenation\n return concatenateOperation(textResults, context);\n },\n aliases: [\"CONCAT\"],\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "96483CED2199205664756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// src/functions/text/exact/exact.ts
|
|
2
|
+
import {
|
|
3
|
+
FormulaError
|
|
4
|
+
} from "src/core/types";
|
|
5
|
+
function cellValueToString(value) {
|
|
6
|
+
switch (value.type) {
|
|
7
|
+
case "string":
|
|
8
|
+
return value.value;
|
|
9
|
+
case "number":
|
|
10
|
+
return value.value.toString();
|
|
11
|
+
case "boolean":
|
|
12
|
+
return value.value ? "TRUE" : "FALSE";
|
|
13
|
+
case "infinity":
|
|
14
|
+
return value.sign === "positive" ? "INFINITY" : "-INFINITY";
|
|
15
|
+
default:
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function createExactSpilledResult({
|
|
20
|
+
text1Result,
|
|
21
|
+
text2Result,
|
|
22
|
+
context
|
|
23
|
+
}) {
|
|
24
|
+
const hasSpilledText1 = text1Result.type === "spilled-values";
|
|
25
|
+
const hasSpilledText2 = text2Result.type === "spilled-values";
|
|
26
|
+
if (!hasSpilledText1 && !hasSpilledText2) {
|
|
27
|
+
throw new Error("createExactSpilledResult called without spilled values");
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
type: "spilled-values",
|
|
31
|
+
spillArea: (origin) => {
|
|
32
|
+
let spillArea;
|
|
33
|
+
const spilledResults = [
|
|
34
|
+
hasSpilledText1 ? text1Result : null,
|
|
35
|
+
hasSpilledText2 ? text2Result : null
|
|
36
|
+
].filter(Boolean);
|
|
37
|
+
for (const result of spilledResults) {
|
|
38
|
+
const currentSpillArea = result.spillArea(origin);
|
|
39
|
+
if (!spillArea) {
|
|
40
|
+
spillArea = currentSpillArea;
|
|
41
|
+
} else {
|
|
42
|
+
spillArea = this.unionRanges(this.projectRange(spillArea, origin), this.projectRange(currentSpillArea, origin));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!spillArea) {
|
|
46
|
+
throw new Error("No spilled values found");
|
|
47
|
+
}
|
|
48
|
+
return spillArea;
|
|
49
|
+
},
|
|
50
|
+
source: "EXACT with spilled values",
|
|
51
|
+
evaluate: (spilledCell, evalContext) => {
|
|
52
|
+
const spillText1Result = hasSpilledText1 ? text1Result.evaluate(spilledCell, evalContext) : text1Result;
|
|
53
|
+
const spillText2Result = hasSpilledText2 ? text2Result.evaluate(spilledCell, evalContext) : text2Result;
|
|
54
|
+
if (spillText1Result === undefined) {
|
|
55
|
+
return {
|
|
56
|
+
type: "error",
|
|
57
|
+
err: FormulaError.REF,
|
|
58
|
+
message: "The spilled text1 argument has not been evaluated",
|
|
59
|
+
errAddress: context.dependencyNode
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (spillText1Result.type === "error" || spillText1Result.type === "awaiting-evaluation") {
|
|
63
|
+
return spillText1Result;
|
|
64
|
+
}
|
|
65
|
+
if (spillText2Result === undefined) {
|
|
66
|
+
return {
|
|
67
|
+
type: "error",
|
|
68
|
+
err: FormulaError.REF,
|
|
69
|
+
message: "The spilled text2 argument has not been evaluated",
|
|
70
|
+
errAddress: context.dependencyNode
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (spillText2Result.type === "error" || spillText2Result.type === "awaiting-evaluation") {
|
|
74
|
+
return spillText2Result;
|
|
75
|
+
}
|
|
76
|
+
if (spillText1Result.type !== "value" || spillText2Result.type !== "value") {
|
|
77
|
+
return {
|
|
78
|
+
type: "error",
|
|
79
|
+
err: FormulaError.VALUE,
|
|
80
|
+
message: "Invalid argument types for EXACT function #1",
|
|
81
|
+
errAddress: context.dependencyNode
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const text1 = cellValueToString(spillText1Result.result);
|
|
85
|
+
const text2 = cellValueToString(spillText2Result.result);
|
|
86
|
+
return {
|
|
87
|
+
type: "value",
|
|
88
|
+
result: { type: "boolean", value: text1 === text2 }
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
evaluateAllCells: (intersectingRange) => {
|
|
92
|
+
throw new Error("WIP: evaluateAllCells for EXACT is not implemented");
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
var EXACT = {
|
|
97
|
+
name: "EXACT",
|
|
98
|
+
evaluate: function(node, context) {
|
|
99
|
+
if (node.args.length !== 2) {
|
|
100
|
+
return {
|
|
101
|
+
type: "error",
|
|
102
|
+
err: FormulaError.VALUE,
|
|
103
|
+
message: "EXACT function takes exactly 2 arguments",
|
|
104
|
+
errAddress: context.dependencyNode
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const text1Result = this.evaluateNode(node.args[0], context);
|
|
108
|
+
if (text1Result.type === "error" || text1Result.type === "awaiting-evaluation") {
|
|
109
|
+
return text1Result;
|
|
110
|
+
}
|
|
111
|
+
const text2Result = this.evaluateNode(node.args[1], context);
|
|
112
|
+
if (text2Result.type === "error" || text2Result.type === "awaiting-evaluation") {
|
|
113
|
+
return text2Result;
|
|
114
|
+
}
|
|
115
|
+
const hasSpilledValues = text1Result.type === "spilled-values" || text2Result.type === "spilled-values";
|
|
116
|
+
if (hasSpilledValues) {
|
|
117
|
+
return createExactSpilledResult.call(this, {
|
|
118
|
+
text1Result,
|
|
119
|
+
text2Result,
|
|
120
|
+
context
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (text1Result.type !== "value" || text2Result.type !== "value") {
|
|
124
|
+
return {
|
|
125
|
+
type: "error",
|
|
126
|
+
err: FormulaError.VALUE,
|
|
127
|
+
message: "Invalid argument types for EXACT function #2",
|
|
128
|
+
errAddress: context.dependencyNode
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const text1 = cellValueToString(text1Result.result);
|
|
132
|
+
const text2 = cellValueToString(text2Result.result);
|
|
133
|
+
return {
|
|
134
|
+
type: "value",
|
|
135
|
+
result: { type: "boolean", value: text1 === text2 }
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
export {
|
|
140
|
+
EXACT
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
//# debugId=ED7D5D40A96E0E7064756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/functions/text/exact/exact.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 ErrorEvaluationResult,\n} from \"src/core/types\";\nimport type { FormulaEvaluator } from \"src/evaluator/formula-evaluator\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\n\n/**\n * EXACT function - Compares two text strings and returns TRUE if they are exactly the same, FALSE otherwise\n * \n * Usage: EXACT(text1, text2)\n * \n * text1: Required. The first text string\n * text2: Required. The second text string\n * \n * Examples:\n * EXACT(\"Apple\", \"Apple\") - returns TRUE\n * EXACT(\"Apple\", \"apple\") - returns FALSE (case-sensitive)\n * EXACT(\"123\", \"123\") - returns TRUE\n * EXACT(\"\", \"\") - returns TRUE (empty strings are equal)\n * \n * Note:\n * - The comparison is case-sensitive\n * - Non-text values are converted to text before comparison\n * - Supports spilled values (dynamic arrays) for both arguments\n */\n\n/**\n * Convert a cell value to string for text comparison\n */\nfunction cellValueToString(value: CellValue): string {\n switch (value.type) {\n case \"string\":\n return value.value;\n case \"number\":\n return value.value.toString();\n case \"boolean\":\n return value.value ? \"TRUE\" : \"FALSE\";\n case \"infinity\":\n return value.sign === \"positive\" ? \"INFINITY\" : \"-INFINITY\";\n default:\n return \"\";\n }\n}\n\n/**\n * Helper for creating spilled-values result for EXACT function\n */\nfunction createExactSpilledResult(\n this: FormulaEvaluator,\n {\n text1Result,\n text2Result,\n context,\n }: {\n text1Result: FunctionEvaluationResult;\n text2Result: FunctionEvaluationResult;\n context: EvaluationContext;\n }\n): SpilledValuesEvaluationResult | ErrorEvaluationResult {\n const hasSpilledText1 = text1Result.type === \"spilled-values\";\n const hasSpilledText2 = text2Result.type === \"spilled-values\";\n\n if (!hasSpilledText1 && !hasSpilledText2) {\n throw new Error(\"createExactSpilledResult 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 let spillArea: SpreadsheetRange | undefined;\n\n const spilledResults = [\n hasSpilledText1 ? text1Result : null,\n hasSpilledText2 ? text2Result : 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: \"EXACT with spilled values\",\n evaluate: (spilledCell: any, evalContext: any): SingleEvaluationResult => {\n // Evaluate both arguments at this spilled position\n const spillText1Result = hasSpilledText1\n ? text1Result.evaluate(spilledCell, evalContext)\n : text1Result;\n const spillText2Result = hasSpilledText2\n ? text2Result.evaluate(spilledCell, evalContext)\n : text2Result;\n\n // Check for errors\n if (spillText1Result === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled text1 argument has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n if (spillText1Result.type === \"error\" || spillText1Result.type === \"awaiting-evaluation\") {\n return spillText1Result;\n }\n\n if (spillText2Result === undefined) {\n return {\n type: \"error\",\n err: FormulaError.REF,\n message: \"The spilled text2 argument has not been evaluated\",\n errAddress: context.dependencyNode,\n };\n }\n if (spillText2Result.type === \"error\" || spillText2Result.type === \"awaiting-evaluation\") {\n return spillText2Result;\n }\n\n // Perform EXACT comparison\n if (spillText1Result.type !== \"value\" || spillText2Result.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Invalid argument types for EXACT function #1\",\n errAddress: context.dependencyNode,\n };\n }\n\n const text1 = cellValueToString(spillText1Result.result);\n const text2 = cellValueToString(spillText2Result.result);\n\n return {\n type: \"value\",\n result: { type: \"boolean\", value: text1 === text2 },\n };\n },\n evaluateAllCells: (intersectingRange: any) => {\n throw new Error(\"WIP: evaluateAllCells for EXACT is not implemented\");\n },\n };\n}\n\n/**\n * EXACT function implementation\n */\nexport const EXACT: FunctionDefinition = {\n name: \"EXACT\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length !== 2) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"EXACT function takes exactly 2 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate both text arguments\n const text1Result = this.evaluateNode(node.args[0]!, context);\n if (text1Result.type === \"error\" || text1Result.type === \"awaiting-evaluation\") {\n return text1Result;\n }\n\n const text2Result = this.evaluateNode(node.args[1]!, context);\n if (text2Result.type === \"error\" || text2Result.type === \"awaiting-evaluation\") {\n return text2Result;\n }\n\n // Handle spilled values\n const hasSpilledValues = \n text1Result.type === \"spilled-values\" ||\n text2Result.type === \"spilled-values\";\n\n if (hasSpilledValues) {\n return createExactSpilledResult.call(this, {\n text1Result,\n text2Result,\n context,\n });\n }\n\n // Both arguments are single values\n if (text1Result.type !== \"value\" || text2Result.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Invalid argument types for EXACT function #2\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Convert both values to strings and compare\n const text1 = cellValueToString(text1Result.result);\n const text2 = cellValueToString(text2Result.result);\n\n return {\n type: \"value\",\n result: { type: \"boolean\", value: text1 === text2 },\n };\n },\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "ED7D5D40A96E0E7064756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|