@svgrid/enterprise 3.0.0 → 3.0.2

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 (390) hide show
  1. package/README.md +95 -95
  2. package/dist/ExpressionEditorHarness.svelte.d.ts +2 -2
  3. package/dist/SvAdvancedFilter.svelte.d.ts +2 -2
  4. package/dist/SvAlertRuleEditor.svelte.d.ts +2 -2
  5. package/dist/SvAlertsManager.svelte.d.ts +3 -3
  6. package/dist/SvAlertsPanel.svelte.d.ts +1 -1
  7. package/dist/SvAuthGate.svelte +115 -115
  8. package/dist/SvAuthGate.svelte.d.ts +1 -1
  9. package/dist/SvBoard.svelte.d.ts +1 -1
  10. package/dist/SvExportMenu.svelte +553 -553
  11. package/dist/SvExportMenu.svelte.d.ts +2 -2
  12. package/dist/SvExpressionEditor.svelte.d.ts +2 -2
  13. package/dist/SvFileInput.svelte +113 -113
  14. package/dist/SvFormulaBar.svelte +606 -0
  15. package/dist/SvFormulaBar.svelte.d.ts +62 -0
  16. package/dist/SvGridAlerts.svelte.d.ts +2 -2
  17. package/dist/SvGridBoard.svelte +2358 -2358
  18. package/dist/SvGridBulkEditDrawer.svelte.d.ts +1 -1
  19. package/dist/SvGridEditPanel.svelte +1157 -1157
  20. package/dist/SvGridEditPanel.svelte.d.ts +3 -3
  21. package/dist/SvGridMasterDetail.svelte +116 -116
  22. package/dist/SvGridMasterDetail.svelte.d.ts +1 -1
  23. package/dist/SvGridScheduler.svelte +5358 -5358
  24. package/dist/SvImportDialog.svelte +1020 -1020
  25. package/dist/SvImportDialog.svelte.d.ts +2 -2
  26. package/dist/SvLookupInput.svelte +180 -180
  27. package/dist/SvLookupInput.svelte.d.ts +1 -1
  28. package/dist/SvPivotDesigner.svelte +2041 -1990
  29. package/dist/SvPivotDesigner.svelte.d.ts +2 -2
  30. package/dist/SvRecordDetail.svelte.d.ts +1 -1
  31. package/dist/SvRibbonIcon.svelte +46 -0
  32. package/dist/SvRibbonIcon.svelte.d.ts +17 -0
  33. package/dist/SvSchedule.svelte.d.ts +1 -1
  34. package/dist/SvSchemaChart.svelte +236 -234
  35. package/dist/SvSchemaChart.svelte.d.ts +2 -2
  36. package/dist/SvSchemaDashboard.svelte +130 -130
  37. package/dist/SvSchemaDashboard.svelte.d.ts +3 -3
  38. package/dist/SvSheet.svelte +4114 -0
  39. package/dist/SvSheet.svelte.d.ts +142 -0
  40. package/dist/SvSheetComment.svelte +98 -0
  41. package/dist/SvSheetComment.svelte.d.ts +22 -0
  42. package/dist/SvSheetConditionalFormat.svelte +162 -0
  43. package/dist/SvSheetConditionalFormat.svelte.d.ts +14 -0
  44. package/dist/SvSheetDataValidation.svelte +249 -0
  45. package/dist/SvSheetDataValidation.svelte.d.ts +14 -0
  46. package/dist/SvSheetFilterMenu.svelte +217 -0
  47. package/dist/SvSheetFilterMenu.svelte.d.ts +17 -0
  48. package/dist/SvSheetFindReplace.svelte +132 -0
  49. package/dist/SvSheetFindReplace.svelte.d.ts +10 -0
  50. package/dist/SvSheetFormatCells.svelte +421 -0
  51. package/dist/SvSheetFormatCells.svelte.d.ts +17 -0
  52. package/dist/SvSheetGoalSeek.svelte +144 -0
  53. package/dist/SvSheetGoalSeek.svelte.d.ts +12 -0
  54. package/dist/SvSheetInsertFunction.svelte +147 -0
  55. package/dist/SvSheetInsertFunction.svelte.d.ts +8 -0
  56. package/dist/SvSheetListPicker.svelte +89 -0
  57. package/dist/SvSheetListPicker.svelte.d.ts +16 -0
  58. package/dist/SvSheetManageRules.svelte +185 -0
  59. package/dist/SvSheetManageRules.svelte.d.ts +16 -0
  60. package/dist/SvSheetNameManager.svelte +225 -0
  61. package/dist/SvSheetNameManager.svelte.d.ts +11 -0
  62. package/dist/SvSheetPasteSpecial.svelte +105 -0
  63. package/dist/SvSheetPasteSpecial.svelte.d.ts +12 -0
  64. package/dist/SvSheetRemoveDuplicates.svelte +149 -0
  65. package/dist/SvSheetRemoveDuplicates.svelte.d.ts +12 -0
  66. package/dist/SvSheetRibbon.svelte +1201 -0
  67. package/dist/SvSheetRibbon.svelte.d.ts +34 -0
  68. package/dist/SvSheetSizeDialog.svelte +58 -0
  69. package/dist/SvSheetSizeDialog.svelte.d.ts +11 -0
  70. package/dist/SvSheetTabs.svelte +441 -0
  71. package/dist/SvSheetTabs.svelte.d.ts +36 -0
  72. package/dist/SvSheetTabs.test-harness.svelte.d.ts +17 -0
  73. package/dist/SvSheetTabs.test-harness.svelte.js +22 -0
  74. package/dist/SvSheetTextToColumns.svelte +172 -0
  75. package/dist/SvSheetTextToColumns.svelte.d.ts +13 -0
  76. package/dist/SvSheetValidationAlert.svelte +83 -0
  77. package/dist/SvSheetValidationAlert.svelte.d.ts +15 -0
  78. package/dist/advanced-filter/expr-columns-from-grid.d.ts +1 -1
  79. package/dist/advanced-filter-enable.js +3 -3
  80. package/dist/alerts/alert-engine-attach.d.ts +2 -2
  81. package/dist/alerts/alert-engine-attach.js +3 -3
  82. package/dist/alerts/alert-engine.d.ts +1 -1
  83. package/dist/alerts/alert-engine.js +2 -2
  84. package/dist/alerts/alert-formats.d.ts +1 -1
  85. package/dist/alerts/alert-formats.js +1 -1
  86. package/dist/alerts/alert-observer.d.ts +3 -3
  87. package/dist/alerts/alert-observer.js +1 -1
  88. package/dist/alerts/alert-storage.d.ts +1 -1
  89. package/dist/alerts/alert-store.svelte.d.ts +1 -1
  90. package/dist/alerts/alert-types.d.ts +2 -2
  91. package/dist/alerts.js +2 -2
  92. package/dist/board.js +2 -2
  93. package/dist/cdn/svgrid-enterprise.svelte-external.js +19046 -5428
  94. package/dist/designer/assets/GridMenus-BlsvL_aU.js +8 -0
  95. package/dist/designer/assets/SvChartMenu-BYO9cYdy.css +1 -0
  96. package/dist/designer/assets/SvChartMenu-D9hEeHar.js +1 -0
  97. package/dist/designer/assets/SvDateRangeInput-BBRzrQeg.js +1 -0
  98. package/dist/designer/assets/SvDateRangeInput-C0iCCZ8o.css +1 -0
  99. package/dist/designer/assets/SvDateTimePicker-DARvKUL2.js +1 -0
  100. package/dist/designer/assets/SvDateTimePicker-DPv09DIT.css +1 -0
  101. package/dist/designer/assets/{preload-helper-CG0n22O7.js → SvGrid.helpers-BgT-gnCo.js} +1 -1
  102. package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +4 -0
  103. package/dist/designer/assets/SvGridChart-B8j1SSy3.js +3 -0
  104. package/dist/designer/assets/SvGridChart-BgLuPO7I.css +1 -0
  105. package/dist/designer/assets/SvGridChartBuilder-08YWWeqY.css +1 -0
  106. package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +1 -0
  107. package/dist/designer/assets/SvGridChartPanel-4Pc8y5yO.css +1 -0
  108. package/dist/designer/assets/SvGridChartPanel-pT6ITc2P.js +4 -0
  109. package/dist/designer/assets/SvGridChartView-7msfnWZT.css +1 -0
  110. package/dist/designer/assets/SvGridChartView-bg281UA1.js +1 -0
  111. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +1 -0
  112. package/dist/designer/assets/SvGridDropdown-CcidB3rm.css +1 -0
  113. package/dist/designer/assets/SvListBox-BDS66lmZ.js +110 -0
  114. package/dist/designer/assets/SvListBox-BXfyqy4a.css +1 -0
  115. package/dist/designer/assets/SvMenuList-DJ47ba1h.css +1 -0
  116. package/dist/designer/assets/SvMenuList-Dgq2D5VN.js +1 -0
  117. package/dist/designer/assets/SvTabs-DKmwb5p1.css +1 -0
  118. package/dist/designer/assets/SvTabs-UFCMTHXS.js +1 -0
  119. package/dist/designer/assets/cell-formatting-wr5wm7US.js +1 -0
  120. package/dist/designer/assets/chart-cIPUsbM5.js +1 -0
  121. package/dist/designer/assets/chart-export-B6bkQ3X8.js +11 -0
  122. package/dist/designer/assets/chart-export-pdf-BbA28-gt.js +11 -0
  123. package/dist/designer/assets/chart-panel-messages-DtTxpBUU.js +1 -0
  124. package/dist/designer/assets/chart-summary-Czu_5epb.js +1 -0
  125. package/dist/designer/assets/chart-trend-D5I5VEe8.js +1 -0
  126. package/dist/designer/assets/chart-validate-BMqM-qkF.js +1 -0
  127. package/dist/designer/assets/column-resize-BYDzR1Ve.js +1 -0
  128. package/dist/designer/assets/date-format-B8JbEtIG.js +1 -0
  129. package/dist/designer/assets/date-format-DKS-z0xS.css +1 -0
  130. package/dist/designer/assets/editor-contract-Bpoa7A5g.js +1 -0
  131. package/dist/designer/assets/export-format-D-eP4b2l.js +6 -0
  132. package/dist/designer/assets/focus-trap-CAreAhlU.js +1 -0
  133. package/dist/designer/assets/index-CMFgAoVV.css +1 -0
  134. package/dist/designer/assets/{index-zUBix-JQ.js → index-DwU7CAMm.js} +2985 -141
  135. package/dist/designer/assets/list-option-BP_dWS66.js +1 -0
  136. package/dist/designer/assets/preload-helper-HclGiUj8.js +1 -0
  137. package/dist/designer/assets/row-resize-DLktcqUK.js +1 -0
  138. package/dist/designer/assets/src-CITpcm6b.js +1 -0
  139. package/dist/designer/assets/src-EdI3Xqds.js +58 -0
  140. package/dist/designer/index.html +32 -23
  141. package/dist/export-conditional.d.ts +1 -1
  142. package/dist/export-pdf.d.ts +89 -0
  143. package/dist/export-pdf.js +130 -0
  144. package/dist/export-print.js +19 -19
  145. package/dist/export-xls.d.ts +2 -2
  146. package/dist/export.d.ts +2 -2
  147. package/dist/export.js +23 -16
  148. package/dist/expressions/builder-tree.d.ts +2 -2
  149. package/dist/expressions/builder-tree.js +1 -1
  150. package/dist/expressions/compile.d.ts +1 -1
  151. package/dist/import.js +1 -1
  152. package/dist/index.d.ts +116 -53
  153. package/dist/index.js +117 -50
  154. package/dist/install.d.ts +4 -4
  155. package/dist/install.js +16 -11
  156. package/dist/license.d.ts +3 -2
  157. package/dist/license.js +9 -4
  158. package/dist/node/studio.js +187 -116
  159. package/dist/pivot-chart.d.ts +26 -2
  160. package/dist/pivot-chart.js +25 -69
  161. package/dist/pivot-designer.d.ts +1 -1
  162. package/dist/pivot-enable.js +3 -3
  163. package/dist/print.d.ts +1 -1
  164. package/dist/print.js +4 -4
  165. package/dist/scheduler-config.d.ts +5 -5
  166. package/dist/scheduler-freebusy.d.ts +1 -1
  167. package/dist/scheduler-freebusy.js +1 -1
  168. package/dist/scheduler.js +2 -2
  169. package/dist/schema-designer.d.ts +1 -1
  170. package/dist/schema-designer.js +2 -2
  171. package/dist/selection-bar.js +2 -2
  172. package/dist/sheet/address.d.ts +43 -0
  173. package/dist/sheet/address.js +81 -0
  174. package/dist/sheet/ast.d.ts +94 -0
  175. package/dist/sheet/ast.js +56 -0
  176. package/dist/sheet/auto-filter.d.ts +66 -0
  177. package/dist/sheet/auto-filter.js +147 -0
  178. package/dist/sheet/autocomplete.d.ts +42 -0
  179. package/dist/sheet/autocomplete.js +162 -0
  180. package/dist/sheet/coerce.d.ts +31 -0
  181. package/dist/sheet/coerce.js +122 -0
  182. package/dist/sheet/commands.d.ts +89 -0
  183. package/dist/sheet/commands.js +230 -0
  184. package/dist/sheet/comments.d.ts +29 -0
  185. package/dist/sheet/comments.js +73 -0
  186. package/dist/sheet/conditional-formats.d.ts +144 -0
  187. package/dist/sheet/conditional-formats.js +316 -0
  188. package/dist/sheet/deps.d.ts +60 -0
  189. package/dist/sheet/deps.js +199 -0
  190. package/dist/sheet/document.d.ts +150 -0
  191. package/dist/sheet/document.js +264 -0
  192. package/dist/sheet/edit-keys.d.ts +14 -0
  193. package/dist/sheet/edit-keys.js +40 -0
  194. package/dist/sheet/entry.d.ts +31 -0
  195. package/dist/sheet/entry.js +76 -0
  196. package/dist/sheet/evaluate.d.ts +61 -0
  197. package/dist/sheet/evaluate.js +337 -0
  198. package/dist/sheet/find-replace.d.ts +62 -0
  199. package/dist/sheet/find-replace.js +152 -0
  200. package/dist/sheet/format-store.d.ts +99 -0
  201. package/dist/sheet/format-store.js +233 -0
  202. package/dist/sheet/freeze.d.ts +54 -0
  203. package/dist/sheet/freeze.js +58 -0
  204. package/dist/sheet/function-catalog.d.ts +10 -0
  205. package/dist/sheet/function-catalog.js +94 -0
  206. package/dist/sheet/functions.d.ts +28 -0
  207. package/dist/sheet/functions.js +362 -0
  208. package/dist/sheet/goal-seek.d.ts +73 -0
  209. package/dist/sheet/goal-seek.js +153 -0
  210. package/dist/sheet/index.d.ts +53 -0
  211. package/dist/sheet/index.js +53 -0
  212. package/dist/sheet/merges.d.ts +71 -0
  213. package/dist/sheet/merges.js +137 -0
  214. package/dist/sheet/names.d.ts +31 -0
  215. package/dist/sheet/names.js +87 -0
  216. package/dist/sheet/navigate.d.ts +52 -0
  217. package/dist/sheet/navigate.js +135 -0
  218. package/dist/sheet/number-format.d.ts +63 -0
  219. package/dist/sheet/number-format.js +508 -0
  220. package/dist/sheet/palette.d.ts +19 -0
  221. package/dist/sheet/palette.js +84 -0
  222. package/dist/sheet/parse.d.ts +13 -0
  223. package/dist/sheet/parse.js +108 -0
  224. package/dist/sheet/paste-special.d.ts +164 -0
  225. package/dist/sheet/paste-special.js +592 -0
  226. package/dist/sheet/protection.d.ts +21 -0
  227. package/dist/sheet/protection.js +48 -0
  228. package/dist/sheet/rects.d.ts +45 -0
  229. package/dist/sheet/rects.js +112 -0
  230. package/dist/sheet/refs.d.ts +82 -0
  231. package/dist/sheet/refs.js +266 -0
  232. package/dist/sheet/ribbon-icons.d.ts +31 -0
  233. package/dist/sheet/ribbon-icons.js +350 -0
  234. package/dist/sheet/ribbon.d.ts +173 -0
  235. package/dist/sheet/ribbon.js +753 -0
  236. package/dist/sheet/shortcuts.d.ts +164 -0
  237. package/dist/sheet/shortcuts.js +623 -0
  238. package/dist/sheet/structure.d.ts +87 -0
  239. package/dist/sheet/structure.js +166 -0
  240. package/dist/sheet/tables.d.ts +70 -0
  241. package/dist/sheet/tables.js +147 -0
  242. package/dist/sheet/tokenize.d.ts +54 -0
  243. package/dist/sheet/tokenize.js +304 -0
  244. package/dist/sheet/transforms.d.ts +76 -0
  245. package/dist/sheet/transforms.js +154 -0
  246. package/dist/sheet/validation.d.ts +92 -0
  247. package/dist/sheet/validation.js +241 -0
  248. package/dist/sheet/workbook.d.ts +72 -0
  249. package/dist/sheet/workbook.js +409 -0
  250. package/dist/sheet-enable.d.ts +6 -0
  251. package/dist/sheet-enable.js +46 -0
  252. package/dist/sources/aggregate.d.ts +1 -1
  253. package/dist/sources/auth-supabase.js +1 -1
  254. package/dist/sources/dashboard.d.ts +2 -2
  255. package/dist/sources/dashboard.js +1 -1
  256. package/dist/sources/index.d.ts +13 -13
  257. package/dist/sources/index.js +13 -13
  258. package/dist/sources/realtime-supabase.js +1 -1
  259. package/dist/sources/relation-lookup.d.ts +1 -1
  260. package/dist/sources/relation-lookup.js +1 -1
  261. package/dist/sources/rest-adapters.d.ts +1 -1
  262. package/dist/sources/rest-adapters.js +1 -1
  263. package/dist/sources/rest.d.ts +2 -2
  264. package/dist/sources/rest.js +3 -3
  265. package/dist/sources/supabase.d.ts +2 -2
  266. package/dist/sources/supabase.js +3 -3
  267. package/dist/sources/with-entity-rules.d.ts +1 -1
  268. package/dist/sources/with-entity-rules.js +1 -1
  269. package/dist/sources/with-relation-labels.d.ts +1 -1
  270. package/dist/studio/emit-project.js +2161 -2127
  271. package/dist/studio/emit-schema.js +369 -369
  272. package/dist/studio/index.d.ts +1 -1
  273. package/dist/studio/index.js +1 -1
  274. package/dist/studio/introspect-db.js +45 -45
  275. package/dist/studio/project.d.ts +10 -0
  276. package/dist/studio/samples/crm.js +6 -6
  277. package/dist/studio/samples/fleet.js +7 -7
  278. package/dist/studio/samples/insurance.js +9 -9
  279. package/dist/studio/samples/inventory.js +12 -12
  280. package/dist/studio/samples/projects.js +5 -5
  281. package/dist/studio/samples/support.js +8 -8
  282. package/dist/studio/scaffold-app.js +104 -104
  283. package/dist/studio/scaffold.js +151 -151
  284. package/dist/studio/ui-components.d.ts +7 -0
  285. package/dist/studio/ui-components.generated.js +63 -1
  286. package/dist/studio/ui-components.js +35 -0
  287. package/dist/sveltekit/in-memory.d.ts +3 -3
  288. package/dist/sveltekit/in-memory.js +4 -4
  289. package/dist/sveltekit/index.d.ts +6 -6
  290. package/dist/sveltekit/index.js +5 -5
  291. package/dist/sveltekit/query-plan.d.ts +1 -1
  292. package/dist/sveltekit/sql-source.d.ts +4 -4
  293. package/dist/sveltekit/sql-source.js +4 -4
  294. package/dist/sveltekit/sql.d.ts +1 -1
  295. package/dist/sveltekit/transport.d.ts +2 -2
  296. package/dist/sveltekit/transport.js +1 -1
  297. package/dist/upgrade-prompt.js +25 -25
  298. package/dist/version.d.ts +1 -1
  299. package/dist/version.js +1 -1
  300. package/package.json +12 -4
  301. package/dist/designer/assets/GridMenus-Cgilexpk.js +0 -8
  302. package/dist/designer/assets/SvDateRangeInput-BV5OXYQ2.css +0 -1
  303. package/dist/designer/assets/SvDateRangeInput-CVn-yqrQ.js +0 -1
  304. package/dist/designer/assets/SvDateTimePicker-BdioTrJQ.js +0 -1
  305. package/dist/designer/assets/SvDateTimePicker-CY8TK4BT.css +0 -1
  306. package/dist/designer/assets/SvField-BF-9TJSd.css +0 -1
  307. package/dist/designer/assets/SvField-BsqiA5me.js +0 -1
  308. package/dist/designer/assets/SvGridCellEditor-dLY7_kk9.js +0 -2
  309. package/dist/designer/assets/SvGridChart-BEDNTdc5.js +0 -2
  310. package/dist/designer/assets/SvGridChart-Vu4Nvjiv.css +0 -1
  311. package/dist/designer/assets/SvGridChartPanel-x3lzSxuf.js +0 -10
  312. package/dist/designer/assets/SvGridChartView-CAKhPELi.js +0 -1
  313. package/dist/designer/assets/SvGridChartView-DX9HfkBR.css +0 -1
  314. package/dist/designer/assets/SvGridDropdown-CAYG7Y-O.js +0 -1
  315. package/dist/designer/assets/SvGridDropdown-Crwb2P3Q.css +0 -1
  316. package/dist/designer/assets/SvListBox-CVYQcLX9.js +0 -1
  317. package/dist/designer/assets/SvListBox-DgN8kvjt.css +0 -1
  318. package/dist/designer/assets/chart-DHEgt4lN.js +0 -1
  319. package/dist/designer/assets/column-resize-C_inr5zT.js +0 -1
  320. package/dist/designer/assets/date-format-4DJvNtG2.js +0 -1
  321. package/dist/designer/assets/date-format-Dzy4mTGh.css +0 -1
  322. package/dist/designer/assets/easing-zaypKrr0.js +0 -3
  323. package/dist/designer/assets/export-format-DwjuTfrQ.js +0 -6
  324. package/dist/designer/assets/index-Cp7fDJ3b.css +0 -1
  325. package/dist/designer/assets/js-scroller.svelte-Bhxqb3-c.js +0 -110
  326. package/dist/designer/assets/row-resize-B0FWHcNr.js +0 -1
  327. package/dist/designer/assets/src-B7DNcoQK.css +0 -1
  328. package/dist/designer/assets/src-BoYyigAC.js +0 -2896
  329. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/_svelte_metadata.json +0 -1
  330. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/_metadata.json +0 -178
  331. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js +0 -3875
  332. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/attachments-BOv1rBKp.js.map +0 -1
  333. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js +0 -21
  334. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/constants-B9vgIdCd.js.map +0 -1
  335. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js +0 -1938
  336. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/dev-T1qbW_qD.js.map +0 -1
  337. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js +0 -205
  338. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/events-Bo11SfVK.js.map +0 -1
  339. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js +0 -18
  340. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/flags-X7D4vfrZ.js.map +0 -1
  341. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js +0 -264
  342. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/hydration-oyUje5i1.js.map +0 -1
  343. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js +0 -697
  344. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/legacy-client-DeSQgSFm.js.map +0 -1
  345. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/package.json +0 -3
  346. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js +0 -134
  347. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte.js.map +0 -1
  348. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js +0 -55
  349. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_animate.js.map +0 -1
  350. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_attachments.js +0 -2
  351. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js +0 -46843
  352. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_compiler.js.map +0 -1
  353. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js +0 -237
  354. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_easing.js.map +0 -1
  355. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_events.js +0 -2
  356. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js +0 -4
  357. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal.js.map +0 -1
  358. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_client.js +0 -7
  359. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js +0 -4
  360. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_disclose-version.js.map +0 -1
  361. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js +0 -5
  362. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_async.js.map +0 -1
  363. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js +0 -5
  364. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_legacy.js.map +0 -1
  365. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js +0 -5
  366. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_flags_tracing.js.map +0 -1
  367. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_internal_server.js +0 -6
  368. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js +0 -83
  369. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_legacy.js.map +0 -1
  370. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js +0 -559
  371. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_motion.js.map +0 -1
  372. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js +0 -24
  373. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity.js.map +0 -1
  374. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js +0 -122
  375. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_reactivity_window.js.map +0 -1
  376. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_server.js +0 -2
  377. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js +0 -89
  378. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_store.js.map +0 -1
  379. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js +0 -241
  380. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/svelte_transition.js.map +0 -1
  381. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js +0 -4938
  382. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-BbWyXNk1.js.map +0 -1
  383. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js +0 -495
  384. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/utils-DI_fC7vt.js.map +0 -1
  385. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js +0 -190
  386. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/validate-Dyr3lQv9.js.map +0 -1
  387. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js +0 -8
  388. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/version-_9FHH-LF.js.map +0 -1
  389. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js +0 -138
  390. package/dist/studio/node_modules/.vite/vitest/be65d27ae088a0e03fd8e1331d90b01649464cb6/deps___vitest__/warnings-CUbSPnyP.js.map +0 -1
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Formula lexer.
3
+ *
4
+ * The awkward part of spreadsheet lexing is that `A1`, `A1:B2`, `Sheet1!A1`,
5
+ * `'Price list'!A1:B2`, `SUM(` and `TRUE` all start life as the same run of
6
+ * letters and digits. Rather than guess, the lexer reads the whole word plus
7
+ * whatever qualifies it (a `!` before, a `:` after, a `(` after) and decides
8
+ * once, with all of it in hand.
9
+ *
10
+ * `$` is part of a word here and stays in the text handed to `parseA1`, which
11
+ * is what keeps absolute references absolute.
12
+ */
13
+ import { parseA1 } from './address.js';
14
+ import { FormulaError } from './ast.js';
15
+ const WORD = /[A-Za-z0-9$_.]/;
16
+ const SPECIFIERS = {
17
+ '#all': '#All',
18
+ '#data': '#Data',
19
+ '#headers': '#Headers',
20
+ '#totals': '#Totals',
21
+ '#this row': '#ThisRow',
22
+ };
23
+ const TWO_CHAR_OPS = new Set(['<=', '>=', '<>']);
24
+ const ONE_CHAR_OPS = '+-*/^%&=<>';
25
+ export function tokenize(src) {
26
+ const out = [];
27
+ let i = 0;
28
+ /** Index of the next non-space character, without consuming anything. */
29
+ const skipSpace = () => {
30
+ let j = i;
31
+ while (j < src.length && /\s/.test(src[j]))
32
+ j += 1;
33
+ return j;
34
+ };
35
+ const readWord = () => {
36
+ const start = i;
37
+ while (i < src.length && WORD.test(src[i]))
38
+ i += 1;
39
+ return src.slice(start, i);
40
+ };
41
+ /**
42
+ * Read a structured reference's bracket, having just consumed the `[`.
43
+ *
44
+ * The grammar is small but irregular: `[Amount]` is a column, `[@Amount]`
45
+ * is this row of it, `[#Totals]` is a specifier, and
46
+ * `[[Qty]:[Amount]]` is a span whose inner brackets are part of the
47
+ * syntax rather than nesting. Reading it as balanced brackets and then
48
+ * picking the pieces apart handles all four without a special case each.
49
+ */
50
+ const readTableBracket = (table) => {
51
+ let depth = 1;
52
+ const start = i;
53
+ while (i < src.length && depth > 0) {
54
+ if (src[i] === '[')
55
+ depth += 1;
56
+ else if (src[i] === ']')
57
+ depth -= 1;
58
+ if (depth > 0)
59
+ i += 1;
60
+ }
61
+ if (depth !== 0)
62
+ throw new FormulaError('#PARSE!');
63
+ const body = src.slice(start, i);
64
+ i += 1; // past the closing ]
65
+ let specifier = '#Data';
66
+ let column = null;
67
+ let columnTo = null;
68
+ // Split on top-level commas, so [#Data],[Amount] arrives as two parts.
69
+ const parts = [];
70
+ let current = '';
71
+ let inner = 0;
72
+ for (const ch of body) {
73
+ if (ch === '[')
74
+ inner += 1;
75
+ else if (ch === ']')
76
+ inner -= 1;
77
+ if (ch === ',' && inner === 0) {
78
+ parts.push(current);
79
+ current = '';
80
+ continue;
81
+ }
82
+ current += ch;
83
+ }
84
+ parts.push(current);
85
+ for (const rawPart of parts) {
86
+ let part = rawPart.trim();
87
+ if (part === '')
88
+ continue;
89
+ if (part.startsWith('@')) {
90
+ specifier = '#ThisRow';
91
+ part = part.slice(1).trim();
92
+ if (part === '')
93
+ continue;
94
+ }
95
+ const known = SPECIFIERS[part.toLowerCase()];
96
+ if (known) {
97
+ specifier = known;
98
+ continue;
99
+ }
100
+ // A span: [Qty]:[Amount]
101
+ const span = /^\[([^\]]*)\]\s*:\s*\[([^\]]*)\]$/.exec(part);
102
+ if (span) {
103
+ column = span[1].trim();
104
+ columnTo = span[2].trim();
105
+ continue;
106
+ }
107
+ // A single bracketed part, which is how a name containing a space or a
108
+ // comma is written - and also how a specifier arrives inside a
109
+ // multi-part reference like [[#Headers],[Amount]], so unwrap FIRST
110
+ // and re-check before assuming it names a column.
111
+ const wrapped = /^\[([^\]]*)\]$/.exec(part);
112
+ const unwrapped = (wrapped ? wrapped[1] : part).trim();
113
+ const inner = SPECIFIERS[unwrapped.toLowerCase()];
114
+ if (inner) {
115
+ specifier = inner;
116
+ continue;
117
+ }
118
+ if (unwrapped.startsWith('@')) {
119
+ specifier = '#ThisRow';
120
+ const rest = unwrapped.slice(1).trim();
121
+ if (rest !== '')
122
+ column = rest;
123
+ continue;
124
+ }
125
+ column = unwrapped;
126
+ }
127
+ return columnTo === null
128
+ ? { t: 'table', table, column, specifier }
129
+ : { t: 'table', table, column, columnTo, specifier };
130
+ };
131
+ /** Turn a word (and possibly `:word` after it) into a ref, range or name. */
132
+ const pushWord = (word, sheet) => {
133
+ const left = parseA1(word, sheet);
134
+ // Excel accepts whitespace around the range colon: `SUM(A1 : B2)`. Look
135
+ // past it before deciding this is a lone reference, or that formula comes
136
+ // back unparseable.
137
+ const afterSpace = skipSpace();
138
+ if (src[afterSpace] === ':') {
139
+ i = afterSpace + 1;
140
+ while (i < src.length && /\s/.test(src[i]))
141
+ i += 1;
142
+ const rightWord = readWord();
143
+ const right = parseA1(rightWord, sheet);
144
+ if (!left || !right)
145
+ throw new FormulaError('#PARSE!');
146
+ out.push({ t: 'range', from: left, to: right });
147
+ return;
148
+ }
149
+ if (!left)
150
+ throw new FormulaError('#PARSE!');
151
+ // A word with no row is a whole-column reference (`A:A` written as `A`),
152
+ // which is a range from row 0 to the end of the sheet.
153
+ if (left.row === null) {
154
+ // A bare word on a sheet-qualified ref is still a column. Unqualified,
155
+ // it could be a defined name - the parser decides using `name` tokens,
156
+ // so only emit a column range when the text looks like one.
157
+ if (sheet !== null) {
158
+ out.push({ t: 'range', from: { ...left, row: 0 }, to: { ...left, row: null } });
159
+ return;
160
+ }
161
+ out.push({ t: 'name', v: word });
162
+ return;
163
+ }
164
+ out.push({ t: 'ref', ref: left });
165
+ };
166
+ while (i < src.length) {
167
+ const ch = src[i];
168
+ if (/\s/.test(ch)) {
169
+ i += 1;
170
+ continue;
171
+ }
172
+ if (ch === '(') {
173
+ out.push({ t: 'lparen' });
174
+ i += 1;
175
+ continue;
176
+ }
177
+ if (ch === ')') {
178
+ out.push({ t: 'rparen' });
179
+ i += 1;
180
+ continue;
181
+ }
182
+ if (ch === ',') {
183
+ out.push({ t: 'comma' });
184
+ i += 1;
185
+ continue;
186
+ }
187
+ // String literal. Excel escapes a quote by doubling it.
188
+ if (ch === '"') {
189
+ i += 1;
190
+ let value = '';
191
+ for (;;) {
192
+ if (i >= src.length)
193
+ throw new FormulaError('#PARSE!');
194
+ if (src[i] === '"') {
195
+ if (src[i + 1] === '"') {
196
+ value += '"';
197
+ i += 2;
198
+ continue;
199
+ }
200
+ i += 1;
201
+ break;
202
+ }
203
+ value += src[i];
204
+ i += 1;
205
+ }
206
+ out.push({ t: 'str', v: value });
207
+ continue;
208
+ }
209
+ // Quoted sheet name: 'Price list'!A1
210
+ if (ch === "'") {
211
+ i += 1;
212
+ let sheet = '';
213
+ for (;;) {
214
+ if (i >= src.length)
215
+ throw new FormulaError('#PARSE!');
216
+ if (src[i] === "'") {
217
+ if (src[i + 1] === "'") {
218
+ sheet += "'";
219
+ i += 2;
220
+ continue;
221
+ }
222
+ i += 1;
223
+ break;
224
+ }
225
+ sheet += src[i];
226
+ i += 1;
227
+ }
228
+ if (src[i] !== '!')
229
+ throw new FormulaError('#PARSE!');
230
+ i += 1;
231
+ pushWord(readWord(), sheet);
232
+ continue;
233
+ }
234
+ if (/[0-9]/.test(ch) || (ch === '.' && /[0-9]/.test(src[i + 1] ?? ''))) {
235
+ const start = i;
236
+ while (i < src.length && /[0-9.]/.test(src[i]))
237
+ i += 1;
238
+ // Scientific notation: 1e5, 2.5E-3.
239
+ if ((src[i] === 'e' || src[i] === 'E') && /[0-9+-]/.test(src[i + 1] ?? '')) {
240
+ i += 1;
241
+ if (src[i] === '+' || src[i] === '-')
242
+ i += 1;
243
+ while (i < src.length && /[0-9]/.test(src[i]))
244
+ i += 1;
245
+ }
246
+ const n = Number(src.slice(start, i));
247
+ if (!Number.isFinite(n))
248
+ throw new FormulaError('#PARSE!');
249
+ out.push({ t: 'num', v: n });
250
+ continue;
251
+ }
252
+ if (/[A-Za-z$_]/.test(ch)) {
253
+ const word = readWord();
254
+ const upper = word.toUpperCase();
255
+ // Unquoted sheet name: Orders!A1
256
+ if (src[i] === '!') {
257
+ i += 1;
258
+ pushWord(readWord(), word);
259
+ continue;
260
+ }
261
+ if (upper === 'TRUE') {
262
+ out.push({ t: 'bool', v: true });
263
+ continue;
264
+ }
265
+ if (upper === 'FALSE') {
266
+ out.push({ t: 'bool', v: false });
267
+ continue;
268
+ }
269
+ // A word followed by `[` is a table: Orders[Amount].
270
+ if (src[i] === '[') {
271
+ i += 1;
272
+ out.push(readTableBracket(word));
273
+ continue;
274
+ }
275
+ // A word followed by `(` is a call, whatever else it might look like.
276
+ if (src[skipSpace()] === '(') {
277
+ out.push({ t: 'fn', v: upper });
278
+ continue;
279
+ }
280
+ pushWord(word, null);
281
+ continue;
282
+ }
283
+ // A bare `[` is the unqualified form, which only means something in a
284
+ // formula sitting inside a table: [@Amount].
285
+ if (ch === '[') {
286
+ i += 1;
287
+ out.push(readTableBracket(null));
288
+ continue;
289
+ }
290
+ const two = src.slice(i, i + 2);
291
+ if (TWO_CHAR_OPS.has(two)) {
292
+ out.push({ t: 'op', v: two });
293
+ i += 2;
294
+ continue;
295
+ }
296
+ if (ONE_CHAR_OPS.includes(ch)) {
297
+ out.push({ t: 'op', v: ch });
298
+ i += 1;
299
+ continue;
300
+ }
301
+ throw new FormulaError('#PARSE!');
302
+ }
303
+ return out;
304
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Text to Columns and Remove Duplicates: the two one-shot transforms an Excel
3
+ * user reaches for on arriving data, before any formula work starts.
4
+ *
5
+ * Both are pure functions over cell text rather than commands that reach into
6
+ * a grid, because both are things a consumer may want to run from a button, a
7
+ * menu, a paste handler or a test, and none of those want a keystroke.
8
+ */
9
+ export type SplitOptions = {
10
+ /**
11
+ * Split on these strings. Excel's dialog offers tab, semicolon, comma, space
12
+ * and "other"; passing several splits on any of them.
13
+ */
14
+ delimiters?: ReadonlyArray<string>;
15
+ /** Treat runs of delimiters as one. Excel's "treat consecutive delimiters as
16
+ * one" checkbox, and what you want for space-separated text. */
17
+ collapse?: boolean;
18
+ /** Text inside these is not split, and the quotes come off. */
19
+ quote?: string;
20
+ /** Trim surrounding whitespace from each field. */
21
+ trim?: boolean;
22
+ /** Stop after this many fields, leaving the rest in the last one. Excel has
23
+ * no equivalent; it is here because "name: free text with: colons" is the
24
+ * common real case. */
25
+ limit?: number;
26
+ };
27
+ /**
28
+ * Split one string into fields.
29
+ *
30
+ * A scan rather than `String.split`, because a quoted field may contain a
31
+ * delimiter and a doubled quote is an escaped one. Splitting first and
32
+ * repairing afterwards is how CSV parsers get subtly wrong.
33
+ */
34
+ export declare function splitText(text: string, options?: SplitOptions): string[];
35
+ /**
36
+ * Split a column of text into a grid, padded so every row is the same width.
37
+ *
38
+ * Padding matters: writing a ragged result into a grid leaves whatever was
39
+ * already in the cell, so a row that split into two fields would keep stale
40
+ * text in the third column.
41
+ */
42
+ export declare function textToColumns(column: ReadonlyArray<string>, options?: SplitOptions): {
43
+ rows: string[][];
44
+ width: number;
45
+ };
46
+ /** Guess which delimiter a column uses, the way Excel's wizard previews one. */
47
+ export declare function guessDelimiter(column: ReadonlyArray<string>, candidates?: ReadonlyArray<string>): string | null;
48
+ export type DuplicateOptions = {
49
+ /** Column indexes that decide identity. Default: every column given. */
50
+ columns?: ReadonlyArray<number>;
51
+ /** Compare case-sensitively. Excel's Remove Duplicates is case
52
+ * INSENSITIVE, which surprises people, so that is the default here too. */
53
+ matchCase?: boolean;
54
+ /** Keep the last of each group rather than the first. */
55
+ keep?: 'first' | 'last';
56
+ };
57
+ export type DuplicateReport = {
58
+ /** Indexes into the input, in order, of the rows to keep. */
59
+ keep: number[];
60
+ /** Indexes of the rows that duplicate another. */
61
+ remove: number[];
62
+ };
63
+ /**
64
+ * Which rows are duplicates.
65
+ *
66
+ * Reports rather than removes, so the caller decides what removal means for
67
+ * its data structure, and so a UI can say "3 duplicates found, 5 unique values
68
+ * remain" before anything is written. That message is most of what Excel's
69
+ * dialog does.
70
+ */
71
+ export declare function findDuplicates(rows: ReadonlyArray<ReadonlyArray<unknown>>, options?: DuplicateOptions): DuplicateReport;
72
+ /** The rows that survive, in their original order, and how many went. */
73
+ export declare function removeDuplicates<T>(rows: ReadonlyArray<T>, toCells: (row: T) => ReadonlyArray<unknown>, options?: DuplicateOptions): {
74
+ rows: T[];
75
+ removed: number;
76
+ };
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Text to Columns and Remove Duplicates: the two one-shot transforms an Excel
3
+ * user reaches for on arriving data, before any formula work starts.
4
+ *
5
+ * Both are pure functions over cell text rather than commands that reach into
6
+ * a grid, because both are things a consumer may want to run from a button, a
7
+ * menu, a paste handler or a test, and none of those want a keystroke.
8
+ */
9
+ const DEFAULTS = {
10
+ delimiters: [','],
11
+ collapse: false,
12
+ quote: '"',
13
+ trim: false,
14
+ };
15
+ /**
16
+ * Split one string into fields.
17
+ *
18
+ * A scan rather than `String.split`, because a quoted field may contain a
19
+ * delimiter and a doubled quote is an escaped one. Splitting first and
20
+ * repairing afterwards is how CSV parsers get subtly wrong.
21
+ */
22
+ export function splitText(text, options = {}) {
23
+ const { delimiters, collapse, quote, trim } = { ...DEFAULTS, ...options };
24
+ const limit = options.limit;
25
+ // Longest first, so ", " wins over "," when both are offered.
26
+ const seps = [...delimiters].filter((d) => d !== '').sort((a, b) => b.length - a.length);
27
+ if (seps.length === 0)
28
+ return [text];
29
+ const out = [];
30
+ let current = '';
31
+ let inQuote = false;
32
+ let i = 0;
33
+ const push = () => {
34
+ out.push(trim ? current.trim() : current);
35
+ current = '';
36
+ };
37
+ while (i < text.length) {
38
+ const ch = text[i];
39
+ if (quote && ch === quote) {
40
+ if (inQuote && text[i + 1] === quote) {
41
+ current += quote;
42
+ i += 2;
43
+ continue;
44
+ }
45
+ inQuote = !inQuote;
46
+ i += 1;
47
+ continue;
48
+ }
49
+ if (!inQuote && (limit === undefined || out.length < limit - 1)) {
50
+ const hit = seps.find((sep) => text.startsWith(sep, i));
51
+ if (hit) {
52
+ push();
53
+ i += hit.length;
54
+ if (collapse) {
55
+ // Swallow the run that follows, so "a b" on a space delimiter
56
+ // gives two fields rather than four.
57
+ for (;;) {
58
+ const more = seps.find((sep) => text.startsWith(sep, i));
59
+ if (!more)
60
+ break;
61
+ i += more.length;
62
+ }
63
+ }
64
+ continue;
65
+ }
66
+ }
67
+ current += ch;
68
+ i += 1;
69
+ }
70
+ push();
71
+ return out;
72
+ }
73
+ /**
74
+ * Split a column of text into a grid, padded so every row is the same width.
75
+ *
76
+ * Padding matters: writing a ragged result into a grid leaves whatever was
77
+ * already in the cell, so a row that split into two fields would keep stale
78
+ * text in the third column.
79
+ */
80
+ export function textToColumns(column, options = {}) {
81
+ const rows = column.map((text) => splitText(text, options));
82
+ const width = rows.reduce((max, row) => Math.max(max, row.length), 0);
83
+ for (const row of rows) {
84
+ while (row.length < width)
85
+ row.push('');
86
+ }
87
+ return { rows, width };
88
+ }
89
+ /** Guess which delimiter a column uses, the way Excel's wizard previews one. */
90
+ export function guessDelimiter(column, candidates = ['\t', ';', ',', '|', ' ']) {
91
+ let best = null;
92
+ for (const sep of candidates) {
93
+ // A good delimiter appears in most rows AND the same number of times in
94
+ // each. A comma in one row out of fifty is prose, not structure.
95
+ const counts = column.map((text) => text.split(sep).length - 1);
96
+ const present = counts.filter((n) => n > 0).length;
97
+ if (present === 0)
98
+ continue;
99
+ const first = counts.find((n) => n > 0) ?? 0;
100
+ const consistent = counts.every((n) => n === 0 || n === first);
101
+ const score = present * (consistent ? 2 : 1);
102
+ if (!best || score > best.score)
103
+ best = { sep, score };
104
+ }
105
+ return best ? best.sep : null;
106
+ }
107
+ /**
108
+ * Which rows are duplicates.
109
+ *
110
+ * Reports rather than removes, so the caller decides what removal means for
111
+ * its data structure, and so a UI can say "3 duplicates found, 5 unique values
112
+ * remain" before anything is written. That message is most of what Excel's
113
+ * dialog does.
114
+ */
115
+ export function findDuplicates(rows, options = {}) {
116
+ const keepWhich = options.keep ?? 'first';
117
+ const matchCase = options.matchCase ?? false;
118
+ const keyOf = (row) => {
119
+ const cols = options.columns ?? row.map((_v, i) => i);
120
+ return cols
121
+ .map((c) => {
122
+ const v = row[c];
123
+ const text = v === null || v === undefined ? '' : String(v);
124
+ return matchCase ? text : text.toLowerCase();
125
+ })
126
+ // A separator a cell cannot contain. Joining on a space would make
127
+ // ["a", "b"] and ["a b"] the same row.
128
+ .join('\u0000');
129
+ };
130
+ const seen = new Map();
131
+ for (let i = 0; i < rows.length; i += 1) {
132
+ const key = keyOf(rows[i]);
133
+ if (!seen.has(key) || keepWhich === 'last')
134
+ seen.set(key, i);
135
+ }
136
+ const kept = new Set(seen.values());
137
+ const keep = [];
138
+ const remove = [];
139
+ for (let i = 0; i < rows.length; i += 1) {
140
+ if (kept.has(i))
141
+ keep.push(i);
142
+ else
143
+ remove.push(i);
144
+ }
145
+ return { keep, remove };
146
+ }
147
+ /** The rows that survive, in their original order, and how many went. */
148
+ export function removeDuplicates(rows, toCells, options = {}) {
149
+ const report = findDuplicates(rows.map(toCells), options);
150
+ return {
151
+ rows: report.keep.map((i) => rows[i]),
152
+ removed: report.remove.length,
153
+ };
154
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Data validation, Excel's: a rule over some cells says what may be typed
3
+ * into them, and an entry that breaks it is stopped (or warned about)
4
+ * before it lands. Only typed entries are checked, as in Excel: paste, fill
5
+ * and the commands write what they are given.
6
+ *
7
+ * Rules keep their rectangles by position and move with an insert or
8
+ * delete; the last rule that covers a cell is the one that applies, which
9
+ * is what lets a later rule over a smaller block override an earlier one.
10
+ * Bounds and custom rules are text (a literal or a formula) evaluated in
11
+ * the sheet through the context the shell supplies, so `=$B$1` as a
12
+ * maximum follows B1.
13
+ */
14
+ import { type CellValue } from './ast.js';
15
+ import type { StructuralEdit } from './refs.js';
16
+ import { type Rect } from './rects.js';
17
+ export type ValidationAllow = 'any' | 'whole' | 'decimal' | 'list' | 'date' | 'textLength' | 'custom';
18
+ export type ValidationOperator = 'between' | 'notBetween' | 'equal' | 'notEqual' | 'greater' | 'less' | 'greaterOrEqual' | 'lessOrEqual';
19
+ /** Everything a rule is but where it applies: what the dialog hands back. */
20
+ export type ValidationSpec = Omit<ValidationRule, 'id' | 'rects'>;
21
+ export type ValidationRule = {
22
+ id: string;
23
+ rects: ReadonlyArray<Rect>;
24
+ allow: ValidationAllow;
25
+ /** For whole, decimal, date and textLength. Default between. */
26
+ operator?: ValidationOperator;
27
+ /** The bound, the value, the list source or the custom formula: a
28
+ * literal, a comma list, or a formula starting with '='. */
29
+ value1?: string;
30
+ /** The upper bound of between / notBetween. */
31
+ value2?: string;
32
+ ignoreBlank: boolean;
33
+ /** List rules: show the arrow and the picker on the cell. */
34
+ inCellDropdown: boolean;
35
+ alert: {
36
+ style: 'stop' | 'warning';
37
+ title?: string;
38
+ message?: string;
39
+ };
40
+ };
41
+ /** How a rule reads the sheet: the shell wires the workbook in. */
42
+ export type ValidationContext = {
43
+ /**
44
+ * A formula or a literal, evaluated in the sheet. With `entry`, the
45
+ * cell being checked reads as that text: Excel's custom rules refer to
46
+ * the cell they guard (`=A1>B1` on A1), and the entry is not written yet.
47
+ */
48
+ evaluate(text: string, entry?: {
49
+ row: number;
50
+ col: number;
51
+ text: string;
52
+ }): CellValue;
53
+ /** The values of a range reference or a name for one; null otherwise. */
54
+ range(text: string): CellValue[][] | null;
55
+ };
56
+ export type ValidationVerdict = {
57
+ ok: true;
58
+ } | {
59
+ ok: false;
60
+ style: 'stop' | 'warning';
61
+ title: string;
62
+ message: string;
63
+ };
64
+ /** Excel's own words when a rule has no message of its own. */
65
+ export declare const DEFAULT_ALERT_MESSAGE = "This value doesn't match the data validation restrictions defined for this cell.";
66
+ export declare const OPERATOR_LABELS: Record<ValidationOperator, string>;
67
+ export declare function validationId(): string;
68
+ /** The rule that applies to (r, c): the last one covering it. */
69
+ export declare function ruleAt(rules: ReadonlyArray<ValidationRule>, r: number, c: number): ValidationRule | undefined;
70
+ /** The rules touching any of the rectangles. */
71
+ export declare function rulesIn(rules: ReadonlyArray<ValidationRule>, rects: ReadonlyArray<Rect>): ValidationRule[];
72
+ /** A date as milliseconds: an ISO text, or an Excel serial. Null otherwise. */
73
+ export declare function dateValue(v: CellValue): number | null;
74
+ /**
75
+ * The choices a list rule offers: a comma list as written, or the cells of
76
+ * a range (or a name for one), blanks left out, as text.
77
+ */
78
+ export declare function listChoices(rule: ValidationRule, ctx: ValidationContext): string[];
79
+ /**
80
+ * Whether `text`, typed into (row, col), passes the rule. The verdict
81
+ * carries the alert to show when it does not.
82
+ */
83
+ export declare function checkEntry(rule: ValidationRule, text: string, at: {
84
+ row: number;
85
+ col: number;
86
+ }, ctx: ValidationContext): ValidationVerdict;
87
+ /** The rules after an insert or delete. */
88
+ export declare function shiftValidation(rules: ReadonlyArray<ValidationRule>, edit: StructuralEdit): ValidationRule[];
89
+ /** The rules with the rectangles cut out of them: Excel's Clear All. */
90
+ export declare function removeValidation(rules: ReadonlyArray<ValidationRule>, rects: ReadonlyArray<Rect>): ValidationRule[];
91
+ /** A short description for a rule, the way Excel's dialog title reads it. */
92
+ export declare function describeRule(rule: ValidationRule): string;