@svgrid/enterprise 3.0.1 → 3.0.3

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 (445) 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 +680 -0
  10. package/dist/SvFormulaBar.svelte.d.ts +69 -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 +263 -54
  18. package/dist/SvPivotDesigner.svelte.d.ts +27 -20
  19. package/dist/SvRibbonIcon.svelte +46 -0
  20. package/dist/SvRibbonIcon.svelte.d.ts +17 -0
  21. package/dist/SvSchemaChart.svelte +4 -2
  22. package/dist/SvSheet.svelte +7914 -0
  23. package/dist/SvSheet.svelte.d.ts +215 -0
  24. package/dist/SvSheetChartSetup.svelte +151 -0
  25. package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
  26. package/dist/SvSheetComment.svelte +283 -0
  27. package/dist/SvSheetComment.svelte.d.ts +22 -0
  28. package/dist/SvSheetConditionalFormat.svelte +159 -0
  29. package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
  30. package/dist/SvSheetDataValidation.svelte +273 -0
  31. package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
  32. package/dist/SvSheetEditRanges.svelte +217 -0
  33. package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
  34. package/dist/SvSheetErrors.svelte +125 -0
  35. package/dist/SvSheetErrors.svelte.d.ts +20 -0
  36. package/dist/SvSheetEvaluate.svelte +133 -0
  37. package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
  38. package/dist/SvSheetFilterMenu.svelte +320 -0
  39. package/dist/SvSheetFilterMenu.svelte.d.ts +22 -0
  40. package/dist/SvSheetFindReplace.svelte +132 -0
  41. package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
  42. package/dist/SvSheetFormatCells.svelte +465 -0
  43. package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
  44. package/dist/SvSheetGoalSeek.svelte +145 -0
  45. package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
  46. package/dist/SvSheetInsertFunction.svelte +149 -0
  47. package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
  48. package/dist/SvSheetIteration.svelte +81 -0
  49. package/dist/SvSheetIteration.svelte.d.ts +10 -0
  50. package/dist/SvSheetLink.svelte +99 -0
  51. package/dist/SvSheetLink.svelte.d.ts +17 -0
  52. package/dist/SvSheetListPicker.svelte +91 -0
  53. package/dist/SvSheetListPicker.svelte.d.ts +10 -0
  54. package/dist/SvSheetManageRules.svelte +187 -0
  55. package/dist/SvSheetManageRules.svelte.d.ts +16 -0
  56. package/dist/SvSheetNameManager.svelte +227 -0
  57. package/dist/SvSheetNameManager.svelte.d.ts +11 -0
  58. package/dist/SvSheetPageSetup.svelte +159 -0
  59. package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
  60. package/dist/SvSheetPasteSpecial.svelte +107 -0
  61. package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
  62. package/dist/SvSheetPivot.svelte +220 -0
  63. package/dist/SvSheetPivot.svelte.d.ts +21 -0
  64. package/dist/SvSheetProtectSheet.svelte +81 -0
  65. package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
  66. package/dist/SvSheetRemoveDuplicates.svelte +152 -0
  67. package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
  68. package/dist/SvSheetRibbon.svelte +1254 -0
  69. package/dist/SvSheetRibbon.svelte.d.ts +34 -0
  70. package/dist/SvSheetSizeDialog.svelte +60 -0
  71. package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
  72. package/dist/SvSheetSort.svelte +218 -0
  73. package/dist/SvSheetSort.svelte.d.ts +28 -0
  74. package/dist/SvSheetSparklines.svelte +135 -0
  75. package/dist/SvSheetSparklines.svelte.d.ts +14 -0
  76. package/dist/SvSheetTable.svelte +160 -0
  77. package/dist/SvSheetTable.svelte.d.ts +24 -0
  78. package/dist/SvSheetTabs.svelte +571 -0
  79. package/dist/SvSheetTabs.svelte.d.ts +50 -0
  80. package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
  81. package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
  82. package/dist/SvSheetTextToColumns.svelte +172 -0
  83. package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
  84. package/dist/SvSheetValidationAlert.svelte +85 -0
  85. package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
  86. package/dist/advanced-filter-enable.js +1 -1
  87. package/dist/alerts/alert-engine.d.ts +6 -0
  88. package/dist/alerts/alert-engine.js +21 -4
  89. package/dist/alerts/alert-formats.js +2 -0
  90. package/dist/alerts/alert-types.d.ts +1 -1
  91. package/dist/alerts.d.ts +1 -1
  92. package/dist/alerts.js +2 -2
  93. package/dist/board.js +2 -2
  94. package/dist/bulk-edit.d.ts +3 -1
  95. package/dist/bulk-edit.js +1 -1
  96. package/dist/cdn/svgrid-enterprise.svelte-external.js +43538 -6539
  97. package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
  98. package/dist/designer/assets/SvChartMenu-BDoeqGz6.js +1 -0
  99. package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
  100. package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
  101. package/dist/designer/assets/SvDateTimePicker-DCPg7WGN.js +1 -0
  102. package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
  103. package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
  104. package/dist/designer/assets/SvGridChart-Cy1ATrWh.js +3 -0
  105. package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
  106. package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
  107. package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
  108. package/dist/designer/assets/SvGridChartPanel-CATdVc9X.js +4 -0
  109. package/dist/designer/assets/{SvGridChartView-DUc-1RUf.css → SvGridChartView-7msfnWZT.css} +1 -1
  110. package/dist/designer/assets/SvGridChartView-CmsZtCED.js +1 -0
  111. package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
  112. package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
  113. package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
  114. package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
  115. package/dist/designer/assets/SvTabs-2mHC6oaz.js +1 -0
  116. package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
  117. package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
  118. package/dist/designer/assets/chart-Cn7MnNqA.js +1 -0
  119. package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
  120. package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
  121. package/dist/designer/assets/chart-panel-messages-Dz7PTIqT.js +1 -0
  122. package/dist/designer/assets/chart-summary-BD1qYB2R.js +1 -0
  123. package/dist/designer/assets/chart-trend-B8xr5LuD.js +1 -0
  124. package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
  125. package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
  126. package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
  127. package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
  128. package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
  129. package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
  130. package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
  131. package/dist/designer/assets/focus-trap-V2-6Fy9I.js +1 -0
  132. package/dist/designer/assets/{index-C_a9Cj8Y.js → index-D5bVbuzI.js} +318 -315
  133. package/dist/designer/assets/index-_JVFxt02.css +1 -0
  134. package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
  135. package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
  136. package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
  137. package/dist/designer/assets/src-CITpcm6b.js +1 -0
  138. package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
  139. package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
  140. package/dist/designer/index.html +29 -19
  141. package/dist/export-pdf.d.ts +164 -0
  142. package/dist/export-pdf.js +346 -15
  143. package/dist/export.js +25 -10
  144. package/dist/gantt/SvGridGantt.svelte +2890 -0
  145. package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
  146. package/dist/gantt/gantt-config.d.ts +73 -0
  147. package/dist/gantt/gantt-config.js +1 -0
  148. package/dist/gantt/gantt-critical-path.d.ts +67 -0
  149. package/dist/gantt/gantt-critical-path.js +207 -0
  150. package/dist/gantt/gantt-model.d.ts +257 -0
  151. package/dist/gantt/gantt-model.js +651 -0
  152. package/dist/gantt/gantt-resources.d.ts +59 -0
  153. package/dist/gantt/gantt-resources.js +71 -0
  154. package/dist/gantt/gantt.d.ts +7 -0
  155. package/dist/gantt/gantt.js +36 -0
  156. package/dist/gantt/index.d.ts +15 -0
  157. package/dist/gantt/index.js +22 -0
  158. package/dist/gantt/timeline-arrows.d.ts +102 -0
  159. package/dist/gantt/timeline-arrows.js +181 -0
  160. package/dist/import.d.ts +2 -2
  161. package/dist/import.js +1 -1
  162. package/dist/index.d.ts +93 -3
  163. package/dist/index.js +107 -3
  164. package/dist/install.js +13 -1
  165. package/dist/license-core.d.ts +17 -1
  166. package/dist/license-core.js +16 -5
  167. package/dist/license.d.ts +18 -2
  168. package/dist/license.js +71 -6
  169. package/dist/node/studio.js +203 -9
  170. package/dist/pivot-chart.d.ts +25 -1
  171. package/dist/pivot-chart.js +25 -69
  172. package/dist/pivot-enable.js +2 -2
  173. package/dist/scheduler-dependencies.d.ts +35 -0
  174. package/dist/scheduler-dependencies.js +36 -1
  175. package/dist/scheduler.js +2 -2
  176. package/dist/selection-bar.js +2 -2
  177. package/dist/server/SvGroupCell.svelte +213 -0
  178. package/dist/server/SvGroupCell.svelte.d.ts +62 -0
  179. package/dist/server/SvRowGroupPanel.svelte +322 -0
  180. package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
  181. package/dist/server/enable.d.ts +17 -0
  182. package/dist/server/enable.js +49 -0
  183. package/dist/server/index.d.ts +22 -0
  184. package/dist/server/index.js +24 -0
  185. package/dist/server/messages.d.ts +45 -0
  186. package/dist/server/messages.js +35 -0
  187. package/dist/server/server-group-model.d.ts +104 -0
  188. package/dist/server/server-group-model.js +272 -0
  189. package/dist/server/server-pivot.d.ts +46 -0
  190. package/dist/server/server-pivot.js +57 -0
  191. package/dist/server/server-row-model.d.ts +547 -0
  192. package/dist/server/server-row-model.js +1551 -0
  193. package/dist/server/server-selection.d.ts +99 -0
  194. package/dist/server/server-selection.js +215 -0
  195. package/dist/server/svgrid-adapter.d.ts +155 -0
  196. package/dist/server/svgrid-adapter.js +202 -0
  197. package/dist/sheet/address.d.ts +43 -0
  198. package/dist/sheet/address.js +81 -0
  199. package/dist/sheet/ast.d.ts +138 -0
  200. package/dist/sheet/ast.js +70 -0
  201. package/dist/sheet/auto-filter.d.ts +120 -0
  202. package/dist/sheet/auto-filter.js +295 -0
  203. package/dist/sheet/autocomplete.d.ts +51 -0
  204. package/dist/sheet/autocomplete.js +248 -0
  205. package/dist/sheet/cell-images.d.ts +39 -0
  206. package/dist/sheet/cell-images.js +90 -0
  207. package/dist/sheet/cell-types.d.ts +58 -0
  208. package/dist/sheet/cell-types.js +96 -0
  209. package/dist/sheet/coerce.d.ts +71 -0
  210. package/dist/sheet/coerce.js +289 -0
  211. package/dist/sheet/commands.d.ts +89 -0
  212. package/dist/sheet/commands.js +230 -0
  213. package/dist/sheet/comments.d.ts +63 -0
  214. package/dist/sheet/comments.js +131 -0
  215. package/dist/sheet/conditional-formats.d.ts +167 -0
  216. package/dist/sheet/conditional-formats.js +341 -0
  217. package/dist/sheet/csv.d.ts +32 -0
  218. package/dist/sheet/csv.js +158 -0
  219. package/dist/sheet/culture.d.ts +87 -0
  220. package/dist/sheet/culture.js +247 -0
  221. package/dist/sheet/delta.d.ts +102 -0
  222. package/dist/sheet/delta.js +203 -0
  223. package/dist/sheet/deps.d.ts +104 -0
  224. package/dist/sheet/deps.js +274 -0
  225. package/dist/sheet/document.d.ts +252 -0
  226. package/dist/sheet/document.js +465 -0
  227. package/dist/sheet/edit-keys.d.ts +14 -0
  228. package/dist/sheet/edit-keys.js +40 -0
  229. package/dist/sheet/engine.d.ts +67 -0
  230. package/dist/sheet/engine.js +19 -0
  231. package/dist/sheet/entry.d.ts +35 -0
  232. package/dist/sheet/entry.js +226 -0
  233. package/dist/sheet/error-check.d.ts +49 -0
  234. package/dist/sheet/error-check.js +83 -0
  235. package/dist/sheet/evaluate-steps.d.ts +48 -0
  236. package/dist/sheet/evaluate-steps.js +196 -0
  237. package/dist/sheet/evaluate.d.ts +128 -0
  238. package/dist/sheet/evaluate.js +1049 -0
  239. package/dist/sheet/filter-files.d.ts +37 -0
  240. package/dist/sheet/filter-files.js +465 -0
  241. package/dist/sheet/find-replace.d.ts +62 -0
  242. package/dist/sheet/find-replace.js +152 -0
  243. package/dist/sheet/format-store.d.ts +114 -0
  244. package/dist/sheet/format-store.js +243 -0
  245. package/dist/sheet/freeze.d.ts +54 -0
  246. package/dist/sheet/freeze.js +58 -0
  247. package/dist/sheet/from-rows.d.ts +14 -0
  248. package/dist/sheet/from-rows.js +50 -0
  249. package/dist/sheet/function-catalog.d.ts +10 -0
  250. package/dist/sheet/function-catalog.js +385 -0
  251. package/dist/sheet/functions.d.ts +28 -0
  252. package/dist/sheet/functions.js +634 -0
  253. package/dist/sheet/goal-seek.d.ts +73 -0
  254. package/dist/sheet/goal-seek.js +153 -0
  255. package/dist/sheet/index.d.ts +80 -0
  256. package/dist/sheet/index.js +80 -0
  257. package/dist/sheet/links.d.ts +57 -0
  258. package/dist/sheet/links.js +174 -0
  259. package/dist/sheet/merges.d.ts +71 -0
  260. package/dist/sheet/merges.js +137 -0
  261. package/dist/sheet/messages.d.ts +778 -0
  262. package/dist/sheet/messages.js +806 -0
  263. package/dist/sheet/names.d.ts +31 -0
  264. package/dist/sheet/names.js +87 -0
  265. package/dist/sheet/navigate.d.ts +52 -0
  266. package/dist/sheet/navigate.js +135 -0
  267. package/dist/sheet/number-format.d.ts +110 -0
  268. package/dist/sheet/number-format.js +905 -0
  269. package/dist/sheet/objects.d.ts +106 -0
  270. package/dist/sheet/objects.js +149 -0
  271. package/dist/sheet/ods-document.d.ts +44 -0
  272. package/dist/sheet/ods-document.js +1275 -0
  273. package/dist/sheet/open-file.d.ts +26 -0
  274. package/dist/sheet/open-file.js +56 -0
  275. package/dist/sheet/outline.d.ts +82 -0
  276. package/dist/sheet/outline.js +228 -0
  277. package/dist/sheet/packs/array.d.ts +16 -0
  278. package/dist/sheet/packs/array.js +172 -0
  279. package/dist/sheet/packs/database.d.ts +42 -0
  280. package/dist/sheet/packs/database.js +142 -0
  281. package/dist/sheet/packs/engineering.d.ts +2 -0
  282. package/dist/sheet/packs/engineering.js +296 -0
  283. package/dist/sheet/packs/financial.d.ts +5 -0
  284. package/dist/sheet/packs/financial.js +220 -0
  285. package/dist/sheet/packs/math-stats.d.ts +2 -0
  286. package/dist/sheet/packs/math-stats.js +372 -0
  287. package/dist/sheet/packs/special.d.ts +44 -0
  288. package/dist/sheet/packs/special.js +187 -0
  289. package/dist/sheet/packs/stats-dist.d.ts +2 -0
  290. package/dist/sheet/packs/stats-dist.js +785 -0
  291. package/dist/sheet/packs/text-date.d.ts +2 -0
  292. package/dist/sheet/packs/text-date.js +332 -0
  293. package/dist/sheet/packs/trig.d.ts +2 -0
  294. package/dist/sheet/packs/trig.js +73 -0
  295. package/dist/sheet/page-setup.d.ts +73 -0
  296. package/dist/sheet/page-setup.js +73 -0
  297. package/dist/sheet/palette.d.ts +19 -0
  298. package/dist/sheet/palette.js +84 -0
  299. package/dist/sheet/parse.d.ts +13 -0
  300. package/dist/sheet/parse.js +140 -0
  301. package/dist/sheet/paste-special.d.ts +186 -0
  302. package/dist/sheet/paste-special.js +601 -0
  303. package/dist/sheet/pivot-range.d.ts +160 -0
  304. package/dist/sheet/pivot-range.js +333 -0
  305. package/dist/sheet/presence.d.ts +73 -0
  306. package/dist/sheet/presence.js +79 -0
  307. package/dist/sheet/print.d.ts +104 -0
  308. package/dist/sheet/print.js +169 -0
  309. package/dist/sheet/protection.d.ts +75 -0
  310. package/dist/sheet/protection.js +101 -0
  311. package/dist/sheet/rects.d.ts +45 -0
  312. package/dist/sheet/rects.js +112 -0
  313. package/dist/sheet/refs.d.ts +130 -0
  314. package/dist/sheet/refs.js +413 -0
  315. package/dist/sheet/ribbon-icons.d.ts +31 -0
  316. package/dist/sheet/ribbon-icons.js +536 -0
  317. package/dist/sheet/ribbon.d.ts +173 -0
  318. package/dist/sheet/ribbon.js +1054 -0
  319. package/dist/sheet/sheet-kinds.d.ts +74 -0
  320. package/dist/sheet/sheet-kinds.js +91 -0
  321. package/dist/sheet/shortcuts.d.ts +174 -0
  322. package/dist/sheet/shortcuts.js +674 -0
  323. package/dist/sheet/sort.d.ts +51 -0
  324. package/dist/sheet/sort.js +107 -0
  325. package/dist/sheet/sparklines.d.ts +111 -0
  326. package/dist/sheet/sparklines.js +204 -0
  327. package/dist/sheet/structure.d.ts +87 -0
  328. package/dist/sheet/structure.js +166 -0
  329. package/dist/sheet/table-styles.d.ts +74 -0
  330. package/dist/sheet/table-styles.js +152 -0
  331. package/dist/sheet/tables.d.ts +89 -0
  332. package/dist/sheet/tables.js +178 -0
  333. package/dist/sheet/tokenize.d.ts +71 -0
  334. package/dist/sheet/tokenize.js +355 -0
  335. package/dist/sheet/transforms.d.ts +76 -0
  336. package/dist/sheet/transforms.js +154 -0
  337. package/dist/sheet/validation.d.ts +108 -0
  338. package/dist/sheet/validation.js +278 -0
  339. package/dist/sheet/workbook.d.ts +217 -0
  340. package/dist/sheet/workbook.js +1120 -0
  341. package/dist/sheet/xls-cfb.d.ts +32 -0
  342. package/dist/sheet/xls-cfb.js +290 -0
  343. package/dist/sheet/xls-document.d.ts +10 -0
  344. package/dist/sheet/xls-document.js +1243 -0
  345. package/dist/sheet/xls-formula.d.ts +40 -0
  346. package/dist/sheet/xls-formula.js +569 -0
  347. package/dist/sheet/xlsx-document.d.ts +108 -0
  348. package/dist/sheet/xlsx-document.js +1849 -0
  349. package/dist/sheet/xlsx-drawing.d.ts +99 -0
  350. package/dist/sheet/xlsx-drawing.js +420 -0
  351. package/dist/sheet-enable.d.ts +6 -0
  352. package/dist/sheet-enable.js +45 -0
  353. package/dist/sheet-text.d.ts +7 -0
  354. package/dist/sheet-text.js +29 -0
  355. package/dist/sources/auth-supabase.js +2 -2
  356. package/dist/sources/realtime-supabase.js +2 -2
  357. package/dist/sources/rest.d.ts +6 -2
  358. package/dist/sources/rest.js +42 -7
  359. package/dist/sources/supabase.d.ts +10 -1
  360. package/dist/sources/supabase.js +73 -40
  361. package/dist/studio/emit-project.js +14 -1
  362. package/dist/studio/index.js +1 -1
  363. package/dist/studio/project.d.ts +11 -2
  364. package/dist/studio/project.js +5 -2
  365. package/dist/studio/ui-components.generated.js +170 -3
  366. package/dist/sveltekit/in-memory.d.ts +2 -2
  367. package/dist/sveltekit/in-memory.js +125 -4
  368. package/dist/sveltekit/index.d.ts +1 -1
  369. package/dist/sveltekit/index.js +1 -1
  370. package/dist/sveltekit/query-plan.d.ts +50 -4
  371. package/dist/sveltekit/query-plan.js +25 -3
  372. package/dist/sveltekit/sql-source.d.ts +6 -0
  373. package/dist/sveltekit/sql-source.js +34 -6
  374. package/dist/sveltekit/sql.d.ts +31 -0
  375. package/dist/sveltekit/sql.js +135 -25
  376. package/dist/sveltekit/transport.d.ts +10 -2
  377. package/dist/sveltekit/transport.js +30 -6
  378. package/dist/upgrade-prompt.d.ts +1 -1
  379. package/dist/version.d.ts +1 -1
  380. package/dist/version.js +1 -1
  381. package/dist/watermark.js +35 -2
  382. package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
  383. package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
  384. package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
  385. package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
  386. package/dist/wc/SvField-B_kurx_P.js +149 -0
  387. package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
  388. package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
  389. package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
  390. package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
  391. package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
  392. package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
  393. package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
  394. package/dist/wc/SvModal-DrfOYYyX.js +189 -0
  395. package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
  396. package/dist/wc/chart-6OXlybVT.js +4341 -0
  397. package/dist/wc/chart-export-CeSADGfi.js +135 -0
  398. package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
  399. package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
  400. package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
  401. package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
  402. package/dist/wc/client-DQIzjDBG.js +3064 -0
  403. package/dist/wc/column-resize-DUPgynvc.js +101 -0
  404. package/dist/wc/date-format-DS-z_h9v.js +1130 -0
  405. package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
  406. package/dist/wc/editor-contract-peBDxir_.js +22 -0
  407. package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
  408. package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
  409. package/dist/wc/list-option-DrRyivWp.js +82 -0
  410. package/dist/wc/popover-WsGlvtQv.js +69 -0
  411. package/dist/wc/positioning-BiKLfu1E.js +112 -0
  412. package/dist/wc/react.d.ts +41 -0
  413. package/dist/wc/react.js +90 -0
  414. package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
  415. package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
  416. package/dist/wc/row-resize-limG_N1z.js +111 -0
  417. package/dist/wc/sv-sheet-element.d.ts +97 -0
  418. package/dist/wc/sv-sheet-element.js +44213 -0
  419. package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
  420. package/dist/wc/validate-BqDthkNr.js +88 -0
  421. package/dist/wc/vue.d.ts +31 -0
  422. package/dist/wc/vue.js +75 -0
  423. package/package.json +36 -6
  424. package/dist/designer/assets/GridMenus-B1JtIN21.js +0 -8
  425. package/dist/designer/assets/SvDateRangeInput-CjO7nn_x.js +0 -1
  426. package/dist/designer/assets/SvDateTimePicker-ByBD_ov6.js +0 -1
  427. package/dist/designer/assets/SvField-YDLipR6O.css +0 -1
  428. package/dist/designer/assets/SvField-cj1PFNgZ.js +0 -1
  429. package/dist/designer/assets/SvGridCellEditor-0W1L2hJ1.js +0 -2
  430. package/dist/designer/assets/SvGridChart-DBOR4xcz.js +0 -2
  431. package/dist/designer/assets/SvGridChart-fkMWeh1J.css +0 -1
  432. package/dist/designer/assets/SvGridChartPanel-symrhNnR.js +0 -11
  433. package/dist/designer/assets/SvGridChartView-BmRxq6mU.js +0 -1
  434. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
  435. package/dist/designer/assets/SvListBox-1oUF6Iav.js +0 -110
  436. package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
  437. package/dist/designer/assets/chart-DXFganU8.js +0 -1
  438. package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
  439. package/dist/designer/assets/date-format-DGagAqRc.css +0 -1
  440. package/dist/designer/assets/date-format-onlYDsrY.js +0 -1
  441. package/dist/designer/assets/easing-zaypKrr0.js +0 -3
  442. package/dist/designer/assets/index-k2stW6L8.css +0 -1
  443. package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
  444. package/dist/designer/assets/src-D9p27OGC.js +0 -58
  445. package/dist/designer/assets/validate-h-aslRV9.js +0 -1
@@ -0,0 +1,634 @@
1
+ /**
2
+ * The function table.
3
+ *
4
+ * Each entry receives its arguments already evaluated, in two shapes:
5
+ * - `flat` every argument flattened into one list, ranges expanded. What
6
+ * SUM and COUNT want.
7
+ * - `args` one list per argument, so a function can tell `SUM(A1:A3, 5)`
8
+ * from `SUM(A1:A3)` and `SUMIF` can line a range up against a
9
+ * parallel one.
10
+ * - `grids` the 2-D shape of any range argument, kept for VLOOKUP / INDEX /
11
+ * MATCH, which lose meaning once flattened.
12
+ *
13
+ * Functions that must NOT evaluate every argument (IF, IFERROR, AND, OR with
14
+ * short-circuit semantics) are handled in the evaluator instead, because by the
15
+ * time a table entry runs, evaluation has already happened.
16
+ */
17
+ import { isError, err } from './ast.js';
18
+ import { toNumber, toBool, toText, looseEquals, compare, patternEquals, hasWildcards, wildcardRegExp, unescapeWildcards, numericOnly, isBlank, toDate, isoDate as iso, criteriaHits, multiCriteriaHits, criteriaPairs, } from './coerce.js';
19
+ import { formatWithPattern } from './number-format.js';
20
+ import { FINANCIAL_FUNCTIONS } from './packs/financial.js';
21
+ import { MATH_STATS_FUNCTIONS } from './packs/math-stats.js';
22
+ import { TEXT_DATE_FUNCTIONS } from './packs/text-date.js';
23
+ import { TRIG_FUNCTIONS } from './packs/trig.js';
24
+ import { ENGINEERING_FUNCTIONS } from './packs/engineering.js';
25
+ import { DATABASE_FUNCTIONS } from './packs/database.js';
26
+ import { STATS_DIST_FUNCTIONS } from './packs/stats-dist.js';
27
+ const first = (a) => a.flat[0] ?? '';
28
+ const nth = (a, i) => a.args[i]?.[0] ?? '';
29
+ function sum(values) {
30
+ return numericOnly(values).reduce((x, y) => x + y, 0);
31
+ }
32
+ function average(values) {
33
+ const ns = numericOnly(values);
34
+ if (ns.length === 0)
35
+ return err('#DIV/0!');
36
+ return ns.reduce((x, y) => x + y, 0) / ns.length;
37
+ }
38
+ function roundTo(value, digits) {
39
+ const f = Math.pow(10, digits);
40
+ // Scale, round, unscale. The epsilon nudge keeps 1.005 -> 1.01 rather than
41
+ // 1.00, which is the binary-float surprise users report as a bug.
42
+ return Math.round((value * f) * (1 + Number.EPSILON)) / f;
43
+ }
44
+ /**
45
+ * Excel's approximate match, which is what the lookup family does when it
46
+ * cannot find the value itself. The column is taken as sorted, and the answer
47
+ * is the entry NEAREST the needle on one side: `dir` 1 for the largest entry
48
+ * not past it (VLOOKUP / HLOOKUP with range_lookup TRUE, MATCH 1, XLOOKUP -1),
49
+ * -1 for the smallest entry not before it (MATCH -1, XLOOKUP 1).
50
+ *
51
+ * Only cells of the needle's own type take part, so the text header sitting
52
+ * above a numeric tier table cannot become the answer. Among equal entries the
53
+ * later one wins, as Excel's own search lands on the last of a run.
54
+ */
55
+ function nearestIndex(pool, needle, dir) {
56
+ let best = -1;
57
+ for (let i = 0; i < pool.length; i += 1) {
58
+ const v = pool[i];
59
+ if (v === undefined || v === '' || isError(v))
60
+ continue;
61
+ if (typeof v !== typeof needle)
62
+ continue;
63
+ const side = compare(v, needle);
64
+ if (dir === 1 ? side > 0 : side < 0)
65
+ continue;
66
+ if (best < 0 || compare(v, pool[best]) * dir >= 0)
67
+ best = i;
68
+ }
69
+ return best;
70
+ }
71
+ /** FIND and SEARCH count their optional start from 1; -1 says the argument
72
+ * is out of range, which Excel reports as #VALUE!. */
73
+ function startPosition(a) {
74
+ if (a.args[2] === undefined)
75
+ return 0;
76
+ const given = Math.trunc(toNumber(nth(a, 2)));
77
+ return given < 1 ? -1 : given - 1;
78
+ }
79
+ /** The index of the `instance`-th `delim` in `s`, counted from the start for
80
+ * a positive instance and from the end for a negative one, or null when
81
+ * there are fewer than that many. Backs TEXTBEFORE and TEXTAFTER. */
82
+ function nthDelimiter(s, delim, instance) {
83
+ const positions = [];
84
+ for (let from = 0;;) {
85
+ const at = s.indexOf(delim, from);
86
+ if (at < 0)
87
+ break;
88
+ positions.push(at);
89
+ from = at + delim.length;
90
+ }
91
+ if (instance > 0)
92
+ return instance <= positions.length ? positions[instance - 1] : null;
93
+ if (instance < 0) {
94
+ const k = positions.length + instance;
95
+ return k >= 0 ? positions[k] : null;
96
+ }
97
+ return null;
98
+ }
99
+ /** Where a wildcard pattern starts inside a text, or -1. Excel reports the
100
+ * earliest position a match can begin at, so the search walks forward and
101
+ * tries every ending from the shortest up. */
102
+ function wildcardSearch(text, pattern, from = 0) {
103
+ const re = wildcardRegExp(pattern);
104
+ for (let start = from; start <= text.length; start += 1) {
105
+ for (let end = start; end <= text.length; end += 1) {
106
+ if (re.test(text.slice(start, end)))
107
+ return start;
108
+ }
109
+ }
110
+ return -1;
111
+ }
112
+ export const FUNCTIONS = {
113
+ // ---- Math and aggregation -------------------------------------------
114
+ SUM: (a) => sum(a.flat),
115
+ AVERAGE: (a) => average(a.flat),
116
+ AVG: (a) => average(a.flat),
117
+ MIN: (a) => { const n = numericOnly(a.flat); return n.length ? Math.min(...n) : 0; },
118
+ MAX: (a) => { const n = numericOnly(a.flat); return n.length ? Math.max(...n) : 0; },
119
+ COUNT: (a) => a.flat.filter((v) => typeof v === 'number').length,
120
+ COUNTA: (a) => a.flat.filter((v) => !isBlank(v)).length,
121
+ COUNTBLANK: (a) => a.flat.filter((v) => isBlank(v)).length,
122
+ ABS: (a) => Math.abs(toNumber(first(a))),
123
+ INT: (a) => Math.floor(toNumber(first(a))),
124
+ MOD: (a) => {
125
+ const d = toNumber(nth(a, 1));
126
+ if (d === 0)
127
+ return err('#DIV/0!');
128
+ // Excel's MOD follows the sign of the divisor, unlike JavaScript's %.
129
+ const n = toNumber(nth(a, 0));
130
+ return n - d * Math.floor(n / d);
131
+ },
132
+ POWER: (a) => {
133
+ // The cube root of a negative is NaN in JavaScript and #NUM! in Excel;
134
+ // letting NaN out reaches the sheet as a blank, which says nothing.
135
+ const out = Math.pow(toNumber(nth(a, 0)), toNumber(nth(a, 1)));
136
+ return Number.isFinite(out) ? out : err('#NUM!');
137
+ },
138
+ /** Excel's NA(): the #N/A a lookup writes when it finds nothing. */
139
+ NA: () => err('#N/A'),
140
+ // Excel's TRUE() and FALSE(). Worth having for their own sake, and a file
141
+ // from LibreOffice writes every boolean cell as one of them.
142
+ TRUE: () => true,
143
+ FALSE: () => false,
144
+ SQRT: (a) => {
145
+ const n = toNumber(first(a));
146
+ return n < 0 ? err('#NUM!') : Math.sqrt(n);
147
+ },
148
+ ROUND: (a) => roundTo(toNumber(nth(a, 0)), Math.round(toNumber(nth(a, 1) || 0))),
149
+ ROUNDUP: (a) => {
150
+ const d = Math.round(toNumber(nth(a, 1) || 0));
151
+ const f = Math.pow(10, d);
152
+ const v = toNumber(nth(a, 0));
153
+ return (v < 0 ? -Math.ceil(-v * f) : Math.ceil(v * f)) / f;
154
+ },
155
+ ROUNDDOWN: (a) => {
156
+ const d = Math.round(toNumber(nth(a, 1) || 0));
157
+ const f = Math.pow(10, d);
158
+ const v = toNumber(nth(a, 0));
159
+ return (v < 0 ? -Math.floor(-v * f) : Math.floor(v * f)) / f;
160
+ },
161
+ MEDIAN: (a) => {
162
+ const n = numericOnly(a.flat).sort((x, y) => x - y);
163
+ if (!n.length)
164
+ return err('#NUM!');
165
+ const mid = Math.floor(n.length / 2);
166
+ return n.length % 2 ? n[mid] : (n[mid - 1] + n[mid]) / 2;
167
+ },
168
+ STDEV: (a) => {
169
+ const n = numericOnly(a.flat);
170
+ if (n.length < 2)
171
+ return err('#DIV/0!');
172
+ const mean = n.reduce((x, y) => x + y, 0) / n.length;
173
+ const variance = n.reduce((acc, v) => acc + (v - mean) ** 2, 0) / (n.length - 1);
174
+ return Math.sqrt(variance);
175
+ },
176
+ RANK: (a) => {
177
+ const value = toNumber(nth(a, 0));
178
+ const pool = numericOnly(a.args[1] ?? []);
179
+ const ascending = a.args[2] !== undefined && toBool(nth(a, 2));
180
+ const sorted = pool.slice().sort((x, y) => (ascending ? x - y : y - x));
181
+ const at = sorted.indexOf(value);
182
+ return at < 0 ? err('#N/A') : at + 1;
183
+ },
184
+ // ---- Conditional aggregation ----------------------------------------
185
+ SUMIF: (a) => {
186
+ const range = a.args[0] ?? [];
187
+ const hits = criteriaHits(range, nth(a, 1));
188
+ // The optional third argument is the range actually summed.
189
+ const target = a.args[2] ?? range;
190
+ return sum(hits.map((i) => target[i] ?? ''));
191
+ },
192
+ COUNTIF: (a) => criteriaHits(a.args[0] ?? [], nth(a, 1)).length,
193
+ AVERAGEIF: (a) => {
194
+ const range = a.args[0] ?? [];
195
+ const hits = criteriaHits(range, nth(a, 1));
196
+ const target = a.args[2] ?? range;
197
+ return average(hits.map((i) => target[i] ?? ''));
198
+ },
199
+ SUMIFS: (a) => {
200
+ const target = a.args[0] ?? [];
201
+ return sum(multiCriteriaHits(criteriaPairs(a.args, 1)).map((i) => target[i] ?? ''));
202
+ },
203
+ COUNTIFS: (a) => multiCriteriaHits(criteriaPairs(a.args, 0)).length,
204
+ // ---- Logical ---------------------------------------------------------
205
+ NOT: (a) => !toBool(first(a)),
206
+ AND: (a) => a.flat.every((v) => toBool(v)),
207
+ OR: (a) => a.flat.some((v) => toBool(v)),
208
+ XOR: (a) => a.flat.filter((v) => toBool(v)).length % 2 === 1,
209
+ // ---- Information -----------------------------------------------------
210
+ // What a value IS, not what it can be coerced to: "12" typed as text is
211
+ // text here, the way Excel answers, and a blank is neither.
212
+ ISNUMBER: (a) => typeof first(a) === 'number',
213
+ ISTEXT: (a) => typeof first(a) === 'string' && first(a) !== '',
214
+ ISLOGICAL: (a) => typeof first(a) === 'boolean',
215
+ ISBLANK: (a) => first(a) === '',
216
+ // ---- Text ------------------------------------------------------------
217
+ LEN: (a) => toText(first(a)).length,
218
+ LEFT: (a) => toText(nth(a, 0)).slice(0, Math.max(0, Math.round(toNumber(a.args[1] ? nth(a, 1) : 1)))),
219
+ RIGHT: (a) => {
220
+ const s = toText(nth(a, 0));
221
+ const n = Math.max(0, Math.round(toNumber(a.args[1] ? nth(a, 1) : 1)));
222
+ return n >= s.length ? s : s.slice(s.length - n);
223
+ },
224
+ MID: (a) => {
225
+ const s = toText(nth(a, 0));
226
+ const start = Math.round(toNumber(nth(a, 1)));
227
+ if (start < 1)
228
+ return err('#VALUE!');
229
+ return s.slice(start - 1, start - 1 + Math.max(0, Math.round(toNumber(nth(a, 2)))));
230
+ },
231
+ UPPER: (a) => toText(first(a)).toUpperCase(),
232
+ LOWER: (a) => toText(first(a)).toLowerCase(),
233
+ TRIM: (a) => toText(first(a)).trim().replace(/\s+/g, ' '),
234
+ // Excel's HYPERLINK shows the friendly name and follows the link. The
235
+ // shell reads the link off the cell (`sheet/links.ts`), which is where a
236
+ // link put there by Insert > Link lives too, so a cell is clickable
237
+ // whichever way its link arrived; the value here is only what it shows.
238
+ HYPERLINK: (a) => {
239
+ const target = toText(first(a));
240
+ const friendly = a.args.length > 1 ? nth(a, 1) : undefined;
241
+ return friendly === undefined || friendly === '' ? target : friendly;
242
+ },
243
+ /**
244
+ * IMAGE(source, [alt]): a picture IN the cell. The value is the source,
245
+ * so the formula reads like any other one and a cell that reads it gets
246
+ * an address rather than a picture it cannot use; the shell is what
247
+ * draws it, from the call it finds on the cell (`sheet/cell-images.ts`).
248
+ */
249
+ IMAGE: (a) => toText(first(a)),
250
+ CONCAT: (a) => a.flat.map((v) => toText(v)).join(''),
251
+ CONCATENATE: (a) => a.flat.map((v) => toText(v)).join(''),
252
+ TEXTJOIN: (a) => {
253
+ const sep = toText(nth(a, 0));
254
+ const skipEmpty = toBool(nth(a, 1));
255
+ const rest = a.args.slice(2).flat();
256
+ return rest.filter((v) => !skipEmpty || !isBlank(v)).map((v) => toText(v)).join(sep);
257
+ },
258
+ // SUBSTITUTE(text, old, new, [instance]): every occurrence by default, or
259
+ // just the instance-th one when the fourth argument names it, the way Excel
260
+ // rewrites the second slash of a date and leaves the first.
261
+ SUBSTITUTE: (a) => {
262
+ const s = toText(nth(a, 0));
263
+ const find = toText(nth(a, 1));
264
+ const replace = toText(nth(a, 2));
265
+ if (find === '')
266
+ return s;
267
+ if (a.args[3] === undefined)
268
+ return s.split(find).join(replace);
269
+ const instance = Math.trunc(toNumber(nth(a, 3)));
270
+ if (instance < 1)
271
+ return err('#VALUE!');
272
+ let count = 0;
273
+ let from = 0;
274
+ for (;;) {
275
+ const at = s.indexOf(find, from);
276
+ // Fewer than `instance` occurrences: Excel leaves the text as it is.
277
+ if (at < 0)
278
+ return s;
279
+ count += 1;
280
+ if (count === instance)
281
+ return s.slice(0, at) + replace + s.slice(at + find.length);
282
+ from = at + find.length;
283
+ }
284
+ },
285
+ // TEXTBEFORE / TEXTAFTER(text, delimiter, [instance]): the part before or
286
+ // after the instance-th delimiter, counted from the end when instance is
287
+ // negative. The delimiter that is not there is #N/A, unless a sixth
288
+ // `if_not_found` is given.
289
+ TEXTBEFORE: (a) => {
290
+ const s = toText(nth(a, 0));
291
+ const delim = toText(nth(a, 1));
292
+ const instance = a.args[2] !== undefined ? Math.trunc(toNumber(nth(a, 2))) : 1;
293
+ if (delim === '')
294
+ return '';
295
+ const at = nthDelimiter(s, delim, instance);
296
+ return at === null ? (a.args[5] !== undefined ? nth(a, 5) : err('#N/A')) : s.slice(0, at);
297
+ },
298
+ TEXTAFTER: (a) => {
299
+ const s = toText(nth(a, 0));
300
+ const delim = toText(nth(a, 1));
301
+ const instance = a.args[2] !== undefined ? Math.trunc(toNumber(nth(a, 2))) : 1;
302
+ if (delim === '')
303
+ return s;
304
+ const at = nthDelimiter(s, delim, instance);
305
+ return at === null ? (a.args[5] !== undefined ? nth(a, 5) : err('#N/A')) : s.slice(at + delim.length);
306
+ },
307
+ // DOLLAR / FIXED(number, [decimals], [no_commas]): a number as the text of
308
+ // a currency or a fixed-decimal figure, grouped in thousands. DOLLAR wraps
309
+ // a negative in parentheses; a negative decimals rounds to the left of the
310
+ // point, so DOLLAR(1234.5, -2) is "$1,200".
311
+ DOLLAR: (a) => {
312
+ const decimals = a.args[1] !== undefined ? Math.trunc(toNumber(nth(a, 1))) : 2;
313
+ const rounded = roundTo(toNumber(nth(a, 0)), decimals);
314
+ const places = Math.max(decimals, 0);
315
+ const body = `$${Math.abs(rounded).toLocaleString('en-US', { minimumFractionDigits: places, maximumFractionDigits: places })}`;
316
+ return rounded < 0 ? `(${body})` : body;
317
+ },
318
+ FIXED: (a) => {
319
+ const decimals = a.args[1] !== undefined ? Math.trunc(toNumber(nth(a, 1))) : 2;
320
+ const noCommas = a.args[2] !== undefined && toBool(nth(a, 2));
321
+ const rounded = roundTo(toNumber(nth(a, 0)), decimals);
322
+ const places = Math.max(decimals, 0);
323
+ return noCommas
324
+ ? rounded.toFixed(places)
325
+ : rounded.toLocaleString('en-US', { minimumFractionDigits: places, maximumFractionDigits: places });
326
+ },
327
+ // COMBIN / PERMUT(n, k): the ways to choose k of n, unordered and ordered.
328
+ // The product form keeps the intermediate values small, so a big n does not
329
+ // overflow the way n! would.
330
+ COMBIN: (a) => {
331
+ const n = Math.trunc(toNumber(nth(a, 0)));
332
+ const k = Math.trunc(toNumber(nth(a, 1)));
333
+ if (n < 0 || k < 0 || k > n)
334
+ return err('#NUM!');
335
+ let result = 1;
336
+ for (let i = 0; i < k; i += 1)
337
+ result = (result * (n - i)) / (i + 1);
338
+ return Math.round(result);
339
+ },
340
+ PERMUT: (a) => {
341
+ const n = Math.trunc(toNumber(nth(a, 0)));
342
+ const k = Math.trunc(toNumber(nth(a, 1)));
343
+ if (n < 0 || k < 0 || k > n)
344
+ return err('#NUM!');
345
+ let result = 1;
346
+ for (let i = 0; i < k; i += 1)
347
+ result *= n - i;
348
+ return result;
349
+ },
350
+ // TYPE(value): 1 a number, 2 text, 4 a logical, 16 an error, 64 an array.
351
+ TYPE: (a) => {
352
+ const grid = a.grids[0];
353
+ if (grid && (grid.length > 1 || (grid[0]?.length ?? 0) > 1))
354
+ return 64;
355
+ const v = nth(a, 0);
356
+ if (isError(v))
357
+ return 16;
358
+ if (typeof v === 'number')
359
+ return 1;
360
+ if (typeof v === 'boolean')
361
+ return 4;
362
+ return 2;
363
+ },
364
+ // FIND(find, within, [start]): case sensitive, 1-based, #VALUE! when the
365
+ // text is not there. The third argument is where the search BEGINS, and
366
+ // the answer is still counted from the start of the text, which is what
367
+ // makes the walk over every occurrence work.
368
+ FIND: (a) => {
369
+ const from = startPosition(a);
370
+ if (from < 0)
371
+ return err('#VALUE!');
372
+ const at = toText(nth(a, 1)).indexOf(toText(nth(a, 0)), from);
373
+ return at < 0 ? err('#VALUE!') : at + 1;
374
+ },
375
+ // SEARCH is FIND's case-insensitive twin, and unlike FIND it reads Excel's
376
+ // wildcards: =SEARCH("n?rth", A1) finds either spelling.
377
+ SEARCH: (a) => {
378
+ const needle = toText(nth(a, 0));
379
+ const hay = toText(nth(a, 1));
380
+ const from = startPosition(a);
381
+ if (from < 0)
382
+ return err('#VALUE!');
383
+ if (hasWildcards(needle)) {
384
+ const at = wildcardSearch(hay, needle, from);
385
+ return at < 0 ? err('#VALUE!') : at + 1;
386
+ }
387
+ const at = hay.toLowerCase().indexOf(unescapeWildcards(needle).toLowerCase(), from);
388
+ return at < 0 ? err('#VALUE!') : at + 1;
389
+ },
390
+ /**
391
+ * TEXT(value, format): the value through a number-format string, which is
392
+ * the same grammar a cell's own format speaks. It reads dates, fractions,
393
+ * elapsed time and the rest, since it is the same compiler; a colour in
394
+ * the pattern is ignored, as Excel ignores it here, and an empty pattern
395
+ * is an empty string.
396
+ */
397
+ TEXT: (a) => {
398
+ const pattern = toText(nth(a, 1));
399
+ if (pattern === '')
400
+ return '';
401
+ return formatWithPattern(first(a), pattern);
402
+ },
403
+ // ---- Date ------------------------------------------------------------
404
+ TODAY: () => iso(new Date()),
405
+ NOW: () => new Date().toISOString().slice(0, 19).replace('T', ' '),
406
+ YEAR: (a) => toDate(first(a)).getUTCFullYear(),
407
+ MONTH: (a) => toDate(first(a)).getUTCMonth() + 1,
408
+ DAY: (a) => toDate(first(a)).getUTCDate(),
409
+ DATE: (a) => iso(new Date(Date.UTC(Math.round(toNumber(nth(a, 0))), Math.round(toNumber(nth(a, 1))) - 1, Math.round(toNumber(nth(a, 2)))))),
410
+ EOMONTH: (a) => {
411
+ const d = toDate(nth(a, 0));
412
+ const months = Math.round(toNumber(nth(a, 1)));
413
+ // Day 0 of the following month is the last day of the target month.
414
+ return iso(new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + months + 1, 0)));
415
+ },
416
+ // DAYS(end, start): whole days, negative when the end comes first.
417
+ DAYS: (a) => Math.round((toDate(nth(a, 0)).getTime() - toDate(nth(a, 1)).getTime()) / 86400000),
418
+ // DATEDIF(start, end, unit): Excel's six units - "d", "m", "y" for the
419
+ // whole difference, and "md", "ym", "yd" for the part left when the higher
420
+ // units are set aside, which is how an age reads "y years, m months, d
421
+ // days". #NUM! when the start comes after the end, as Excel gives.
422
+ DATEDIF: (a) => {
423
+ const start = toDate(nth(a, 0));
424
+ const end = toDate(nth(a, 1));
425
+ if (end.getTime() < start.getTime())
426
+ return err('#NUM!');
427
+ const unit = toText(nth(a, 2)).toUpperCase();
428
+ const day = 86400000;
429
+ if (unit === 'D')
430
+ return Math.floor((end.getTime() - start.getTime()) / day);
431
+ let months = (end.getUTCFullYear() - start.getUTCFullYear()) * 12 + (end.getUTCMonth() - start.getUTCMonth());
432
+ if (end.getUTCDate() < start.getUTCDate())
433
+ months -= 1;
434
+ if (unit === 'M')
435
+ return months;
436
+ if (unit === 'Y')
437
+ return Math.floor(months / 12);
438
+ // Months ignoring years: the month part of the whole difference.
439
+ if (unit === 'YM')
440
+ return months % 12;
441
+ // Days ignoring months and years: the days past the last whole month.
442
+ // Anchoring `months` months onto the start, its day clamped to that
443
+ // month's length, keeps the count from going negative on the awkward
444
+ // month-end cases Excel itself is inconsistent about (Jan 31 -> Mar 1).
445
+ if (unit === 'MD') {
446
+ const anchorMonth = start.getUTCMonth() + months;
447
+ const lastDay = new Date(Date.UTC(start.getUTCFullYear(), anchorMonth + 1, 0)).getUTCDate();
448
+ const anchorDay = Math.min(start.getUTCDate(), lastDay);
449
+ const anchor = Date.UTC(start.getUTCFullYear(), anchorMonth, anchorDay);
450
+ return Math.floor((end.getTime() - anchor) / day);
451
+ }
452
+ // Days ignoring years: the days between, with the start moved to end's
453
+ // year (or the year before, when that would overshoot the end).
454
+ if (unit === 'YD') {
455
+ let anchor = Date.UTC(end.getUTCFullYear(), start.getUTCMonth(), start.getUTCDate());
456
+ if (anchor > end.getTime())
457
+ anchor = Date.UTC(end.getUTCFullYear() - 1, start.getUTCMonth(), start.getUTCDate());
458
+ return Math.floor((end.getTime() - anchor) / day);
459
+ }
460
+ return err('#NUM!');
461
+ },
462
+ // ---- Lookup ----------------------------------------------------------
463
+ // VLOOKUP(lookup, table, colIndex, [rangeLookup]). The fourth argument is
464
+ // Excel's range_lookup and it defaults to TRUE: the banded lookup - tax
465
+ // brackets, commission tiers, a grade table - is the DEFAULT reading, and
466
+ // FALSE is how you ask for an exact match.
467
+ VLOOKUP: (a) => {
468
+ const needle = nth(a, 0);
469
+ const grid = a.grids[1];
470
+ if (!grid)
471
+ return err('#REF!');
472
+ const col = Math.round(toNumber(nth(a, 2)));
473
+ if (col < 1)
474
+ return err('#VALUE!');
475
+ const keys = grid.map((row) => row[0] ?? '');
476
+ const exact = a.args[3] !== undefined && !toBool(nth(a, 3));
477
+ const at = exact
478
+ ? keys.findIndex((v) => patternEquals(v, needle))
479
+ : nearestIndex(keys, needle, 1);
480
+ if (at < 0)
481
+ return err('#N/A');
482
+ const cell = grid[at][col - 1];
483
+ return cell === undefined ? err('#REF!') : cell;
484
+ },
485
+ // HLOOKUP reads the same way, along the header row instead of down the
486
+ // first column.
487
+ HLOOKUP: (a) => {
488
+ const needle = nth(a, 0);
489
+ const grid = a.grids[1];
490
+ if (!grid)
491
+ return err('#REF!');
492
+ const rowIndex = Math.round(toNumber(nth(a, 2)));
493
+ if (rowIndex < 1)
494
+ return err('#VALUE!');
495
+ const header = grid[0] ?? [];
496
+ const exact = a.args[3] !== undefined && !toBool(nth(a, 3));
497
+ const at = exact
498
+ ? header.findIndex((v) => patternEquals(v, needle))
499
+ : nearestIndex(header, needle, 1);
500
+ if (at < 0)
501
+ return err('#N/A');
502
+ const cell = grid[rowIndex - 1]?.[at];
503
+ return cell === undefined ? err('#REF!') : cell;
504
+ },
505
+ MATCH: (a) => {
506
+ const needle = nth(a, 0);
507
+ const pool = a.args[1] ?? [];
508
+ const mode = a.args[2] ? Math.round(toNumber(nth(a, 2))) : 1;
509
+ if (mode === 0) {
510
+ // An exact match takes Excel's wildcards: =MATCH("North*", ...).
511
+ const at = pool.findIndex((v) => patternEquals(v, needle));
512
+ return at < 0 ? err('#N/A') : at + 1;
513
+ }
514
+ // Ordered search: 1 wants the last value not past the needle in an
515
+ // ascending range, -1 the last value not before it in a descending one.
516
+ const best = nearestIndex(pool, needle, mode === 1 ? 1 : -1);
517
+ return best < 0 ? err('#N/A') : best + 1;
518
+ },
519
+ INDEX: (a) => {
520
+ const grid = a.grids[0];
521
+ if (!grid) {
522
+ const at = Math.round(toNumber(nth(a, 1)));
523
+ const v = (a.args[0] ?? [])[at - 1];
524
+ return v === undefined ? err('#REF!') : v;
525
+ }
526
+ const given = Math.round(toNumber(nth(a, 1)));
527
+ // With one number, a one-column range indexes by row and a one-row range
528
+ // by column, as Excel does: =INDEX(B4:D4, 2) is the second scenario
529
+ // heading, not #REF!.
530
+ const oneRow = grid.length === 1 && !a.args[2];
531
+ const rowIndex = oneRow ? 1 : given;
532
+ const colIndex = oneRow ? given : a.args[2] ? Math.round(toNumber(nth(a, 2))) : 1;
533
+ const row = grid[rowIndex - 1];
534
+ if (!row)
535
+ return err('#REF!');
536
+ const cell = row[colIndex - 1];
537
+ return cell === undefined ? err('#REF!') : cell;
538
+ },
539
+ // XLOOKUP(lookup, haystack, results, [ifMissing], [matchMode], [searchMode]).
540
+ // matchMode 0 is the exact match it defaults to, -1 falls back to the next
541
+ // smaller item, 1 to the next larger one and 2 reads the value as a wildcard
542
+ // pattern; a negative searchMode reads the range from the end, which is how
543
+ // you pick the LAST of several matches.
544
+ XLOOKUP: (a) => {
545
+ const needle = nth(a, 0);
546
+ const haystack = a.args[1] ?? [];
547
+ const results = a.args[2] ?? [];
548
+ const mode = a.args[4] !== undefined ? Math.round(toNumber(nth(a, 4))) : 0;
549
+ const back = a.args[5] !== undefined && Math.round(toNumber(nth(a, 5))) < 0;
550
+ // Unlike the older lookups, XLOOKUP reads wildcards only when asked:
551
+ // match mode 2.
552
+ const same = mode === 2
553
+ ? (v) => patternEquals(v, needle)
554
+ : (v) => looseEquals(v, needle);
555
+ let at = -1;
556
+ for (let i = 0; i < haystack.length; i += 1) {
557
+ const j = back ? haystack.length - 1 - i : i;
558
+ if (same(haystack[j])) {
559
+ at = j;
560
+ break;
561
+ }
562
+ }
563
+ if (at < 0 && mode === -1)
564
+ at = nearestIndex(haystack, needle, 1);
565
+ if (at < 0 && mode === 1)
566
+ at = nearestIndex(haystack, needle, -1);
567
+ if (at < 0)
568
+ return a.args[3] !== undefined ? nth(a, 3) : err('#N/A');
569
+ const cell = results[at];
570
+ return cell === undefined ? err('#REF!') : cell;
571
+ },
572
+ // LOOKUP(value, vector, [result]): the old approximate lookup that assumes
573
+ // its vector is sorted ascending and takes the largest item not past the
574
+ // value, returning the matching cell of the result vector - the lookup
575
+ // vector itself when none is given.
576
+ LOOKUP: (a) => {
577
+ const needle = nth(a, 0);
578
+ const vector = a.args[1] ?? [];
579
+ const result = a.args[2] ?? vector;
580
+ const at = nearestIndex(vector, needle, 1);
581
+ if (at < 0)
582
+ return err('#N/A');
583
+ const cell = result[at];
584
+ return cell === undefined ? err('#N/A') : cell;
585
+ },
586
+ // XMATCH(value, array, [matchMode], [searchMode]): MATCH's modern twin.
587
+ // matchMode 0 is the exact default, -1 falls back to the next smaller item,
588
+ // 1 to the next larger, 2 reads a wildcard; a negative searchMode reads from
589
+ // the end, so it finds the LAST of several matches.
590
+ XMATCH: (a) => {
591
+ const needle = nth(a, 0);
592
+ const pool = a.args[1] ?? [];
593
+ const mode = a.args[2] !== undefined ? Math.round(toNumber(nth(a, 2))) : 0;
594
+ const back = a.args[3] !== undefined && Math.round(toNumber(nth(a, 3))) < 0;
595
+ const same = mode === 2
596
+ ? (v) => patternEquals(v, needle)
597
+ : (v) => looseEquals(v, needle);
598
+ let at = -1;
599
+ for (let i = 0; i < pool.length; i += 1) {
600
+ const j = back ? pool.length - 1 - i : i;
601
+ if (same(pool[j])) {
602
+ at = j;
603
+ break;
604
+ }
605
+ }
606
+ if (at < 0 && mode === -1)
607
+ at = nearestIndex(pool, needle, 1);
608
+ if (at < 0 && mode === 1)
609
+ at = nearestIndex(pool, needle, -1);
610
+ return at < 0 ? err('#N/A') : at + 1;
611
+ },
612
+ // ---- The packs: financial, more math and statistics, more text and
613
+ // date. Each lives in its own module under ./packs so this table stays
614
+ // readable; all of them are on by default, as a sheet user expects PMT
615
+ // to work without registering anything.
616
+ ...FINANCIAL_FUNCTIONS,
617
+ ...MATH_STATS_FUNCTIONS,
618
+ ...TEXT_DATE_FUNCTIONS,
619
+ ...TRIG_FUNCTIONS,
620
+ ...ENGINEERING_FUNCTIONS,
621
+ ...DATABASE_FUNCTIONS,
622
+ ...STATS_DIST_FUNCTIONS,
623
+ };
624
+ /** Merge caller-supplied functions over the built-ins. Keys are uppercased so
625
+ * a consumer can register `myFn` and write `=MYFN()`. */
626
+ export function withCustomFunctions(custom) {
627
+ if (!custom)
628
+ return FUNCTIONS;
629
+ const out = { ...FUNCTIONS };
630
+ for (const [name, fn] of Object.entries(custom))
631
+ out[name.toUpperCase()] = fn;
632
+ return out;
633
+ }
634
+ export { isError };