@cj-tech-master/excelts 9.2.1 → 9.3.0

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 (383) hide show
  1. package/README.md +25 -2
  2. package/README_zh.md +29 -6
  3. package/dist/browser/index.browser.d.ts +1 -1
  4. package/dist/browser/index.browser.js +4 -0
  5. package/dist/browser/index.d.ts +1 -1
  6. package/dist/browser/index.js +4 -0
  7. package/dist/browser/modules/excel/cell.d.ts +17 -3
  8. package/dist/browser/modules/excel/cell.js +170 -22
  9. package/dist/browser/modules/excel/defined-names.d.ts +96 -1
  10. package/dist/browser/modules/excel/defined-names.js +411 -21
  11. package/dist/browser/modules/excel/image.d.ts +11 -0
  12. package/dist/browser/modules/excel/image.js +24 -1
  13. package/dist/browser/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
  14. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +14 -0
  15. package/dist/browser/modules/excel/stream/workbook-reader.d.ts +2 -1
  16. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
  17. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +48 -1
  18. package/dist/browser/modules/excel/stream/workbook-writer.d.ts +3 -2
  19. package/dist/browser/modules/excel/stream/worksheet-reader.js +17 -1
  20. package/dist/browser/modules/excel/stream/worksheet-writer.d.ts +39 -6
  21. package/dist/browser/modules/excel/stream/worksheet-writer.js +45 -5
  22. package/dist/browser/modules/excel/table.js +15 -2
  23. package/dist/browser/modules/excel/types.d.ts +133 -2
  24. package/dist/browser/modules/excel/utils/col-cache.d.ts +1 -0
  25. package/dist/browser/modules/excel/utils/col-cache.js +15 -0
  26. package/dist/browser/modules/excel/utils/drawing-utils.d.ts +3 -3
  27. package/dist/browser/modules/excel/utils/drawing-utils.js +4 -0
  28. package/dist/browser/modules/excel/utils/external-link-formula.d.ts +76 -0
  29. package/dist/browser/modules/excel/utils/external-link-formula.js +208 -0
  30. package/dist/browser/modules/excel/utils/iterate-stream.d.ts +9 -3
  31. package/dist/browser/modules/excel/utils/iterate-stream.js +3 -1
  32. package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +19 -0
  33. package/dist/browser/modules/excel/utils/ooxml-paths.js +37 -2
  34. package/dist/browser/modules/excel/utils/shared-strings.d.ts +8 -3
  35. package/dist/browser/modules/excel/utils/shared-strings.js +21 -2
  36. package/dist/browser/modules/excel/utils/workbook-protection.d.ts +30 -0
  37. package/dist/browser/modules/excel/utils/workbook-protection.js +30 -0
  38. package/dist/browser/modules/excel/workbook.browser.d.ts +257 -6
  39. package/dist/browser/modules/excel/workbook.browser.js +318 -34
  40. package/dist/browser/modules/excel/workbook.d.ts +1 -1
  41. package/dist/browser/modules/excel/worksheet.d.ts +3 -1
  42. package/dist/browser/modules/excel/worksheet.js +21 -2
  43. package/dist/browser/modules/excel/xlsx/rel-type.d.ts +15 -0
  44. package/dist/browser/modules/excel/xlsx/rel-type.js +16 -1
  45. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
  46. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  47. package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
  48. package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
  49. package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
  50. package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
  51. package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
  52. package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  53. package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
  54. package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
  55. package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  56. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
  57. package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
  58. package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
  59. package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
  60. package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
  61. package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  62. package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  63. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
  64. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  65. package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  66. package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
  67. package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
  68. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  69. package/dist/browser/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  70. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
  71. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +410 -20
  72. package/dist/browser/modules/excel/xlsx/xlsx.d.ts +7 -4
  73. package/dist/browser/modules/excel/xlsx/xlsx.js +4 -5
  74. package/dist/browser/modules/formula/compile/address-utils.d.ts +62 -0
  75. package/dist/browser/modules/formula/compile/address-utils.js +83 -0
  76. package/dist/browser/modules/formula/compile/binder.d.ts +42 -0
  77. package/dist/browser/modules/formula/compile/binder.js +487 -0
  78. package/dist/browser/modules/formula/compile/bound-ast.d.ts +230 -0
  79. package/dist/browser/modules/formula/compile/bound-ast.js +80 -0
  80. package/dist/browser/modules/formula/compile/compiled-formula.d.ts +137 -0
  81. package/dist/browser/modules/formula/compile/compiled-formula.js +383 -0
  82. package/dist/browser/modules/formula/compile/dependency-analysis.d.ts +93 -0
  83. package/dist/browser/modules/formula/compile/dependency-analysis.js +432 -0
  84. package/dist/browser/modules/formula/compile/structured-ref-utils.d.ts +93 -0
  85. package/dist/browser/modules/formula/compile/structured-ref-utils.js +136 -0
  86. package/dist/browser/modules/formula/default-syntax-probe.d.ts +79 -0
  87. package/dist/browser/modules/formula/default-syntax-probe.js +83 -0
  88. package/dist/browser/modules/formula/functions/_date-context.d.ts +4 -0
  89. package/dist/browser/modules/formula/functions/_date-context.js +29 -0
  90. package/dist/browser/modules/formula/functions/_shared.d.ts +121 -0
  91. package/dist/browser/modules/formula/functions/_shared.js +381 -0
  92. package/dist/browser/modules/formula/functions/conditional.d.ts +27 -0
  93. package/dist/browser/modules/formula/functions/conditional.js +343 -0
  94. package/dist/browser/modules/formula/functions/database.d.ts +37 -0
  95. package/dist/browser/modules/formula/functions/database.js +274 -0
  96. package/dist/browser/modules/formula/functions/date.d.ts +61 -0
  97. package/dist/browser/modules/formula/functions/date.js +855 -0
  98. package/dist/browser/modules/formula/functions/dynamic-array.d.ts +23 -0
  99. package/dist/browser/modules/formula/functions/dynamic-array.js +860 -0
  100. package/dist/browser/modules/formula/functions/engineering.d.ts +57 -0
  101. package/dist/browser/modules/formula/functions/engineering.js +1128 -0
  102. package/dist/browser/modules/formula/functions/financial.d.ts +202 -0
  103. package/dist/browser/modules/formula/functions/financial.js +2296 -0
  104. package/dist/browser/modules/formula/functions/lookup.d.ts +18 -0
  105. package/dist/browser/modules/formula/functions/lookup.js +886 -0
  106. package/dist/browser/modules/formula/functions/math.d.ts +114 -0
  107. package/dist/browser/modules/formula/functions/math.js +1406 -0
  108. package/dist/browser/modules/formula/functions/statistical.d.ts +193 -0
  109. package/dist/browser/modules/formula/functions/statistical.js +3390 -0
  110. package/dist/browser/modules/formula/functions/text.d.ts +86 -0
  111. package/dist/browser/modules/formula/functions/text.js +1845 -0
  112. package/dist/browser/modules/formula/host-registry.d.ts +53 -0
  113. package/dist/browser/modules/formula/host-registry.js +69 -0
  114. package/dist/browser/modules/formula/index.d.ts +39 -0
  115. package/dist/browser/modules/formula/index.js +49 -0
  116. package/dist/browser/modules/formula/install.d.ts +62 -0
  117. package/dist/browser/modules/formula/install.js +88 -0
  118. package/dist/browser/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
  119. package/dist/browser/modules/formula/integration/apply-writeback-plan.js +210 -0
  120. package/dist/browser/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
  121. package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +616 -0
  122. package/dist/browser/modules/formula/integration/calculate-formulas.d.ts +67 -0
  123. package/dist/browser/modules/formula/integration/calculate-formulas.js +68 -0
  124. package/dist/browser/modules/formula/integration/formula-instance.d.ts +64 -0
  125. package/dist/browser/modules/formula/integration/formula-instance.js +79 -0
  126. package/dist/browser/modules/formula/integration/workbook-adapter.d.ts +26 -0
  127. package/dist/browser/modules/formula/integration/workbook-adapter.js +324 -0
  128. package/dist/browser/modules/formula/integration/workbook-snapshot.d.ts +267 -0
  129. package/dist/browser/modules/formula/integration/workbook-snapshot.js +77 -0
  130. package/dist/browser/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
  131. package/dist/browser/modules/formula/materialize/build-writeback-plan.js +473 -0
  132. package/dist/browser/modules/formula/materialize/spill-engine.d.ts +9 -0
  133. package/dist/browser/modules/formula/materialize/spill-engine.js +38 -0
  134. package/dist/browser/modules/formula/materialize/types.d.ts +179 -0
  135. package/dist/browser/modules/formula/materialize/types.js +29 -0
  136. package/dist/browser/modules/formula/materialize/writeback-plan.d.ts +167 -0
  137. package/dist/browser/modules/formula/materialize/writeback-plan.js +27 -0
  138. package/dist/browser/modules/formula/runtime/evaluator.d.ts +151 -0
  139. package/dist/browser/modules/formula/runtime/evaluator.js +2291 -0
  140. package/dist/browser/modules/formula/runtime/function-registry.d.ts +47 -0
  141. package/dist/browser/modules/formula/runtime/function-registry.js +840 -0
  142. package/dist/browser/modules/formula/runtime/values.d.ts +211 -0
  143. package/dist/browser/modules/formula/runtime/values.js +385 -0
  144. package/dist/browser/modules/formula/syntax/ast.d.ts +129 -0
  145. package/dist/browser/modules/formula/syntax/ast.js +28 -0
  146. package/dist/browser/modules/formula/syntax/parser.d.ts +18 -0
  147. package/dist/browser/modules/formula/syntax/parser.js +439 -0
  148. package/dist/browser/modules/formula/syntax/token-types.d.ts +153 -0
  149. package/dist/browser/modules/formula/syntax/token-types.js +59 -0
  150. package/dist/browser/modules/formula/syntax/tokenizer.d.ts +10 -0
  151. package/dist/browser/modules/formula/syntax/tokenizer.js +1074 -0
  152. package/dist/browser/modules/pdf/excel-bridge.js +9 -0
  153. package/dist/cjs/index.js +4 -0
  154. package/dist/cjs/modules/excel/cell.js +170 -22
  155. package/dist/cjs/modules/excel/defined-names.js +411 -21
  156. package/dist/cjs/modules/excel/image.js +24 -1
  157. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +14 -0
  158. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +48 -1
  159. package/dist/cjs/modules/excel/stream/worksheet-reader.js +17 -1
  160. package/dist/cjs/modules/excel/stream/worksheet-writer.js +45 -5
  161. package/dist/cjs/modules/excel/table.js +15 -2
  162. package/dist/cjs/modules/excel/utils/col-cache.js +15 -0
  163. package/dist/cjs/modules/excel/utils/drawing-utils.js +4 -0
  164. package/dist/cjs/modules/excel/utils/external-link-formula.js +212 -0
  165. package/dist/cjs/modules/excel/utils/iterate-stream.js +3 -1
  166. package/dist/cjs/modules/excel/utils/ooxml-paths.js +42 -2
  167. package/dist/cjs/modules/excel/utils/shared-strings.js +21 -2
  168. package/dist/cjs/modules/excel/utils/workbook-protection.js +33 -0
  169. package/dist/cjs/modules/excel/workbook.browser.js +318 -34
  170. package/dist/cjs/modules/excel/worksheet.js +20 -1
  171. package/dist/cjs/modules/excel/xlsx/rel-type.js +16 -1
  172. package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  173. package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +333 -0
  174. package/dist/cjs/modules/excel/xlsx/xform/book/external-reference-xform.js +27 -0
  175. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  176. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-protection-xform.js +69 -0
  177. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  178. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +18 -0
  179. package/dist/cjs/modules/excel/xlsx/xform/core/metadata-xform.js +161 -0
  180. package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +108 -0
  181. package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  182. package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  183. package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  184. package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  185. package/dist/cjs/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +83 -0
  186. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  187. package/dist/cjs/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  188. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +408 -18
  189. package/dist/cjs/modules/excel/xlsx/xlsx.js +4 -5
  190. package/dist/cjs/modules/formula/compile/address-utils.js +89 -0
  191. package/dist/cjs/modules/formula/compile/binder.js +489 -0
  192. package/dist/cjs/modules/formula/compile/bound-ast.js +68 -0
  193. package/dist/cjs/modules/formula/compile/compiled-formula.js +387 -0
  194. package/dist/cjs/modules/formula/compile/dependency-analysis.js +437 -0
  195. package/dist/cjs/modules/formula/compile/structured-ref-utils.js +141 -0
  196. package/dist/cjs/modules/formula/default-syntax-probe.js +87 -0
  197. package/dist/cjs/modules/formula/functions/_date-context.js +33 -0
  198. package/dist/cjs/modules/formula/functions/_shared.js +396 -0
  199. package/dist/cjs/modules/formula/functions/conditional.js +354 -0
  200. package/dist/cjs/modules/formula/functions/database.js +288 -0
  201. package/dist/cjs/modules/formula/functions/date.js +883 -0
  202. package/dist/cjs/modules/formula/functions/dynamic-array.js +881 -0
  203. package/dist/cjs/modules/formula/functions/engineering.js +1183 -0
  204. package/dist/cjs/modules/formula/functions/financial.js +2348 -0
  205. package/dist/cjs/modules/formula/functions/lookup.js +902 -0
  206. package/dist/cjs/modules/formula/functions/math.js +1487 -0
  207. package/dist/cjs/modules/formula/functions/statistical.js +3488 -0
  208. package/dist/cjs/modules/formula/functions/text.js +1889 -0
  209. package/dist/cjs/modules/formula/host-registry.js +75 -0
  210. package/dist/cjs/modules/formula/index.js +58 -0
  211. package/dist/cjs/modules/formula/install.js +93 -0
  212. package/dist/cjs/modules/formula/integration/apply-writeback-plan.js +213 -0
  213. package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +619 -0
  214. package/dist/cjs/modules/formula/integration/calculate-formulas.js +71 -0
  215. package/dist/cjs/modules/formula/integration/formula-instance.js +82 -0
  216. package/dist/cjs/modules/formula/integration/workbook-adapter.js +327 -0
  217. package/dist/cjs/modules/formula/integration/workbook-snapshot.js +84 -0
  218. package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +475 -0
  219. package/dist/cjs/modules/formula/materialize/spill-engine.js +42 -0
  220. package/dist/cjs/modules/formula/materialize/types.js +32 -0
  221. package/dist/cjs/modules/formula/materialize/writeback-plan.js +28 -0
  222. package/dist/cjs/modules/formula/runtime/evaluator.js +2298 -0
  223. package/dist/cjs/modules/formula/runtime/function-registry.js +846 -0
  224. package/dist/cjs/modules/formula/runtime/values.js +385 -0
  225. package/dist/cjs/modules/formula/syntax/ast.js +8 -0
  226. package/dist/cjs/modules/formula/syntax/parser.js +440 -0
  227. package/dist/cjs/modules/formula/syntax/token-types.js +32 -0
  228. package/dist/cjs/modules/formula/syntax/tokenizer.js +1076 -0
  229. package/dist/cjs/modules/pdf/excel-bridge.js +9 -0
  230. package/dist/esm/index.browser.js +4 -0
  231. package/dist/esm/index.js +4 -0
  232. package/dist/esm/modules/excel/cell.js +170 -22
  233. package/dist/esm/modules/excel/defined-names.js +411 -21
  234. package/dist/esm/modules/excel/image.js +24 -1
  235. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +14 -0
  236. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +48 -1
  237. package/dist/esm/modules/excel/stream/worksheet-reader.js +17 -1
  238. package/dist/esm/modules/excel/stream/worksheet-writer.js +45 -5
  239. package/dist/esm/modules/excel/table.js +15 -2
  240. package/dist/esm/modules/excel/utils/col-cache.js +15 -0
  241. package/dist/esm/modules/excel/utils/drawing-utils.js +4 -0
  242. package/dist/esm/modules/excel/utils/external-link-formula.js +208 -0
  243. package/dist/esm/modules/excel/utils/iterate-stream.js +3 -1
  244. package/dist/esm/modules/excel/utils/ooxml-paths.js +37 -2
  245. package/dist/esm/modules/excel/utils/shared-strings.js +21 -2
  246. package/dist/esm/modules/excel/utils/workbook-protection.js +30 -0
  247. package/dist/esm/modules/excel/workbook.browser.js +318 -34
  248. package/dist/esm/modules/excel/worksheet.js +21 -2
  249. package/dist/esm/modules/excel/xlsx/rel-type.js +16 -1
  250. package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  251. package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
  252. package/dist/esm/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
  253. package/dist/esm/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  254. package/dist/esm/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
  255. package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  256. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
  257. package/dist/esm/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
  258. package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
  259. package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  260. package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  261. package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  262. package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  263. package/dist/esm/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
  264. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  265. package/dist/esm/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  266. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +410 -20
  267. package/dist/esm/modules/excel/xlsx/xlsx.js +4 -5
  268. package/dist/esm/modules/formula/compile/address-utils.js +83 -0
  269. package/dist/esm/modules/formula/compile/binder.js +487 -0
  270. package/dist/esm/modules/formula/compile/bound-ast.js +80 -0
  271. package/dist/esm/modules/formula/compile/compiled-formula.js +383 -0
  272. package/dist/esm/modules/formula/compile/dependency-analysis.js +432 -0
  273. package/dist/esm/modules/formula/compile/structured-ref-utils.js +136 -0
  274. package/dist/esm/modules/formula/default-syntax-probe.js +83 -0
  275. package/dist/esm/modules/formula/functions/_date-context.js +29 -0
  276. package/dist/esm/modules/formula/functions/_shared.js +381 -0
  277. package/dist/esm/modules/formula/functions/conditional.js +343 -0
  278. package/dist/esm/modules/formula/functions/database.js +274 -0
  279. package/dist/esm/modules/formula/functions/date.js +855 -0
  280. package/dist/esm/modules/formula/functions/dynamic-array.js +860 -0
  281. package/dist/esm/modules/formula/functions/engineering.js +1128 -0
  282. package/dist/esm/modules/formula/functions/financial.js +2296 -0
  283. package/dist/esm/modules/formula/functions/lookup.js +886 -0
  284. package/dist/esm/modules/formula/functions/math.js +1406 -0
  285. package/dist/esm/modules/formula/functions/statistical.js +3390 -0
  286. package/dist/esm/modules/formula/functions/text.js +1845 -0
  287. package/dist/esm/modules/formula/host-registry.js +69 -0
  288. package/dist/esm/modules/formula/index.js +49 -0
  289. package/dist/esm/modules/formula/install.js +88 -0
  290. package/dist/esm/modules/formula/integration/apply-writeback-plan.js +210 -0
  291. package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +616 -0
  292. package/dist/esm/modules/formula/integration/calculate-formulas.js +68 -0
  293. package/dist/esm/modules/formula/integration/formula-instance.js +79 -0
  294. package/dist/esm/modules/formula/integration/workbook-adapter.js +324 -0
  295. package/dist/esm/modules/formula/integration/workbook-snapshot.js +77 -0
  296. package/dist/esm/modules/formula/materialize/build-writeback-plan.js +473 -0
  297. package/dist/esm/modules/formula/materialize/spill-engine.js +38 -0
  298. package/dist/esm/modules/formula/materialize/types.js +29 -0
  299. package/dist/esm/modules/formula/materialize/writeback-plan.js +27 -0
  300. package/dist/esm/modules/formula/runtime/evaluator.js +2291 -0
  301. package/dist/esm/modules/formula/runtime/function-registry.js +840 -0
  302. package/dist/esm/modules/formula/runtime/values.js +385 -0
  303. package/dist/esm/modules/formula/syntax/ast.js +28 -0
  304. package/dist/esm/modules/formula/syntax/parser.js +439 -0
  305. package/dist/esm/modules/formula/syntax/token-types.js +59 -0
  306. package/dist/esm/modules/formula/syntax/tokenizer.js +1074 -0
  307. package/dist/esm/modules/pdf/excel-bridge.js +9 -0
  308. package/dist/iife/excelts.iife.js +2302 -373
  309. package/dist/iife/excelts.iife.js.map +1 -1
  310. package/dist/iife/excelts.iife.min.js +34 -34
  311. package/dist/types/index.browser.d.ts +1 -1
  312. package/dist/types/index.d.ts +1 -1
  313. package/dist/types/modules/excel/cell.d.ts +17 -3
  314. package/dist/types/modules/excel/defined-names.d.ts +96 -1
  315. package/dist/types/modules/excel/image.d.ts +11 -0
  316. package/dist/types/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
  317. package/dist/types/modules/excel/stream/workbook-reader.d.ts +2 -1
  318. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
  319. package/dist/types/modules/excel/stream/workbook-writer.d.ts +3 -2
  320. package/dist/types/modules/excel/stream/worksheet-writer.d.ts +39 -6
  321. package/dist/types/modules/excel/types.d.ts +133 -2
  322. package/dist/types/modules/excel/utils/col-cache.d.ts +1 -0
  323. package/dist/types/modules/excel/utils/drawing-utils.d.ts +3 -3
  324. package/dist/types/modules/excel/utils/external-link-formula.d.ts +76 -0
  325. package/dist/types/modules/excel/utils/iterate-stream.d.ts +9 -3
  326. package/dist/types/modules/excel/utils/ooxml-paths.d.ts +19 -0
  327. package/dist/types/modules/excel/utils/shared-strings.d.ts +8 -3
  328. package/dist/types/modules/excel/utils/workbook-protection.d.ts +30 -0
  329. package/dist/types/modules/excel/workbook.browser.d.ts +257 -6
  330. package/dist/types/modules/excel/workbook.d.ts +1 -1
  331. package/dist/types/modules/excel/worksheet.d.ts +3 -1
  332. package/dist/types/modules/excel/xlsx/rel-type.d.ts +15 -0
  333. package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
  334. package/dist/types/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
  335. package/dist/types/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
  336. package/dist/types/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
  337. package/dist/types/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
  338. package/dist/types/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
  339. package/dist/types/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
  340. package/dist/types/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
  341. package/dist/types/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
  342. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
  343. package/dist/types/modules/excel/xlsx/xlsx.d.ts +7 -4
  344. package/dist/types/modules/formula/compile/address-utils.d.ts +62 -0
  345. package/dist/types/modules/formula/compile/binder.d.ts +42 -0
  346. package/dist/types/modules/formula/compile/bound-ast.d.ts +230 -0
  347. package/dist/types/modules/formula/compile/compiled-formula.d.ts +137 -0
  348. package/dist/types/modules/formula/compile/dependency-analysis.d.ts +93 -0
  349. package/dist/types/modules/formula/compile/structured-ref-utils.d.ts +93 -0
  350. package/dist/types/modules/formula/default-syntax-probe.d.ts +79 -0
  351. package/dist/types/modules/formula/functions/_date-context.d.ts +4 -0
  352. package/dist/types/modules/formula/functions/_shared.d.ts +121 -0
  353. package/dist/types/modules/formula/functions/conditional.d.ts +27 -0
  354. package/dist/types/modules/formula/functions/database.d.ts +37 -0
  355. package/dist/types/modules/formula/functions/date.d.ts +61 -0
  356. package/dist/types/modules/formula/functions/dynamic-array.d.ts +23 -0
  357. package/dist/types/modules/formula/functions/engineering.d.ts +57 -0
  358. package/dist/types/modules/formula/functions/financial.d.ts +202 -0
  359. package/dist/types/modules/formula/functions/lookup.d.ts +18 -0
  360. package/dist/types/modules/formula/functions/math.d.ts +114 -0
  361. package/dist/types/modules/formula/functions/statistical.d.ts +193 -0
  362. package/dist/types/modules/formula/functions/text.d.ts +86 -0
  363. package/dist/types/modules/formula/host-registry.d.ts +53 -0
  364. package/dist/types/modules/formula/index.d.ts +39 -0
  365. package/dist/types/modules/formula/install.d.ts +62 -0
  366. package/dist/types/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
  367. package/dist/types/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
  368. package/dist/types/modules/formula/integration/calculate-formulas.d.ts +67 -0
  369. package/dist/types/modules/formula/integration/formula-instance.d.ts +64 -0
  370. package/dist/types/modules/formula/integration/workbook-adapter.d.ts +26 -0
  371. package/dist/types/modules/formula/integration/workbook-snapshot.d.ts +267 -0
  372. package/dist/types/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
  373. package/dist/types/modules/formula/materialize/spill-engine.d.ts +9 -0
  374. package/dist/types/modules/formula/materialize/types.d.ts +179 -0
  375. package/dist/types/modules/formula/materialize/writeback-plan.d.ts +167 -0
  376. package/dist/types/modules/formula/runtime/evaluator.d.ts +151 -0
  377. package/dist/types/modules/formula/runtime/function-registry.d.ts +47 -0
  378. package/dist/types/modules/formula/runtime/values.d.ts +211 -0
  379. package/dist/types/modules/formula/syntax/ast.d.ts +129 -0
  380. package/dist/types/modules/formula/syntax/parser.d.ts +18 -0
  381. package/dist/types/modules/formula/syntax/token-types.d.ts +153 -0
  382. package/dist/types/modules/formula/syntax/tokenizer.d.ts +10 -0
  383. package/package.json +28 -28
@@ -0,0 +1,1183 @@
1
+ "use strict";
2
+ /**
3
+ * Engineering Functions — Native RuntimeValue implementation.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.fnBITLSHIFT = exports.fnBITXOR = exports.fnBITOR = exports.fnBITAND = exports.fnIMCOTH = exports.fnIMSECH = exports.fnIMCSCH = exports.fnIMTANH = exports.fnIMCOSH = exports.fnIMSINH = exports.fnIMCOT = exports.fnIMSEC = exports.fnIMCSC = exports.fnIMTAN = exports.fnIMCOS = exports.fnIMSIN = exports.fnIMEXP = exports.fnIMLOG10 = exports.fnIMLOG2 = exports.fnIMLN = exports.fnIMSQRT = exports.fnIMPOWER = exports.fnIMDIV = exports.fnIMPRODUCT = exports.fnIMSUB = exports.fnIMSUM = exports.fnIMCONJUGATE = exports.fnIMARGUMENT = exports.fnIMABS = exports.fnIMAGINARY = exports.fnIMREAL = exports.fnCOMPLEX = exports.fnGESTEP = exports.fnDELTA = exports.fnBESSELY = exports.fnBESSELK = exports.fnBESSELI = exports.fnBESSELJ = exports.fnOCT2HEX = exports.fnOCT2BIN = exports.fnHEX2OCT = exports.fnHEX2BIN = exports.fnBIN2OCT = exports.fnBIN2HEX = exports.fnDEC2OCT = exports.fnOCT2DEC = exports.fnDEC2HEX = exports.fnHEX2DEC = exports.fnDEC2BIN = exports.fnBIN2DEC = void 0;
7
+ exports.fnBITRSHIFT = void 0;
8
+ const values_1 = require("../runtime/values");
9
+ const _shared_1 = require("./_shared");
10
+ // ============================================================================
11
+ // Base Conversion Functions
12
+ // ============================================================================
13
+ const fnBIN2DEC = args => {
14
+ const err = (0, _shared_1.checkError)(args[0]);
15
+ if (err) {
16
+ return err;
17
+ }
18
+ const s = (0, values_1.toStringRV)(args[0]);
19
+ if (!/^[01]{1,10}$/.test(s)) {
20
+ return values_1.ERRORS.NUM;
21
+ }
22
+ // 10-bit two's complement
23
+ if (s.length === 10 && s[0] === "1") {
24
+ return (0, values_1.rvNumber)(parseInt(s.slice(1), 2) - 512);
25
+ }
26
+ return (0, values_1.rvNumber)(parseInt(s, 2));
27
+ };
28
+ exports.fnBIN2DEC = fnBIN2DEC;
29
+ const fnDEC2BIN = args => {
30
+ const nRV = (0, values_1.toNumberRV)(args[0]);
31
+ if ((0, values_1.isError)(nRV)) {
32
+ return nRV;
33
+ }
34
+ // Excel's DEC→BASE family truncates toward zero, so negative fractions
35
+ // become `0`, not `-1` as `Math.floor` would produce.
36
+ const n = Math.trunc(nRV.value);
37
+ if (n < -512 || n > 511) {
38
+ return values_1.ERRORS.NUM;
39
+ }
40
+ // `places` is only meaningful when supplied and the input is non-negative.
41
+ // Excel restricts it to the [1, 10] range and returns #NUM! otherwise.
42
+ // For negative inputs Excel ignores `places` entirely, so we validate it
43
+ // only on the non-negative branch below.
44
+ const hasPlaces = args.length > 1 && args[1].kind !== 0 /* RVKind.Blank */;
45
+ const placesRV = hasPlaces ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
46
+ if ((0, values_1.isError)(placesRV)) {
47
+ return placesRV;
48
+ }
49
+ const places = Math.trunc(placesRV.value);
50
+ if (n < 0) {
51
+ return (0, values_1.rvString)((n + 1024).toString(2));
52
+ }
53
+ if (hasPlaces && (places < 1 || places > 10)) {
54
+ return values_1.ERRORS.NUM;
55
+ }
56
+ const result = n.toString(2);
57
+ return (0, values_1.rvString)(places > 0 ? result.padStart(places, "0") : result);
58
+ };
59
+ exports.fnDEC2BIN = fnDEC2BIN;
60
+ const fnHEX2DEC = args => {
61
+ const err = (0, _shared_1.checkError)(args[0]);
62
+ if (err) {
63
+ return err;
64
+ }
65
+ const s = (0, values_1.toStringRV)(args[0]);
66
+ if (!/^[0-9A-Fa-f]{1,10}$/.test(s)) {
67
+ return values_1.ERRORS.NUM;
68
+ }
69
+ const num = parseInt(s, 16);
70
+ // 10-digit hex: 40-bit two's complement
71
+ if (s.length === 10 && parseInt(s[0], 16) >= 8) {
72
+ return (0, values_1.rvNumber)(num - Math.pow(16, 10));
73
+ }
74
+ return (0, values_1.rvNumber)(num);
75
+ };
76
+ exports.fnHEX2DEC = fnHEX2DEC;
77
+ const fnDEC2HEX = args => {
78
+ const nRV = (0, values_1.toNumberRV)(args[0]);
79
+ if ((0, values_1.isError)(nRV)) {
80
+ return nRV;
81
+ }
82
+ // Excel's DEC→BASE family truncates toward zero, so negative fractions
83
+ // become `0`, not `-1` as `Math.floor` would produce.
84
+ const n = Math.trunc(nRV.value);
85
+ // Excel rejects anything outside the 40-bit signed range.
86
+ // Without this check, inputs like 1e14 produce a 13-digit hex string
87
+ // and inputs below -2^39 wrap into spurious positive values prefixed
88
+ // with `-`. See R6-P0-1.
89
+ if (n < -549755813888 || n > 549755813887) {
90
+ return values_1.ERRORS.NUM;
91
+ }
92
+ // Same places semantics as DEC2BIN: validate only when `places` is
93
+ // supplied and the input is non-negative; Excel ignores `places` for
94
+ // negative numbers.
95
+ const hasPlaces = args.length > 1 && args[1].kind !== 0 /* RVKind.Blank */;
96
+ const placesRV = hasPlaces ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
97
+ if ((0, values_1.isError)(placesRV)) {
98
+ return placesRV;
99
+ }
100
+ const places = Math.trunc(placesRV.value);
101
+ if (n < 0) {
102
+ return (0, values_1.rvString)((n + Math.pow(16, 10)).toString(16).toUpperCase());
103
+ }
104
+ if (hasPlaces && (places < 1 || places > 10)) {
105
+ return values_1.ERRORS.NUM;
106
+ }
107
+ const result = n.toString(16).toUpperCase();
108
+ return (0, values_1.rvString)(places > 0 ? result.padStart(places, "0") : result);
109
+ };
110
+ exports.fnDEC2HEX = fnDEC2HEX;
111
+ const fnOCT2DEC = args => {
112
+ const err = (0, _shared_1.checkError)(args[0]);
113
+ if (err) {
114
+ return err;
115
+ }
116
+ const s = (0, values_1.toStringRV)(args[0]);
117
+ if (!/^[0-7]{1,10}$/.test(s)) {
118
+ return values_1.ERRORS.NUM;
119
+ }
120
+ const num = parseInt(s, 8);
121
+ if (s.length === 10 && parseInt(s[0]) >= 4) {
122
+ return (0, values_1.rvNumber)(num - Math.pow(8, 10));
123
+ }
124
+ return (0, values_1.rvNumber)(num);
125
+ };
126
+ exports.fnOCT2DEC = fnOCT2DEC;
127
+ const fnDEC2OCT = args => {
128
+ const nRV = (0, values_1.toNumberRV)(args[0]);
129
+ if ((0, values_1.isError)(nRV)) {
130
+ return nRV;
131
+ }
132
+ // Excel's DEC→BASE family truncates toward zero, so negative fractions
133
+ // become `0`, not `-1` as `Math.floor` would produce.
134
+ const n = Math.trunc(nRV.value);
135
+ // Excel's DEC2OCT range is the 30-bit signed range (-2^29 .. 2^29-1).
136
+ // Values outside this range are #NUM! in Excel; we silently wrapped
137
+ // into bogus sign-prefixed strings without this guard. See R6-P0-1.
138
+ if (n < -536870912 || n > 536870911) {
139
+ return values_1.ERRORS.NUM;
140
+ }
141
+ // Same places semantics as DEC2BIN: validate only when `places` is
142
+ // supplied and the input is non-negative; Excel ignores `places` for
143
+ // negative numbers.
144
+ const hasPlaces = args.length > 1 && args[1].kind !== 0 /* RVKind.Blank */;
145
+ const placesRV = hasPlaces ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
146
+ if ((0, values_1.isError)(placesRV)) {
147
+ return placesRV;
148
+ }
149
+ const places = Math.trunc(placesRV.value);
150
+ if (n < 0) {
151
+ return (0, values_1.rvString)((n + Math.pow(8, 10)).toString(8));
152
+ }
153
+ if (hasPlaces && (places < 1 || places > 10)) {
154
+ return values_1.ERRORS.NUM;
155
+ }
156
+ const result = n.toString(8);
157
+ return (0, values_1.rvString)(places > 0 ? result.padStart(places, "0") : result);
158
+ };
159
+ exports.fnDEC2OCT = fnDEC2OCT;
160
+ /**
161
+ * Generic helper for the X2Y conversion family (BIN2HEX, HEX2BIN, …).
162
+ *
163
+ * `parseNInput` extracts the signed decimal value of the input string in
164
+ * its source base, enforcing the Excel length / digit-alphabet rules.
165
+ * `formatN` serialises the decimal back in the target base, honouring
166
+ * the optional `places` argument and the 10-digit two's-complement
167
+ * convention for negatives. Returning an `ErrorValue` from either stage
168
+ * aborts with that error — keeps each pairwise converter a three-liner.
169
+ */
170
+ function convertBase(args, parseNInput, format) {
171
+ const err = (0, _shared_1.checkError)(args[0]);
172
+ if (err) {
173
+ return err;
174
+ }
175
+ const s = (0, values_1.toStringRV)(args[0]);
176
+ const n = parseNInput(s);
177
+ if (typeof n !== "number") {
178
+ return n;
179
+ }
180
+ const hasPlaces = args.length > 1 && args[1].kind !== 0 /* RVKind.Blank */;
181
+ const placesRV = hasPlaces ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
182
+ if ((0, values_1.isError)(placesRV)) {
183
+ return placesRV;
184
+ }
185
+ const places = Math.trunc(placesRV.value);
186
+ return format(n, places, hasPlaces);
187
+ }
188
+ /** Parse a binary input string as a signed decimal, or return #NUM!. */
189
+ function parseBinInput(s) {
190
+ if (!/^[01]{1,10}$/.test(s)) {
191
+ return values_1.ERRORS.NUM;
192
+ }
193
+ const num = parseInt(s, 2);
194
+ return s.length === 10 && s[0] === "1" ? num - Math.pow(2, 10) : num;
195
+ }
196
+ function parseOctInput(s) {
197
+ if (!/^[0-7]{1,10}$/.test(s)) {
198
+ return values_1.ERRORS.NUM;
199
+ }
200
+ const num = parseInt(s, 8);
201
+ return s.length === 10 && parseInt(s[0]) >= 4 ? num - Math.pow(8, 10) : num;
202
+ }
203
+ function parseHexInput(s) {
204
+ if (!/^[0-9A-Fa-f]{1,10}$/.test(s)) {
205
+ return values_1.ERRORS.NUM;
206
+ }
207
+ const num = parseInt(s, 16);
208
+ return s.length === 10 && parseInt(s[0], 16) >= 8 ? num - Math.pow(16, 10) : num;
209
+ }
210
+ /** Format a signed decimal to the target base; handles 10-digit negatives. */
211
+ function formatToBase(n, base, maxDigits, places, hasPlaces) {
212
+ if (n < 0) {
213
+ // Two's-complement style: Excel emits the full 10-digit width.
214
+ return (0, values_1.rvString)((n + Math.pow(base, 10)).toString(base).toUpperCase());
215
+ }
216
+ if (hasPlaces && (places < 1 || places > maxDigits)) {
217
+ return values_1.ERRORS.NUM;
218
+ }
219
+ const result = n.toString(base).toUpperCase();
220
+ return (0, values_1.rvString)(places > 0 ? result.padStart(places, "0") : result);
221
+ }
222
+ const fnBIN2HEX = args => convertBase(args, parseBinInput, (n, places, hasPlaces) => formatToBase(n, 16, 10, places, hasPlaces));
223
+ exports.fnBIN2HEX = fnBIN2HEX;
224
+ const fnBIN2OCT = args => convertBase(args, parseBinInput, (n, places, hasPlaces) => formatToBase(n, 8, 10, places, hasPlaces));
225
+ exports.fnBIN2OCT = fnBIN2OCT;
226
+ const fnHEX2BIN = args => convertBase(args, parseHexInput, (n, places, hasPlaces) => {
227
+ // BIN can only hold values in [-512, 511]; Excel rejects anything wider.
228
+ if (n < -512 || n > 511) {
229
+ return values_1.ERRORS.NUM;
230
+ }
231
+ return formatToBase(n, 2, 10, places, hasPlaces);
232
+ });
233
+ exports.fnHEX2BIN = fnHEX2BIN;
234
+ const fnHEX2OCT = args => convertBase(args, parseHexInput, (n, places, hasPlaces) => {
235
+ // OCT holds values in [-2^29, 2^29 − 1].
236
+ if (n < -536870912 || n > 536870911) {
237
+ return values_1.ERRORS.NUM;
238
+ }
239
+ return formatToBase(n, 8, 10, places, hasPlaces);
240
+ });
241
+ exports.fnHEX2OCT = fnHEX2OCT;
242
+ const fnOCT2BIN = args => convertBase(args, parseOctInput, (n, places, hasPlaces) => {
243
+ if (n < -512 || n > 511) {
244
+ return values_1.ERRORS.NUM;
245
+ }
246
+ return formatToBase(n, 2, 10, places, hasPlaces);
247
+ });
248
+ exports.fnOCT2BIN = fnOCT2BIN;
249
+ const fnOCT2HEX = args => convertBase(args, parseOctInput, (n, places, hasPlaces) => formatToBase(n, 16, 10, places, hasPlaces));
250
+ exports.fnOCT2HEX = fnOCT2HEX;
251
+ // ============================================================================
252
+ // Bessel functions
253
+ // ============================================================================
254
+ //
255
+ // The four Bessel variants (J, I, K, Y) satisfy recurrences that make a
256
+ // rolling evaluation both simple and numerically stable for modest
257
+ // arguments. Excel restricts these to integer order n >= 0 and real
258
+ // x >= 0; we enforce those bounds and otherwise match the standard
259
+ // power-series / backward-recurrence algorithms used across numerical
260
+ // libraries. Accuracy is better than ~1e-6 relative for |x| <= 30 and n
261
+ // <= 30 — the realistic domain where anyone actually uses BESSEL in a
262
+ // spreadsheet.
263
+ function besselJ(n, x) {
264
+ // Series expansion for moderate x, Miller's backward recurrence for
265
+ // larger x. Switch point chosen empirically where the direct series
266
+ // begins to lose precision.
267
+ if (x === 0) {
268
+ return n === 0 ? 1 : 0;
269
+ }
270
+ const ax = Math.abs(x);
271
+ if (ax < 15) {
272
+ // Direct power series: Jₙ(x) = Σ (-1)^k (x/2)^(n+2k) / (k! (n+k)!)
273
+ const half = x / 2;
274
+ let term = Math.pow(half, n);
275
+ for (let k = 1; k <= n; k++) {
276
+ term /= k;
277
+ }
278
+ let sum = term;
279
+ for (let k = 1; k < 100; k++) {
280
+ term = (-term * half * half) / (k * (n + k));
281
+ sum += term;
282
+ if (Math.abs(term) < 1e-15 * Math.abs(sum)) {
283
+ break;
284
+ }
285
+ }
286
+ return sum;
287
+ }
288
+ // Backward recurrence (Miller's algorithm). Start from a high order,
289
+ // iterate down, normalise using the known sum ∑(−1)ᵏJ₂ₖ = 1.
290
+ //
291
+ // The starting order needs to be (a) even, (b) higher than `n`, and
292
+ // (c) large enough that the recurrence has converged. The classic
293
+ // `2 * (n + ceil(sqrt(40 * n)))` formula collapses to 0 when `n = 0`,
294
+ // which makes the loop never execute and leaves `ans = 0` (wrong —
295
+ // J₀(20) ≈ 0.167, not 0). Floor the start at `2*ceil(x + 20)` so
296
+ // small-`n` large-`x` inputs still get a meaningful number of
297
+ // recurrence steps.
298
+ const startRaw = 2 * (n + Math.ceil(Math.sqrt(40 * Math.max(n, 1))));
299
+ const startMin = 2 * Math.ceil(x + 20);
300
+ let start = Math.max(startRaw, startMin);
301
+ // Make sure start is even so the Σ(-1)^k J_{2k} = 1 identity applies
302
+ // cleanly during the loop below.
303
+ if (start % 2 !== 0) {
304
+ start++;
305
+ }
306
+ let bjp = 0;
307
+ let bj = 1;
308
+ let ans = 0;
309
+ let sum = 0;
310
+ for (let j = start; j > 0; j--) {
311
+ const bjm = (2 * j * bj) / x - bjp;
312
+ bjp = bj;
313
+ bj = bjm;
314
+ if (Math.abs(bj) > 1e10) {
315
+ bj *= 1e-10;
316
+ bjp *= 1e-10;
317
+ ans *= 1e-10;
318
+ sum *= 1e-10;
319
+ }
320
+ if (j % 2 === 0) {
321
+ sum += bj;
322
+ }
323
+ if (j === n) {
324
+ ans = bjp;
325
+ }
326
+ }
327
+ sum = 2 * sum - bj;
328
+ return ans / sum;
329
+ }
330
+ function besselI(n, x) {
331
+ if (x === 0) {
332
+ return n === 0 ? 1 : 0;
333
+ }
334
+ // Iₙ(x) = Σ (x/2)^(n+2k) / (k! (n+k)!)
335
+ const half = x / 2;
336
+ let term = Math.pow(half, n);
337
+ for (let k = 1; k <= n; k++) {
338
+ term /= k;
339
+ }
340
+ let sum = term;
341
+ for (let k = 1; k < 200; k++) {
342
+ term = (term * half * half) / (k * (n + k));
343
+ sum += term;
344
+ if (Math.abs(term) < 1e-15 * Math.abs(sum)) {
345
+ break;
346
+ }
347
+ }
348
+ return sum;
349
+ }
350
+ function besselY(n, x) {
351
+ // Y₀ / Y₁ via standard small-argument expansions; higher orders via
352
+ // forward recurrence. Accuracy is modest (~1e-5) but matches Excel's
353
+ // own precision for BESSELY.
354
+ if (x === 0) {
355
+ return Number.NEGATIVE_INFINITY;
356
+ }
357
+ const y0 = (xv) => {
358
+ if (xv < 8) {
359
+ const y = xv * xv;
360
+ const ans1 = -2957821389 +
361
+ y *
362
+ (7062834065 +
363
+ y * (-512359803.6 + y * (10879881.29 + y * (-86327.92757 + y * 228.4622733))));
364
+ const ans2 = 40076544269 +
365
+ y * (745249964.8 + y * (7189466.438 + y * (47447.2647 + y * (226.1030244 + y))));
366
+ return ans1 / ans2 + 0.636619772 * besselJ(0, xv) * Math.log(xv);
367
+ }
368
+ const z = 8 / xv;
369
+ const y = z * z;
370
+ const ans1 = 1 +
371
+ y * (-0.1098628627e-2 + y * (0.2734510407e-4 + y * (-0.2073370639e-5 + y * 0.2093887211e-6)));
372
+ const ans2 = -0.1562499995e-1 +
373
+ y * (0.1430488765e-3 + y * (-0.6911147651e-5 + y * (0.7621095161e-6 + y * -0.934945152e-7)));
374
+ return (Math.sqrt(0.636619772 / xv) *
375
+ (Math.sin(xv - 0.785398164) * ans1 + z * Math.cos(xv - 0.785398164) * ans2));
376
+ };
377
+ const y1 = (xv) => {
378
+ if (xv < 8) {
379
+ const y = xv * xv;
380
+ const ans1 = xv *
381
+ (-0.4900604943e13 +
382
+ y *
383
+ (0.127527439e13 +
384
+ y *
385
+ (-0.5153438139e11 +
386
+ y * (0.7349264551e9 + y * (-0.4237922726e7 + y * 0.8511937935e4)))));
387
+ const ans2 = 0.249958057e14 +
388
+ y *
389
+ (0.4244419664e12 +
390
+ y *
391
+ (0.3733650367e10 +
392
+ y * (0.2245904002e8 + y * (0.102042605e6 + y * (0.3549632885e3 + y)))));
393
+ return ans1 / ans2 + 0.636619772 * (besselJ(1, xv) * Math.log(xv) - 1 / xv);
394
+ }
395
+ const z = 8 / xv;
396
+ const y = z * z;
397
+ const ans1 = 1 + y * (0.183105e-2 + y * (-0.3516396496e-4 + y * (0.2457520174e-5 + y * -0.240337019e-6)));
398
+ const ans2 = 0.04687499995 +
399
+ y * (-0.2002690873e-3 + y * (0.8449199096e-5 + y * (-0.88228987e-6 + y * 0.105787412e-6)));
400
+ return (Math.sqrt(0.636619772 / xv) *
401
+ (Math.sin(xv - 2.356194491) * ans1 + z * Math.cos(xv - 2.356194491) * ans2));
402
+ };
403
+ if (n === 0) {
404
+ return y0(x);
405
+ }
406
+ if (n === 1) {
407
+ return y1(x);
408
+ }
409
+ let bym = y0(x);
410
+ let by = y1(x);
411
+ for (let j = 1; j < n; j++) {
412
+ const byp = (2 * j * by) / x - bym;
413
+ bym = by;
414
+ by = byp;
415
+ }
416
+ return by;
417
+ }
418
+ function besselK(n, x) {
419
+ if (x === 0) {
420
+ return Number.POSITIVE_INFINITY;
421
+ }
422
+ const k0 = (xv) => {
423
+ if (xv <= 2) {
424
+ const y = (xv * xv) / 4;
425
+ return (-Math.log(xv / 2) * besselI(0, xv) +
426
+ (-0.57721566 +
427
+ y *
428
+ (0.4227842 +
429
+ y *
430
+ (0.23069756 +
431
+ y * (0.0348859 + y * (0.00262698 + y * (0.0001075 + y * 0.0000074)))))));
432
+ }
433
+ const y = 2 / xv;
434
+ return ((Math.exp(-xv) / Math.sqrt(xv)) *
435
+ (1.25331414 +
436
+ y *
437
+ (-0.07832358 +
438
+ y *
439
+ (0.02189568 +
440
+ y * (-0.01062446 + y * (0.00587872 + y * (-0.0025154 + y * 0.00053208)))))));
441
+ };
442
+ const k1 = (xv) => {
443
+ if (xv <= 2) {
444
+ const y = (xv * xv) / 4;
445
+ return (Math.log(xv / 2) * besselI(1, xv) +
446
+ (1 / xv) *
447
+ (1 +
448
+ y *
449
+ (0.15443144 +
450
+ y *
451
+ (-0.67278579 +
452
+ y * (-0.18156897 + y * (-0.01919402 + y * (-0.00110404 + y * -0.00004686)))))));
453
+ }
454
+ const y = 2 / xv;
455
+ return ((Math.exp(-xv) / Math.sqrt(xv)) *
456
+ (1.25331414 +
457
+ y *
458
+ (0.23498619 +
459
+ y *
460
+ (-0.0365562 +
461
+ y * (0.01504268 + y * (-0.00780353 + y * (0.00325614 + y * -0.00068245)))))));
462
+ };
463
+ if (n === 0) {
464
+ return k0(x);
465
+ }
466
+ if (n === 1) {
467
+ return k1(x);
468
+ }
469
+ // Kₙ₊₁(x) = (2n/x) Kₙ(x) + Kₙ₋₁(x)
470
+ let bkm = k0(x);
471
+ let bk = k1(x);
472
+ for (let j = 1; j < n; j++) {
473
+ const bkp = (2 * j * bk) / x + bkm;
474
+ bkm = bk;
475
+ bk = bkp;
476
+ }
477
+ return bk;
478
+ }
479
+ /** Common validation + dispatch for the four BESSEL* functions. */
480
+ function bessel(args, compute, allowZeroX) {
481
+ const xRV = (0, values_1.toNumberRV)(args[0]);
482
+ if ((0, values_1.isError)(xRV)) {
483
+ return xRV;
484
+ }
485
+ const nRV = (0, values_1.toNumberRV)(args[1]);
486
+ if ((0, values_1.isError)(nRV)) {
487
+ return nRV;
488
+ }
489
+ const n = Math.trunc(nRV.value);
490
+ // Excel accepts any real x for BESSELJ / BESSELI but requires x > 0
491
+ // for BESSELK / BESSELY (the log-term blows up at zero). For all four
492
+ // the order n must be a non-negative integer.
493
+ if (n < 0) {
494
+ return values_1.ERRORS.NUM;
495
+ }
496
+ if (!allowZeroX && xRV.value <= 0) {
497
+ return values_1.ERRORS.NUM;
498
+ }
499
+ if (allowZeroX && xRV.value < 0) {
500
+ return values_1.ERRORS.NUM;
501
+ }
502
+ const result = compute(n, xRV.value);
503
+ return Number.isFinite(result) ? (0, values_1.rvNumber)(result) : values_1.ERRORS.NUM;
504
+ }
505
+ const fnBESSELJ = args => bessel(args, besselJ, true);
506
+ exports.fnBESSELJ = fnBESSELJ;
507
+ const fnBESSELI = args => bessel(args, besselI, true);
508
+ exports.fnBESSELI = fnBESSELI;
509
+ const fnBESSELK = args => bessel(args, besselK, false);
510
+ exports.fnBESSELK = fnBESSELK;
511
+ const fnBESSELY = args => bessel(args, besselY, false);
512
+ exports.fnBESSELY = fnBESSELY;
513
+ const fnDELTA = args => {
514
+ const n1 = (0, values_1.toNumberRV)(args[0]);
515
+ if ((0, values_1.isError)(n1)) {
516
+ return n1;
517
+ }
518
+ const n2 = args.length > 1 ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
519
+ if ((0, values_1.isError)(n2)) {
520
+ return n2;
521
+ }
522
+ return (0, values_1.rvNumber)(n1.value === n2.value ? 1 : 0);
523
+ };
524
+ exports.fnDELTA = fnDELTA;
525
+ const fnGESTEP = args => {
526
+ const n = (0, values_1.toNumberRV)(args[0]);
527
+ if ((0, values_1.isError)(n)) {
528
+ return n;
529
+ }
530
+ const step = args.length > 1 ? (0, values_1.toNumberRV)(args[1]) : (0, values_1.rvNumber)(0);
531
+ if ((0, values_1.isError)(step)) {
532
+ return step;
533
+ }
534
+ return (0, values_1.rvNumber)(n.value >= step.value ? 1 : 0);
535
+ };
536
+ exports.fnGESTEP = fnGESTEP;
537
+ // ============================================================================
538
+ // Complex Numbers, Bit Operations
539
+ // ============================================================================
540
+ function parseComplex(s) {
541
+ const text = s.trim();
542
+ if (text === "") {
543
+ return null;
544
+ }
545
+ // A valid numeric component (real or imaginary coefficient) must match
546
+ // this strict decimal grammar. Without it, the permissive fallback
547
+ // regex below lets garbage like "1.2.3+4i" or "ee+i" match and we
548
+ // then coerced NaN to 0, silently returning bogus complex numbers for
549
+ // 19 downstream IM* call sites. See R6-P0-2.
550
+ const NUM_RE = /^[+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?$/;
551
+ const toNumStrict = (x) => (NUM_RE.test(x) ? Number(x) : Number.NaN);
552
+ const pureReal = toNumStrict(text);
553
+ if (!Number.isNaN(pureReal) && !text.endsWith("i") && !text.endsWith("j")) {
554
+ return [pureReal, 0];
555
+ }
556
+ if (text === "i" || text === "j") {
557
+ return [0, 1];
558
+ }
559
+ if (text === "-i" || text === "-j") {
560
+ return [0, -1];
561
+ }
562
+ if (text === "+i" || text === "+j") {
563
+ return [0, 1];
564
+ }
565
+ // Pure imaginary "<num>i" or "<num>j"
566
+ if (text.endsWith("i") || text.endsWith("j")) {
567
+ const coef = text.slice(0, -1);
568
+ const coefNum = toNumStrict(coef);
569
+ if (!Number.isNaN(coefNum)) {
570
+ return [0, coefNum];
571
+ }
572
+ }
573
+ // Mixed real+imaginary form.
574
+ const re = /^([+-]?[\d.eE+-]*?)([+-][\d.eE]*)?[ij]$/;
575
+ const m = re.exec(text);
576
+ if (!m) {
577
+ return null;
578
+ }
579
+ const realRaw = m[1] ?? "";
580
+ const imagRaw = m[2] ?? "";
581
+ // Validate each component with the strict grammar (treating the bare
582
+ // sign tokens "+"/"-" as implicit coefficients of 1 / -1, matching
583
+ // Excel's "x+i" == "x+1i" shorthand).
584
+ const realPart = realRaw === "" || realRaw === "+" ? 0 : realRaw === "-" ? 0 : toNumStrict(realRaw);
585
+ const imagPart = imagRaw === "" ? 0 : imagRaw === "+" ? 1 : imagRaw === "-" ? -1 : toNumStrict(imagRaw);
586
+ if (Number.isNaN(realPart) || Number.isNaN(imagPart)) {
587
+ return null;
588
+ }
589
+ if (imagRaw === "" && realRaw !== "") {
590
+ // "5i" form already handled above; this branch would only fire
591
+ // for something like "+i" / "-i" which is caught earlier.
592
+ return null;
593
+ }
594
+ return [realPart, imagPart];
595
+ }
596
+ function formatComplex(re, im, suffix = "i") {
597
+ if (im === 0) {
598
+ return String(re);
599
+ }
600
+ if (re === 0) {
601
+ if (im === 1) {
602
+ return suffix;
603
+ }
604
+ if (im === -1) {
605
+ return "-" + suffix;
606
+ }
607
+ return im + suffix;
608
+ }
609
+ const imStr = im === 1 ? "+" + suffix : im === -1 ? "-" + suffix : (im > 0 ? "+" : "") + im + suffix;
610
+ return re + imStr;
611
+ }
612
+ const fnCOMPLEX = args => {
613
+ const re = (0, values_1.toNumberRV)(args[0]);
614
+ if ((0, values_1.isError)(re)) {
615
+ return re;
616
+ }
617
+ const im = (0, values_1.toNumberRV)(args[1]);
618
+ if ((0, values_1.isError)(im)) {
619
+ return im;
620
+ }
621
+ let suffix = "i";
622
+ if (args.length > 2) {
623
+ const e2 = (0, _shared_1.checkError)(args[2]);
624
+ if (e2) {
625
+ return e2;
626
+ }
627
+ suffix = (0, values_1.toStringRV)(args[2]);
628
+ }
629
+ if (suffix !== "i" && suffix !== "j") {
630
+ return values_1.ERRORS.VALUE;
631
+ }
632
+ return (0, values_1.rvString)(formatComplex(re.value, im.value, suffix));
633
+ };
634
+ exports.fnCOMPLEX = fnCOMPLEX;
635
+ const fnIMREAL = args => {
636
+ const err = (0, _shared_1.checkError)(args[0]);
637
+ if (err) {
638
+ return err;
639
+ }
640
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
641
+ return c ? (0, values_1.rvNumber)(c[0]) : values_1.ERRORS.NUM;
642
+ };
643
+ exports.fnIMREAL = fnIMREAL;
644
+ const fnIMAGINARY = args => {
645
+ const err = (0, _shared_1.checkError)(args[0]);
646
+ if (err) {
647
+ return err;
648
+ }
649
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
650
+ return c ? (0, values_1.rvNumber)(c[1]) : values_1.ERRORS.NUM;
651
+ };
652
+ exports.fnIMAGINARY = fnIMAGINARY;
653
+ const fnIMABS = args => {
654
+ const err = (0, _shared_1.checkError)(args[0]);
655
+ if (err) {
656
+ return err;
657
+ }
658
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
659
+ if (!c) {
660
+ return values_1.ERRORS.NUM;
661
+ }
662
+ return (0, values_1.rvNumber)(Math.sqrt(c[0] * c[0] + c[1] * c[1]));
663
+ };
664
+ exports.fnIMABS = fnIMABS;
665
+ const fnIMARGUMENT = args => {
666
+ const err = (0, _shared_1.checkError)(args[0]);
667
+ if (err) {
668
+ return err;
669
+ }
670
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
671
+ if (!c) {
672
+ return values_1.ERRORS.NUM;
673
+ }
674
+ if (c[0] === 0 && c[1] === 0) {
675
+ return values_1.ERRORS.DIV0;
676
+ }
677
+ return (0, values_1.rvNumber)(Math.atan2(c[1], c[0]));
678
+ };
679
+ exports.fnIMARGUMENT = fnIMARGUMENT;
680
+ const fnIMCONJUGATE = args => {
681
+ const err = (0, _shared_1.checkError)(args[0]);
682
+ if (err) {
683
+ return err;
684
+ }
685
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
686
+ if (!c) {
687
+ return values_1.ERRORS.NUM;
688
+ }
689
+ return (0, values_1.rvString)(formatComplex(c[0], -c[1]));
690
+ };
691
+ exports.fnIMCONJUGATE = fnIMCONJUGATE;
692
+ /**
693
+ * Iterate every scalar cell in a complex-number argument, invoking `step`
694
+ * on the parsed `[re, im]` pair. Accepts arrays, ranges and single
695
+ * scalars; numbers are treated as real, errors propagate, blanks are
696
+ * skipped, non-parseable strings yield `#NUM!`.
697
+ */
698
+ function forEachComplexCell(arg, step) {
699
+ const visit = (cell) => {
700
+ if (cell.kind === 4 /* RVKind.Error */) {
701
+ return cell;
702
+ }
703
+ if (cell.kind === 0 /* RVKind.Blank */) {
704
+ return null;
705
+ }
706
+ if (cell.kind === 1 /* RVKind.Number */) {
707
+ step(cell.value, 0);
708
+ return null;
709
+ }
710
+ if (cell.kind === 3 /* RVKind.Boolean */) {
711
+ step(cell.value ? 1 : 0, 0);
712
+ return null;
713
+ }
714
+ if (cell.kind === 2 /* RVKind.String */) {
715
+ const c = parseComplex(cell.value);
716
+ if (!c) {
717
+ return values_1.ERRORS.NUM;
718
+ }
719
+ step(c[0], c[1]);
720
+ return null;
721
+ }
722
+ return null;
723
+ };
724
+ if (arg.kind === 5 /* RVKind.Array */) {
725
+ for (const row of arg.rows) {
726
+ for (const cell of row) {
727
+ const err = visit(cell);
728
+ if (err) {
729
+ return err;
730
+ }
731
+ }
732
+ }
733
+ return null;
734
+ }
735
+ // Non-array: visit the scalar directly (references have already been
736
+ // dereferenced to either an array or a scalar by the evaluator).
737
+ return visit(arg);
738
+ }
739
+ const fnIMSUM = args => {
740
+ let re = 0;
741
+ let im = 0;
742
+ for (const a of args) {
743
+ const err = (0, _shared_1.checkError)(a);
744
+ if (err) {
745
+ return err;
746
+ }
747
+ const walkErr = forEachComplexCell(a, (r, i) => {
748
+ re += r;
749
+ im += i;
750
+ });
751
+ if (walkErr) {
752
+ return walkErr;
753
+ }
754
+ }
755
+ return (0, values_1.rvString)(formatComplex(re, im));
756
+ };
757
+ exports.fnIMSUM = fnIMSUM;
758
+ const fnIMSUB = args => {
759
+ const e0 = (0, _shared_1.checkError)(args[0]);
760
+ if (e0) {
761
+ return e0;
762
+ }
763
+ const e1 = (0, _shared_1.checkError)(args[1]);
764
+ if (e1) {
765
+ return e1;
766
+ }
767
+ const c1 = parseComplex((0, values_1.toStringRV)(args[0]));
768
+ const c2 = parseComplex((0, values_1.toStringRV)(args[1]));
769
+ if (!c1 || !c2) {
770
+ return values_1.ERRORS.NUM;
771
+ }
772
+ return (0, values_1.rvString)(formatComplex(c1[0] - c2[0], c1[1] - c2[1]));
773
+ };
774
+ exports.fnIMSUB = fnIMSUB;
775
+ const fnIMPRODUCT = args => {
776
+ let re = 1;
777
+ let im = 0;
778
+ for (const a of args) {
779
+ const err = (0, _shared_1.checkError)(a);
780
+ if (err) {
781
+ return err;
782
+ }
783
+ const walkErr = forEachComplexCell(a, (r, i) => {
784
+ const nRe = re * r - im * i;
785
+ const nIm = re * i + im * r;
786
+ re = nRe;
787
+ im = nIm;
788
+ });
789
+ if (walkErr) {
790
+ return walkErr;
791
+ }
792
+ }
793
+ return (0, values_1.rvString)(formatComplex(re, im));
794
+ };
795
+ exports.fnIMPRODUCT = fnIMPRODUCT;
796
+ const fnIMDIV = args => {
797
+ const e0 = (0, _shared_1.checkError)(args[0]);
798
+ if (e0) {
799
+ return e0;
800
+ }
801
+ const e1 = (0, _shared_1.checkError)(args[1]);
802
+ if (e1) {
803
+ return e1;
804
+ }
805
+ const c1 = parseComplex((0, values_1.toStringRV)(args[0]));
806
+ const c2 = parseComplex((0, values_1.toStringRV)(args[1]));
807
+ if (!c1 || !c2) {
808
+ return values_1.ERRORS.NUM;
809
+ }
810
+ const d = c2[0] * c2[0] + c2[1] * c2[1];
811
+ if (d === 0) {
812
+ // Division by 0+0i. Excel's IMDIV returns `#NUM!` historically but
813
+ // our newer `cdiv` helper (used by IMTAN/IMCSC/etc.) returns
814
+ // `#DIV/0!`. Route to `#DIV/0!` here for engine-wide consistency
815
+ // with how the rest of the complex family handles the same
816
+ // singularity.
817
+ return values_1.ERRORS.DIV0;
818
+ }
819
+ return (0, values_1.rvString)(formatComplex((c1[0] * c2[0] + c1[1] * c2[1]) / d, (c1[1] * c2[0] - c1[0] * c2[1]) / d));
820
+ };
821
+ exports.fnIMDIV = fnIMDIV;
822
+ const fnIMPOWER = args => {
823
+ const err = (0, _shared_1.checkError)(args[0]);
824
+ if (err) {
825
+ return err;
826
+ }
827
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
828
+ if (!c) {
829
+ return values_1.ERRORS.NUM;
830
+ }
831
+ const n = (0, values_1.toNumberRV)(args[1]);
832
+ if ((0, values_1.isError)(n)) {
833
+ return n;
834
+ }
835
+ const r = Math.sqrt(c[0] * c[0] + c[1] * c[1]);
836
+ const theta = Math.atan2(c[1], c[0]);
837
+ const rn = Math.pow(r, n.value);
838
+ return (0, values_1.rvString)(formatComplex(rn * Math.cos(n.value * theta), rn * Math.sin(n.value * theta)));
839
+ };
840
+ exports.fnIMPOWER = fnIMPOWER;
841
+ const fnIMSQRT = args => {
842
+ const err = (0, _shared_1.checkError)(args[0]);
843
+ if (err) {
844
+ return err;
845
+ }
846
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
847
+ if (!c) {
848
+ return values_1.ERRORS.NUM;
849
+ }
850
+ const r = Math.sqrt(c[0] * c[0] + c[1] * c[1]);
851
+ const theta = Math.atan2(c[1], c[0]);
852
+ const sr = Math.sqrt(r);
853
+ return (0, values_1.rvString)(formatComplex(sr * Math.cos(theta / 2), sr * Math.sin(theta / 2)));
854
+ };
855
+ exports.fnIMSQRT = fnIMSQRT;
856
+ const fnIMLN = args => {
857
+ const err = (0, _shared_1.checkError)(args[0]);
858
+ if (err) {
859
+ return err;
860
+ }
861
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
862
+ if (!c) {
863
+ return values_1.ERRORS.NUM;
864
+ }
865
+ const r = Math.sqrt(c[0] * c[0] + c[1] * c[1]);
866
+ if (r === 0) {
867
+ return values_1.ERRORS.NUM;
868
+ }
869
+ return (0, values_1.rvString)(formatComplex(Math.log(r), Math.atan2(c[1], c[0])));
870
+ };
871
+ exports.fnIMLN = fnIMLN;
872
+ const fnIMLOG2 = args => {
873
+ const err = (0, _shared_1.checkError)(args[0]);
874
+ if (err) {
875
+ return err;
876
+ }
877
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
878
+ if (!c) {
879
+ return values_1.ERRORS.NUM;
880
+ }
881
+ const r = Math.sqrt(c[0] * c[0] + c[1] * c[1]);
882
+ if (r === 0) {
883
+ return values_1.ERRORS.NUM;
884
+ }
885
+ const ln2 = Math.log(2);
886
+ return (0, values_1.rvString)(formatComplex(Math.log(r) / ln2, Math.atan2(c[1], c[0]) / ln2));
887
+ };
888
+ exports.fnIMLOG2 = fnIMLOG2;
889
+ const fnIMLOG10 = args => {
890
+ const err = (0, _shared_1.checkError)(args[0]);
891
+ if (err) {
892
+ return err;
893
+ }
894
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
895
+ if (!c) {
896
+ return values_1.ERRORS.NUM;
897
+ }
898
+ const r = Math.sqrt(c[0] * c[0] + c[1] * c[1]);
899
+ if (r === 0) {
900
+ return values_1.ERRORS.NUM;
901
+ }
902
+ const ln10 = Math.log(10);
903
+ return (0, values_1.rvString)(formatComplex(Math.log(r) / ln10, Math.atan2(c[1], c[0]) / ln10));
904
+ };
905
+ exports.fnIMLOG10 = fnIMLOG10;
906
+ const fnIMEXP = args => {
907
+ const err = (0, _shared_1.checkError)(args[0]);
908
+ if (err) {
909
+ return err;
910
+ }
911
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
912
+ if (!c) {
913
+ return values_1.ERRORS.NUM;
914
+ }
915
+ const er = Math.exp(c[0]);
916
+ return (0, values_1.rvString)(formatComplex(er * Math.cos(c[1]), er * Math.sin(c[1])));
917
+ };
918
+ exports.fnIMEXP = fnIMEXP;
919
+ const fnIMSIN = args => {
920
+ const err = (0, _shared_1.checkError)(args[0]);
921
+ if (err) {
922
+ return err;
923
+ }
924
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
925
+ if (!c) {
926
+ return values_1.ERRORS.NUM;
927
+ }
928
+ return (0, values_1.rvString)(formatComplex(Math.sin(c[0]) * Math.cosh(c[1]), Math.cos(c[0]) * Math.sinh(c[1])));
929
+ };
930
+ exports.fnIMSIN = fnIMSIN;
931
+ const fnIMCOS = args => {
932
+ const err = (0, _shared_1.checkError)(args[0]);
933
+ if (err) {
934
+ return err;
935
+ }
936
+ const c = parseComplex((0, values_1.toStringRV)(args[0]));
937
+ if (!c) {
938
+ return values_1.ERRORS.NUM;
939
+ }
940
+ return (0, values_1.rvString)(formatComplex(Math.cos(c[0]) * Math.cosh(c[1]), -Math.sin(c[0]) * Math.sinh(c[1])));
941
+ };
942
+ exports.fnIMCOS = fnIMCOS;
943
+ /**
944
+ * Shared helper: parse a single complex argument and either hand it to
945
+ * `compute` (which returns `[re, im]` or an error) or short-circuit the
946
+ * error. All the IM* functions added in R7 share this shape.
947
+ */
948
+ function unaryComplex(args, compute) {
949
+ const err = (0, _shared_1.checkError)(args[0]);
950
+ if (err) {
951
+ return err;
952
+ }
953
+ // Allow number / boolean direct inputs: complex parser expects a
954
+ // string, but Excel's IM* family coerces booleans to 1/0 and numbers
955
+ // to pure-real complex. Falling through to `toStringRV` would render
956
+ // "TRUE" and then fail parsing.
957
+ const scalar = (0, values_1.topLeft)(args[0]);
958
+ let c;
959
+ if (scalar.kind === 1 /* RVKind.Number */) {
960
+ c = [scalar.value, 0];
961
+ }
962
+ else if (scalar.kind === 3 /* RVKind.Boolean */) {
963
+ c = [scalar.value ? 1 : 0, 0];
964
+ }
965
+ else if (scalar.kind === 0 /* RVKind.Blank */) {
966
+ c = [0, 0];
967
+ }
968
+ else {
969
+ c = parseComplex((0, values_1.toStringRV)(scalar));
970
+ }
971
+ if (!c) {
972
+ return values_1.ERRORS.NUM;
973
+ }
974
+ const result = compute(c[0], c[1]);
975
+ if ("kind" in result && result.kind === 4 /* RVKind.Error */) {
976
+ return result;
977
+ }
978
+ const [re, im] = result;
979
+ if (!Number.isFinite(re) || !Number.isFinite(im)) {
980
+ return values_1.ERRORS.NUM;
981
+ }
982
+ return (0, values_1.rvString)(formatComplex(re, im));
983
+ }
984
+ /** Divide two complex numbers (a / b). */
985
+ function cdiv(a, b) {
986
+ const denom = b[0] * b[0] + b[1] * b[1];
987
+ if (denom === 0) {
988
+ return values_1.ERRORS.DIV0;
989
+ }
990
+ return [(a[0] * b[0] + a[1] * b[1]) / denom, (a[1] * b[0] - a[0] * b[1]) / denom];
991
+ }
992
+ const fnIMTAN = args => unaryComplex(args, (re, im) => {
993
+ // tan(z) = sin(z) / cos(z)
994
+ const sinZ = [Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im)];
995
+ const cosZ = [Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im)];
996
+ return cdiv(sinZ, cosZ);
997
+ });
998
+ exports.fnIMTAN = fnIMTAN;
999
+ const fnIMCSC = args => unaryComplex(args, (re, im) => {
1000
+ // csc(z) = 1 / sin(z)
1001
+ const sinZ = [Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im)];
1002
+ return cdiv([1, 0], sinZ);
1003
+ });
1004
+ exports.fnIMCSC = fnIMCSC;
1005
+ const fnIMSEC = args => unaryComplex(args, (re, im) => {
1006
+ // sec(z) = 1 / cos(z)
1007
+ const cosZ = [Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im)];
1008
+ return cdiv([1, 0], cosZ);
1009
+ });
1010
+ exports.fnIMSEC = fnIMSEC;
1011
+ const fnIMCOT = args => unaryComplex(args, (re, im) => {
1012
+ // cot(z) = cos(z) / sin(z)
1013
+ const sinZ = [Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im)];
1014
+ const cosZ = [Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im)];
1015
+ return cdiv(cosZ, sinZ);
1016
+ });
1017
+ exports.fnIMCOT = fnIMCOT;
1018
+ const fnIMSINH = args => unaryComplex(args, (re, im) => [Math.sinh(re) * Math.cos(im), Math.cosh(re) * Math.sin(im)]);
1019
+ exports.fnIMSINH = fnIMSINH;
1020
+ const fnIMCOSH = args => unaryComplex(args, (re, im) => [Math.cosh(re) * Math.cos(im), Math.sinh(re) * Math.sin(im)]);
1021
+ exports.fnIMCOSH = fnIMCOSH;
1022
+ const fnIMTANH = args => unaryComplex(args, (re, im) => {
1023
+ // tanh(z) = sinh(z) / cosh(z)
1024
+ const sinhZ = [Math.sinh(re) * Math.cos(im), Math.cosh(re) * Math.sin(im)];
1025
+ const coshZ = [Math.cosh(re) * Math.cos(im), Math.sinh(re) * Math.sin(im)];
1026
+ return cdiv(sinhZ, coshZ);
1027
+ });
1028
+ exports.fnIMTANH = fnIMTANH;
1029
+ const fnIMCSCH = args => unaryComplex(args, (re, im) => {
1030
+ const sinhZ = [Math.sinh(re) * Math.cos(im), Math.cosh(re) * Math.sin(im)];
1031
+ return cdiv([1, 0], sinhZ);
1032
+ });
1033
+ exports.fnIMCSCH = fnIMCSCH;
1034
+ const fnIMSECH = args => unaryComplex(args, (re, im) => {
1035
+ const coshZ = [Math.cosh(re) * Math.cos(im), Math.sinh(re) * Math.sin(im)];
1036
+ return cdiv([1, 0], coshZ);
1037
+ });
1038
+ exports.fnIMSECH = fnIMSECH;
1039
+ const fnIMCOTH = args => unaryComplex(args, (re, im) => {
1040
+ const sinhZ = [Math.sinh(re) * Math.cos(im), Math.cosh(re) * Math.sin(im)];
1041
+ const coshZ = [Math.cosh(re) * Math.cos(im), Math.sinh(re) * Math.sin(im)];
1042
+ return cdiv(coshZ, sinhZ);
1043
+ });
1044
+ exports.fnIMCOTH = fnIMCOTH;
1045
+ // Excel's bitwise family (BITAND/BITOR/BITXOR/BITLSHIFT/BITRSHIFT) operates
1046
+ // on integers in the range [0, 2^48 − 1]. JavaScript's `&`/`|`/`^` truncate
1047
+ // to 32 bits, so we emulate 48-bit semantics by splitting each operand into
1048
+ // a 24-bit low half and a 24-bit high half, combining those halves with
1049
+ // native 32-bit bitwise ops, and recombining. The shift functions use the
1050
+ // same split so `BITLSHIFT(2^30, 10)` doesn't silently lose bits.
1051
+ const BIT_MAX = 2 ** 48 - 1;
1052
+ function bitOp(op) {
1053
+ return (a, b) => {
1054
+ const aHi = Math.floor(a / 0x1000000);
1055
+ const aLo = a - aHi * 0x1000000;
1056
+ const bHi = Math.floor(b / 0x1000000);
1057
+ const bLo = b - bHi * 0x1000000;
1058
+ return op(aHi, bHi) * 0x1000000 + (op(aLo, bLo) >>> 0);
1059
+ };
1060
+ }
1061
+ const bitAnd48 = bitOp((a, b) => (a & b) >>> 0);
1062
+ const bitOr48 = bitOp((a, b) => (a | b) >>> 0);
1063
+ const bitXor48 = bitOp((a, b) => (a ^ b) >>> 0);
1064
+ function validateBitOperand(v) {
1065
+ if (v < 0 || v > BIT_MAX) {
1066
+ return values_1.ERRORS.NUM;
1067
+ }
1068
+ // Excel rejects non-integer operands with #NUM!, rather than silently
1069
+ // truncating. Use the strict `v !== floor(v)` check so `5.9` does not
1070
+ // pass as `5`.
1071
+ if (v !== Math.floor(v)) {
1072
+ return values_1.ERRORS.NUM;
1073
+ }
1074
+ return v;
1075
+ }
1076
+ const fnBITAND = args => {
1077
+ const a = (0, values_1.toNumberRV)(args[0]);
1078
+ if ((0, values_1.isError)(a)) {
1079
+ return a;
1080
+ }
1081
+ const b = (0, values_1.toNumberRV)(args[1]);
1082
+ if ((0, values_1.isError)(b)) {
1083
+ return b;
1084
+ }
1085
+ const av = validateBitOperand(a.value);
1086
+ if (typeof av !== "number") {
1087
+ return av;
1088
+ }
1089
+ const bv = validateBitOperand(b.value);
1090
+ if (typeof bv !== "number") {
1091
+ return bv;
1092
+ }
1093
+ return (0, values_1.rvNumber)(bitAnd48(av, bv));
1094
+ };
1095
+ exports.fnBITAND = fnBITAND;
1096
+ const fnBITOR = args => {
1097
+ const a = (0, values_1.toNumberRV)(args[0]);
1098
+ if ((0, values_1.isError)(a)) {
1099
+ return a;
1100
+ }
1101
+ const b = (0, values_1.toNumberRV)(args[1]);
1102
+ if ((0, values_1.isError)(b)) {
1103
+ return b;
1104
+ }
1105
+ const av = validateBitOperand(a.value);
1106
+ if (typeof av !== "number") {
1107
+ return av;
1108
+ }
1109
+ const bv = validateBitOperand(b.value);
1110
+ if (typeof bv !== "number") {
1111
+ return bv;
1112
+ }
1113
+ return (0, values_1.rvNumber)(bitOr48(av, bv));
1114
+ };
1115
+ exports.fnBITOR = fnBITOR;
1116
+ const fnBITXOR = args => {
1117
+ const a = (0, values_1.toNumberRV)(args[0]);
1118
+ if ((0, values_1.isError)(a)) {
1119
+ return a;
1120
+ }
1121
+ const b = (0, values_1.toNumberRV)(args[1]);
1122
+ if ((0, values_1.isError)(b)) {
1123
+ return b;
1124
+ }
1125
+ const av = validateBitOperand(a.value);
1126
+ if (typeof av !== "number") {
1127
+ return av;
1128
+ }
1129
+ const bv = validateBitOperand(b.value);
1130
+ if (typeof bv !== "number") {
1131
+ return bv;
1132
+ }
1133
+ return (0, values_1.rvNumber)(bitXor48(av, bv));
1134
+ };
1135
+ exports.fnBITXOR = fnBITXOR;
1136
+ const fnBITLSHIFT = args => {
1137
+ const num = (0, values_1.toNumberRV)(args[0]);
1138
+ if ((0, values_1.isError)(num)) {
1139
+ return num;
1140
+ }
1141
+ const shift = (0, values_1.toNumberRV)(args[1]);
1142
+ if ((0, values_1.isError)(shift)) {
1143
+ return shift;
1144
+ }
1145
+ const nv = validateBitOperand(num.value);
1146
+ if (typeof nv !== "number") {
1147
+ return nv;
1148
+ }
1149
+ const s = Math.trunc(shift.value);
1150
+ if (s < -53 || s > 53) {
1151
+ return values_1.ERRORS.NUM;
1152
+ }
1153
+ const result = s >= 0 ? nv * Math.pow(2, s) : Math.floor(nv / Math.pow(2, -s));
1154
+ if (result > BIT_MAX) {
1155
+ return values_1.ERRORS.NUM;
1156
+ }
1157
+ return (0, values_1.rvNumber)(result);
1158
+ };
1159
+ exports.fnBITLSHIFT = fnBITLSHIFT;
1160
+ const fnBITRSHIFT = args => {
1161
+ const num = (0, values_1.toNumberRV)(args[0]);
1162
+ if ((0, values_1.isError)(num)) {
1163
+ return num;
1164
+ }
1165
+ const shift = (0, values_1.toNumberRV)(args[1]);
1166
+ if ((0, values_1.isError)(shift)) {
1167
+ return shift;
1168
+ }
1169
+ const nv = validateBitOperand(num.value);
1170
+ if (typeof nv !== "number") {
1171
+ return nv;
1172
+ }
1173
+ const s = Math.trunc(shift.value);
1174
+ if (s < -53 || s > 53) {
1175
+ return values_1.ERRORS.NUM;
1176
+ }
1177
+ const result = s >= 0 ? Math.floor(nv / Math.pow(2, s)) : nv * Math.pow(2, -s);
1178
+ if (result > BIT_MAX) {
1179
+ return values_1.ERRORS.NUM;
1180
+ }
1181
+ return (0, values_1.rvNumber)(result);
1182
+ };
1183
+ exports.fnBITRSHIFT = fnBITRSHIFT;