@svgrid/enterprise 3.0.2 → 3.1.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 (364) hide show
  1. package/LICENSE +94 -24
  2. package/README.md +36 -4
  3. package/dist/SvAdvancedFilter.svelte +1 -1
  4. package/dist/SvAlertsManager.svelte +2 -1
  5. package/dist/SvBoard.svelte +2 -1
  6. package/dist/SvExportMenu.svelte +4 -1
  7. package/dist/SvExportMenu.svelte.d.ts +0 -13
  8. package/dist/SvExpressionEditor.svelte +3 -3
  9. package/dist/SvFormulaBar.svelte +94 -20
  10. package/dist/SvFormulaBar.svelte.d.ts +7 -0
  11. package/dist/SvGridAlerts.svelte +49 -9
  12. package/dist/SvGridBoard.svelte +13 -8
  13. package/dist/SvGridBulkEditDrawer.svelte +26 -2
  14. package/dist/SvGridEditPanel.svelte +3 -0
  15. package/dist/SvGridScheduler.svelte +69 -40
  16. package/dist/SvGridSelectionBar.svelte +10 -3
  17. package/dist/SvPivotDesigner.svelte +198 -40
  18. package/dist/SvPivotDesigner.svelte.d.ts +27 -20
  19. package/dist/SvSheet.svelte +4043 -243
  20. package/dist/SvSheet.svelte.d.ts +76 -3
  21. package/dist/SvSheetChartSetup.svelte +151 -0
  22. package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
  23. package/dist/SvSheetComment.svelte +216 -31
  24. package/dist/SvSheetComment.svelte.d.ts +11 -11
  25. package/dist/SvSheetConditionalFormat.svelte +28 -31
  26. package/dist/SvSheetDataValidation.svelte +66 -42
  27. package/dist/SvSheetEditRanges.svelte +217 -0
  28. package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
  29. package/dist/SvSheetErrors.svelte +125 -0
  30. package/dist/SvSheetErrors.svelte.d.ts +20 -0
  31. package/dist/SvSheetEvaluate.svelte +133 -0
  32. package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
  33. package/dist/SvSheetFilterMenu.svelte +137 -34
  34. package/dist/SvSheetFilterMenu.svelte.d.ts +5 -0
  35. package/dist/SvSheetFindReplace.svelte +19 -19
  36. package/dist/SvSheetFormatCells.svelte +125 -81
  37. package/dist/SvSheetGoalSeek.svelte +17 -16
  38. package/dist/SvSheetInsertFunction.svelte +15 -13
  39. package/dist/SvSheetIteration.svelte +81 -0
  40. package/dist/SvSheetIteration.svelte.d.ts +10 -0
  41. package/dist/SvSheetLink.svelte +99 -0
  42. package/dist/SvSheetLink.svelte.d.ts +17 -0
  43. package/dist/SvSheetListPicker.svelte +4 -2
  44. package/dist/SvSheetListPicker.svelte.d.ts +0 -6
  45. package/dist/SvSheetManageRules.svelte +20 -18
  46. package/dist/SvSheetNameManager.svelte +17 -15
  47. package/dist/SvSheetPageSetup.svelte +159 -0
  48. package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
  49. package/dist/SvSheetPasteSpecial.svelte +22 -20
  50. package/dist/SvSheetPivot.svelte +220 -0
  51. package/dist/SvSheetPivot.svelte.d.ts +21 -0
  52. package/dist/SvSheetProtectSheet.svelte +81 -0
  53. package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
  54. package/dist/SvSheetRemoveDuplicates.svelte +13 -10
  55. package/dist/SvSheetRibbon.svelte +104 -51
  56. package/dist/SvSheetSizeDialog.svelte +4 -2
  57. package/dist/SvSheetSort.svelte +218 -0
  58. package/dist/SvSheetSort.svelte.d.ts +28 -0
  59. package/dist/SvSheetSparklines.svelte +135 -0
  60. package/dist/SvSheetSparklines.svelte.d.ts +14 -0
  61. package/dist/SvSheetTable.svelte +160 -0
  62. package/dist/SvSheetTable.svelte.d.ts +24 -0
  63. package/dist/SvSheetTabs.svelte +161 -31
  64. package/dist/SvSheetTabs.svelte.d.ts +22 -8
  65. package/dist/SvSheetTextToColumns.svelte +20 -20
  66. package/dist/SvSheetValidationAlert.svelte +8 -6
  67. package/dist/advanced-filter-enable.js +1 -1
  68. package/dist/alerts/alert-engine.d.ts +6 -0
  69. package/dist/alerts/alert-engine.js +21 -4
  70. package/dist/alerts/alert-formats.js +2 -0
  71. package/dist/alerts/alert-types.d.ts +1 -1
  72. package/dist/alerts.d.ts +1 -1
  73. package/dist/alerts.js +2 -2
  74. package/dist/board.js +2 -2
  75. package/dist/bulk-edit.d.ts +3 -1
  76. package/dist/bulk-edit.js +1 -1
  77. package/dist/cdn/svgrid-enterprise.svelte-external.js +39827 -16429
  78. package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
  79. package/dist/designer/assets/{SvChartMenu-D9hEeHar.js → SvChartMenu-BDoeqGz6.js} +1 -1
  80. package/dist/designer/assets/{SvDateTimePicker-DARvKUL2.js → SvDateTimePicker-DCPg7WGN.js} +1 -1
  81. package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
  82. package/dist/designer/assets/{SvGridChart-B8j1SSy3.js → SvGridChart-Cy1ATrWh.js} +2 -2
  83. package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
  84. package/dist/designer/assets/{SvGridChartPanel-pT6ITc2P.js → SvGridChartPanel-CATdVc9X.js} +3 -3
  85. package/dist/designer/assets/{SvGridChartView-bg281UA1.js → SvGridChartView-CmsZtCED.js} +1 -1
  86. package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
  87. package/dist/designer/assets/{SvTabs-UFCMTHXS.js → SvTabs-2mHC6oaz.js} +1 -1
  88. package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
  89. package/dist/designer/assets/{chart-cIPUsbM5.js → chart-Cn7MnNqA.js} +1 -1
  90. package/dist/designer/assets/{chart-panel-messages-DtTxpBUU.js → chart-panel-messages-Dz7PTIqT.js} +1 -1
  91. package/dist/designer/assets/{chart-summary-Czu_5epb.js → chart-summary-BD1qYB2R.js} +1 -1
  92. package/dist/designer/assets/{chart-trend-D5I5VEe8.js → chart-trend-B8xr5LuD.js} +1 -1
  93. package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
  94. package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
  95. package/dist/designer/assets/{focus-trap-CAreAhlU.js → focus-trap-V2-6Fy9I.js} +1 -1
  96. package/dist/designer/assets/{index-DwU7CAMm.js → index-BSjv6Qec.js} +317 -315
  97. package/dist/designer/assets/index-_JVFxt02.css +1 -0
  98. package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
  99. package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
  100. package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
  101. package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
  102. package/dist/designer/index.html +17 -16
  103. package/dist/export-pdf.d.ts +75 -0
  104. package/dist/export-pdf.js +216 -15
  105. package/dist/export.js +10 -2
  106. package/dist/gantt/SvGridGantt.svelte +2890 -0
  107. package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
  108. package/dist/gantt/gantt-config.d.ts +73 -0
  109. package/dist/gantt/gantt-config.js +1 -0
  110. package/dist/gantt/gantt-critical-path.d.ts +67 -0
  111. package/dist/gantt/gantt-critical-path.js +207 -0
  112. package/dist/gantt/gantt-model.d.ts +257 -0
  113. package/dist/gantt/gantt-model.js +651 -0
  114. package/dist/gantt/gantt-resources.d.ts +59 -0
  115. package/dist/gantt/gantt-resources.js +71 -0
  116. package/dist/gantt/gantt.d.ts +7 -0
  117. package/dist/gantt/gantt.js +36 -0
  118. package/dist/gantt/index.d.ts +15 -0
  119. package/dist/gantt/index.js +22 -0
  120. package/dist/gantt/timeline-arrows.d.ts +102 -0
  121. package/dist/gantt/timeline-arrows.js +181 -0
  122. package/dist/import.d.ts +2 -2
  123. package/dist/import.js +1 -1
  124. package/dist/index.d.ts +34 -7
  125. package/dist/index.js +44 -7
  126. package/dist/install.js +8 -1
  127. package/dist/license-core.d.ts +17 -1
  128. package/dist/license-core.js +16 -5
  129. package/dist/license.d.ts +18 -2
  130. package/dist/license.js +71 -6
  131. package/dist/node/studio.js +140 -8
  132. package/dist/pivot-enable.js +2 -2
  133. package/dist/scheduler-dependencies.d.ts +35 -0
  134. package/dist/scheduler-dependencies.js +36 -1
  135. package/dist/scheduler.js +2 -2
  136. package/dist/selection-bar.js +2 -2
  137. package/dist/server/SvGroupCell.svelte +213 -0
  138. package/dist/server/SvGroupCell.svelte.d.ts +62 -0
  139. package/dist/server/SvRowGroupPanel.svelte +322 -0
  140. package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
  141. package/dist/server/enable.d.ts +17 -0
  142. package/dist/server/enable.js +49 -0
  143. package/dist/server/index.d.ts +22 -0
  144. package/dist/server/index.js +24 -0
  145. package/dist/server/messages.d.ts +45 -0
  146. package/dist/server/messages.js +35 -0
  147. package/dist/server/server-group-model.d.ts +104 -0
  148. package/dist/server/server-group-model.js +272 -0
  149. package/dist/server/server-pivot.d.ts +46 -0
  150. package/dist/server/server-pivot.js +57 -0
  151. package/dist/server/server-row-model.d.ts +547 -0
  152. package/dist/server/server-row-model.js +1551 -0
  153. package/dist/server/server-selection.d.ts +99 -0
  154. package/dist/server/server-selection.js +215 -0
  155. package/dist/server/svgrid-adapter.d.ts +155 -0
  156. package/dist/server/svgrid-adapter.js +202 -0
  157. package/dist/sheet/ast.d.ts +45 -1
  158. package/dist/sheet/ast.js +14 -0
  159. package/dist/sheet/auto-filter.d.ts +58 -4
  160. package/dist/sheet/auto-filter.js +159 -11
  161. package/dist/sheet/autocomplete.d.ts +9 -0
  162. package/dist/sheet/autocomplete.js +90 -4
  163. package/dist/sheet/cell-images.d.ts +39 -0
  164. package/dist/sheet/cell-images.js +90 -0
  165. package/dist/sheet/cell-types.d.ts +58 -0
  166. package/dist/sheet/cell-types.js +96 -0
  167. package/dist/sheet/coerce.d.ts +40 -0
  168. package/dist/sheet/coerce.js +170 -3
  169. package/dist/sheet/comments.d.ts +43 -9
  170. package/dist/sheet/comments.js +85 -27
  171. package/dist/sheet/conditional-formats.d.ts +29 -6
  172. package/dist/sheet/conditional-formats.js +37 -12
  173. package/dist/sheet/csv.d.ts +32 -0
  174. package/dist/sheet/csv.js +158 -0
  175. package/dist/sheet/culture.d.ts +87 -0
  176. package/dist/sheet/culture.js +247 -0
  177. package/dist/sheet/delta.d.ts +102 -0
  178. package/dist/sheet/delta.js +203 -0
  179. package/dist/sheet/deps.d.ts +45 -1
  180. package/dist/sheet/deps.js +77 -2
  181. package/dist/sheet/document.d.ts +106 -4
  182. package/dist/sheet/document.js +204 -3
  183. package/dist/sheet/engine.d.ts +67 -0
  184. package/dist/sheet/engine.js +19 -0
  185. package/dist/sheet/entry.d.ts +8 -4
  186. package/dist/sheet/entry.js +171 -21
  187. package/dist/sheet/error-check.d.ts +49 -0
  188. package/dist/sheet/error-check.js +83 -0
  189. package/dist/sheet/evaluate-steps.d.ts +48 -0
  190. package/dist/sheet/evaluate-steps.js +196 -0
  191. package/dist/sheet/evaluate.d.ts +67 -0
  192. package/dist/sheet/evaluate.js +725 -13
  193. package/dist/sheet/filter-files.d.ts +37 -0
  194. package/dist/sheet/filter-files.js +465 -0
  195. package/dist/sheet/format-store.d.ts +15 -0
  196. package/dist/sheet/format-store.js +11 -1
  197. package/dist/sheet/from-rows.d.ts +14 -0
  198. package/dist/sheet/from-rows.js +50 -0
  199. package/dist/sheet/function-catalog.d.ts +1 -1
  200. package/dist/sheet/function-catalog.js +296 -5
  201. package/dist/sheet/functions.js +363 -91
  202. package/dist/sheet/index.d.ts +35 -8
  203. package/dist/sheet/index.js +35 -8
  204. package/dist/sheet/links.d.ts +57 -0
  205. package/dist/sheet/links.js +174 -0
  206. package/dist/sheet/messages.d.ts +778 -0
  207. package/dist/sheet/messages.js +806 -0
  208. package/dist/sheet/number-format.d.ts +52 -5
  209. package/dist/sheet/number-format.js +465 -68
  210. package/dist/sheet/objects.d.ts +106 -0
  211. package/dist/sheet/objects.js +149 -0
  212. package/dist/sheet/ods-document.d.ts +44 -0
  213. package/dist/sheet/ods-document.js +1275 -0
  214. package/dist/sheet/open-file.d.ts +26 -0
  215. package/dist/sheet/open-file.js +56 -0
  216. package/dist/sheet/outline.d.ts +82 -0
  217. package/dist/sheet/outline.js +228 -0
  218. package/dist/sheet/packs/array.d.ts +16 -0
  219. package/dist/sheet/packs/array.js +172 -0
  220. package/dist/sheet/packs/database.d.ts +42 -0
  221. package/dist/sheet/packs/database.js +142 -0
  222. package/dist/sheet/packs/engineering.d.ts +2 -0
  223. package/dist/sheet/packs/engineering.js +296 -0
  224. package/dist/sheet/packs/financial.d.ts +5 -0
  225. package/dist/sheet/packs/financial.js +220 -0
  226. package/dist/sheet/packs/math-stats.d.ts +2 -0
  227. package/dist/sheet/packs/math-stats.js +372 -0
  228. package/dist/sheet/packs/special.d.ts +44 -0
  229. package/dist/sheet/packs/special.js +187 -0
  230. package/dist/sheet/packs/stats-dist.d.ts +2 -0
  231. package/dist/sheet/packs/stats-dist.js +785 -0
  232. package/dist/sheet/packs/text-date.d.ts +2 -0
  233. package/dist/sheet/packs/text-date.js +332 -0
  234. package/dist/sheet/packs/trig.d.ts +2 -0
  235. package/dist/sheet/packs/trig.js +73 -0
  236. package/dist/sheet/page-setup.d.ts +73 -0
  237. package/dist/sheet/page-setup.js +73 -0
  238. package/dist/sheet/parse.js +42 -10
  239. package/dist/sheet/paste-special.d.ts +22 -0
  240. package/dist/sheet/paste-special.js +14 -5
  241. package/dist/sheet/pivot-range.d.ts +160 -0
  242. package/dist/sheet/pivot-range.js +333 -0
  243. package/dist/sheet/presence.d.ts +73 -0
  244. package/dist/sheet/presence.js +79 -0
  245. package/dist/sheet/print.d.ts +104 -0
  246. package/dist/sheet/print.js +169 -0
  247. package/dist/sheet/protection.d.ts +55 -1
  248. package/dist/sheet/protection.js +55 -2
  249. package/dist/sheet/rects.d.ts +1 -1
  250. package/dist/sheet/refs.d.ts +48 -0
  251. package/dist/sheet/refs.js +155 -8
  252. package/dist/sheet/ribbon-icons.d.ts +1 -1
  253. package/dist/sheet/ribbon-icons.js +186 -0
  254. package/dist/sheet/ribbon.d.ts +1 -1
  255. package/dist/sheet/ribbon.js +324 -23
  256. package/dist/sheet/sheet-kinds.d.ts +74 -0
  257. package/dist/sheet/sheet-kinds.js +91 -0
  258. package/dist/sheet/shortcuts.d.ts +13 -3
  259. package/dist/sheet/shortcuts.js +63 -12
  260. package/dist/sheet/sort.d.ts +51 -0
  261. package/dist/sheet/sort.js +107 -0
  262. package/dist/sheet/sparklines.d.ts +111 -0
  263. package/dist/sheet/sparklines.js +204 -0
  264. package/dist/sheet/table-styles.d.ts +74 -0
  265. package/dist/sheet/table-styles.js +152 -0
  266. package/dist/sheet/tables.d.ts +19 -0
  267. package/dist/sheet/tables.js +31 -0
  268. package/dist/sheet/tokenize.d.ts +18 -1
  269. package/dist/sheet/tokenize.js +60 -9
  270. package/dist/sheet/validation.d.ts +16 -0
  271. package/dist/sheet/validation.js +37 -0
  272. package/dist/sheet/workbook.d.ts +148 -3
  273. package/dist/sheet/workbook.js +742 -31
  274. package/dist/sheet/xls-cfb.d.ts +32 -0
  275. package/dist/sheet/xls-cfb.js +290 -0
  276. package/dist/sheet/xls-document.d.ts +10 -0
  277. package/dist/sheet/xls-document.js +1243 -0
  278. package/dist/sheet/xls-formula.d.ts +40 -0
  279. package/dist/sheet/xls-formula.js +569 -0
  280. package/dist/sheet/xlsx-document.d.ts +108 -0
  281. package/dist/sheet/xlsx-document.js +1849 -0
  282. package/dist/sheet/xlsx-drawing.d.ts +99 -0
  283. package/dist/sheet/xlsx-drawing.js +420 -0
  284. package/dist/sheet-enable.js +6 -7
  285. package/dist/sheet-text.d.ts +7 -0
  286. package/dist/sheet-text.js +29 -0
  287. package/dist/sources/auth-supabase.js +2 -2
  288. package/dist/sources/realtime-supabase.js +2 -2
  289. package/dist/sources/rest.d.ts +6 -2
  290. package/dist/sources/rest.js +42 -7
  291. package/dist/sources/supabase.d.ts +10 -1
  292. package/dist/sources/supabase.js +73 -40
  293. package/dist/studio/emit-project.js +14 -1
  294. package/dist/studio/index.js +1 -1
  295. package/dist/studio/project.d.ts +11 -2
  296. package/dist/studio/project.js +5 -2
  297. package/dist/studio/ui-components.generated.js +107 -2
  298. package/dist/sveltekit/in-memory.d.ts +2 -2
  299. package/dist/sveltekit/in-memory.js +125 -4
  300. package/dist/sveltekit/index.d.ts +1 -1
  301. package/dist/sveltekit/index.js +1 -1
  302. package/dist/sveltekit/query-plan.d.ts +50 -4
  303. package/dist/sveltekit/query-plan.js +25 -3
  304. package/dist/sveltekit/sql-source.d.ts +6 -0
  305. package/dist/sveltekit/sql-source.js +34 -6
  306. package/dist/sveltekit/sql.d.ts +31 -0
  307. package/dist/sveltekit/sql.js +135 -25
  308. package/dist/sveltekit/transport.d.ts +10 -2
  309. package/dist/sveltekit/transport.js +30 -6
  310. package/dist/upgrade-prompt.d.ts +1 -1
  311. package/dist/version.d.ts +1 -1
  312. package/dist/version.js +1 -1
  313. package/dist/watermark.js +35 -2
  314. package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
  315. package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
  316. package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
  317. package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
  318. package/dist/wc/SvField-B_kurx_P.js +149 -0
  319. package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
  320. package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
  321. package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
  322. package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
  323. package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
  324. package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
  325. package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
  326. package/dist/wc/SvModal-DrfOYYyX.js +189 -0
  327. package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
  328. package/dist/wc/chart-6OXlybVT.js +4341 -0
  329. package/dist/wc/chart-export-CeSADGfi.js +135 -0
  330. package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
  331. package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
  332. package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
  333. package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
  334. package/dist/wc/client-DQIzjDBG.js +3064 -0
  335. package/dist/wc/column-resize-DUPgynvc.js +101 -0
  336. package/dist/wc/date-format-DS-z_h9v.js +1130 -0
  337. package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
  338. package/dist/wc/editor-contract-peBDxir_.js +22 -0
  339. package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
  340. package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
  341. package/dist/wc/list-option-DrRyivWp.js +82 -0
  342. package/dist/wc/popover-WsGlvtQv.js +69 -0
  343. package/dist/wc/positioning-BiKLfu1E.js +112 -0
  344. package/dist/wc/react.d.ts +41 -0
  345. package/dist/wc/react.js +90 -0
  346. package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
  347. package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
  348. package/dist/wc/row-resize-limG_N1z.js +111 -0
  349. package/dist/wc/sv-sheet-element.d.ts +97 -0
  350. package/dist/wc/sv-sheet-element.js +44213 -0
  351. package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
  352. package/dist/wc/validate-BqDthkNr.js +88 -0
  353. package/dist/wc/vue.d.ts +31 -0
  354. package/dist/wc/vue.js +75 -0
  355. package/package.json +30 -5
  356. package/dist/designer/assets/GridMenus-BlsvL_aU.js +0 -8
  357. package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +0 -4
  358. package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +0 -1
  359. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
  360. package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
  361. package/dist/designer/assets/index-CMFgAoVV.css +0 -1
  362. package/dist/designer/assets/row-resize-DLktcqUK.js +0 -1
  363. package/dist/designer/assets/src-EdI3Xqds.js +0 -58
  364. package/dist/designer/assets/validate-h-aslRV9.js +0 -1
@@ -0,0 +1,40 @@
1
+ /** The function a token index names, for the reader. */
2
+ export declare const xlsFunctionName: (id: number) => string | undefined;
3
+ /** The token index and fixed arity of a function, for the writer. */
4
+ export declare const xlsFunction: (name: string) => [id: number, args: number] | undefined;
5
+ export declare const xlsErrorText: (code: number) => string;
6
+ export declare const xlsErrorCode: (text: string) => number;
7
+ export type XlsReadContext = {
8
+ /** The sheet, or sheet span, a 3d reference index names. */
9
+ sheetAt(index: number): string | null;
10
+ /** A defined name by its one-based index. */
11
+ nameAt(index: number): string | null;
12
+ /** The cell the formula sits in: the relative forms are offsets from it. */
13
+ row: number;
14
+ col: number;
15
+ };
16
+ /**
17
+ * The text of a formula stored as RPN, or null when a token is one this
18
+ * reader does not translate.
19
+ *
20
+ * `relative` is set for a shared formula, whose references are offsets from
21
+ * the cell rather than addresses.
22
+ */
23
+ export declare function formulaFromRpn(bytes: Uint8Array, ctx: XlsReadContext): string | null;
24
+ /**
25
+ * The function a name stands for. Excel has no token for a function it
26
+ * gained after 2003, so it writes `_xlfn.XLOOKUP` as a defined name and
27
+ * calls that; the name is the function, and this is where it turns back
28
+ * into one.
29
+ */
30
+ export declare const modernName: (name: string) => string;
31
+ /** Whether a defined name is only Excel's wrapper for a modern function. */
32
+ export declare const isModernFunctionName: (name: string) => boolean;
33
+ export type XlsWriteContext = {
34
+ /** The index a reference to this sheet takes, adding one if needed. */
35
+ sheetRef(name: string): number;
36
+ /** The index of a defined name, or null when the workbook has no such name. */
37
+ nameRef(name: string): number | null;
38
+ };
39
+ /** The RPN for a formula, or null when something in it BIFF8 cannot say. */
40
+ export declare function rpnFromFormula(text: string, ctx: XlsWriteContext): Uint8Array | null;
@@ -0,0 +1,569 @@
1
+ /**
2
+ * Formulas in an .xls, which are not text.
3
+ *
4
+ * BIFF8 keeps a formula as RPN: a run of tokens, each a byte and its
5
+ * operand, that a stack machine would run. `=SUM(A1:A3)*2` is stored as an
6
+ * area token, a function token, a number token and a multiply token, and
7
+ * nothing in the file spells the formula out. So reading one means walking
8
+ * the tokens back into text, and writing one means walking our own AST into
9
+ * tokens.
10
+ *
11
+ * Not every formula translates. Excel 97 had no XLOOKUP and no LET, and
12
+ * there is no token for a function it did not have, so `rpnFromFormula`
13
+ * answers null and the writer falls back to the cached value. Reading works
14
+ * the same way round: a token this module does not know stops the walk and
15
+ * the cell keeps the value the file cached for it.
16
+ */
17
+ import { colToLetters } from './address.js';
18
+ import { parseFormula } from './parse.js';
19
+ /**
20
+ * Excel's function table: the index a token names, and how many arguments
21
+ * the function takes when that count is fixed.
22
+ *
23
+ * A fixed-arity function is written with ptgFunc, which carries only the
24
+ * index; everything else is ptgFuncVar, which carries the count as well.
25
+ * Getting that wrong produces a file that opens with the wrong formula, so
26
+ * the table is checked against files written by a real spreadsheet in
27
+ * `xls-formula.test.ts` rather than trusted.
28
+ */
29
+ const FUNCTIONS = {
30
+ COUNT: [0, -1], IF: [1, -1], ISNA: [2, 1], ISERROR: [3, 1], SUM: [4, -1], AVERAGE: [5, -1],
31
+ MIN: [6, -1], MAX: [7, -1], ROW: [8, -1], COLUMN: [9, -1], NA: [10, 0], NPV: [11, -1],
32
+ STDEV: [12, -1], DOLLAR: [13, -1], FIXED: [14, -1], SIN: [15, 1], COS: [16, 1], TAN: [17, 1],
33
+ ATAN: [18, 1], PI: [19, 0], SQRT: [20, 1], EXP: [21, 1], LN: [22, 1], LOG10: [23, 1],
34
+ ABS: [24, 1], INT: [25, 1], SIGN: [26, 1], ROUND: [27, 2], LOOKUP: [28, -1], INDEX: [29, -1],
35
+ REPT: [30, 2], MID: [31, 3], LEN: [32, 1], VALUE: [33, 1], TRUE: [34, 0], FALSE: [35, 0],
36
+ AND: [36, -1], OR: [37, -1], NOT: [38, 1], MOD: [39, 2], DCOUNT: [40, 3], DSUM: [41, 3],
37
+ DAVERAGE: [42, 3], DMIN: [43, 3], DMAX: [44, 3], DSTDEV: [45, 3], VAR: [46, -1], DVAR: [47, 3],
38
+ TEXT: [48, 2], PV: [56, -1], FV: [57, -1], NPER: [58, -1], PMT: [59, -1], RATE: [60, -1],
39
+ MIRR: [61, 3], IRR: [62, -1], RAND: [63, 0], MATCH: [64, -1], DATE: [65, 3], TIME: [66, 3],
40
+ DAY: [67, 1], MONTH: [68, 1], YEAR: [69, 1], WEEKDAY: [70, -1], HOUR: [71, 1], MINUTE: [72, 1],
41
+ SECOND: [73, 1], NOW: [74, 0], AREAS: [75, 1], ROWS: [76, 1], COLUMNS: [77, 1], OFFSET: [78, -1],
42
+ SEARCH: [82, -1], TRANSPOSE: [83, 1], TYPE: [86, 1], ATAN2: [97, 2], ASIN: [98, 1], ACOS: [99, 1],
43
+ CHOOSE: [100, -1], HLOOKUP: [101, -1], VLOOKUP: [102, -1], ISREF: [105, 1], LOG: [109, -1],
44
+ CHAR: [111, 1], LOWER: [112, 1], UPPER: [113, 1], PROPER: [114, 1], LEFT: [115, -1],
45
+ RIGHT: [116, -1], EXACT: [117, 2], TRIM: [118, 1], REPLACE: [119, 4], SUBSTITUTE: [120, -1],
46
+ CODE: [121, 1], FIND: [124, -1], CELL: [125, -1], ISERR: [126, 1], ISTEXT: [127, 1],
47
+ ISNUMBER: [128, 1], ISBLANK: [129, 1], T: [130, 1], N: [131, 1], DATEVALUE: [140, 1],
48
+ TIMEVALUE: [141, 1], SLN: [142, 3], SYD: [143, 4], DDB: [144, -1], INDIRECT: [148, -1],
49
+ CLEAN: [162, 1], MDETERM: [163, 1], MINVERSE: [164, 1], MMULT: [165, 2], IPMT: [167, -1],
50
+ PPMT: [168, -1], COUNTA: [169, -1], PRODUCT: [183, -1], FACT: [184, 1], DPRODUCT: [189, 3],
51
+ ISNONTEXT: [190, 1], STDEVP: [193, -1], VARP: [194, -1], DSTDEVP: [195, 3], DVARP: [196, 3],
52
+ TRUNC: [197, -1], ISLOGICAL: [198, 1], DCOUNTA: [199, 3], ROUNDUP: [212, 2], ROUNDDOWN: [213, 2],
53
+ RANK: [216, -1], ADDRESS: [219, -1], DAYS360: [220, -1], TODAY: [221, 0], VDB: [222, -1],
54
+ MEDIAN: [227, -1], SUMPRODUCT: [228, -1], SINH: [229, 1], COSH: [230, 1], TANH: [231, 1],
55
+ ASINH: [232, 1], ACOSH: [233, 1], ATANH: [234, 1], DGET: [235, 3], INFO: [244, 1], DB: [247, -1],
56
+ FREQUENCY: [252, 2], 'ERROR.TYPE': [261, 1], AVEDEV: [269, -1], BETADIST: [270, -1],
57
+ GAMMALN: [271, 1], BETAINV: [272, -1], BINOMDIST: [273, 4], CHIDIST: [274, 2], CHIINV: [275, 2],
58
+ COMBIN: [276, 2], CONFIDENCE: [277, 3], CRITBINOM: [278, 3], EVEN: [279, 1], EXPONDIST: [280, 3],
59
+ FDIST: [281, 3], FINV: [282, 3], FISHER: [283, 1], FISHERINV: [284, 1], FLOOR: [285, 2],
60
+ GAMMADIST: [286, 4], GAMMAINV: [287, 3], CEILING: [288, 2], HYPGEOMDIST: [289, 4],
61
+ LOGNORMDIST: [290, 3], LOGINV: [291, 3], NEGBINOMDIST: [292, 3], NORMDIST: [293, 4],
62
+ NORMSDIST: [294, 1], NORMINV: [295, 3], NORMSINV: [296, 1], STANDARDIZE: [297, 3], ODD: [298, 1],
63
+ PERMUT: [299, 2], POISSON: [300, 3], TDIST: [301, 3], WEIBULL: [302, 4], SUMXMY2: [303, 2],
64
+ SUMX2MY2: [304, 2], SUMX2PY2: [305, 2], CHITEST: [306, 2], CORREL: [307, 2], COVAR: [308, 2],
65
+ FORECAST: [309, 3], FTEST: [310, 2], INTERCEPT: [311, 2], PEARSON: [312, 2], RSQ: [313, 2],
66
+ STEYX: [314, 2], SLOPE: [315, 2], TTEST: [316, 4], PROB: [317, -1], DEVSQ: [318, -1],
67
+ GEOMEAN: [319, -1], HARMEAN: [320, -1], SUMSQ: [321, -1], KURT: [322, -1], SKEW: [323, -1],
68
+ ZTEST: [324, -1], LARGE: [325, 2], SMALL: [326, 2], QUARTILE: [327, 2], PERCENTILE: [328, 2],
69
+ PERCENTRANK: [329, -1], MODE: [330, -1], TRIMMEAN: [331, 2], TINV: [332, 2],
70
+ CONCATENATE: [336, -1], POWER: [337, 2], RADIANS: [342, 1], DEGREES: [343, 1],
71
+ SUBTOTAL: [344, -1], SUMIF: [345, -1], COUNTIF: [346, 2], COUNTBLANK: [347, 1], ISPMT: [350, 4],
72
+ ROMAN: [354, -1], HYPERLINK: [359, -1], AVERAGEA: [361, -1], MAXA: [362, -1], MINA: [363, -1],
73
+ STDEVPA: [364, -1], VARPA: [365, -1], STDEVA: [366, -1], VARA: [367, -1],
74
+ };
75
+ const FUNCTION_NAMES = new Map();
76
+ for (const [name, [id]] of Object.entries(FUNCTIONS))
77
+ if (!FUNCTION_NAMES.has(id))
78
+ FUNCTION_NAMES.set(id, name);
79
+ /** The function a token index names, for the reader. */
80
+ export const xlsFunctionName = (id) => FUNCTION_NAMES.get(id);
81
+ /** The token index and fixed arity of a function, for the writer. */
82
+ export const xlsFunction = (name) => FUNCTIONS[name.toUpperCase()];
83
+ /** The error codes BIFF8 numbers, both ways. */
84
+ const ERROR_CODES = {
85
+ 0x00: '#NULL!', 0x07: '#DIV/0!', 0x0f: '#VALUE!', 0x17: '#REF!',
86
+ 0x1d: '#NAME?', 0x24: '#NUM!', 0x2a: '#N/A',
87
+ };
88
+ export const xlsErrorText = (code) => ERROR_CODES[code] ?? '#VALUE!';
89
+ export const xlsErrorCode = (text) => {
90
+ const found = Object.entries(ERROR_CODES).find(([, t]) => t === text.toUpperCase());
91
+ return found ? Number(found[0]) : 0x0f;
92
+ };
93
+ const ATOM = 8;
94
+ const OPERATORS = {
95
+ 0x03: ['+', 3], 0x04: ['-', 3], 0x05: ['*', 4], 0x06: ['/', 4], 0x07: ['^', 5], 0x08: ['&', 2],
96
+ 0x09: ['<', 1], 0x0a: ['<=', 1], 0x0b: ['=', 1], 0x0c: ['>=', 1], 0x0d: ['>', 1], 0x0e: ['<>', 1],
97
+ 0x0f: [' ', 6], 0x10: [',', 6], 0x11: [':', 7],
98
+ };
99
+ const cellText = (row, col, rowRel, colRel) => `${colRel ? '' : '$'}${colToLetters(col)}${rowRel ? '' : '$'}${row + 1}`;
100
+ /** A relative offset as stored: signed, and wrapped at the sheet's edge. */
101
+ const signed16 = (v) => (v << 16) >> 16;
102
+ const signed8 = (v) => (v << 24) >> 24;
103
+ /**
104
+ * The text of a formula stored as RPN, or null when a token is one this
105
+ * reader does not translate.
106
+ *
107
+ * `relative` is set for a shared formula, whose references are offsets from
108
+ * the cell rather than addresses.
109
+ */
110
+ export function formulaFromRpn(bytes, ctx) {
111
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
112
+ const stack = [];
113
+ const push = (text, power = ATOM) => { stack.push({ text, power }); };
114
+ /** An operand, wrapped when it binds more loosely than what is around it. */
115
+ const pop = (power) => {
116
+ const piece = stack.pop();
117
+ if (!piece)
118
+ return null;
119
+ return piece.power < power ? `(${piece.text})` : piece.text;
120
+ };
121
+ let at = 0;
122
+ while (at < bytes.length) {
123
+ const token = bytes[at];
124
+ at += 1;
125
+ const base = token < 0x20 ? token : (token & 0x1f) | 0x20;
126
+ const operator = OPERATORS[base];
127
+ if (operator) {
128
+ const [op, power] = operator;
129
+ // The right operand of a left-associative operator needs the bracket
130
+ // at equal power too: a - (b - c) is not a - b - c.
131
+ const right = pop(op === '-' || op === '/' || op === '^' ? power + 1 : power);
132
+ const left = pop(power);
133
+ if (left === null || right === null)
134
+ return null;
135
+ push(`${left}${op}${right}`, power);
136
+ continue;
137
+ }
138
+ switch (base) {
139
+ case 0x12: { // unary plus
140
+ const arg = pop(6);
141
+ if (arg === null)
142
+ return null;
143
+ push(`+${arg}`, 6);
144
+ break;
145
+ }
146
+ case 0x13: { // unary minus
147
+ const arg = pop(6);
148
+ if (arg === null)
149
+ return null;
150
+ push(`-${arg}`, 6);
151
+ break;
152
+ }
153
+ case 0x14: { // percent
154
+ const arg = pop(6);
155
+ if (arg === null)
156
+ return null;
157
+ push(`${arg}%`, 6);
158
+ break;
159
+ }
160
+ case 0x15: { // the brackets the user typed
161
+ const arg = stack.pop();
162
+ if (!arg)
163
+ return null;
164
+ push(`(${arg.text})`);
165
+ break;
166
+ }
167
+ case 0x16: // a skipped argument
168
+ push('');
169
+ break;
170
+ case 0x17: { // a text literal
171
+ const read = shortString(bytes, at);
172
+ if (!read)
173
+ return null;
174
+ at = read.next;
175
+ push(`"${read.text.replace(/"/g, '""')}"`);
176
+ break;
177
+ }
178
+ case 0x19: { // an attribute: mostly hints, but one of them is a SUM
179
+ const grbit = bytes[at];
180
+ const word = view.getUint16(at + 1, true);
181
+ at += 3;
182
+ if (grbit & 0x04)
183
+ at += (word + 1) * 2; // the jump table of a CHOOSE
184
+ if (grbit & 0x10) { // the one-argument SUM Excel writes as an attribute
185
+ const arg = pop(0);
186
+ if (arg === null)
187
+ return null;
188
+ push(`SUM(${arg})`);
189
+ }
190
+ break;
191
+ }
192
+ case 0x1c: // an error value
193
+ push(xlsErrorText(bytes[at]));
194
+ at += 1;
195
+ break;
196
+ case 0x1d:
197
+ push(bytes[at] ? 'TRUE' : 'FALSE');
198
+ at += 1;
199
+ break;
200
+ case 0x1e:
201
+ push(String(view.getUint16(at, true)));
202
+ at += 2;
203
+ break;
204
+ case 0x1f:
205
+ push(String(view.getFloat64(at, true)));
206
+ at += 8;
207
+ break;
208
+ case 0x21: { // a function with a fixed number of arguments
209
+ const id = view.getUint16(at, true);
210
+ at += 2;
211
+ const name = xlsFunctionName(id);
212
+ if (!name)
213
+ return null;
214
+ const count = FUNCTIONS[name][1];
215
+ const args = takeArgs(stack, count < 0 ? 0 : count);
216
+ if (!args)
217
+ return null;
218
+ push(`${name}(${args.join(',')})`);
219
+ break;
220
+ }
221
+ case 0x22: { // a function with a stated number of arguments
222
+ const count = bytes[at] & 0x7f;
223
+ const id = view.getUint16(at + 1, true) & 0x7fff;
224
+ at += 3;
225
+ const args = takeArgs(stack, count);
226
+ if (!args)
227
+ return null;
228
+ // 255 is "a function this format has no number for": Excel writes a
229
+ // name in front of the arguments and calls that, which is how a
230
+ // modern function survives being saved as an .xls at all.
231
+ if (id === 255) {
232
+ const called = args.shift();
233
+ if (!called)
234
+ return null;
235
+ push(`${modernName(called)}(${args.join(',')})`);
236
+ break;
237
+ }
238
+ const name = xlsFunctionName(id);
239
+ if (!name)
240
+ return null;
241
+ push(`${name}(${args.join(',')})`);
242
+ break;
243
+ }
244
+ case 0x23: { // a defined name
245
+ const name = ctx.nameAt(view.getUint16(at, true));
246
+ at += 4;
247
+ if (!name)
248
+ return null;
249
+ push(modernName(name));
250
+ break;
251
+ }
252
+ case 0x24: { // a cell
253
+ const row = view.getUint16(at, true);
254
+ const col = view.getUint16(at + 2, true);
255
+ at += 4;
256
+ push(cellText(row, col & 0x3fff, (col & 0x8000) !== 0, (col & 0x4000) !== 0));
257
+ break;
258
+ }
259
+ case 0x25: { // a rectangle
260
+ const r1 = view.getUint16(at, true);
261
+ const r2 = view.getUint16(at + 2, true);
262
+ const c1 = view.getUint16(at + 4, true);
263
+ const c2 = view.getUint16(at + 6, true);
264
+ at += 8;
265
+ push(`${cellText(r1, c1 & 0x3fff, (c1 & 0x8000) !== 0, (c1 & 0x4000) !== 0)}:${cellText(r2, c2 & 0x3fff, (c2 & 0x8000) !== 0, (c2 & 0x4000) !== 0)}`);
266
+ break;
267
+ }
268
+ case 0x26: // a cached area list: the expression itself follows
269
+ case 0x27:
270
+ at += 6;
271
+ break;
272
+ case 0x29: // a subexpression whose length is stated and then walked
273
+ at += 2;
274
+ break;
275
+ case 0x2a: // a reference that was deleted out from under the formula
276
+ at += 4;
277
+ push('#REF!');
278
+ break;
279
+ case 0x2b:
280
+ at += 8;
281
+ push('#REF!');
282
+ break;
283
+ case 0x2c: { // a cell, as an offset from this one
284
+ const row = view.getUint16(at, true);
285
+ const col = view.getUint16(at + 2, true);
286
+ at += 4;
287
+ const rowRel = (col & 0x8000) !== 0;
288
+ const colRel = (col & 0x4000) !== 0;
289
+ const here = rowRel ? ctx.row + signed16(row) : row;
290
+ const there = colRel ? ctx.col + signed8(col & 0xff) : col & 0x3fff;
291
+ if (here < 0 || there < 0) {
292
+ push('#REF!');
293
+ break;
294
+ }
295
+ push(cellText(here, there, rowRel, colRel));
296
+ break;
297
+ }
298
+ case 0x2d: { // a rectangle, as offsets from this cell
299
+ const r1 = view.getUint16(at, true);
300
+ const r2 = view.getUint16(at + 2, true);
301
+ const c1 = view.getUint16(at + 4, true);
302
+ const c2 = view.getUint16(at + 6, true);
303
+ at += 8;
304
+ const from = offsetCell(r1, c1, ctx);
305
+ const to = offsetCell(r2, c2, ctx);
306
+ if (!from || !to) {
307
+ push('#REF!');
308
+ break;
309
+ }
310
+ push(`${from}:${to}`);
311
+ break;
312
+ }
313
+ case 0x39: { // a name in another workbook
314
+ const name = ctx.nameAt(view.getUint16(at + 2, true));
315
+ at += 6;
316
+ if (!name)
317
+ return null;
318
+ push(modernName(name));
319
+ break;
320
+ }
321
+ case 0x3a: { // a cell on another sheet
322
+ const sheet = ctx.sheetAt(view.getUint16(at, true));
323
+ const row = view.getUint16(at + 2, true);
324
+ const col = view.getUint16(at + 4, true);
325
+ at += 6;
326
+ const cell = cellText(row, col & 0x3fff, (col & 0x8000) !== 0, (col & 0x4000) !== 0);
327
+ push(sheet ? `${sheet}!${cell}` : cell);
328
+ break;
329
+ }
330
+ case 0x3b: { // a rectangle on another sheet
331
+ const sheet = ctx.sheetAt(view.getUint16(at, true));
332
+ const r1 = view.getUint16(at + 2, true);
333
+ const r2 = view.getUint16(at + 4, true);
334
+ const c1 = view.getUint16(at + 6, true);
335
+ const c2 = view.getUint16(at + 8, true);
336
+ at += 10;
337
+ const rect = `${cellText(r1, c1 & 0x3fff, (c1 & 0x8000) !== 0, (c1 & 0x4000) !== 0)}:${cellText(r2, c2 & 0x3fff, (c2 & 0x8000) !== 0, (c2 & 0x4000) !== 0)}`;
338
+ push(sheet ? `${sheet}!${rect}` : rect);
339
+ break;
340
+ }
341
+ case 0x3c:
342
+ at += 6;
343
+ push('#REF!');
344
+ break;
345
+ case 0x3d:
346
+ at += 10;
347
+ push('#REF!');
348
+ break;
349
+ default:
350
+ return null;
351
+ }
352
+ }
353
+ // A walk that ends with anything but one value on the stack read a token
354
+ // wrongly somewhere, and half a formula is worse than none.
355
+ const answer = stack.pop();
356
+ return answer && stack.length === 0 ? answer.text : null;
357
+ }
358
+ /**
359
+ * The function a name stands for. Excel has no token for a function it
360
+ * gained after 2003, so it writes `_xlfn.XLOOKUP` as a defined name and
361
+ * calls that; the name is the function, and this is where it turns back
362
+ * into one.
363
+ */
364
+ export const modernName = (name) => name.startsWith('_xlfn.') ? name.slice('_xlfn.'.length).replace(/^_xlws\./, '') : name;
365
+ /** Whether a defined name is only Excel's wrapper for a modern function. */
366
+ export const isModernFunctionName = (name) => name.startsWith('_xlfn.');
367
+ function offsetCell(row, col, ctx) {
368
+ const rowRel = (col & 0x8000) !== 0;
369
+ const colRel = (col & 0x4000) !== 0;
370
+ const here = rowRel ? ctx.row + signed16(row) : row;
371
+ const there = colRel ? ctx.col + signed8(col & 0xff) : col & 0x3fff;
372
+ return here < 0 || there < 0 ? null : cellText(here, there, rowRel, colRel);
373
+ }
374
+ /** The last `count` values, in the order they were written. */
375
+ function takeArgs(stack, count) {
376
+ if (stack.length < count)
377
+ return null;
378
+ const args = stack.splice(stack.length - count, count).map((p) => p.text);
379
+ return args;
380
+ }
381
+ /** A string token: a length byte, a flag byte, then the characters. */
382
+ function shortString(bytes, at) {
383
+ const count = bytes[at];
384
+ const flags = bytes[at + 1];
385
+ if (count === undefined || flags === undefined)
386
+ return null;
387
+ const wide = (flags & 0x01) !== 0;
388
+ let text = '';
389
+ let cursor = at + 2;
390
+ for (let i = 0; i < count; i += 1) {
391
+ if (wide) {
392
+ text += String.fromCharCode(bytes[cursor] | (bytes[cursor + 1] << 8));
393
+ cursor += 2;
394
+ }
395
+ else {
396
+ text += String.fromCharCode(bytes[cursor]);
397
+ cursor += 1;
398
+ }
399
+ }
400
+ return { text, next: cursor };
401
+ }
402
+ class Bytes {
403
+ constructor() {
404
+ this.data = [];
405
+ }
406
+ byte(v) { this.data.push(v & 0xff); }
407
+ word(v) { this.data.push(v & 0xff, (v >> 8) & 0xff); }
408
+ double(v) {
409
+ const buffer = new DataView(new ArrayBuffer(8));
410
+ buffer.setFloat64(0, v, true);
411
+ for (let i = 0; i < 8; i += 1)
412
+ this.data.push(buffer.getUint8(i));
413
+ }
414
+ push(...values) { for (const v of values)
415
+ this.data.push(v & 0xff); }
416
+ get length() { return this.data.length; }
417
+ toBytes() { return Uint8Array.from(this.data); }
418
+ }
419
+ /** The RPN for a formula, or null when something in it BIFF8 cannot say. */
420
+ export function rpnFromFormula(text, ctx) {
421
+ let node;
422
+ try {
423
+ node = parseFormula(text.startsWith('=') ? text.slice(1) : text);
424
+ }
425
+ catch {
426
+ return null;
427
+ }
428
+ const out = new Bytes();
429
+ return emit(node, out, ctx) ? out.toBytes() : null;
430
+ }
431
+ const OPERATOR_TOKENS = {
432
+ '+': 0x03, '-': 0x04, '*': 0x05, '/': 0x06, '^': 0x07, '&': 0x08,
433
+ '<': 0x09, '<=': 0x0a, '=': 0x0b, '>=': 0x0c, '>': 0x0d, '<>': 0x0e,
434
+ };
435
+ /** The row and column words of a reference, flags and all. */
436
+ function refWords(out, row, col, rowAbs, colAbs) {
437
+ out.word(row);
438
+ out.word((col & 0x3fff) | (rowAbs ? 0 : 0x8000) | (colAbs ? 0 : 0x4000));
439
+ }
440
+ /** The last row of a sheet in Excel 97-2003, which is where a whole-column
441
+ * reference has to stop. */
442
+ const LAST_ROW = 65535;
443
+ const LAST_COL = 255;
444
+ function emit(node, out, ctx) {
445
+ switch (node.k) {
446
+ case 'num':
447
+ // A small whole number has a token of its own, two bytes instead of eight.
448
+ if (Number.isInteger(node.v) && node.v >= 0 && node.v <= 0xffff) {
449
+ out.byte(0x1e);
450
+ out.word(node.v);
451
+ }
452
+ else {
453
+ out.byte(0x1f);
454
+ out.double(node.v);
455
+ }
456
+ return true;
457
+ case 'str': {
458
+ if (node.v.length > 255)
459
+ return false;
460
+ out.byte(0x17);
461
+ out.byte(node.v.length);
462
+ out.byte(0x01);
463
+ for (const ch of node.v)
464
+ out.word(ch.charCodeAt(0));
465
+ return true;
466
+ }
467
+ case 'bool':
468
+ out.byte(0x1d);
469
+ out.byte(node.v ? 1 : 0);
470
+ return true;
471
+ case 'err':
472
+ out.byte(0x1c);
473
+ out.byte(xlsErrorCode(node.v));
474
+ return true;
475
+ case 'empty':
476
+ out.byte(0x16);
477
+ return true;
478
+ case 'ref': {
479
+ const row = node.ref.row ?? 0;
480
+ if (node.ref.col > LAST_COL || row > LAST_ROW)
481
+ return false;
482
+ if (node.ref.sheet) {
483
+ out.byte(0x7a);
484
+ out.word(ctx.sheetRef(node.ref.sheet));
485
+ }
486
+ else {
487
+ out.byte(0x44);
488
+ }
489
+ refWords(out, row, node.ref.col, node.ref.rowAbs, node.ref.colAbs);
490
+ return true;
491
+ }
492
+ case 'range': {
493
+ const { from, to } = node;
494
+ if (from.col > LAST_COL || to.col > LAST_COL)
495
+ return false;
496
+ const r1 = from.row ?? 0;
497
+ const r2 = to.row ?? LAST_ROW;
498
+ if (r1 > LAST_ROW || r2 > LAST_ROW)
499
+ return false;
500
+ const sheet = from.sheet ?? to.sheet;
501
+ if (sheet) {
502
+ out.byte(0x7b);
503
+ out.word(ctx.sheetRef(sheet));
504
+ }
505
+ else {
506
+ out.byte(0x45);
507
+ }
508
+ out.word(r1);
509
+ out.word(r2);
510
+ out.word((from.col & 0x3fff) | (from.rowAbs ? 0 : 0x8000) | (from.colAbs ? 0 : 0x4000));
511
+ out.word((to.col & 0x3fff) | (to.rowAbs ? 0 : 0x8000) | (to.colAbs ? 0 : 0x4000));
512
+ return true;
513
+ }
514
+ case 'name': {
515
+ const index = ctx.nameRef(node.name);
516
+ if (index === null)
517
+ return false;
518
+ out.byte(0x43);
519
+ out.word(index);
520
+ out.word(0);
521
+ return true;
522
+ }
523
+ case 'unary':
524
+ if (node.op === '%') {
525
+ if (!emit(node.arg, out, ctx))
526
+ return false;
527
+ out.byte(0x14);
528
+ return true;
529
+ }
530
+ if (!emit(node.arg, out, ctx))
531
+ return false;
532
+ out.byte(node.op === '-' ? 0x13 : 0x12);
533
+ return true;
534
+ case 'binary':
535
+ if (!emit(node.left, out, ctx))
536
+ return false;
537
+ if (!emit(node.right, out, ctx))
538
+ return false;
539
+ out.byte(OPERATOR_TOKENS[node.op]);
540
+ return true;
541
+ case 'fn': {
542
+ const found = xlsFunction(node.name);
543
+ if (!found)
544
+ return false;
545
+ const [id, args] = found;
546
+ if (node.args.length > 0x7f)
547
+ return false;
548
+ for (const arg of node.args)
549
+ if (!emit(arg, out, ctx))
550
+ return false;
551
+ if (args >= 0) {
552
+ if (node.args.length !== args)
553
+ return false;
554
+ out.byte(0x41);
555
+ out.word(id);
556
+ }
557
+ else {
558
+ out.byte(0x42);
559
+ out.byte(node.args.length);
560
+ out.word(id);
561
+ }
562
+ return true;
563
+ }
564
+ // A table reference means nothing in a file this old, and neither an
565
+ // array constant nor a spill has a token: the cell keeps its value.
566
+ default:
567
+ return false;
568
+ }
569
+ }