@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.
Files changed (569) hide show
  1. package/README.md +100 -0
  2. package/dist/cjs/core/ast-traverser.cjs +124 -0
  3. package/dist/cjs/core/ast-traverser.cjs.map +10 -0
  4. package/dist/cjs/core/autofill-utils.cjs +304 -0
  5. package/dist/cjs/core/autofill-utils.cjs.map +10 -0
  6. package/dist/cjs/core/engine.cjs +390 -0
  7. package/dist/cjs/core/engine.cjs.map +10 -0
  8. package/dist/cjs/core/managers/cache-manager.cjs +58 -0
  9. package/dist/cjs/core/managers/cache-manager.cjs.map +10 -0
  10. package/dist/cjs/core/managers/dependency-manager.cjs +620 -0
  11. package/dist/cjs/core/managers/dependency-manager.cjs.map +10 -0
  12. package/dist/cjs/core/managers/dependency-node.cjs +24 -0
  13. package/dist/cjs/core/managers/dependency-node.cjs.map +9 -0
  14. package/dist/cjs/core/managers/evaluation-manager.cjs +433 -0
  15. package/dist/cjs/core/managers/evaluation-manager.cjs.map +10 -0
  16. package/dist/cjs/core/managers/event-manager.cjs +49 -0
  17. package/dist/cjs/core/managers/event-manager.cjs.map +10 -0
  18. package/dist/cjs/core/managers/frontier-dependency-manager.cjs +181 -0
  19. package/dist/cjs/core/managers/frontier-dependency-manager.cjs.map +10 -0
  20. package/dist/cjs/core/managers/index.cjs +49 -0
  21. package/dist/cjs/core/managers/index.cjs.map +10 -0
  22. package/dist/cjs/core/managers/isDependencyNode.cjs +44 -0
  23. package/dist/cjs/core/managers/isDependencyNode.cjs.map +10 -0
  24. package/dist/cjs/core/managers/named-expression-manager.cjs +379 -0
  25. package/dist/cjs/core/managers/named-expression-manager.cjs.map +10 -0
  26. package/dist/cjs/core/managers/range-eval-order-builder.cjs +644 -0
  27. package/dist/cjs/core/managers/range-eval-order-builder.cjs.map +10 -0
  28. package/dist/cjs/core/managers/table-manager.cjs +254 -0
  29. package/dist/cjs/core/managers/table-manager.cjs.map +10 -0
  30. package/dist/cjs/core/managers/workbook-manager.cjs +474 -0
  31. package/dist/cjs/core/managers/workbook-manager.cjs.map +10 -0
  32. package/dist/cjs/core/map-serializer.cjs +69 -0
  33. package/dist/cjs/core/map-serializer.cjs.map +10 -0
  34. package/dist/cjs/core/named-expression-renamer.cjs +88 -0
  35. package/dist/cjs/core/named-expression-renamer.cjs.map +10 -0
  36. package/dist/cjs/core/sheet-renamer.cjs +89 -0
  37. package/dist/cjs/core/sheet-renamer.cjs.map +10 -0
  38. package/dist/cjs/core/sheet-utils.cjs +39 -0
  39. package/dist/cjs/core/sheet-utils.cjs.map +10 -0
  40. package/dist/cjs/core/table-renamer.cjs +88 -0
  41. package/dist/cjs/core/table-renamer.cjs.map +10 -0
  42. package/dist/cjs/core/types.cjs +48 -0
  43. package/dist/cjs/core/types.cjs.map +10 -0
  44. package/dist/cjs/core/utils/range-serializer.cjs +65 -0
  45. package/dist/cjs/core/utils/range-serializer.cjs.map +10 -0
  46. package/dist/cjs/core/utils/spreadsheet-visualizer.cjs +142 -0
  47. package/dist/cjs/core/utils/spreadsheet-visualizer.cjs.map +10 -0
  48. package/dist/cjs/core/utils.cjs +434 -0
  49. package/dist/cjs/core/utils.cjs.map +10 -0
  50. package/dist/cjs/core/workbook-renamer.cjs +106 -0
  51. package/dist/cjs/core/workbook-renamer.cjs.map +10 -0
  52. package/dist/cjs/debug/flags.cjs +47 -0
  53. package/dist/cjs/debug/flags.cjs.map +10 -0
  54. package/dist/cjs/evaluator/arithmetic/add/add.cjs +82 -0
  55. package/dist/cjs/evaluator/arithmetic/add/add.cjs.map +10 -0
  56. package/dist/cjs/evaluator/arithmetic/divide/divide.cjs +107 -0
  57. package/dist/cjs/evaluator/arithmetic/divide/divide.cjs.map +10 -0
  58. package/dist/cjs/evaluator/arithmetic/multiply/multiply.cjs +93 -0
  59. package/dist/cjs/evaluator/arithmetic/multiply/multiply.cjs.map +10 -0
  60. package/dist/cjs/evaluator/arithmetic/power/power.cjs +125 -0
  61. package/dist/cjs/evaluator/arithmetic/power/power.cjs.map +10 -0
  62. package/dist/cjs/evaluator/arithmetic/subtract/subtract.cjs +84 -0
  63. package/dist/cjs/evaluator/arithmetic/subtract/subtract.cjs.map +10 -0
  64. package/dist/cjs/evaluator/comparison/equals.cjs +64 -0
  65. package/dist/cjs/evaluator/comparison/equals.cjs.map +10 -0
  66. package/dist/cjs/evaluator/comparison/greater-than-or-equal.cjs +61 -0
  67. package/dist/cjs/evaluator/comparison/greater-than-or-equal.cjs.map +10 -0
  68. package/dist/cjs/evaluator/comparison/greater-than.cjs +61 -0
  69. package/dist/cjs/evaluator/comparison/greater-than.cjs.map +10 -0
  70. package/dist/cjs/evaluator/comparison/less-than-or-equal.cjs +69 -0
  71. package/dist/cjs/evaluator/comparison/less-than-or-equal.cjs.map +10 -0
  72. package/dist/cjs/evaluator/comparison/less-than.cjs +68 -0
  73. package/dist/cjs/evaluator/comparison/less-than.cjs.map +10 -0
  74. package/dist/cjs/evaluator/comparison/not-equals.cjs +53 -0
  75. package/dist/cjs/evaluator/comparison/not-equals.cjs.map +10 -0
  76. package/dist/cjs/evaluator/concatenation/concatenate.cjs +72 -0
  77. package/dist/cjs/evaluator/concatenation/concatenate.cjs.map +10 -0
  78. package/dist/cjs/evaluator/dependency-nodes/ast-evaluation-node.cjs +58 -0
  79. package/dist/cjs/evaluator/dependency-nodes/ast-evaluation-node.cjs.map +10 -0
  80. package/dist/cjs/evaluator/dependency-nodes/base-eval-node.cjs +112 -0
  81. package/dist/cjs/evaluator/dependency-nodes/base-eval-node.cjs.map +10 -0
  82. package/dist/cjs/evaluator/dependency-nodes/cell-value-node.cjs +54 -0
  83. package/dist/cjs/evaluator/dependency-nodes/cell-value-node.cjs.map +10 -0
  84. package/dist/cjs/evaluator/dependency-nodes/empty-cell-evaluation-node.cjs +108 -0
  85. package/dist/cjs/evaluator/dependency-nodes/empty-cell-evaluation-node.cjs.map +10 -0
  86. package/dist/cjs/evaluator/dependency-nodes/spill-meta-node.cjs +50 -0
  87. package/dist/cjs/evaluator/dependency-nodes/spill-meta-node.cjs.map +10 -0
  88. package/dist/cjs/evaluator/evaluate-scalar-operator.cjs +254 -0
  89. package/dist/cjs/evaluator/evaluate-scalar-operator.cjs.map +10 -0
  90. package/dist/cjs/evaluator/evaluation-context.cjs +154 -0
  91. package/dist/cjs/evaluator/evaluation-context.cjs.map +10 -0
  92. package/dist/cjs/evaluator/evaluation-error.cjs +75 -0
  93. package/dist/cjs/evaluator/evaluation-error.cjs.map +10 -0
  94. package/dist/cjs/evaluator/formula-evaluator.cjs +797 -0
  95. package/dist/cjs/evaluator/formula-evaluator.cjs.map +10 -0
  96. package/dist/cjs/evaluator/range-evaluation-node.cjs +88 -0
  97. package/dist/cjs/evaluator/range-evaluation-node.cjs.map +10 -0
  98. package/dist/cjs/functions/_template/template.cjs +42 -0
  99. package/dist/cjs/functions/_template/template.cjs.map +10 -0
  100. package/dist/cjs/functions/array/sequence/sequence.cjs +315 -0
  101. package/dist/cjs/functions/array/sequence/sequence.cjs.map +10 -0
  102. package/dist/cjs/functions/criteria-parser.cjs +217 -0
  103. package/dist/cjs/functions/criteria-parser.cjs.map +10 -0
  104. package/dist/cjs/functions/criteria-utils.cjs +291 -0
  105. package/dist/cjs/functions/criteria-utils.cjs.map +10 -0
  106. package/dist/cjs/functions/function-utils.cjs +63 -0
  107. package/dist/cjs/functions/function-utils.cjs.map +10 -0
  108. package/dist/cjs/functions/index.cjs +125 -0
  109. package/dist/cjs/functions/index.cjs.map +10 -0
  110. package/dist/cjs/functions/information/cell/cell.cjs +196 -0
  111. package/dist/cjs/functions/information/cell/cell.cjs.map +10 -0
  112. package/dist/cjs/functions/information/column/column.cjs +144 -0
  113. package/dist/cjs/functions/information/column/column.cjs.map +10 -0
  114. package/dist/cjs/functions/information/row/row.cjs +150 -0
  115. package/dist/cjs/functions/information/row/row.cjs.map +10 -0
  116. package/dist/cjs/functions/logical/and/and.cjs +112 -0
  117. package/dist/cjs/functions/logical/and/and.cjs.map +10 -0
  118. package/dist/cjs/functions/logical/if/if.cjs +195 -0
  119. package/dist/cjs/functions/logical/if/if.cjs.map +10 -0
  120. package/dist/cjs/functions/logical/iferror/iferror.cjs +126 -0
  121. package/dist/cjs/functions/logical/iferror/iferror.cjs.map +10 -0
  122. package/dist/cjs/functions/logical/or/or.cjs +112 -0
  123. package/dist/cjs/functions/logical/or/or.cjs.map +10 -0
  124. package/dist/cjs/functions/lookup/count/count-utils.cjs +65 -0
  125. package/dist/cjs/functions/lookup/count/count-utils.cjs.map +10 -0
  126. package/dist/cjs/functions/lookup/count/count.cjs +48 -0
  127. package/dist/cjs/functions/lookup/count/count.cjs.map +10 -0
  128. package/dist/cjs/functions/lookup/count/countif.cjs +94 -0
  129. package/dist/cjs/functions/lookup/count/countif.cjs.map +10 -0
  130. package/dist/cjs/functions/lookup/count/countifs.cjs +63 -0
  131. package/dist/cjs/functions/lookup/count/countifs.cjs.map +10 -0
  132. package/dist/cjs/functions/lookup/index-lookup/index-lookup.cjs +187 -0
  133. package/dist/cjs/functions/lookup/index-lookup/index-lookup.cjs.map +10 -0
  134. package/dist/cjs/functions/lookup/match/match.cjs +168 -0
  135. package/dist/cjs/functions/lookup/match/match.cjs.map +10 -0
  136. package/dist/cjs/functions/lookup/xlookup/xlookup.cjs +410 -0
  137. package/dist/cjs/functions/lookup/xlookup/xlookup.cjs.map +10 -0
  138. package/dist/cjs/functions/math/average/average-utils.cjs +72 -0
  139. package/dist/cjs/functions/math/average/average-utils.cjs.map +10 -0
  140. package/dist/cjs/functions/math/average/average.cjs +48 -0
  141. package/dist/cjs/functions/math/average/average.cjs.map +10 -0
  142. package/dist/cjs/functions/math/average/averageif.cjs +83 -0
  143. package/dist/cjs/functions/math/average/averageif.cjs.map +10 -0
  144. package/dist/cjs/functions/math/average/averageifs.cjs +61 -0
  145. package/dist/cjs/functions/math/average/averageifs.cjs.map +10 -0
  146. package/dist/cjs/functions/math/ceiling/ceiling.cjs +219 -0
  147. package/dist/cjs/functions/math/ceiling/ceiling.cjs.map +10 -0
  148. package/dist/cjs/functions/math/max/max-utils.cjs +71 -0
  149. package/dist/cjs/functions/math/max/max-utils.cjs.map +10 -0
  150. package/dist/cjs/functions/math/max/max.cjs +48 -0
  151. package/dist/cjs/functions/math/max/max.cjs.map +10 -0
  152. package/dist/cjs/functions/math/max/maxif.cjs +83 -0
  153. package/dist/cjs/functions/math/max/maxif.cjs.map +10 -0
  154. package/dist/cjs/functions/math/max/maxifs.cjs +61 -0
  155. package/dist/cjs/functions/math/max/maxifs.cjs.map +10 -0
  156. package/dist/cjs/functions/math/min/min-utils.cjs +71 -0
  157. package/dist/cjs/functions/math/min/min-utils.cjs.map +10 -0
  158. package/dist/cjs/functions/math/min/min.cjs +48 -0
  159. package/dist/cjs/functions/math/min/min.cjs.map +10 -0
  160. package/dist/cjs/functions/math/min/minif.cjs +83 -0
  161. package/dist/cjs/functions/math/min/minif.cjs.map +10 -0
  162. package/dist/cjs/functions/math/min/minifs.cjs +61 -0
  163. package/dist/cjs/functions/math/min/minifs.cjs.map +10 -0
  164. package/dist/cjs/functions/math/sum/sum.cjs +48 -0
  165. package/dist/cjs/functions/math/sum/sum.cjs.map +10 -0
  166. package/dist/cjs/functions/math/sum/sumif.cjs +83 -0
  167. package/dist/cjs/functions/math/sum/sumif.cjs.map +10 -0
  168. package/dist/cjs/functions/math/sum/sumifs.cjs +60 -0
  169. package/dist/cjs/functions/math/sum/sumifs.cjs.map +10 -0
  170. package/dist/cjs/functions/math/sum/summation-utils.cjs +57 -0
  171. package/dist/cjs/functions/math/sum/summation-utils.cjs.map +10 -0
  172. package/dist/cjs/functions/reference/address/address.cjs +163 -0
  173. package/dist/cjs/functions/reference/address/address.cjs.map +10 -0
  174. package/dist/cjs/functions/reference/indirect/indirect.cjs +102 -0
  175. package/dist/cjs/functions/reference/indirect/indirect.cjs.map +10 -0
  176. package/dist/cjs/functions/reference/offset/offset.cjs +233 -0
  177. package/dist/cjs/functions/reference/offset/offset.cjs.map +10 -0
  178. package/dist/cjs/functions/text/concatenate/concatenate.cjs +167 -0
  179. package/dist/cjs/functions/text/concatenate/concatenate.cjs.map +10 -0
  180. package/dist/cjs/functions/text/exact/exact.cjs +171 -0
  181. package/dist/cjs/functions/text/exact/exact.cjs.map +10 -0
  182. package/dist/cjs/functions/text/find/find.cjs +397 -0
  183. package/dist/cjs/functions/text/find/find.cjs.map +10 -0
  184. package/dist/cjs/functions/text/left/left.cjs +109 -0
  185. package/dist/cjs/functions/text/left/left.cjs.map +10 -0
  186. package/dist/cjs/functions/text/len/len.cjs +119 -0
  187. package/dist/cjs/functions/text/len/len.cjs.map +10 -0
  188. package/dist/cjs/functions/text/mid/mid.cjs +103 -0
  189. package/dist/cjs/functions/text/mid/mid.cjs.map +10 -0
  190. package/dist/cjs/functions/text/right/right.cjs +167 -0
  191. package/dist/cjs/functions/text/right/right.cjs.map +10 -0
  192. package/dist/cjs/functions/text/text-helpers.cjs +179 -0
  193. package/dist/cjs/functions/text/text-helpers.cjs.map +10 -0
  194. package/dist/cjs/functions/text/textjoin/textjoin.cjs +173 -0
  195. package/dist/cjs/functions/text/textjoin/textjoin.cjs.map +10 -0
  196. package/dist/cjs/package.json +5 -0
  197. package/dist/cjs/parser/ast.cjs +175 -0
  198. package/dist/cjs/parser/ast.cjs.map +10 -0
  199. package/dist/cjs/parser/formatter.cjs +319 -0
  200. package/dist/cjs/parser/formatter.cjs.map +10 -0
  201. package/dist/cjs/parser/grammar.cjs +375 -0
  202. package/dist/cjs/parser/grammar.cjs.map +10 -0
  203. package/dist/cjs/parser/lexer.cjs +443 -0
  204. package/dist/cjs/parser/lexer.cjs.map +10 -0
  205. package/dist/cjs/parser/parser.cjs +1700 -0
  206. package/dist/cjs/parser/parser.cjs.map +10 -0
  207. package/dist/cjs/react/hooks.cjs +59 -0
  208. package/dist/cjs/react/hooks.cjs.map +10 -0
  209. package/dist/mjs/core/ast-traverser.mjs +94 -0
  210. package/dist/mjs/core/ast-traverser.mjs.map +10 -0
  211. package/dist/mjs/core/autofill-utils.mjs +274 -0
  212. package/dist/mjs/core/autofill-utils.mjs.map +10 -0
  213. package/dist/mjs/core/engine.mjs +366 -0
  214. package/dist/mjs/core/engine.mjs.map +10 -0
  215. package/dist/mjs/core/managers/cache-manager.mjs +27 -0
  216. package/dist/mjs/core/managers/cache-manager.mjs.map +10 -0
  217. package/dist/mjs/core/managers/dependency-manager.mjs +593 -0
  218. package/dist/mjs/core/managers/dependency-manager.mjs.map +10 -0
  219. package/dist/mjs/core/managers/dependency-node.mjs +2 -0
  220. package/dist/mjs/core/managers/dependency-node.mjs.map +9 -0
  221. package/dist/mjs/core/managers/evaluation-manager.mjs +415 -0
  222. package/dist/mjs/core/managers/evaluation-manager.mjs.map +10 -0
  223. package/dist/mjs/core/managers/event-manager.mjs +18 -0
  224. package/dist/mjs/core/managers/event-manager.mjs.map +10 -0
  225. package/dist/mjs/core/managers/frontier-dependency-manager.mjs +151 -0
  226. package/dist/mjs/core/managers/frontier-dependency-manager.mjs.map +10 -0
  227. package/dist/mjs/core/managers/index.mjs +21 -0
  228. package/dist/mjs/core/managers/index.mjs.map +10 -0
  229. package/dist/mjs/core/managers/isDependencyNode.mjs +14 -0
  230. package/dist/mjs/core/managers/isDependencyNode.mjs.map +10 -0
  231. package/dist/mjs/core/managers/named-expression-manager.mjs +348 -0
  232. package/dist/mjs/core/managers/named-expression-manager.mjs.map +10 -0
  233. package/dist/mjs/core/managers/range-eval-order-builder.mjs +618 -0
  234. package/dist/mjs/core/managers/range-eval-order-builder.mjs.map +10 -0
  235. package/dist/mjs/core/managers/table-manager.mjs +224 -0
  236. package/dist/mjs/core/managers/table-manager.mjs.map +10 -0
  237. package/dist/mjs/core/managers/workbook-manager.mjs +447 -0
  238. package/dist/mjs/core/managers/workbook-manager.mjs.map +10 -0
  239. package/dist/mjs/core/map-serializer.mjs +39 -0
  240. package/dist/mjs/core/map-serializer.mjs.map +10 -0
  241. package/dist/mjs/core/named-expression-renamer.mjs +58 -0
  242. package/dist/mjs/core/named-expression-renamer.mjs.map +10 -0
  243. package/dist/mjs/core/sheet-renamer.mjs +59 -0
  244. package/dist/mjs/core/sheet-renamer.mjs.map +10 -0
  245. package/dist/mjs/core/sheet-utils.mjs +8 -0
  246. package/dist/mjs/core/sheet-utils.mjs.map +10 -0
  247. package/dist/mjs/core/table-renamer.mjs +58 -0
  248. package/dist/mjs/core/table-renamer.mjs.map +10 -0
  249. package/dist/mjs/core/types.mjs +18 -0
  250. package/dist/mjs/core/types.mjs.map +10 -0
  251. package/dist/mjs/core/utils/range-serializer.mjs +35 -0
  252. package/dist/mjs/core/utils/range-serializer.mjs.map +10 -0
  253. package/dist/mjs/core/utils/spreadsheet-visualizer.mjs +112 -0
  254. package/dist/mjs/core/utils/spreadsheet-visualizer.mjs.map +10 -0
  255. package/dist/mjs/core/utils.mjs +409 -0
  256. package/dist/mjs/core/utils.mjs.map +10 -0
  257. package/dist/mjs/core/workbook-renamer.mjs +76 -0
  258. package/dist/mjs/core/workbook-renamer.mjs.map +10 -0
  259. package/dist/mjs/debug/flags.mjs +17 -0
  260. package/dist/mjs/debug/flags.mjs.map +10 -0
  261. package/dist/mjs/evaluator/arithmetic/add/add.mjs +52 -0
  262. package/dist/mjs/evaluator/arithmetic/add/add.mjs.map +10 -0
  263. package/dist/mjs/evaluator/arithmetic/divide/divide.mjs +77 -0
  264. package/dist/mjs/evaluator/arithmetic/divide/divide.mjs.map +10 -0
  265. package/dist/mjs/evaluator/arithmetic/multiply/multiply.mjs +63 -0
  266. package/dist/mjs/evaluator/arithmetic/multiply/multiply.mjs.map +10 -0
  267. package/dist/mjs/evaluator/arithmetic/power/power.mjs +95 -0
  268. package/dist/mjs/evaluator/arithmetic/power/power.mjs.map +10 -0
  269. package/dist/mjs/evaluator/arithmetic/subtract/subtract.mjs +54 -0
  270. package/dist/mjs/evaluator/arithmetic/subtract/subtract.mjs.map +10 -0
  271. package/dist/mjs/evaluator/comparison/equals.mjs +34 -0
  272. package/dist/mjs/evaluator/comparison/equals.mjs.map +10 -0
  273. package/dist/mjs/evaluator/comparison/greater-than-or-equal.mjs +31 -0
  274. package/dist/mjs/evaluator/comparison/greater-than-or-equal.mjs.map +10 -0
  275. package/dist/mjs/evaluator/comparison/greater-than.mjs +31 -0
  276. package/dist/mjs/evaluator/comparison/greater-than.mjs.map +10 -0
  277. package/dist/mjs/evaluator/comparison/less-than-or-equal.mjs +39 -0
  278. package/dist/mjs/evaluator/comparison/less-than-or-equal.mjs.map +10 -0
  279. package/dist/mjs/evaluator/comparison/less-than.mjs +38 -0
  280. package/dist/mjs/evaluator/comparison/less-than.mjs.map +10 -0
  281. package/dist/mjs/evaluator/comparison/not-equals.mjs +23 -0
  282. package/dist/mjs/evaluator/comparison/not-equals.mjs.map +10 -0
  283. package/dist/mjs/evaluator/concatenation/concatenate.mjs +42 -0
  284. package/dist/mjs/evaluator/concatenation/concatenate.mjs.map +10 -0
  285. package/dist/mjs/evaluator/dependency-nodes/ast-evaluation-node.mjs +28 -0
  286. package/dist/mjs/evaluator/dependency-nodes/ast-evaluation-node.mjs.map +10 -0
  287. package/dist/mjs/evaluator/dependency-nodes/base-eval-node.mjs +81 -0
  288. package/dist/mjs/evaluator/dependency-nodes/base-eval-node.mjs.map +10 -0
  289. package/dist/mjs/evaluator/dependency-nodes/cell-value-node.mjs +24 -0
  290. package/dist/mjs/evaluator/dependency-nodes/cell-value-node.mjs.map +10 -0
  291. package/dist/mjs/evaluator/dependency-nodes/empty-cell-evaluation-node.mjs +78 -0
  292. package/dist/mjs/evaluator/dependency-nodes/empty-cell-evaluation-node.mjs.map +10 -0
  293. package/dist/mjs/evaluator/dependency-nodes/spill-meta-node.mjs +20 -0
  294. package/dist/mjs/evaluator/dependency-nodes/spill-meta-node.mjs.map +10 -0
  295. package/dist/mjs/evaluator/evaluate-scalar-operator.mjs +226 -0
  296. package/dist/mjs/evaluator/evaluate-scalar-operator.mjs.map +10 -0
  297. package/dist/mjs/evaluator/evaluation-context.mjs +123 -0
  298. package/dist/mjs/evaluator/evaluation-context.mjs.map +10 -0
  299. package/dist/mjs/evaluator/evaluation-error.mjs +44 -0
  300. package/dist/mjs/evaluator/evaluation-error.mjs.map +10 -0
  301. package/dist/mjs/evaluator/formula-evaluator.mjs +780 -0
  302. package/dist/mjs/evaluator/formula-evaluator.mjs.map +10 -0
  303. package/dist/mjs/evaluator/range-evaluation-node.mjs +58 -0
  304. package/dist/mjs/evaluator/range-evaluation-node.mjs.map +10 -0
  305. package/dist/mjs/functions/_template/template.mjs +12 -0
  306. package/dist/mjs/functions/_template/template.mjs.map +10 -0
  307. package/dist/mjs/functions/array/sequence/sequence.mjs +287 -0
  308. package/dist/mjs/functions/array/sequence/sequence.mjs.map +10 -0
  309. package/dist/mjs/functions/criteria-parser.mjs +187 -0
  310. package/dist/mjs/functions/criteria-parser.mjs.map +10 -0
  311. package/dist/mjs/functions/criteria-utils.mjs +268 -0
  312. package/dist/mjs/functions/criteria-utils.mjs.map +10 -0
  313. package/dist/mjs/functions/function-utils.mjs +33 -0
  314. package/dist/mjs/functions/function-utils.mjs.map +10 -0
  315. package/dist/mjs/functions/index.mjs +95 -0
  316. package/dist/mjs/functions/index.mjs.map +10 -0
  317. package/dist/mjs/functions/information/cell/cell.mjs +168 -0
  318. package/dist/mjs/functions/information/cell/cell.mjs.map +10 -0
  319. package/dist/mjs/functions/information/column/column.mjs +120 -0
  320. package/dist/mjs/functions/information/column/column.mjs.map +10 -0
  321. package/dist/mjs/functions/information/row/row.mjs +126 -0
  322. package/dist/mjs/functions/information/row/row.mjs.map +10 -0
  323. package/dist/mjs/functions/logical/and/and.mjs +84 -0
  324. package/dist/mjs/functions/logical/and/and.mjs.map +10 -0
  325. package/dist/mjs/functions/logical/if/if.mjs +167 -0
  326. package/dist/mjs/functions/logical/if/if.mjs.map +10 -0
  327. package/dist/mjs/functions/logical/iferror/iferror.mjs +98 -0
  328. package/dist/mjs/functions/logical/iferror/iferror.mjs.map +10 -0
  329. package/dist/mjs/functions/logical/or/or.mjs +84 -0
  330. package/dist/mjs/functions/logical/or/or.mjs.map +10 -0
  331. package/dist/mjs/functions/lookup/count/count-utils.mjs +35 -0
  332. package/dist/mjs/functions/lookup/count/count-utils.mjs.map +10 -0
  333. package/dist/mjs/functions/lookup/count/count.mjs +18 -0
  334. package/dist/mjs/functions/lookup/count/count.mjs.map +10 -0
  335. package/dist/mjs/functions/lookup/count/countif.mjs +68 -0
  336. package/dist/mjs/functions/lookup/count/countif.mjs.map +10 -0
  337. package/dist/mjs/functions/lookup/count/countifs.mjs +37 -0
  338. package/dist/mjs/functions/lookup/count/countifs.mjs.map +10 -0
  339. package/dist/mjs/functions/lookup/index-lookup/index-lookup.mjs +159 -0
  340. package/dist/mjs/functions/lookup/index-lookup/index-lookup.mjs.map +10 -0
  341. package/dist/mjs/functions/lookup/match/match.mjs +140 -0
  342. package/dist/mjs/functions/lookup/match/match.mjs.map +10 -0
  343. package/dist/mjs/functions/lookup/xlookup/xlookup.mjs +382 -0
  344. package/dist/mjs/functions/lookup/xlookup/xlookup.mjs.map +10 -0
  345. package/dist/mjs/functions/math/average/average-utils.mjs +44 -0
  346. package/dist/mjs/functions/math/average/average-utils.mjs.map +10 -0
  347. package/dist/mjs/functions/math/average/average.mjs +18 -0
  348. package/dist/mjs/functions/math/average/average.mjs.map +10 -0
  349. package/dist/mjs/functions/math/average/averageif.mjs +58 -0
  350. package/dist/mjs/functions/math/average/averageif.mjs.map +10 -0
  351. package/dist/mjs/functions/math/average/averageifs.mjs +35 -0
  352. package/dist/mjs/functions/math/average/averageifs.mjs.map +10 -0
  353. package/dist/mjs/functions/math/ceiling/ceiling.mjs +191 -0
  354. package/dist/mjs/functions/math/ceiling/ceiling.mjs.map +10 -0
  355. package/dist/mjs/functions/math/max/max-utils.mjs +43 -0
  356. package/dist/mjs/functions/math/max/max-utils.mjs.map +10 -0
  357. package/dist/mjs/functions/math/max/max.mjs +18 -0
  358. package/dist/mjs/functions/math/max/max.mjs.map +10 -0
  359. package/dist/mjs/functions/math/max/maxif.mjs +58 -0
  360. package/dist/mjs/functions/math/max/maxif.mjs.map +10 -0
  361. package/dist/mjs/functions/math/max/maxifs.mjs +35 -0
  362. package/dist/mjs/functions/math/max/maxifs.mjs.map +10 -0
  363. package/dist/mjs/functions/math/min/min-utils.mjs +43 -0
  364. package/dist/mjs/functions/math/min/min-utils.mjs.map +10 -0
  365. package/dist/mjs/functions/math/min/min.mjs +18 -0
  366. package/dist/mjs/functions/math/min/min.mjs.map +10 -0
  367. package/dist/mjs/functions/math/min/minif.mjs +58 -0
  368. package/dist/mjs/functions/math/min/minif.mjs.map +10 -0
  369. package/dist/mjs/functions/math/min/minifs.mjs +35 -0
  370. package/dist/mjs/functions/math/min/minifs.mjs.map +10 -0
  371. package/dist/mjs/functions/math/sum/sum.mjs +18 -0
  372. package/dist/mjs/functions/math/sum/sum.mjs.map +10 -0
  373. package/dist/mjs/functions/math/sum/sumif.mjs +58 -0
  374. package/dist/mjs/functions/math/sum/sumif.mjs.map +10 -0
  375. package/dist/mjs/functions/math/sum/sumifs.mjs +34 -0
  376. package/dist/mjs/functions/math/sum/sumifs.mjs.map +10 -0
  377. package/dist/mjs/functions/math/sum/summation-utils.mjs +27 -0
  378. package/dist/mjs/functions/math/sum/summation-utils.mjs.map +10 -0
  379. package/dist/mjs/functions/reference/address/address.mjs +135 -0
  380. package/dist/mjs/functions/reference/address/address.mjs.map +10 -0
  381. package/dist/mjs/functions/reference/indirect/indirect.mjs +74 -0
  382. package/dist/mjs/functions/reference/indirect/indirect.mjs.map +10 -0
  383. package/dist/mjs/functions/reference/offset/offset.mjs +205 -0
  384. package/dist/mjs/functions/reference/offset/offset.mjs.map +10 -0
  385. package/dist/mjs/functions/text/concatenate/concatenate.mjs +139 -0
  386. package/dist/mjs/functions/text/concatenate/concatenate.mjs.map +10 -0
  387. package/dist/mjs/functions/text/exact/exact.mjs +143 -0
  388. package/dist/mjs/functions/text/exact/exact.mjs.map +10 -0
  389. package/dist/mjs/functions/text/find/find.mjs +369 -0
  390. package/dist/mjs/functions/text/find/find.mjs.map +10 -0
  391. package/dist/mjs/functions/text/left/left.mjs +81 -0
  392. package/dist/mjs/functions/text/left/left.mjs.map +10 -0
  393. package/dist/mjs/functions/text/len/len.mjs +91 -0
  394. package/dist/mjs/functions/text/len/len.mjs.map +10 -0
  395. package/dist/mjs/functions/text/mid/mid.mjs +75 -0
  396. package/dist/mjs/functions/text/mid/mid.mjs.map +10 -0
  397. package/dist/mjs/functions/text/right/right.mjs +143 -0
  398. package/dist/mjs/functions/text/right/right.mjs.map +10 -0
  399. package/dist/mjs/functions/text/text-helpers.mjs +151 -0
  400. package/dist/mjs/functions/text/text-helpers.mjs.map +10 -0
  401. package/dist/mjs/functions/text/textjoin/textjoin.mjs +145 -0
  402. package/dist/mjs/functions/text/textjoin/textjoin.mjs.map +10 -0
  403. package/dist/mjs/package.json +5 -0
  404. package/dist/mjs/parser/ast.mjs +145 -0
  405. package/dist/mjs/parser/ast.mjs.map +10 -0
  406. package/dist/mjs/parser/formatter.mjs +289 -0
  407. package/dist/mjs/parser/formatter.mjs.map +10 -0
  408. package/dist/mjs/parser/grammar.mjs +345 -0
  409. package/dist/mjs/parser/grammar.mjs.map +10 -0
  410. package/dist/mjs/parser/lexer.mjs +412 -0
  411. package/dist/mjs/parser/lexer.mjs.map +10 -0
  412. package/dist/mjs/parser/parser.mjs +1692 -0
  413. package/dist/mjs/parser/parser.mjs.map +10 -0
  414. package/dist/mjs/react/hooks.mjs +16 -0
  415. package/dist/mjs/react/hooks.mjs.map +10 -0
  416. package/dist/types/core/ast-traverser.d.ts +28 -0
  417. package/dist/types/core/autofill-utils.d.ts +32 -0
  418. package/dist/types/core/engine.d.ts +184 -0
  419. package/dist/types/core/managers/cache-manager.d.ts +14 -0
  420. package/dist/types/core/managers/dependency-manager.d.ts +147 -0
  421. package/dist/types/core/managers/dependency-node.d.ts +13 -0
  422. package/dist/types/core/managers/evaluation-manager.d.ts +30 -0
  423. package/dist/types/core/managers/event-manager.d.ts +8 -0
  424. package/dist/types/core/managers/frontier-dependency-manager.d.ts +69 -0
  425. package/dist/types/core/managers/index.d.ts +7 -0
  426. package/dist/types/core/managers/isDependencyNode.d.ts +2 -0
  427. package/dist/types/core/managers/named-expression-manager.d.ts +101 -0
  428. package/dist/types/core/managers/range-eval-order-builder.d.ts +33 -0
  429. package/dist/types/core/managers/table-manager.d.ts +84 -0
  430. package/dist/types/core/managers/workbook-manager.d.ts +136 -0
  431. package/dist/types/core/map-serializer.d.ts +4 -0
  432. package/dist/types/core/named-expression-renamer.d.ts +21 -0
  433. package/dist/types/core/sheet-renamer.d.ts +28 -0
  434. package/dist/types/core/sheet-utils.d.ts +2 -0
  435. package/dist/types/core/table-renamer.d.ts +21 -0
  436. package/dist/types/core/types.d.ts +272 -0
  437. package/dist/types/core/utils/cell-address-parsing.test.d.ts +1 -0
  438. package/dist/types/core/utils/range-serializer.d.ts +22 -0
  439. package/dist/types/core/utils/range-serializer.test.d.ts +1 -0
  440. package/dist/types/core/utils/spreadsheet-visualizer.d.ts +30 -0
  441. package/dist/types/core/utils.d.ts +48 -0
  442. package/dist/types/core/workbook-renamer.d.ts +28 -0
  443. package/dist/types/debug/flags.d.ts +11 -0
  444. package/dist/types/evaluator/arithmetic/add/add.d.ts +2 -0
  445. package/dist/types/evaluator/arithmetic/add/add.test.d.ts +1 -0
  446. package/dist/types/evaluator/arithmetic/divide/divide.d.ts +2 -0
  447. package/dist/types/evaluator/arithmetic/divide/divide.test.d.ts +1 -0
  448. package/dist/types/evaluator/arithmetic/multiply/multiply.d.ts +2 -0
  449. package/dist/types/evaluator/arithmetic/multiply/multiply.test.d.ts +1 -0
  450. package/dist/types/evaluator/arithmetic/power/power.d.ts +2 -0
  451. package/dist/types/evaluator/arithmetic/power/power.test.d.ts +1 -0
  452. package/dist/types/evaluator/arithmetic/subtract/subtract.d.ts +2 -0
  453. package/dist/types/evaluator/arithmetic/subtract/subtract.test.d.ts +1 -0
  454. package/dist/types/evaluator/comparison/comparison-operators.test.d.ts +1 -0
  455. package/dist/types/evaluator/comparison/equals.d.ts +6 -0
  456. package/dist/types/evaluator/comparison/greater-than-or-equal.d.ts +6 -0
  457. package/dist/types/evaluator/comparison/greater-than.d.ts +6 -0
  458. package/dist/types/evaluator/comparison/less-than-or-equal.d.ts +6 -0
  459. package/dist/types/evaluator/comparison/less-than.d.ts +6 -0
  460. package/dist/types/evaluator/comparison/not-equals.d.ts +6 -0
  461. package/dist/types/evaluator/concatenation/concatenate.d.ts +6 -0
  462. package/dist/types/evaluator/concatenation/concatenate.test.d.ts +1 -0
  463. package/dist/types/evaluator/dependency-nodes/ast-evaluation-node.d.ts +12 -0
  464. package/dist/types/evaluator/dependency-nodes/base-eval-node.d.ts +31 -0
  465. package/dist/types/evaluator/dependency-nodes/cell-value-node.d.ts +10 -0
  466. package/dist/types/evaluator/dependency-nodes/empty-cell-evaluation-node.d.ts +17 -0
  467. package/dist/types/evaluator/dependency-nodes/spill-meta-node.d.ts +7 -0
  468. package/dist/types/evaluator/evaluate-scalar-operator.d.ts +12 -0
  469. package/dist/types/evaluator/evaluation-context.d.ts +66 -0
  470. package/dist/types/evaluator/evaluation-error.d.ts +20 -0
  471. package/dist/types/evaluator/formula-evaluator.d.ts +67 -0
  472. package/dist/types/evaluator/open-range-evaluator.test.d.ts +1 -0
  473. package/dist/types/evaluator/range-evaluation-node.d.ts +16 -0
  474. package/dist/types/functions/_template/template.d.ts +5 -0
  475. package/dist/types/functions/_template/template.test.d.ts +1 -0
  476. package/dist/types/functions/array/sequence/performance-test.d.ts +1 -0
  477. package/dist/types/functions/array/sequence/sequence.d.ts +14 -0
  478. package/dist/types/functions/array/sequence/sequence.test.d.ts +1 -0
  479. package/dist/types/functions/criteria-parser.d.ts +27 -0
  480. package/dist/types/functions/criteria-utils.d.ts +61 -0
  481. package/dist/types/functions/function-utils.d.ts +21 -0
  482. package/dist/types/functions/index.d.ts +2 -0
  483. package/dist/types/functions/information/cell/cell.d.ts +24 -0
  484. package/dist/types/functions/information/cell/cell.test.d.ts +1 -0
  485. package/dist/types/functions/information/column/column.d.ts +14 -0
  486. package/dist/types/functions/information/column/column.test.d.ts +1 -0
  487. package/dist/types/functions/information/row/row.d.ts +14 -0
  488. package/dist/types/functions/information/row/row.test.d.ts +1 -0
  489. package/dist/types/functions/logical/and/and.d.ts +5 -0
  490. package/dist/types/functions/logical/and/and.test.d.ts +1 -0
  491. package/dist/types/functions/logical/if/if.d.ts +5 -0
  492. package/dist/types/functions/logical/if/if.test.d.ts +1 -0
  493. package/dist/types/functions/logical/iferror/iferror.d.ts +5 -0
  494. package/dist/types/functions/logical/iferror/iferror.test.d.ts +1 -0
  495. package/dist/types/functions/logical/or/or.d.ts +5 -0
  496. package/dist/types/functions/logical/or/or.test.d.ts +1 -0
  497. package/dist/types/functions/lookup/count/count-utils.d.ts +14 -0
  498. package/dist/types/functions/lookup/count/count.d.ts +21 -0
  499. package/dist/types/functions/lookup/count/count.test.d.ts +1 -0
  500. package/dist/types/functions/lookup/count/countif.d.ts +26 -0
  501. package/dist/types/functions/lookup/count/countif.test.d.ts +1 -0
  502. package/dist/types/functions/lookup/count/countifs.d.ts +21 -0
  503. package/dist/types/functions/lookup/count/countifs.test.d.ts +1 -0
  504. package/dist/types/functions/lookup/index-lookup/index-lookup.d.ts +2 -0
  505. package/dist/types/functions/lookup/index-lookup/index-lookup.test.d.ts +1 -0
  506. package/dist/types/functions/lookup/match/match.d.ts +2 -0
  507. package/dist/types/functions/lookup/match/match.test.d.ts +1 -0
  508. package/dist/types/functions/lookup/xlookup/xlookup.d.ts +2 -0
  509. package/dist/types/functions/lookup/xlookup/xlookup.test.d.ts +1 -0
  510. package/dist/types/functions/math/average/average-utils.d.ts +10 -0
  511. package/dist/types/functions/math/average/average.d.ts +18 -0
  512. package/dist/types/functions/math/average/average.test.d.ts +1 -0
  513. package/dist/types/functions/math/average/averageif.d.ts +23 -0
  514. package/dist/types/functions/math/average/averageif.test.d.ts +1 -0
  515. package/dist/types/functions/math/average/averageifs.d.ts +21 -0
  516. package/dist/types/functions/math/average/averageifs.test.d.ts +1 -0
  517. package/dist/types/functions/math/ceiling/ceiling.d.ts +5 -0
  518. package/dist/types/functions/math/ceiling/ceiling.test.d.ts +1 -0
  519. package/dist/types/functions/math/max/max-utils.d.ts +20 -0
  520. package/dist/types/functions/math/max/max.d.ts +18 -0
  521. package/dist/types/functions/math/max/max.test.d.ts +1 -0
  522. package/dist/types/functions/math/max/maxif.d.ts +23 -0
  523. package/dist/types/functions/math/max/maxif.test.d.ts +1 -0
  524. package/dist/types/functions/math/max/maxifs.d.ts +21 -0
  525. package/dist/types/functions/math/max/maxifs.test.d.ts +1 -0
  526. package/dist/types/functions/math/min/min-utils.d.ts +20 -0
  527. package/dist/types/functions/math/min/min.d.ts +5 -0
  528. package/dist/types/functions/math/min/min.test.d.ts +1 -0
  529. package/dist/types/functions/math/min/minif.d.ts +23 -0
  530. package/dist/types/functions/math/min/minif.test.d.ts +1 -0
  531. package/dist/types/functions/math/min/minifs.d.ts +21 -0
  532. package/dist/types/functions/math/min/minifs.test.d.ts +1 -0
  533. package/dist/types/functions/math/sum/sum.d.ts +5 -0
  534. package/dist/types/functions/math/sum/sum.test.d.ts +1 -0
  535. package/dist/types/functions/math/sum/sumif.d.ts +23 -0
  536. package/dist/types/functions/math/sum/sumif.test.d.ts +1 -0
  537. package/dist/types/functions/math/sum/sumifs.d.ts +21 -0
  538. package/dist/types/functions/math/sum/sumifs.test.d.ts +1 -0
  539. package/dist/types/functions/math/sum/summation-utils.d.ts +19 -0
  540. package/dist/types/functions/reference/address/address.d.ts +18 -0
  541. package/dist/types/functions/reference/address/address.test.d.ts +1 -0
  542. package/dist/types/functions/reference/indirect/indirect.d.ts +20 -0
  543. package/dist/types/functions/reference/indirect/indirect.test.d.ts +1 -0
  544. package/dist/types/functions/reference/offset/offset.d.ts +23 -0
  545. package/dist/types/functions/reference/offset/offset.test.d.ts +1 -0
  546. package/dist/types/functions/text/concatenate/concatenate.d.ts +5 -0
  547. package/dist/types/functions/text/concatenate/concatenate.test.d.ts +1 -0
  548. package/dist/types/functions/text/exact/exact.d.ts +5 -0
  549. package/dist/types/functions/text/exact/exact.test.d.ts +1 -0
  550. package/dist/types/functions/text/find/find.d.ts +20 -0
  551. package/dist/types/functions/text/find/find.test.d.ts +1 -0
  552. package/dist/types/functions/text/left/left.d.ts +19 -0
  553. package/dist/types/functions/text/left/left.test.d.ts +1 -0
  554. package/dist/types/functions/text/len/len.d.ts +16 -0
  555. package/dist/types/functions/text/len/len.test.d.ts +1 -0
  556. package/dist/types/functions/text/mid/mid.d.ts +20 -0
  557. package/dist/types/functions/text/mid/mid.test.d.ts +1 -0
  558. package/dist/types/functions/text/right/right.d.ts +2 -0
  559. package/dist/types/functions/text/right/right.test.d.ts +1 -0
  560. package/dist/types/functions/text/text-helpers.d.ts +27 -0
  561. package/dist/types/functions/text/textjoin/textjoin.d.ts +5 -0
  562. package/dist/types/functions/text/textjoin/textjoin.test.d.ts +1 -0
  563. package/dist/types/parser/ast.d.ts +275 -0
  564. package/dist/types/parser/formatter.d.ts +6 -0
  565. package/dist/types/parser/grammar.d.ts +203 -0
  566. package/dist/types/parser/lexer.d.ts +144 -0
  567. package/dist/types/parser/parser.d.ts +159 -0
  568. package/dist/types/react/hooks.d.ts +5 -0
  569. 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
+ }