@svgrid/enterprise 3.0.2 → 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 (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-D5bVbuzI.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,26 @@
1
+ /**
2
+ * One door for a file the user picked.
3
+ *
4
+ * A spreadsheet arrives as one of four things, whatever the picker called
5
+ * it: an .xlsx from Excel or Google Sheets, an .ods from LibreOffice (or
6
+ * Google Sheets, which offers both), an .xls from any Excel since 1997, or a
7
+ * .csv, which every one of them exports. The kind is read from the BYTES
8
+ * rather than from the name: a file picked on a phone often arrives with no
9
+ * extension and no media type, a zip always starts PK with the package
10
+ * inside saying which package it is, and an .xls starts with the compound
11
+ * file signature.
12
+ */
13
+ import { type ZipCtor } from './xlsx-document.js';
14
+ import type { SheetState } from './document.js';
15
+ export type OpenedFile = {
16
+ state: SheetState;
17
+ kind: 'xlsx' | 'ods' | 'xls' | 'csv';
18
+ };
19
+ /** What a file holds, and which kind of file it turned out to be. */
20
+ export declare function readSpreadsheetFile(file: Blob & {
21
+ name?: string;
22
+ }, JSZip?: ZipCtor): Promise<OpenedFile>;
23
+ /** The document a file holds: .xlsx, .ods, .xls or .csv, decided by its bytes. */
24
+ export declare function documentFromFile(file: Blob & {
25
+ name?: string;
26
+ }, JSZip?: ZipCtor): Promise<SheetState>;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * One door for a file the user picked.
3
+ *
4
+ * A spreadsheet arrives as one of four things, whatever the picker called
5
+ * it: an .xlsx from Excel or Google Sheets, an .ods from LibreOffice (or
6
+ * Google Sheets, which offers both), an .xls from any Excel since 1997, or a
7
+ * .csv, which every one of them exports. The kind is read from the BYTES
8
+ * rather than from the name: a file picked on a phone often arrives with no
9
+ * extension and no media type, a zip always starts PK with the package
10
+ * inside saying which package it is, and an .xls starts with the compound
11
+ * file signature.
12
+ */
13
+ import { documentFromXlsxParts, loadZip } from './xlsx-document.js';
14
+ import { sheetStateFromOds } from './ods-document.js';
15
+ import { sheetStateFromCsv } from './csv.js';
16
+ import { isXlsFile, sheetStateFromXls } from './xls-document.js';
17
+ /** A picture travels as the data URL the document holds, as in the xlsx reader. */
18
+ const MEDIA_PREFIX = 'xl/media/';
19
+ const mediaTypeOf = (path) => {
20
+ const extension = path.slice(path.lastIndexOf('.') + 1).toLowerCase();
21
+ return extension === 'jpg' || extension === 'jpeg' ? 'image/jpeg' : `image/${extension || 'png'}`;
22
+ };
23
+ /** What a file holds, and which kind of file it turned out to be. */
24
+ export async function readSpreadsheetFile(file, JSZip) {
25
+ const head = new Uint8Array(await file.slice(0, 8).arrayBuffer());
26
+ if (isXlsFile(head))
27
+ return { state: sheetStateFromXls(new Uint8Array(await file.arrayBuffer())), kind: 'xls' };
28
+ if (head[0] !== 0x50 || head[1] !== 0x4b) {
29
+ const name = (file.name ?? '').replace(/\.[^.]+$/, '');
30
+ return { state: sheetStateFromCsv(await file.text(), (name || 'Sheet1').slice(0, 31)), kind: 'csv' };
31
+ }
32
+ const Zip = await loadZip(JSZip);
33
+ const zip = await Zip.loadAsync(file);
34
+ const parts = {};
35
+ const pending = [];
36
+ zip.forEach((path, entry) => {
37
+ if (entry.dir)
38
+ return;
39
+ const clean = path.replace(/^\//, '');
40
+ if (clean.startsWith(MEDIA_PREFIX)) {
41
+ pending.push(entry.async('base64').then((base64) => { parts[clean] = `data:${mediaTypeOf(clean)};base64,${base64}`; }));
42
+ return;
43
+ }
44
+ if (!/\.(xml|rels|vml)$/i.test(clean))
45
+ return;
46
+ pending.push(entry.async('string').then((text) => { parts[clean] = text; }));
47
+ });
48
+ await Promise.all(pending);
49
+ if (parts['content.xml'] && !parts['xl/workbook.xml'])
50
+ return { state: sheetStateFromOds(parts), kind: 'ods' };
51
+ return { state: documentFromXlsxParts(parts), kind: 'xlsx' };
52
+ }
53
+ /** The document a file holds: .xlsx, .ods, .xls or .csv, decided by its bytes. */
54
+ export async function documentFromFile(file, JSZip) {
55
+ return (await readSpreadsheetFile(file, JSZip)).state;
56
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Excel's row and column outline: Data > Group, Ungroup and the little
3
+ * numbered bar down the side that collapses a section away.
4
+ *
5
+ * Modelled the way the FILE models it, a level per line rather than a list
6
+ * of ranges, because that is what `<row outlineLevel="2">` carries and
7
+ * because ranges have to be split, merged and renumbered on every
8
+ * structural edit while levels only have to be shifted. A group is then
9
+ * not a stored object at all: it is a maximal run of lines whose level is
10
+ * higher than the summary line beside it.
11
+ *
12
+ * `summaryBelow` is Excel's own default and says which side the summary
13
+ * line sits on. With it on, grouping rows 2 to 5 puts the collapse button
14
+ * on row 6, because that is where the total goes; with it off the button
15
+ * is on row 1. Columns have the same idea under `summaryRight`.
16
+ *
17
+ * Nothing here touches the cells. Hiding a line is the shell's business,
18
+ * and `hiddenByOutline` is what tells it which.
19
+ */
20
+ /** Excel allows eight levels, 1 to 7 plus the ungrouped 0. */
21
+ export declare const MAX_OUTLINE_LEVEL = 7;
22
+ export type OutlineState = {
23
+ /** Level per line index, 1 to 7. A line with no entry is at level 0. */
24
+ levels: Record<number, number>;
25
+ /** Summary lines whose group is collapsed. */
26
+ collapsed: number[];
27
+ };
28
+ export type OutlineSide = {
29
+ /** The summary sits after the detail (Excel's default for rows). */
30
+ summaryBelow: boolean;
31
+ };
32
+ export declare const emptyOutline: () => OutlineState;
33
+ export declare const outlineLevel: (state: OutlineState, line: number) => number;
34
+ /** True where nothing is grouped, so the shell can skip the whole gutter. */
35
+ export declare const isOutlined: (state: OutlineState) => boolean;
36
+ /** The deepest level in use, which is how many buttons the level bar shows. */
37
+ export declare function deepestLevel(state: OutlineState): number;
38
+ /**
39
+ * Group `from`..`to`, deepening each line by one.
40
+ *
41
+ * Grouping an already grouped run is how a nested group is made, which is
42
+ * why this adds a level rather than setting one.
43
+ */
44
+ export declare function groupLines(state: OutlineState, from: number, to: number): OutlineState;
45
+ /** Ungroup `from`..`to`, taking one level off each line. */
46
+ export declare function ungroupLines(state: OutlineState, from: number, to: number): OutlineState;
47
+ /** Remove every group on this axis. */
48
+ export declare const clearOutline: () => OutlineState;
49
+ /** The lines a summary line owns, or an empty range when it owns none. */
50
+ export declare function detailRange(state: OutlineState, summary: number, side: OutlineSide): {
51
+ from: number;
52
+ to: number;
53
+ } | null;
54
+ /** Collapse or expand the group `summary` owns. */
55
+ export declare function toggleCollapsed(state: OutlineState, summary: number): OutlineState;
56
+ /** Which lines an outline hides, detail of every collapsed group included. */
57
+ export declare function hiddenByOutline(state: OutlineState, side: OutlineSide): Set<number>;
58
+ /**
59
+ * Show levels up to `level` and collapse everything deeper: the numbered
60
+ * buttons at the corner of the outline bar.
61
+ *
62
+ * Level 1 is the most collapsed view, showing only the outermost
63
+ * summaries; the deepest level shows everything.
64
+ */
65
+ export declare function showLevel(state: OutlineState, level: number, side: OutlineSide): OutlineState;
66
+ /**
67
+ * The outline after lines were inserted or deleted, so a group follows the
68
+ * rows it was put around.
69
+ *
70
+ * An inserted line takes the level of the line it pushed down, which is
71
+ * what Excel does and what makes a row added inside a group part of it.
72
+ */
73
+ export declare function shiftOutline(state: OutlineState, at: number, count: number): OutlineState;
74
+ /**
75
+ * An outline read off a block's shape: Excel's Auto Outline.
76
+ *
77
+ * A line is detail when the line on the summary side holds a formula that
78
+ * reads back over it, which is what a SUBTOTAL or SUM column looks like.
79
+ * `isSummary` answers that for one line, so this module stays free of the
80
+ * workbook.
81
+ */
82
+ export declare function autoOutline(from: number, to: number, isSummary: (line: number) => boolean, side: OutlineSide): OutlineState;
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Excel's row and column outline: Data > Group, Ungroup and the little
3
+ * numbered bar down the side that collapses a section away.
4
+ *
5
+ * Modelled the way the FILE models it, a level per line rather than a list
6
+ * of ranges, because that is what `<row outlineLevel="2">` carries and
7
+ * because ranges have to be split, merged and renumbered on every
8
+ * structural edit while levels only have to be shifted. A group is then
9
+ * not a stored object at all: it is a maximal run of lines whose level is
10
+ * higher than the summary line beside it.
11
+ *
12
+ * `summaryBelow` is Excel's own default and says which side the summary
13
+ * line sits on. With it on, grouping rows 2 to 5 puts the collapse button
14
+ * on row 6, because that is where the total goes; with it off the button
15
+ * is on row 1. Columns have the same idea under `summaryRight`.
16
+ *
17
+ * Nothing here touches the cells. Hiding a line is the shell's business,
18
+ * and `hiddenByOutline` is what tells it which.
19
+ */
20
+ /** Excel allows eight levels, 1 to 7 plus the ungrouped 0. */
21
+ export const MAX_OUTLINE_LEVEL = 7;
22
+ export const emptyOutline = () => ({ levels: {}, collapsed: [] });
23
+ export const outlineLevel = (state, line) => state.levels[line] ?? 0;
24
+ /** True where nothing is grouped, so the shell can skip the whole gutter. */
25
+ export const isOutlined = (state) => Object.values(state.levels).some((l) => l > 0);
26
+ /** The deepest level in use, which is how many buttons the level bar shows. */
27
+ export function deepestLevel(state) {
28
+ let max = 0;
29
+ for (const l of Object.values(state.levels))
30
+ if (l > max)
31
+ max = l;
32
+ return max;
33
+ }
34
+ const clone = (state) => ({
35
+ levels: { ...state.levels },
36
+ collapsed: [...state.collapsed],
37
+ });
38
+ /** Drop levels that fell to zero, so the record stays sparse. */
39
+ function tidy(state) {
40
+ for (const [key, value] of Object.entries(state.levels)) {
41
+ if (value <= 0)
42
+ delete state.levels[Number(key)];
43
+ }
44
+ // A summary line whose group has gone is no longer collapsed.
45
+ state.collapsed = [...new Set(state.collapsed)].sort((a, b) => a - b);
46
+ return state;
47
+ }
48
+ /**
49
+ * Group `from`..`to`, deepening each line by one.
50
+ *
51
+ * Grouping an already grouped run is how a nested group is made, which is
52
+ * why this adds a level rather than setting one.
53
+ */
54
+ export function groupLines(state, from, to) {
55
+ const next = clone(state);
56
+ const lo = Math.min(from, to);
57
+ const hi = Math.max(from, to);
58
+ for (let line = lo; line <= hi; line += 1) {
59
+ next.levels[line] = Math.min(outlineLevel(next, line) + 1, MAX_OUTLINE_LEVEL);
60
+ }
61
+ return tidy(next);
62
+ }
63
+ /** Ungroup `from`..`to`, taking one level off each line. */
64
+ export function ungroupLines(state, from, to) {
65
+ const next = clone(state);
66
+ const lo = Math.min(from, to);
67
+ const hi = Math.max(from, to);
68
+ for (let line = lo; line <= hi; line += 1) {
69
+ const level = outlineLevel(next, line) - 1;
70
+ if (level > 0)
71
+ next.levels[line] = level;
72
+ else
73
+ delete next.levels[line];
74
+ }
75
+ // A line that is no longer in a group cannot be a collapsed summary of
76
+ // one either, or its detail would stay hidden with nothing to show it.
77
+ next.collapsed = next.collapsed.filter((line) => {
78
+ if (line < lo || line > hi)
79
+ return true;
80
+ return hasDetail({ ...next }, line, { summaryBelow: true })
81
+ || hasDetail({ ...next }, line, { summaryBelow: false });
82
+ });
83
+ return tidy(next);
84
+ }
85
+ /** Remove every group on this axis. */
86
+ export const clearOutline = () => emptyOutline();
87
+ /** The lines a summary line owns, or an empty range when it owns none. */
88
+ export function detailRange(state, summary, side) {
89
+ const own = outlineLevel(state, summary);
90
+ const step = side.summaryBelow ? -1 : 1;
91
+ let line = summary + step;
92
+ if (outlineLevel(state, line) <= own)
93
+ return null;
94
+ while (outlineLevel(state, line + step) > own)
95
+ line += step;
96
+ return side.summaryBelow ? { from: line, to: summary - 1 } : { from: summary + 1, to: line };
97
+ }
98
+ const hasDetail = (state, summary, side) => detailRange(state, summary, side) !== null;
99
+ /** Collapse or expand the group `summary` owns. */
100
+ export function toggleCollapsed(state, summary) {
101
+ const next = clone(state);
102
+ const at = next.collapsed.indexOf(summary);
103
+ if (at >= 0)
104
+ next.collapsed.splice(at, 1);
105
+ else
106
+ next.collapsed.push(summary);
107
+ return tidy(next);
108
+ }
109
+ /** Which lines an outline hides, detail of every collapsed group included. */
110
+ export function hiddenByOutline(state, side) {
111
+ const hidden = new Set();
112
+ for (const summary of state.collapsed) {
113
+ const range = detailRange(state, summary, side);
114
+ if (!range)
115
+ continue;
116
+ for (let line = range.from; line <= range.to; line += 1)
117
+ hidden.add(line);
118
+ }
119
+ return hidden;
120
+ }
121
+ /**
122
+ * Show levels up to `level` and collapse everything deeper: the numbered
123
+ * buttons at the corner of the outline bar.
124
+ *
125
+ * Level 1 is the most collapsed view, showing only the outermost
126
+ * summaries; the deepest level shows everything.
127
+ */
128
+ export function showLevel(state, level, side) {
129
+ const next = clone(state);
130
+ next.collapsed = [];
131
+ const lines = Object.keys(next.levels).map(Number);
132
+ if (lines.length === 0)
133
+ return tidy(next);
134
+ const lo = Math.min(...lines);
135
+ const hi = Math.max(...lines);
136
+ // A summary sits just outside its detail, so the sweep runs one line
137
+ // wider than the outlined block on both sides.
138
+ for (let line = lo - 1; line <= hi + 1; line += 1) {
139
+ const range = detailRange(next, line, side);
140
+ if (!range)
141
+ continue;
142
+ // A line at level L is visible under button N when L < N, so the group
143
+ // whose detail starts at the summary's level plus one has to close as
144
+ // soon as that depth reaches N rather than only once it passes it.
145
+ if (outlineLevel(next, line) + 1 >= level)
146
+ next.collapsed.push(line);
147
+ }
148
+ return tidy(next);
149
+ }
150
+ /**
151
+ * The outline after lines were inserted or deleted, so a group follows the
152
+ * rows it was put around.
153
+ *
154
+ * An inserted line takes the level of the line it pushed down, which is
155
+ * what Excel does and what makes a row added inside a group part of it.
156
+ */
157
+ export function shiftOutline(state, at, count) {
158
+ const next = emptyOutline();
159
+ const move = (line) => {
160
+ if (count > 0)
161
+ return line >= at ? line + count : line;
162
+ // A deleted line takes its level with it.
163
+ if (line >= at && line < at - count)
164
+ return null;
165
+ return line >= at ? line + count : line;
166
+ };
167
+ for (const [key, level] of Object.entries(state.levels)) {
168
+ const to = move(Number(key));
169
+ if (to !== null)
170
+ next.levels[to] = level;
171
+ }
172
+ if (count > 0) {
173
+ // An insertion inside a group inherits the level of what it displaced.
174
+ const inherited = state.levels[at];
175
+ if (inherited !== undefined) {
176
+ for (let i = 0; i < count; i += 1)
177
+ next.levels[at + i] = inherited;
178
+ }
179
+ }
180
+ for (const summary of state.collapsed) {
181
+ const to = move(summary);
182
+ if (to !== null)
183
+ next.collapsed.push(to);
184
+ }
185
+ return tidy(next);
186
+ }
187
+ /**
188
+ * An outline read off a block's shape: Excel's Auto Outline.
189
+ *
190
+ * A line is detail when the line on the summary side holds a formula that
191
+ * reads back over it, which is what a SUBTOTAL or SUM column looks like.
192
+ * `isSummary` answers that for one line, so this module stays free of the
193
+ * workbook.
194
+ */
195
+ export function autoOutline(from, to, isSummary, side) {
196
+ const next = emptyOutline();
197
+ let runStart = null;
198
+ const close = (summary, start, end) => {
199
+ if (end < start)
200
+ return;
201
+ for (let line = start; line <= end; line += 1)
202
+ next.levels[line] = 1;
203
+ void summary;
204
+ };
205
+ if (side.summaryBelow) {
206
+ for (let line = from; line <= to; line += 1) {
207
+ if (isSummary(line)) {
208
+ if (runStart !== null)
209
+ close(line, runStart, line - 1);
210
+ runStart = null;
211
+ }
212
+ else if (runStart === null)
213
+ runStart = line;
214
+ }
215
+ }
216
+ else {
217
+ for (let line = to; line >= from; line -= 1) {
218
+ if (isSummary(line)) {
219
+ if (runStart !== null)
220
+ close(line, line + 1, runStart);
221
+ runStart = null;
222
+ }
223
+ else if (runStart === null)
224
+ runStart = line;
225
+ }
226
+ }
227
+ return tidy(next);
228
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The array pack: Excel's dynamic array functions, the ones whose answer
3
+ * is a grid rather than a value. FILTER, UNIQUE, SORT, SORTBY, SEQUENCE,
4
+ * TRANSPOSE and TEXTSPLIT. Each takes its arguments the way every other
5
+ * function does (`FnArgs`, with the 2-D shape of a range in `grids`) and
6
+ * returns `CellValue[][]`; the evaluator spills a grid over the cells
7
+ * below and to the right of the formula, or reads its top-left cell where
8
+ * only a value fits. A grid with nothing in it is `#CALC!`, as in Excel.
9
+ */
10
+ import { type CellValue } from '../ast.js';
11
+ import type { FnArgs } from '../functions.js';
12
+ export type Grid = CellValue[][];
13
+ export type ArrayFunction = (a: FnArgs) => Grid | CellValue;
14
+ /** The i-th argument as a grid: a range keeps its shape, a value is 1 x 1. */
15
+ export declare function gridArg(a: FnArgs, i: number): Grid | null;
16
+ export declare const ARRAY_FUNCTIONS: Record<string, ArrayFunction>;
@@ -0,0 +1,172 @@
1
+ /**
2
+ * The array pack: Excel's dynamic array functions, the ones whose answer
3
+ * is a grid rather than a value. FILTER, UNIQUE, SORT, SORTBY, SEQUENCE,
4
+ * TRANSPOSE and TEXTSPLIT. Each takes its arguments the way every other
5
+ * function does (`FnArgs`, with the 2-D shape of a range in `grids`) and
6
+ * returns `CellValue[][]`; the evaluator spills a grid over the cells
7
+ * below and to the right of the formula, or reads its top-left cell where
8
+ * only a value fits. A grid with nothing in it is `#CALC!`, as in Excel.
9
+ */
10
+ import { isError, err } from '../ast.js';
11
+ import { toNumber, toBool, toText, compare, isBlank } from '../coerce.js';
12
+ /** The i-th argument as a grid: a range keeps its shape, a value is 1 x 1. */
13
+ export function gridArg(a, i) {
14
+ const grid = a.grids[i];
15
+ if (grid)
16
+ return grid.map((row) => [...row]);
17
+ const list = a.args[i];
18
+ return list === undefined ? null : [[list[0] ?? '']];
19
+ }
20
+ const scalar = (a, i) => a.args[i]?.[0] ?? '';
21
+ const given = (a, i) => a.args[i] !== undefined && !(a.args[i].length === 1 && a.args[i][0] === '');
22
+ /** The values of a 1-D array, whichever way it runs. */
23
+ const line = (grid) => (grid.length === 1 ? [...grid[0]] : grid.map((row) => row[0] ?? ''));
24
+ const transpose = (grid) => {
25
+ const cols = grid.reduce((m, row) => Math.max(m, row.length), 0);
26
+ return Array.from({ length: cols }, (_, c) => grid.map((row) => row[c] ?? ''));
27
+ };
28
+ const rowsEqual = (a, b) => a.length === b.length && a.every((v, i) => compare(v, b[i]) === 0 && typeof v === typeof b[i]);
29
+ /** Rows of `grid` in the order `keys` says, a stable sort. */
30
+ function sortRows(grid, keys) {
31
+ const index = grid.map((_, i) => i);
32
+ index.sort((x, y) => {
33
+ for (const key of keys) {
34
+ const a = key.values[x] ?? '';
35
+ const b = key.values[y] ?? '';
36
+ const blankA = isBlank(a);
37
+ const blankB = isBlank(b);
38
+ // Blanks sort last whichever way, as Excel's SORT puts them.
39
+ if (blankA !== blankB)
40
+ return blankA ? 1 : -1;
41
+ const d = compare(a, b);
42
+ if (d !== 0)
43
+ return key.descending ? -d : d;
44
+ }
45
+ return x - y;
46
+ });
47
+ return index.map((i) => grid[i]);
48
+ }
49
+ const empty = () => err('#CALC!');
50
+ export const ARRAY_FUNCTIONS = {
51
+ /** FILTER(array, include, [if_empty]): the rows (or columns) where include is true. */
52
+ FILTER: (a) => {
53
+ const array = gridArg(a, 0);
54
+ const include = gridArg(a, 1);
55
+ if (!array || !include)
56
+ return err('#VALUE!');
57
+ const flags = line(include);
58
+ const byRows = include.length > 1 || (include.length === 1 && include[0].length === 1 && array.length === 1);
59
+ const along = byRows && include.length !== 1 ? 'rows' : include[0].length > 1 ? 'cols' : 'rows';
60
+ const count = along === 'rows' ? array.length : (array[0]?.length ?? 0);
61
+ if (flags.length !== count)
62
+ return err('#VALUE!');
63
+ for (const f of flags)
64
+ if (isError(f))
65
+ return f;
66
+ const keep = flags.map((f) => toBool(f));
67
+ const out = along === 'rows' ? array.filter((_, i) => keep[i]) : array.map((row) => row.filter((_, i) => keep[i]));
68
+ if (!out.length || !out[0].length)
69
+ return given(a, 2) ? scalar(a, 2) : empty();
70
+ return out;
71
+ },
72
+ /** UNIQUE(array, [by_col], [exactly_once]): the distinct rows, first seen first. */
73
+ UNIQUE: (a) => {
74
+ const array = gridArg(a, 0);
75
+ if (!array)
76
+ return err('#VALUE!');
77
+ const byCol = given(a, 1) && toBool(scalar(a, 1));
78
+ const once = given(a, 2) && toBool(scalar(a, 2));
79
+ const rows = byCol ? transpose(array) : array;
80
+ const counts = rows.map((row) => rows.filter((other) => rowsEqual(row, other)).length);
81
+ const out = [];
82
+ rows.forEach((row, i) => {
83
+ if (once ? counts[i] === 1 : !out.some((seen) => rowsEqual(seen, row)))
84
+ out.push([...row]);
85
+ });
86
+ if (!out.length)
87
+ return empty();
88
+ return byCol ? transpose(out) : out;
89
+ },
90
+ /** SORT(array, [sort_index], [sort_order], [by_col]). */
91
+ SORT: (a) => {
92
+ const array = gridArg(a, 0);
93
+ if (!array)
94
+ return err('#VALUE!');
95
+ const index = given(a, 1) ? Math.trunc(toNumber(scalar(a, 1))) : 1;
96
+ const order = given(a, 2) ? Math.trunc(toNumber(scalar(a, 2))) : 1;
97
+ const byCol = given(a, 3) && toBool(scalar(a, 3));
98
+ if (index < 1 || (order !== 1 && order !== -1))
99
+ return err('#VALUE!');
100
+ const rows = byCol ? transpose(array) : array;
101
+ if (index > (rows[0]?.length ?? 0))
102
+ return err('#VALUE!');
103
+ const sorted = sortRows(rows, [{ values: rows.map((row) => row[index - 1] ?? ''), descending: order === -1 }]);
104
+ return byCol ? transpose(sorted) : sorted;
105
+ },
106
+ /** SORTBY(array, by_array1, [order1], [by_array2, order2], ...). */
107
+ SORTBY: (a) => {
108
+ const array = gridArg(a, 0);
109
+ if (!array)
110
+ return err('#VALUE!');
111
+ const keys = [];
112
+ for (let i = 1; i < a.args.length; i += 2) {
113
+ const by = gridArg(a, i);
114
+ if (!by)
115
+ return err('#VALUE!');
116
+ const values = line(by);
117
+ if (values.length !== array.length)
118
+ return err('#VALUE!');
119
+ const order = given(a, i + 1) ? Math.trunc(toNumber(scalar(a, i + 1))) : 1;
120
+ if (order !== 1 && order !== -1)
121
+ return err('#VALUE!');
122
+ keys.push({ values, descending: order === -1 });
123
+ }
124
+ if (!keys.length)
125
+ return err('#VALUE!');
126
+ return sortRows(array, keys);
127
+ },
128
+ /** SEQUENCE(rows, [columns], [start], [step]). */
129
+ SEQUENCE: (a) => {
130
+ const rows = Math.trunc(toNumber(scalar(a, 0)));
131
+ const cols = given(a, 1) ? Math.trunc(toNumber(scalar(a, 1))) : 1;
132
+ const start = given(a, 2) ? toNumber(scalar(a, 2)) : 1;
133
+ const step = given(a, 3) ? toNumber(scalar(a, 3)) : 1;
134
+ if (rows < 1 || cols < 1)
135
+ return err('#VALUE!');
136
+ if (rows * cols > 1000000)
137
+ return err('#NUM!');
138
+ let n = start;
139
+ return Array.from({ length: rows }, () => Array.from({ length: cols }, () => { const v = n; n += step; return v; }));
140
+ },
141
+ /** TRANSPOSE(array). */
142
+ TRANSPOSE: (a) => {
143
+ const array = gridArg(a, 0);
144
+ if (!array)
145
+ return err('#VALUE!');
146
+ return transpose(array);
147
+ },
148
+ /** TEXTSPLIT(text, col_delimiter, [row_delimiter], [ignore_empty]). */
149
+ TEXTSPLIT: (a) => {
150
+ const text = scalar(a, 0);
151
+ if (isError(text))
152
+ return text;
153
+ const colDelim = given(a, 1) ? toText(scalar(a, 1)) : '';
154
+ const rowDelim = given(a, 2) ? toText(scalar(a, 2)) : '';
155
+ const ignoreEmpty = given(a, 3) && toBool(scalar(a, 3));
156
+ const split = (s, d) => (d === '' ? [s] : s.split(d));
157
+ const rows = split(toText(text), rowDelim).map((row) => split(row, colDelim));
158
+ const kept = ignoreEmpty ? rows.map((row) => row.filter((v) => v !== '')).filter((row) => row.length) : rows;
159
+ if (!kept.length)
160
+ return empty();
161
+ const width = kept.reduce((m, row) => Math.max(m, row.length), 0);
162
+ return kept.map((row) => Array.from({ length: width }, (_, i) => (i < row.length ? asValue(row[i]) : err('#N/A'))));
163
+ },
164
+ };
165
+ /** A piece of split text as the cell would read it: a number where it parses. */
166
+ function asValue(piece) {
167
+ const t = piece.trim();
168
+ if (t === '')
169
+ return '';
170
+ const n = Number(t);
171
+ return Number.isFinite(n) ? n : piece;
172
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Excel's Database family: the twelve aggregates that read a labelled
3
+ * block of records through a labelled block of criteria.
4
+ *
5
+ * All twelve share one shape, `D<agg>(database, field, criteria)`, and all
6
+ * the interesting behaviour is in how the criteria block is read:
7
+ *
8
+ * - Its first row is header names, matched against the database's own
9
+ * headers by text, ignoring case. A header the database does not have
10
+ * matches nothing.
11
+ * - Every row UNDER the header is one alternative: the conditions across
12
+ * a row are ANDed, and the rows are ORed. That is Excel's advanced
13
+ * filter grammar, and it is why the criteria block is two-dimensional
14
+ * rather than a list.
15
+ * - An empty criteria cell places no condition, so a criteria block that
16
+ * is nothing but headers matches every record.
17
+ *
18
+ * `field` is either a header's text or its one-based position. Excel takes
19
+ * both, and a model built by hand usually holds the text while one built
20
+ * by a formula holds the number.
21
+ *
22
+ * These are the only aggregates that need the 2-D shape of their range
23
+ * rather than its flattened values, so they read `a.grids` throughout.
24
+ */
25
+ import { type CellValue } from '../ast.js';
26
+ import type { SheetFunction } from '../functions.js';
27
+ type Grid = ReadonlyArray<ReadonlyArray<CellValue>>;
28
+ /** The column `field` names, or -1 when it names none. */
29
+ declare function fieldColumn(field: CellValue, header: ReadonlyArray<CellValue>): number;
30
+ /**
31
+ * The records that satisfy the criteria block, as rows of the database.
32
+ *
33
+ * A criteria row with every cell blank matches everything, which is what
34
+ * Excel does and what makes a criteria block of headers alone a no-op.
35
+ */
36
+ declare function selected(database: Grid, criteria: Grid): Array<ReadonlyArray<CellValue>>;
37
+ export declare const DATABASE_FUNCTIONS: Record<string, SheetFunction>;
38
+ /** Exported for the tests, which check the criteria grammar on its own. */
39
+ export declare const __selectRecords: typeof selected;
40
+ /** Exported for the tests: `field` resolution takes text or a position. */
41
+ export declare const __fieldColumn: typeof fieldColumn;
42
+ export {};