@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,75 @@
1
+ // src/functions/text/mid/mid.ts
2
+ import {
3
+ FormulaError
4
+ } from "src/core/types";
5
+ import { midOperation, createMidSpilledResult } from "../text-helpers.mjs";
6
+ var MID = {
7
+ name: "MID",
8
+ evaluate: function(node, context) {
9
+ if (node.args.length !== 3) {
10
+ return {
11
+ type: "error",
12
+ err: FormulaError.VALUE,
13
+ message: "MID function takes exactly 3 arguments",
14
+ errAddress: context.dependencyNode
15
+ };
16
+ }
17
+ const textResult = this.evaluateNode(node.args[0], context);
18
+ if (textResult.type === "error" || textResult.type === "awaiting-evaluation") {
19
+ return textResult;
20
+ }
21
+ const startNumResult = this.evaluateNode(node.args[1], context);
22
+ if (startNumResult.type === "error" || startNumResult.type === "awaiting-evaluation") {
23
+ return startNumResult;
24
+ }
25
+ const numCharsResult = this.evaluateNode(node.args[2], context);
26
+ if (numCharsResult.type === "error" || numCharsResult.type === "awaiting-evaluation") {
27
+ return numCharsResult;
28
+ }
29
+ if (textResult.type === "spilled-values" || startNumResult.type === "spilled-values" || numCharsResult.type === "spilled-values") {
30
+ return createMidSpilledResult.call(this, {
31
+ textResult,
32
+ startNumResult,
33
+ numCharsResult,
34
+ context
35
+ });
36
+ }
37
+ if (textResult.result.type !== "string") {
38
+ return {
39
+ type: "error",
40
+ err: FormulaError.VALUE,
41
+ message: "Text argument must be a string",
42
+ errAddress: context.dependencyNode
43
+ };
44
+ }
45
+ if (startNumResult.result.type !== "number") {
46
+ return {
47
+ type: "error",
48
+ err: FormulaError.VALUE,
49
+ message: "Start_num argument must be a number",
50
+ errAddress: context.dependencyNode
51
+ };
52
+ }
53
+ if (numCharsResult.result.type !== "number") {
54
+ return {
55
+ type: "error",
56
+ err: FormulaError.VALUE,
57
+ message: "Num_chars argument must be a number",
58
+ errAddress: context.dependencyNode
59
+ };
60
+ }
61
+ const result = midOperation(textResult, startNumResult, numCharsResult, context);
62
+ if (result.type === "error" || result.type === "awaiting-evaluation") {
63
+ return result;
64
+ }
65
+ return {
66
+ type: "value",
67
+ result: result.result
68
+ };
69
+ }
70
+ };
71
+ export {
72
+ MID
73
+ };
74
+
75
+ //# debugId=F4075A7448E40AEC64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/functions/text/mid/mid.ts"],
4
+ "sourcesContent": [
5
+ "import {\n FormulaError,\n type FunctionDefinition,\n type FunctionEvaluationResult,\n} from \"src/core/types\";\nimport { midOperation, createMidSpilledResult } from \"../text-helpers.mjs\";\n\n/**\n * MID function - Returns characters from the middle of a text string\n *\n * Usage: MID(text, start_num, num_chars)\n *\n * text: The text string to extract characters from.\n * start_num: The position of the first character to extract (1-based).\n * num_chars: The number of characters to extract.\n *\n * Example: MID(\"Hello, World!\", 8, 5) returns \"World\"\n *\n * Note:\n * - If start_num is less than 1, the function returns an error.\n * - If num_chars is less than 0, the function returns an error.\n * - If start_num is greater than the length of text, the function returns an empty string.\n * - Supports dynamic arrays (spilled values) for all arguments\n * - Strict type checking: text must be string, start_num and num_chars must be numbers\n */\nexport const MID: FunctionDefinition = {\n name: \"MID\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length !== 3) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"MID function takes exactly 3 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate the text argument\n const textResult = this.evaluateNode(node.args[0]!, context);\n if (\n textResult.type === \"error\" ||\n textResult.type === \"awaiting-evaluation\"\n ) {\n return textResult;\n }\n\n // Evaluate the start_num argument\n const startNumResult = this.evaluateNode(node.args[1]!, context);\n if (\n startNumResult.type === \"error\" ||\n startNumResult.type === \"awaiting-evaluation\"\n ) {\n return startNumResult;\n }\n\n // Evaluate the num_chars argument\n const numCharsResult = this.evaluateNode(node.args[2]!, context);\n if (\n numCharsResult.type === \"error\" ||\n numCharsResult.type === \"awaiting-evaluation\"\n ) {\n return numCharsResult;\n }\n\n // Handle spilled-values inputs\n if (\n textResult.type === \"spilled-values\" ||\n startNumResult.type === \"spilled-values\" ||\n numCharsResult.type === \"spilled-values\"\n ) {\n return createMidSpilledResult.call(this, {\n textResult,\n startNumResult,\n numCharsResult,\n context,\n });\n }\n\n // Strict type checking - no coercion\n if (textResult.result.type !== \"string\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Text argument must be a string\",\n errAddress: context.dependencyNode,\n };\n }\n\n if (startNumResult.result.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Start_num argument must be a number\",\n errAddress: context.dependencyNode,\n };\n }\n\n if (numCharsResult.result.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Num_chars argument must be a number\",\n errAddress: context.dependencyNode,\n };\n }\n\n const result = midOperation(\n textResult,\n startNumResult,\n numCharsResult,\n context\n );\n if (result.type === \"error\" || result.type === \"awaiting-evaluation\") {\n return result;\n }\n return {\n type: \"value\",\n result: result.result,\n };\n },\n};\n"
6
+ ],
7
+ "mappings": ";AAAA;AAAA;AAAA;AAKA;AAoBO,IAAM,MAA0B;AAAA,EACrC,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAC3D,IAAI,KAAK,KAAK,WAAW,GAAG;AAAA,MAC1B,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,MAAM,aAAa,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IAC3D,IACE,WAAW,SAAS,WACpB,WAAW,SAAS,uBACpB;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,iBAAiB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IAC/D,IACE,eAAe,SAAS,WACxB,eAAe,SAAS,uBACxB;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,iBAAiB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IAC/D,IACE,eAAe,SAAS,WACxB,eAAe,SAAS,uBACxB;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IAGA,IACE,WAAW,SAAS,oBACpB,eAAe,SAAS,oBACxB,eAAe,SAAS,kBACxB;AAAA,MACA,OAAO,uBAAuB,KAAK,MAAM;AAAA,QACvC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAGA,IAAI,WAAW,OAAO,SAAS,UAAU;AAAA,MACvC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAEA,IAAI,eAAe,OAAO,SAAS,UAAU;AAAA,MAC3C,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAEA,IAAI,eAAe,OAAO,SAAS,UAAU;AAAA,MAC3C,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAEA,MAAM,SAAS,aACb,YACA,gBACA,gBACA,OACF;AAAA,IACA,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,uBAAuB;AAAA,MACpE,OAAO;AAAA,IACT;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,OAAO;AAAA,IACjB;AAAA;AAEJ;",
8
+ "debugId": "F4075A7448E40AEC64756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,143 @@
1
+ // src/functions/text/right/right.ts
2
+ import {
3
+ FormulaError
4
+ } from "src/core/types";
5
+ import {
6
+ midOperation,
7
+ convertToString,
8
+ extractNumericValue
9
+ } from "../text-helpers.mjs";
10
+ function rightOperation(textResult, numCharsResult, context) {
11
+ const textStr = convertToString(textResult, context);
12
+ const numChars = extractNumericValue(numCharsResult, context);
13
+ if (typeof textStr === "object" && (textStr.type === "awaiting-evaluation" || textStr.type === "error")) {
14
+ return textStr;
15
+ }
16
+ if (typeof numChars === "object" && (numChars.type === "awaiting-evaluation" || numChars.type === "error")) {
17
+ return numChars;
18
+ }
19
+ const textValue = textStr;
20
+ const numCharsValue = numChars;
21
+ if (numCharsValue < 0) {
22
+ return {
23
+ type: "error",
24
+ err: FormulaError.VALUE,
25
+ message: "NumChars argument must be a positive number",
26
+ errAddress: context.dependencyNode
27
+ };
28
+ }
29
+ const textLength = textValue.length;
30
+ const startPos = Math.max(1, textLength - Math.floor(numCharsValue) + 1);
31
+ const startNumResult = {
32
+ type: "value",
33
+ result: { type: "number", value: startPos }
34
+ };
35
+ return midOperation(textResult, startNumResult, numCharsResult, context);
36
+ }
37
+ var RIGHT = {
38
+ name: "RIGHT",
39
+ evaluate: function(node, context) {
40
+ if (node.args.length < 1 || node.args.length > 2) {
41
+ return {
42
+ type: "error",
43
+ err: FormulaError.VALUE,
44
+ message: "RIGHT function takes 1 or 2 arguments",
45
+ errAddress: context.dependencyNode
46
+ };
47
+ }
48
+ const textResult = this.evaluateNode(node.args[0], context);
49
+ if (textResult.type === "error" || textResult.type === "awaiting-evaluation") {
50
+ return textResult;
51
+ }
52
+ let numCharsResult;
53
+ if (node.args.length > 1) {
54
+ numCharsResult = this.evaluateNode(node.args[1], context);
55
+ if (numCharsResult.type === "error" || numCharsResult.type === "awaiting-evaluation") {
56
+ return numCharsResult;
57
+ }
58
+ } else {
59
+ numCharsResult = {
60
+ type: "value",
61
+ result: { type: "number", value: 1 }
62
+ };
63
+ }
64
+ if (textResult.type === "spilled-values" || numCharsResult.type === "spilled-values") {
65
+ return createRightSpilledResult.call(this, {
66
+ textResult,
67
+ numCharsResult,
68
+ context
69
+ });
70
+ }
71
+ if (textResult.result.type !== "string") {
72
+ return {
73
+ type: "error",
74
+ err: FormulaError.VALUE,
75
+ message: "Text argument must be a string",
76
+ errAddress: context.dependencyNode
77
+ };
78
+ }
79
+ if (numCharsResult.result.type !== "number") {
80
+ return {
81
+ type: "error",
82
+ err: FormulaError.VALUE,
83
+ message: "NumChars argument must be a number",
84
+ errAddress: context.dependencyNode
85
+ };
86
+ }
87
+ return rightOperation(textResult, numCharsResult, context);
88
+ }
89
+ };
90
+ function createRightSpilledResult({
91
+ textResult,
92
+ numCharsResult,
93
+ context
94
+ }) {
95
+ if (textResult.type !== "spilled-values" && numCharsResult.type !== "spilled-values") {
96
+ throw new Error("createRightSpilledResult called without spilled values");
97
+ }
98
+ return {
99
+ type: "spilled-values",
100
+ spillArea: (origin) => {
101
+ let spillArea;
102
+ if (textResult.type === "spilled-values") {
103
+ spillArea = textResult.spillArea(origin);
104
+ } else if (numCharsResult.type === "spilled-values") {
105
+ spillArea = numCharsResult.spillArea(origin);
106
+ } else {
107
+ throw new Error("No spilled values found");
108
+ }
109
+ if (textResult.type === "spilled-values" && numCharsResult.type === "spilled-values") {
110
+ spillArea = this.unionRanges(this.projectRange(textResult.spillArea(origin), origin), this.projectRange(numCharsResult.spillArea(origin), origin));
111
+ }
112
+ return spillArea;
113
+ },
114
+ source: "RIGHT with spilled values",
115
+ evaluate: (spilledCell, evalContext) => {
116
+ const spillTextResult = textResult.type === "spilled-values" ? textResult.evaluate(spilledCell, evalContext) : textResult;
117
+ const spillNumResult = numCharsResult.type === "spilled-values" ? numCharsResult.evaluate(spilledCell, evalContext) : numCharsResult;
118
+ if (spillTextResult === undefined || spillNumResult === undefined) {
119
+ return {
120
+ type: "error",
121
+ err: FormulaError.REF,
122
+ message: "The spilled results have not been evaluated",
123
+ errAddress: context.dependencyNode
124
+ };
125
+ }
126
+ if (spillNumResult.type === "error") {
127
+ return spillNumResult;
128
+ }
129
+ if (spillTextResult.type === "error") {
130
+ return spillTextResult;
131
+ }
132
+ return rightOperation(spillTextResult, spillNumResult, context);
133
+ },
134
+ evaluateAllCells: (intersectingRange) => {
135
+ throw new Error("WIP: evaluateAllCells for RIGHT is not implemented");
136
+ }
137
+ };
138
+ }
139
+ export {
140
+ RIGHT
141
+ };
142
+
143
+ //# debugId=3F45A73A185160C264756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/functions/text/right/right.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 {\n midOperation,\n createMidSpilledResult,\n convertToString,\n extractNumericValue,\n} from \"../text-helpers.mjs\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\n\n/**\n * RIGHT function - Returns the rightmost characters from a text string\n *\n * Usage: RIGHT(text, num_chars)\n *\n * text: The text string to extract characters from.\n * num_chars: The number of characters to extract from the right side of the text.\n *\n * Example: RIGHT(\"Hello, World!\", 6) returns \"World!\"\n *\n * Note:\n * - If num_chars is less than 0, the function returns an error.\n * - If num_chars is greater than the length of text, the function returns the entire text.\n * - Supports dynamic arrays (spilled values) for both arguments\n * - Strict type checking: text must be string, num_chars must be number\n * - Implemented as MID(text, LEN(text) - num_chars + 1, num_chars)\n */\n\n/**\n * Helper function to calculate RIGHT operation using MID\n */\nfunction rightOperation(\n textResult: FunctionEvaluationResult,\n numCharsResult: FunctionEvaluationResult,\n context: EvaluationContext\n): { type: \"value\"; result: CellString } | ErrorEvaluationResult {\n const textStr = convertToString(textResult, context);\n const numChars = extractNumericValue(numCharsResult, context);\n\n // Check if any of the results are awaiting evaluation or errors\n if (\n typeof textStr === \"object\" &&\n (textStr.type === \"awaiting-evaluation\" || textStr.type === \"error\")\n ) {\n return textStr;\n }\n if (\n typeof numChars === \"object\" &&\n (numChars.type === \"awaiting-evaluation\" || numChars.type === \"error\")\n ) {\n return numChars;\n }\n\n // At this point, all values should be primitive types\n const textValue = textStr as string;\n const numCharsValue = numChars as number;\n\n // Validate numChars\n if (numCharsValue < 0) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"NumChars argument must be a positive number\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Calculate start position: LEN(text) - num_chars + 1\n const textLength = textValue.length;\n const startPos = Math.max(1, textLength - Math.floor(numCharsValue) + 1);\n\n // Create start_num result\n const startNumResult: FunctionEvaluationResult = {\n type: \"value\",\n result: { type: \"number\", value: startPos },\n };\n\n // Use MID operation\n return midOperation(textResult, startNumResult, numCharsResult, context);\n}\n\nexport const RIGHT: FunctionDefinition = {\n name: \"RIGHT\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length < 1 || node.args.length > 2) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"RIGHT function takes 1 or 2 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate the text argument\n const textResult = this.evaluateNode(node.args[0]!, context);\n if (\n textResult.type === \"error\" ||\n textResult.type === \"awaiting-evaluation\"\n ) {\n return textResult;\n }\n\n // Evaluate the numChars argument (optional, defaults to 1)\n let numCharsResult: FunctionEvaluationResult;\n if (node.args.length > 1) {\n numCharsResult = this.evaluateNode(node.args[1]!, context);\n if (\n numCharsResult.type === \"error\" ||\n numCharsResult.type === \"awaiting-evaluation\"\n ) {\n return numCharsResult;\n }\n } else {\n numCharsResult = {\n type: \"value\",\n result: { type: \"number\", value: 1 },\n };\n }\n\n // Handle spilled-values inputs\n if (\n textResult.type === \"spilled-values\" ||\n numCharsResult.type === \"spilled-values\"\n ) {\n // For RIGHT with spilled values, we need a custom spilled result handler\n // because we need to calculate start_num dynamically for each text value\n return createRightSpilledResult.call(this, {\n textResult,\n numCharsResult,\n context,\n });\n }\n\n // Strict type checking - no coercion\n if (textResult.result.type !== \"string\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Text argument must be a string\",\n errAddress: context.dependencyNode,\n };\n }\n\n if (numCharsResult.result.type !== \"number\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"NumChars argument must be a number\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Use RIGHT operation: RIGHT(text, num_chars) = MID(text, LEN(text) - num_chars + 1, num_chars)\n return rightOperation(textResult, numCharsResult, context);\n },\n};\n\n/**\n * Helper for creating spilled-values result for RIGHT function\n */\nfunction createRightSpilledResult(\n this: FormulaEvaluator,\n {\n textResult,\n numCharsResult,\n context,\n }: {\n textResult: FunctionEvaluationResult;\n numCharsResult: FunctionEvaluationResult;\n context: EvaluationContext;\n }\n): SpilledValuesEvaluationResult | ErrorEvaluationResult {\n if (\n textResult.type !== \"spilled-values\" &&\n numCharsResult.type !== \"spilled-values\"\n ) {\n throw new Error(\"createRightSpilledResult called without spilled values\");\n }\n\n return {\n type: \"spilled-values\",\n spillArea: (origin: CellAddress): SpreadsheetRange => {\n // Calculate spill area\n let spillArea;\n if (textResult.type === \"spilled-values\") {\n spillArea = textResult.spillArea(origin);\n } else if (numCharsResult.type === \"spilled-values\") {\n spillArea = numCharsResult.spillArea(origin);\n } else {\n throw new Error(\"No spilled values found\");\n }\n\n // Union spill areas if both are spilled\n if (\n textResult.type === \"spilled-values\" &&\n numCharsResult.type === \"spilled-values\"\n ) {\n spillArea = this.unionRanges(\n this.projectRange(textResult.spillArea(origin), origin),\n this.projectRange(numCharsResult.spillArea(origin), origin)\n );\n }\n return spillArea;\n },\n source: \"RIGHT with spilled values\",\n evaluate: (spilledCell, evalContext): SingleEvaluationResult => {\n // Evaluate arguments at this spilled position\n const spillTextResult =\n textResult.type === \"spilled-values\"\n ? textResult.evaluate(spilledCell, evalContext)\n : textResult;\n const spillNumResult =\n numCharsResult.type === \"spilled-values\"\n ? numCharsResult.evaluate(spilledCell, evalContext)\n : numCharsResult;\n\n if (spillTextResult === undefined || spillNumResult === 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 (spillNumResult.type === \"error\") {\n return spillNumResult;\n }\n if (spillTextResult.type === \"error\") {\n return spillTextResult;\n }\n\n return rightOperation(spillTextResult, spillNumResult, context);\n },\n evaluateAllCells: (intersectingRange) => {\n throw new Error(\"WIP: evaluateAllCells for RIGHT is not implemented\");\n },\n };\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "3F45A73A185160C264756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,151 @@
1
+ // src/functions/text/text-helpers.ts
2
+ import {
3
+ FormulaError
4
+ } from "src/core/types";
5
+ function convertToString(result, context) {
6
+ if (result.type === "awaiting-evaluation") {
7
+ return result;
8
+ }
9
+ if (result.type !== "value") {
10
+ return {
11
+ type: "error",
12
+ err: FormulaError.VALUE,
13
+ message: "Expected a value result",
14
+ errAddress: context.dependencyNode
15
+ };
16
+ }
17
+ if (result.result.type === "string") {
18
+ return result.result.value;
19
+ } else {
20
+ return {
21
+ type: "error",
22
+ err: FormulaError.VALUE,
23
+ message: "Expected a string value",
24
+ errAddress: context.dependencyNode
25
+ };
26
+ }
27
+ }
28
+ function extractNumericValue(result, context) {
29
+ if (result.type === "awaiting-evaluation") {
30
+ return result;
31
+ }
32
+ if (result.type !== "value") {
33
+ return {
34
+ type: "error",
35
+ err: FormulaError.VALUE,
36
+ message: "Expected a value result",
37
+ errAddress: context.dependencyNode
38
+ };
39
+ }
40
+ if (result.result.type === "number") {
41
+ return result.result.value;
42
+ } else {
43
+ return {
44
+ type: "error",
45
+ err: FormulaError.VALUE,
46
+ message: "Expected a number value",
47
+ errAddress: context.dependencyNode
48
+ };
49
+ }
50
+ }
51
+ function midOperation(textResult, startNumResult, numCharsResult, context) {
52
+ const textStr = convertToString(textResult, context);
53
+ const startNum = extractNumericValue(startNumResult, context);
54
+ const numChars = extractNumericValue(numCharsResult, context);
55
+ if (typeof textStr === "object" && (textStr.type === "awaiting-evaluation" || textStr.type === "error")) {
56
+ return textStr;
57
+ }
58
+ if (typeof startNum === "object" && (startNum.type === "awaiting-evaluation" || startNum.type === "error")) {
59
+ return startNum;
60
+ }
61
+ if (typeof numChars === "object" && (numChars.type === "awaiting-evaluation" || numChars.type === "error")) {
62
+ return numChars;
63
+ }
64
+ const textValue = textStr;
65
+ const startNumValue = startNum;
66
+ const numCharsValue = numChars;
67
+ if (startNumValue < 1) {
68
+ return {
69
+ type: "error",
70
+ err: FormulaError.VALUE,
71
+ message: "StartNum argument must be a positive number",
72
+ errAddress: context.dependencyNode
73
+ };
74
+ }
75
+ if (numCharsValue < 0) {
76
+ return {
77
+ type: "error",
78
+ err: FormulaError.VALUE,
79
+ message: "NumChars argument must be a positive number",
80
+ errAddress: context.dependencyNode
81
+ };
82
+ }
83
+ const startIndex = Math.floor(startNumValue) - 1;
84
+ const length = Math.floor(numCharsValue);
85
+ const result = textValue.substring(startIndex, startIndex + length);
86
+ return { type: "value", result: { type: "string", value: result } };
87
+ }
88
+ function createMidSpilledResult({
89
+ textResult,
90
+ startNumResult,
91
+ numCharsResult,
92
+ context
93
+ }) {
94
+ const hasSpilledText = textResult.type === "spilled-values";
95
+ const hasSpilledStart = startNumResult.type === "spilled-values";
96
+ const hasSpilledNum = numCharsResult.type === "spilled-values";
97
+ if (!hasSpilledText && !hasSpilledStart && !hasSpilledNum) {
98
+ throw new Error("createMidSpilledResult called without spilled values");
99
+ }
100
+ return {
101
+ type: "spilled-values",
102
+ spillArea: (origin) => {
103
+ let spillArea;
104
+ if (hasSpilledText && textResult.type === "spilled-values") {
105
+ spillArea = textResult.spillArea(origin);
106
+ } else if (hasSpilledStart && startNumResult.type === "spilled-values") {
107
+ spillArea = startNumResult.spillArea(origin);
108
+ } else if (hasSpilledNum && numCharsResult.type === "spilled-values") {
109
+ spillArea = numCharsResult.spillArea(origin);
110
+ } else {
111
+ throw new Error("No spilled values found");
112
+ }
113
+ if (hasSpilledText && hasSpilledStart && textResult.type === "spilled-values" && startNumResult.type === "spilled-values") {
114
+ spillArea = this.unionRanges(this.projectRange(textResult.spillArea(origin), origin), this.projectRange(startNumResult.spillArea(origin), origin));
115
+ }
116
+ if ((hasSpilledText || hasSpilledStart) && hasSpilledNum && numCharsResult.type === "spilled-values") {
117
+ const projectedSpillArea = this.projectRange(spillArea, origin);
118
+ const numSpillArea = this.projectRange(numCharsResult.spillArea(origin), origin);
119
+ spillArea = this.unionRanges(projectedSpillArea, numSpillArea);
120
+ }
121
+ return spillArea;
122
+ },
123
+ source: "MID with spilled values",
124
+ evaluate: (spilledCell, evalContext) => {
125
+ const spillTextResult = hasSpilledText ? textResult.evaluate(spilledCell, evalContext) : textResult;
126
+ const spillStartResult = hasSpilledStart ? startNumResult.evaluate(spilledCell, evalContext) : startNumResult;
127
+ const spillNumResult = hasSpilledNum ? numCharsResult.evaluate(spilledCell, evalContext) : numCharsResult;
128
+ if (!spillTextResult || spillTextResult.type === "error") {
129
+ return spillTextResult;
130
+ }
131
+ if (!spillStartResult || spillStartResult.type === "error") {
132
+ return spillStartResult;
133
+ }
134
+ if (!spillNumResult || spillNumResult.type === "error") {
135
+ return spillNumResult;
136
+ }
137
+ return midOperation(spillTextResult, spillStartResult, spillNumResult, evalContext);
138
+ },
139
+ evaluateAllCells: (intersectingRange) => {
140
+ throw new Error("WIP: evaluateAllCells for MID is not implemented");
141
+ }
142
+ };
143
+ }
144
+ export {
145
+ midOperation,
146
+ extractNumericValue,
147
+ createMidSpilledResult,
148
+ convertToString
149
+ };
150
+
151
+ //# debugId=99031B729F5EA4C764756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/functions/text/text-helpers.ts"],
4
+ "sourcesContent": [
5
+ "import {\n FormulaError,\n type CellString,\n type FunctionEvaluationResult,\n type ValueEvaluationResult,\n type CellAddress,\n type SpreadsheetRange,\n type ErrorEvaluationResult,\n type SingleEvaluationResult,\n} from \"src/core/types\";\nimport type { FormulaEngine } from \"src/core/engine\";\nimport type { FormulaEvaluator } from \"src/evaluator/formula-evaluator\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\n\n/**\n * Strictly extracts string value without type coercion\n */\nexport function convertToString(result: FunctionEvaluationResult, context: EvaluationContext): string | ErrorEvaluationResult {\n if (result.type === \"awaiting-evaluation\") {\n return result;\n }\n \n if (result.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Expected a value result\",\n errAddress: context.dependencyNode,\n };\n }\n\n if (result.result.type === \"string\") {\n return result.result.value;\n } else {\n // No type coercion - only strings are valid\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Expected a string value\",\n errAddress: context.dependencyNode,\n };\n }\n}\n\n/**\n * Strictly extracts numeric value without type coercion\n */\nexport function extractNumericValue(result: FunctionEvaluationResult, context: EvaluationContext): number | ErrorEvaluationResult {\n if (result.type === \"awaiting-evaluation\") {\n return result;\n }\n \n if (result.type !== \"value\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Expected a value result\",\n errAddress: context.dependencyNode,\n };\n }\n\n if (result.result.type === \"number\") {\n return result.result.value;\n } else {\n // No type coercion - only numbers are valid\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"Expected a number value\",\n errAddress: context.dependencyNode,\n };\n }\n}\n\n/**\n * MID substring operation for MID function\n */\nexport function midOperation(\n textResult: FunctionEvaluationResult,\n startNumResult: FunctionEvaluationResult,\n numCharsResult: FunctionEvaluationResult,\n context: EvaluationContext\n): { type: \"value\"; result: CellString } | ErrorEvaluationResult {\n const textStr = convertToString(textResult, context);\n const startNum = extractNumericValue(startNumResult, context);\n const numChars = extractNumericValue(numCharsResult, context);\n\n // Check if any of the results are awaiting evaluation or errors\n if (typeof textStr === \"object\" && (textStr.type === \"awaiting-evaluation\" || textStr.type === \"error\")) {\n return textStr;\n }\n if (typeof startNum === \"object\" && (startNum.type === \"awaiting-evaluation\" || startNum.type === \"error\")) {\n return startNum;\n }\n if (typeof numChars === \"object\" && (numChars.type === \"awaiting-evaluation\" || numChars.type === \"error\")) {\n return numChars;\n }\n\n // At this point, all values should be primitive types\n const textValue = textStr as string;\n const startNumValue = startNum as number;\n const numCharsValue = numChars as number;\n\n // Validate startNum and numChars\n if (startNumValue < 1) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"StartNum argument must be a positive number\",\n errAddress: context.dependencyNode,\n };\n }\n if (numCharsValue < 0) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"NumChars argument must be a positive number\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Convert to 0-based index (Excel uses 1-based)\n const startIndex = Math.floor(startNumValue) - 1;\n const length = Math.floor(numCharsValue);\n\n // Extract substring\n const result = textValue.substring(startIndex, startIndex + length);\n\n return { type: \"value\", result: { type: \"string\", value: result } };\n}\n\n/**\n * Helper for creating spilled-values result for MID function (3 parameters)\n */\nexport function createMidSpilledResult(\n this: FormulaEvaluator,\n {\n textResult,\n startNumResult,\n numCharsResult,\n context,\n }: {\n textResult: FunctionEvaluationResult;\n startNumResult: FunctionEvaluationResult;\n numCharsResult: FunctionEvaluationResult;\n context: EvaluationContext;\n }\n): FunctionEvaluationResult {\n const hasSpilledText = textResult.type === \"spilled-values\";\n const hasSpilledStart = startNumResult.type === \"spilled-values\";\n const hasSpilledNum = numCharsResult.type === \"spilled-values\";\n\n if (!hasSpilledText && !hasSpilledStart && !hasSpilledNum) {\n throw new Error(\"createMidSpilledResult called without spilled values\");\n }\n\n return {\n type: \"spilled-values\",\n spillArea: (origin: CellAddress) => {\n // Calculate spill area (union of all spilled ranges)\n let spillArea: SpreadsheetRange;\n\n if (hasSpilledText && textResult.type === \"spilled-values\") {\n spillArea = textResult.spillArea(origin);\n } else if (hasSpilledStart && startNumResult.type === \"spilled-values\") {\n spillArea = startNumResult.spillArea(origin);\n } else if (hasSpilledNum && numCharsResult.type === \"spilled-values\") {\n spillArea = numCharsResult.spillArea(origin);\n } else {\n // This shouldn't happen since we check for spilled values at the beginning\n throw new Error(\"No spilled values found\");\n }\n\n // Union with other spilled ranges if they exist\n if (\n hasSpilledText &&\n hasSpilledStart &&\n textResult.type === \"spilled-values\" &&\n startNumResult.type === \"spilled-values\"\n ) {\n spillArea = this.unionRanges(\n this.projectRange(textResult.spillArea(origin), origin),\n this.projectRange(startNumResult.spillArea(origin), origin)\n );\n }\n\n if (\n (hasSpilledText || hasSpilledStart) &&\n hasSpilledNum &&\n numCharsResult.type === \"spilled-values\"\n ) {\n const projectedSpillArea = this.projectRange(spillArea, origin);\n const numSpillArea = this.projectRange(\n numCharsResult.spillArea(origin),\n origin\n );\n spillArea = this.unionRanges(projectedSpillArea, numSpillArea);\n }\n return spillArea;\n },\n source: \"MID with spilled values\",\n evaluate: (\n spilledCell,\n evalContext\n ): SingleEvaluationResult => {\n // Evaluate all arguments at this spilled position\n const spillTextResult = hasSpilledText\n ? textResult.evaluate(spilledCell, evalContext)\n : textResult;\n const spillStartResult = hasSpilledStart\n ? startNumResult.evaluate(spilledCell, evalContext)\n : startNumResult;\n const spillNumResult = hasSpilledNum\n ? numCharsResult.evaluate(spilledCell, evalContext)\n : numCharsResult;\n\n if (!spillTextResult || spillTextResult.type === \"error\") {\n return spillTextResult;\n }\n if (!spillStartResult || spillStartResult.type === \"error\") {\n return spillStartResult;\n }\n if (!spillNumResult || spillNumResult.type === \"error\") {\n return spillNumResult;\n }\n\n return midOperation(spillTextResult, spillStartResult, spillNumResult, evalContext);\n },\n evaluateAllCells: (intersectingRange) => {\n throw new Error(\"WIP: evaluateAllCells for MID is not implemented\");\n },\n };\n}\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "99031B729F5EA4C764756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,145 @@
1
+ // src/functions/text/textjoin/textjoin.ts
2
+ import {
3
+ FormulaError
4
+ } from "src/core/types";
5
+ var MAX_TEXT_LENGTH = 32767;
6
+ function coerceToString(value) {
7
+ switch (value.type) {
8
+ case "string":
9
+ return value.value;
10
+ case "number":
11
+ if (value.value === Infinity) {
12
+ return "INFINITY";
13
+ } else if (value.value === -Infinity) {
14
+ return "-INFINITY";
15
+ } else if (isNaN(value.value)) {
16
+ return "NaN";
17
+ } else {
18
+ return value.value.toString();
19
+ }
20
+ case "boolean":
21
+ return value.value ? "TRUE" : "FALSE";
22
+ case "infinity":
23
+ return value.sign === "positive" ? "INFINITY" : "-INFINITY";
24
+ default:
25
+ return "";
26
+ }
27
+ }
28
+ function collectTextItems(args, ignoreEmpty, context) {
29
+ const textItems = [];
30
+ for (const arg of args) {
31
+ if (arg.type === "error") {
32
+ return arg;
33
+ }
34
+ if (arg.type === "value") {
35
+ const text = coerceToString(arg.result);
36
+ if (!ignoreEmpty || text !== "") {
37
+ textItems.push(text);
38
+ }
39
+ } else if (arg.type === "spilled-values") {
40
+ const cellValues = arg.evaluateAllCells.call(this, {
41
+ context,
42
+ origin: context.cellAddress,
43
+ evaluate: arg.evaluate,
44
+ lookupOrder: "col-major"
45
+ });
46
+ if (cellValues.type !== "values") {
47
+ return cellValues;
48
+ }
49
+ for (const cellValue of cellValues.values) {
50
+ if (cellValue.result.type === "error" || cellValue.result.type === "awaiting-evaluation") {
51
+ return cellValue.result;
52
+ }
53
+ if (cellValue.result.type === "value") {
54
+ const text = coerceToString(cellValue.result.result);
55
+ if (!ignoreEmpty || text !== "") {
56
+ textItems.push(text);
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ return textItems;
63
+ }
64
+ var TEXTJOIN = {
65
+ name: "TEXTJOIN",
66
+ evaluate: function(node, context) {
67
+ if (node.args.length < 3) {
68
+ return {
69
+ type: "error",
70
+ err: FormulaError.VALUE,
71
+ message: "TEXTJOIN function requires at least 3 arguments",
72
+ errAddress: context.dependencyNode
73
+ };
74
+ }
75
+ const delimiterResult = this.evaluateNode(node.args[0], context);
76
+ if (delimiterResult.type === "error") {
77
+ return delimiterResult;
78
+ }
79
+ if (delimiterResult.type === "awaiting-evaluation") {
80
+ return delimiterResult;
81
+ }
82
+ if (delimiterResult.type === "spilled-values") {
83
+ return {
84
+ type: "error",
85
+ err: FormulaError.VALUE,
86
+ message: "TEXTJOIN delimiter must be a single value",
87
+ errAddress: context.dependencyNode
88
+ };
89
+ }
90
+ const delimiter = coerceToString(delimiterResult.result);
91
+ const ignoreEmptyResult = this.evaluateNode(node.args[1], context);
92
+ if (ignoreEmptyResult.type === "error") {
93
+ return ignoreEmptyResult;
94
+ }
95
+ if (ignoreEmptyResult.type === "awaiting-evaluation") {
96
+ return ignoreEmptyResult;
97
+ }
98
+ if (ignoreEmptyResult.type === "spilled-values") {
99
+ return {
100
+ type: "error",
101
+ err: FormulaError.VALUE,
102
+ message: "TEXTJOIN ignore_empty must be a single value",
103
+ errAddress: context.dependencyNode
104
+ };
105
+ }
106
+ let ignoreEmpty = false;
107
+ if (ignoreEmptyResult.result.type === "boolean") {
108
+ ignoreEmpty = ignoreEmptyResult.result.value;
109
+ } else if (ignoreEmptyResult.result.type === "number") {
110
+ ignoreEmpty = ignoreEmptyResult.result.value !== 0;
111
+ } else if (ignoreEmptyResult.result.type === "string") {
112
+ ignoreEmpty = ignoreEmptyResult.result.value !== "";
113
+ }
114
+ const textArgs = [];
115
+ for (let i = 2;i < node.args.length; i++) {
116
+ const result2 = this.evaluateNode(node.args[i], context);
117
+ if (result2.type === "error" || result2.type === "awaiting-evaluation") {
118
+ return result2;
119
+ }
120
+ textArgs.push(result2);
121
+ }
122
+ const textItems = collectTextItems.call(this, textArgs, ignoreEmpty, context);
123
+ if (!Array.isArray(textItems)) {
124
+ return textItems;
125
+ }
126
+ const result = textItems.join(delimiter);
127
+ if (result.length > MAX_TEXT_LENGTH) {
128
+ return {
129
+ type: "error",
130
+ err: FormulaError.VALUE,
131
+ message: `TEXTJOIN result exceeds ${MAX_TEXT_LENGTH} character limit`,
132
+ errAddress: context.dependencyNode
133
+ };
134
+ }
135
+ return {
136
+ type: "value",
137
+ result: { type: "string", value: result }
138
+ };
139
+ }
140
+ };
141
+ export {
142
+ TEXTJOIN
143
+ };
144
+
145
+ //# debugId=C520C9CA8A80F6D964756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/functions/text/textjoin/textjoin.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 type CellString,\n} from \"src/core/types\";\nimport type { EvaluationContext } from \"src/evaluator/evaluation-context\";\nimport type { FormulaEvaluator } from \"src/evaluator/formula-evaluator\";\n\n/**\n * TEXTJOIN function - Joins text from multiple ranges and/or strings with a specified delimiter\n *\n * Usage: TEXTJOIN(delimiter, ignore_empty, text1, [text2], ...)\n *\n * delimiter: String to insert between text items (can be empty string \"\")\n * ignore_empty: If TRUE, empty cells/strings are ignored; if FALSE, they are included\n * text1, text2, ...: Text items to join (can be strings, ranges, or arrays)\n *\n * Examples:\n * TEXTJOIN(\", \", TRUE, A1:A3) - joins A1, A2, A3 with \", \" separator, ignoring empty cells\n * TEXTJOIN(\"-\", FALSE, \"a\", \"b\", \"c\") - returns \"a-b-c\"\n * TEXTJOIN(\", \", TRUE, \"Red\", \"\", \"Blue\") - returns \"Red, Blue\" (empty string ignored)\n *\n * Note:\n * - Supports type coercion: numbers and booleans are converted to strings\n * - Returns #VALUE! if result exceeds 32,767 characters\n */\n\nconst MAX_TEXT_LENGTH = 32767;\n\n/**\n * Helper function to convert a cell value to string with type coercion\n */\nfunction coerceToString(value: CellValue): string {\n switch (value.type) {\n case \"string\":\n return value.value;\n case \"number\":\n // Convert number to string\n if (value.value === Infinity) {\n return \"INFINITY\";\n } else if (value.value === -Infinity) {\n return \"-INFINITY\";\n } else if (isNaN(value.value)) {\n return \"NaN\";\n } else {\n return value.value.toString();\n }\n case \"boolean\":\n // Convert boolean to string\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 function to collect all text items from arguments, handling ranges\n */\nfunction collectTextItems(\n this: FormulaEvaluator,\n args: FunctionEvaluationResult[],\n ignoreEmpty: boolean,\n context: EvaluationContext\n): string[] | ErrorEvaluationResult {\n const textItems: string[] = [];\n\n for (const arg of args) {\n if (arg.type === \"error\") {\n return arg;\n }\n\n if (arg.type === \"value\") {\n const text = coerceToString(arg.result);\n if (!ignoreEmpty || text !== \"\") {\n textItems.push(text);\n }\n } else if (arg.type === \"spilled-values\") {\n // Extract all values from the range\n const cellValues = arg.evaluateAllCells.call(this, {\n context,\n origin: context.cellAddress,\n evaluate: arg.evaluate,\n lookupOrder: \"col-major\",\n });\n\n if (cellValues.type !== \"values\") {\n return cellValues;\n }\n\n for (const cellValue of cellValues.values) {\n if (\n cellValue.result.type === \"error\" ||\n cellValue.result.type === \"awaiting-evaluation\"\n ) {\n return cellValue.result;\n }\n if (cellValue.result.type === \"value\") {\n const text = coerceToString(cellValue.result.result);\n if (!ignoreEmpty || text !== \"\") {\n textItems.push(text);\n }\n }\n }\n }\n }\n\n return textItems;\n}\n\n/**\n * TEXTJOIN function implementation\n */\nexport const TEXTJOIN: FunctionDefinition = {\n name: \"TEXTJOIN\",\n evaluate: function (node, context): FunctionEvaluationResult {\n if (node.args.length < 3) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"TEXTJOIN function requires at least 3 arguments\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Evaluate delimiter (first argument)\n const delimiterResult = this.evaluateNode(node.args[0]!, context);\n if (delimiterResult.type === \"error\") {\n return delimiterResult;\n }\n if (delimiterResult.type === \"awaiting-evaluation\") {\n return delimiterResult;\n }\n\n // Delimiter must be a single value\n if (delimiterResult.type === \"spilled-values\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"TEXTJOIN delimiter must be a single value\",\n errAddress: context.dependencyNode,\n };\n }\n\n const delimiter = coerceToString(delimiterResult.result);\n\n // Evaluate ignore_empty (second argument)\n const ignoreEmptyResult = this.evaluateNode(node.args[1]!, context);\n if (ignoreEmptyResult.type === \"error\") {\n return ignoreEmptyResult;\n }\n if (ignoreEmptyResult.type === \"awaiting-evaluation\") {\n return ignoreEmptyResult;\n }\n\n // ignore_empty must be a single value\n if (ignoreEmptyResult.type === \"spilled-values\") {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: \"TEXTJOIN ignore_empty must be a single value\",\n errAddress: context.dependencyNode,\n };\n }\n\n // Convert ignore_empty to boolean\n let ignoreEmpty = false;\n if (ignoreEmptyResult.result.type === \"boolean\") {\n ignoreEmpty = ignoreEmptyResult.result.value;\n } else if (ignoreEmptyResult.result.type === \"number\") {\n ignoreEmpty = ignoreEmptyResult.result.value !== 0;\n } else if (ignoreEmptyResult.result.type === \"string\") {\n ignoreEmpty = ignoreEmptyResult.result.value !== \"\";\n }\n\n // Evaluate text arguments (remaining arguments)\n const textArgs: FunctionEvaluationResult[] = [];\n for (let i = 2; i < node.args.length; i++) {\n const result = this.evaluateNode(node.args[i]!, context);\n if (result.type === \"error\" || result.type === \"awaiting-evaluation\") {\n return result;\n }\n textArgs.push(result);\n }\n\n // Collect all text items from arguments\n const textItems = collectTextItems.call(\n this,\n textArgs,\n ignoreEmpty,\n context\n );\n\n // Check if we got an error\n if (!Array.isArray(textItems)) {\n return textItems;\n }\n\n // Join text items with delimiter\n const result = textItems.join(delimiter);\n\n // Check length limit\n if (result.length > MAX_TEXT_LENGTH) {\n return {\n type: \"error\",\n err: FormulaError.VALUE,\n message: `TEXTJOIN result exceeds ${MAX_TEXT_LENGTH} character limit`,\n errAddress: context.dependencyNode,\n };\n }\n\n return {\n type: \"value\",\n result: { type: \"string\", value: result },\n };\n },\n};\n"
6
+ ],
7
+ "mappings": ";AAAA;AAAA;AAAA;AAoCA,IAAM,kBAAkB;AAKxB,SAAS,cAAc,CAAC,OAA0B;AAAA,EAChD,QAAQ,MAAM;AAAA,SACP;AAAA,MACH,OAAO,MAAM;AAAA,SACV;AAAA,MAEH,IAAI,MAAM,UAAU,UAAU;AAAA,QAC5B,OAAO;AAAA,MACT,EAAO,SAAI,MAAM,UAAU,WAAW;AAAA,QACpC,OAAO;AAAA,MACT,EAAO,SAAI,MAAM,MAAM,KAAK,GAAG;AAAA,QAC7B,OAAO;AAAA,MACT,EAAO;AAAA,QACL,OAAO,MAAM,MAAM,SAAS;AAAA;AAAA,SAE3B;AAAA,MAEH,OAAO,MAAM,QAAQ,SAAS;AAAA,SAC3B;AAAA,MACH,OAAO,MAAM,SAAS,aAAa,aAAa;AAAA;AAAA,MAEhD,OAAO;AAAA;AAAA;AAOb,SAAS,gBAAgB,CAEvB,MACA,aACA,SACkC;AAAA,EAClC,MAAM,YAAsB,CAAC;AAAA,EAE7B,WAAW,OAAO,MAAM;AAAA,IACtB,IAAI,IAAI,SAAS,SAAS;AAAA,MACxB,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,IAAI,SAAS,SAAS;AAAA,MACxB,MAAM,OAAO,eAAe,IAAI,MAAM;AAAA,MACtC,IAAI,CAAC,eAAe,SAAS,IAAI;AAAA,QAC/B,UAAU,KAAK,IAAI;AAAA,MACrB;AAAA,IACF,EAAO,SAAI,IAAI,SAAS,kBAAkB;AAAA,MAExC,MAAM,aAAa,IAAI,iBAAiB,KAAK,MAAM;AAAA,QACjD;AAAA,QACA,QAAQ,QAAQ;AAAA,QAChB,UAAU,IAAI;AAAA,QACd,aAAa;AAAA,MACf,CAAC;AAAA,MAED,IAAI,WAAW,SAAS,UAAU;AAAA,QAChC,OAAO;AAAA,MACT;AAAA,MAEA,WAAW,aAAa,WAAW,QAAQ;AAAA,QACzC,IACE,UAAU,OAAO,SAAS,WAC1B,UAAU,OAAO,SAAS,uBAC1B;AAAA,UACA,OAAO,UAAU;AAAA,QACnB;AAAA,QACA,IAAI,UAAU,OAAO,SAAS,SAAS;AAAA,UACrC,MAAM,OAAO,eAAe,UAAU,OAAO,MAAM;AAAA,UACnD,IAAI,CAAC,eAAe,SAAS,IAAI;AAAA,YAC/B,UAAU,KAAK,IAAI;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAMF,IAAM,WAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,UAAU,QAAS,CAAC,MAAM,SAAmC;AAAA,IAC3D,IAAI,KAAK,KAAK,SAAS,GAAG;AAAA,MACxB,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,MAAM,kBAAkB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IAChE,IAAI,gBAAgB,SAAS,SAAS;AAAA,MACpC,OAAO;AAAA,IACT;AAAA,IACA,IAAI,gBAAgB,SAAS,uBAAuB;AAAA,MAClD,OAAO;AAAA,IACT;AAAA,IAGA,IAAI,gBAAgB,SAAS,kBAAkB;AAAA,MAC7C,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAEA,MAAM,YAAY,eAAe,gBAAgB,MAAM;AAAA,IAGvD,MAAM,oBAAoB,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,IAClE,IAAI,kBAAkB,SAAS,SAAS;AAAA,MACtC,OAAO;AAAA,IACT;AAAA,IACA,IAAI,kBAAkB,SAAS,uBAAuB;AAAA,MACpD,OAAO;AAAA,IACT;AAAA,IAGA,IAAI,kBAAkB,SAAS,kBAAkB;AAAA,MAC/C,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS;AAAA,QACT,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAGA,IAAI,cAAc;AAAA,IAClB,IAAI,kBAAkB,OAAO,SAAS,WAAW;AAAA,MAC/C,cAAc,kBAAkB,OAAO;AAAA,IACzC,EAAO,SAAI,kBAAkB,OAAO,SAAS,UAAU;AAAA,MACrD,cAAc,kBAAkB,OAAO,UAAU;AAAA,IACnD,EAAO,SAAI,kBAAkB,OAAO,SAAS,UAAU;AAAA,MACrD,cAAc,kBAAkB,OAAO,UAAU;AAAA,IACnD;AAAA,IAGA,MAAM,WAAuC,CAAC;AAAA,IAC9C,SAAS,IAAI,EAAG,IAAI,KAAK,KAAK,QAAQ,KAAK;AAAA,MACzC,MAAM,UAAS,KAAK,aAAa,KAAK,KAAK,IAAK,OAAO;AAAA,MACvD,IAAI,QAAO,SAAS,WAAW,QAAO,SAAS,uBAAuB;AAAA,QACpE,OAAO;AAAA,MACT;AAAA,MACA,SAAS,KAAK,OAAM;AAAA,IACtB;AAAA,IAGA,MAAM,YAAY,iBAAiB,KACjC,MACA,UACA,aACA,OACF;AAAA,IAGA,IAAI,CAAC,MAAM,QAAQ,SAAS,GAAG;AAAA,MAC7B,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,SAAS,UAAU,KAAK,SAAS;AAAA,IAGvC,IAAI,OAAO,SAAS,iBAAiB;AAAA,MACnC,OAAO;AAAA,QACL,MAAM;AAAA,QACN,KAAK,aAAa;AAAA,QAClB,SAAS,2BAA2B;AAAA,QACpC,YAAY,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IAEA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,UAAU,OAAO,OAAO;AAAA,IAC1C;AAAA;AAEJ;",
8
+ "debugId": "C520C9CA8A80F6D964756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@ricsam/formula-engine",
3
+ "version": "0.0.1",
4
+ "type": "module"
5
+ }