@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,94 @@
1
+ /**
2
+ * What Insert Function shows for each function: its group, the argument
3
+ * list, and one line on what it does. The engine's table (`FUNCTIONS`) is
4
+ * the source of truth for which names exist; a name missing here is listed
5
+ * with a bare `NAME(...)` and no description rather than left out, so a
6
+ * custom function registered through `withCustomFunctions` appears too.
7
+ */
8
+ import { FUNCTIONS } from './functions.js';
9
+ import { SIGNATURES } from './autocomplete.js';
10
+ const CATALOG = {
11
+ SUM: { group: 'Math', description: 'Adds all the numbers in a range of cells.', signature: 'SUM(number1, [number2], ...)' },
12
+ ABS: { group: 'Math', description: 'Returns the absolute value of a number, a number without its sign.', signature: 'ABS(number)' },
13
+ INT: { group: 'Math', description: 'Rounds a number down to the nearest integer.', signature: 'INT(number)' },
14
+ MOD: { group: 'Math', description: 'Returns the remainder after a number is divided by a divisor.', signature: 'MOD(number, divisor)' },
15
+ POWER: { group: 'Math', description: 'Returns the result of a number raised to a power.', signature: 'POWER(number, power)' },
16
+ SQRT: { group: 'Math', description: 'Returns the square root of a number.', signature: 'SQRT(number)' },
17
+ ROUND: { group: 'Math', description: 'Rounds a number to a specified number of digits.' },
18
+ ROUNDUP: { group: 'Math', description: 'Rounds a number up, away from zero.', signature: 'ROUNDUP(number, digits)' },
19
+ ROUNDDOWN: { group: 'Math', description: 'Rounds a number down, toward zero.', signature: 'ROUNDDOWN(number, digits)' },
20
+ SUMIF: { group: 'Math', description: 'Adds the cells specified by a given condition or criteria.' },
21
+ SUMIFS: { group: 'Math', description: 'Adds the cells specified by a given set of conditions or criteria.' },
22
+ AVERAGE: { group: 'Statistical', description: 'Returns the average (arithmetic mean) of its arguments.', signature: 'AVERAGE(number1, [number2], ...)' },
23
+ AVG: { group: 'Statistical', description: 'The same as AVERAGE.', signature: 'AVG(number1, [number2], ...)' },
24
+ MIN: { group: 'Statistical', description: 'Returns the smallest number in a set of values.', signature: 'MIN(number1, [number2], ...)' },
25
+ MAX: { group: 'Statistical', description: 'Returns the largest value in a set of values.', signature: 'MAX(number1, [number2], ...)' },
26
+ COUNT: { group: 'Statistical', description: 'Counts the number of cells in a range that contain numbers.', signature: 'COUNT(value1, [value2], ...)' },
27
+ COUNTA: { group: 'Statistical', description: 'Counts the number of cells in a range that are not empty.', signature: 'COUNTA(value1, [value2], ...)' },
28
+ COUNTBLANK: { group: 'Statistical', description: 'Counts the number of empty cells in a range.', signature: 'COUNTBLANK(range)' },
29
+ MEDIAN: { group: 'Statistical', description: 'Returns the median, the number in the middle of a set of numbers.', signature: 'MEDIAN(number1, [number2], ...)' },
30
+ STDEV: { group: 'Statistical', description: 'Estimates standard deviation based on a sample.', signature: 'STDEV(number1, [number2], ...)' },
31
+ RANK: { group: 'Statistical', description: 'Returns the rank of a number in a list of numbers.', signature: 'RANK(number, ref, [order])' },
32
+ COUNTIF: { group: 'Statistical', description: 'Counts the number of cells within a range that meet the given condition.' },
33
+ COUNTIFS: { group: 'Statistical', description: 'Counts the number of cells specified by a given set of conditions.' },
34
+ AVERAGEIF: { group: 'Statistical', description: 'Finds the average of the cells specified by a given condition.' },
35
+ IF: { group: 'Logical', description: 'Checks whether a condition is met, and returns one value if TRUE and another if FALSE.' },
36
+ IFS: { group: 'Logical', description: 'Checks whether one or more conditions are met and returns a value corresponding to the first TRUE condition.' },
37
+ IFERROR: { group: 'Logical', description: 'Returns a value you specify if a formula evaluates to an error; otherwise, returns the result of the formula.' },
38
+ IFNA: { group: 'Logical', description: 'Returns the value you specify if the expression resolves to #N/A, otherwise returns the result of the expression.', signature: 'IFNA(value, fallback)' },
39
+ SWITCH: { group: 'Logical', description: 'Evaluates an expression against a list of values and returns the result corresponding to the first matching value.' },
40
+ AND: { group: 'Logical', description: 'Checks whether all arguments are TRUE, and returns TRUE if all arguments are TRUE.', signature: 'AND(logical1, [logical2], ...)' },
41
+ OR: { group: 'Logical', description: 'Checks whether any of the arguments are TRUE, and returns TRUE or FALSE.', signature: 'OR(logical1, [logical2], ...)' },
42
+ NOT: { group: 'Logical', description: 'Changes FALSE to TRUE, or TRUE to FALSE.', signature: 'NOT(logical)' },
43
+ XOR: { group: 'Logical', description: 'Returns a logical exclusive OR of all arguments.', signature: 'XOR(logical1, [logical2], ...)' },
44
+ ISNUMBER: { group: 'Information', description: 'Checks whether a value is a number, and returns TRUE or FALSE.', signature: 'ISNUMBER(value)' },
45
+ ISTEXT: { group: 'Information', description: 'Checks whether a value is text, and returns TRUE or FALSE.', signature: 'ISTEXT(value)' },
46
+ ISLOGICAL: { group: 'Information', description: 'Checks whether a value is a logical value (TRUE or FALSE), and returns TRUE or FALSE.', signature: 'ISLOGICAL(value)' },
47
+ ISBLANK: { group: 'Information', description: 'Checks whether a reference is to an empty cell, and returns TRUE or FALSE.', signature: 'ISBLANK(value)' },
48
+ LEN: { group: 'Text', description: 'Returns the number of characters in a text string.', signature: 'LEN(text)' },
49
+ LEFT: { group: 'Text', description: 'Returns the specified number of characters from the start of a text string.', signature: 'LEFT(text, [count])' },
50
+ RIGHT: { group: 'Text', description: 'Returns the specified number of characters from the end of a text string.', signature: 'RIGHT(text, [count])' },
51
+ MID: { group: 'Text', description: 'Returns the characters from the middle of a text string, given a starting position and length.' },
52
+ UPPER: { group: 'Text', description: 'Converts a text string to all uppercase letters.', signature: 'UPPER(text)' },
53
+ LOWER: { group: 'Text', description: 'Converts all letters in a text string to lowercase.', signature: 'LOWER(text)' },
54
+ TRIM: { group: 'Text', description: 'Removes all spaces from a text string except for single spaces between words.', signature: 'TRIM(text)' },
55
+ CONCAT: { group: 'Text', description: 'Concatenates a list or range of text strings.', signature: 'CONCAT(text1, [text2], ...)' },
56
+ CONCATENATE: { group: 'Text', description: 'Joins several text strings into one text string.', signature: 'CONCATENATE(text1, [text2], ...)' },
57
+ TEXTJOIN: { group: 'Text', description: 'Concatenates a list or range of text strings using a delimiter.' },
58
+ SUBSTITUTE: { group: 'Text', description: 'Replaces existing text with new text in a text string.' },
59
+ FIND: { group: 'Text', description: 'Returns the starting position of one text string within another; case-sensitive.', signature: 'FIND(find, within, [start])' },
60
+ SEARCH: { group: 'Text', description: 'Returns the position of one text string within another; not case-sensitive.', signature: 'SEARCH(find, within, [start])' },
61
+ TEXT: { group: 'Text', description: 'Converts a value to text in a specific number format.' },
62
+ TODAY: { group: 'Date & Time', description: "Returns the current date formatted as a date.", signature: 'TODAY()' },
63
+ NOW: { group: 'Date & Time', description: 'Returns the current date and time formatted as a date and time.', signature: 'NOW()' },
64
+ YEAR: { group: 'Date & Time', description: 'Returns the year of a date, an integer in the range 1900 - 9999.', signature: 'YEAR(date)' },
65
+ MONTH: { group: 'Date & Time', description: 'Returns the month, a number from 1 (January) to 12 (December).', signature: 'MONTH(date)' },
66
+ DAY: { group: 'Date & Time', description: 'Returns the day of the month, a number from 1 to 31.', signature: 'DAY(date)' },
67
+ DATE: { group: 'Date & Time', description: 'Returns the date for a given year, month and day.' },
68
+ EOMONTH: { group: 'Date & Time', description: 'Returns the last day of the month before or after a specified number of months.' },
69
+ DAYS: { group: 'Date & Time', description: 'Returns the number of days between two dates.', signature: 'DAYS(end_date, start_date)' },
70
+ DATEDIF: { group: 'Date & Time', description: 'Calculates the number of days, months or years between two dates.', signature: 'DATEDIF(start_date, end_date, unit)' },
71
+ VLOOKUP: { group: 'Lookup & Reference', description: 'Looks for a value in the leftmost column of a table, and returns a value in the same row from a column you specify.' },
72
+ HLOOKUP: { group: 'Lookup & Reference', description: 'Looks for a value in the top row of a table, and returns a value in the same column from a row you specify.' },
73
+ XLOOKUP: { group: 'Lookup & Reference', description: 'Searches a range for a match and returns the corresponding item from a second range.' },
74
+ INDEX: { group: 'Lookup & Reference', description: 'Returns a value from a range at the intersection of a given row and column.' },
75
+ MATCH: { group: 'Lookup & Reference', description: 'Returns the relative position of an item in a range that matches a specified value.' },
76
+ };
77
+ /** The IF family is dispatched by the evaluator, not the function table. */
78
+ const EVALUATOR_FUNCTIONS = ['IF', 'IFS', 'IFERROR', 'IFNA', 'SWITCH'];
79
+ export const FUNCTION_GROUPS = [
80
+ 'Math', 'Statistical', 'Logical', 'Information', 'Text', 'Date & Time', 'Lookup & Reference', 'Other',
81
+ ];
82
+ /** Every function the engine knows, described, alphabetical. */
83
+ export function functionCatalog() {
84
+ const names = new Set([...Object.keys(FUNCTIONS), ...EVALUATOR_FUNCTIONS]);
85
+ return [...names].sort().map((name) => {
86
+ const entry = CATALOG[name];
87
+ return {
88
+ name,
89
+ group: entry?.group ?? 'Other',
90
+ signature: entry?.signature ?? SIGNATURES[name] ?? `${name}(...)`,
91
+ description: entry?.description ?? '',
92
+ };
93
+ });
94
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The function table.
3
+ *
4
+ * Each entry receives its arguments already evaluated, in two shapes:
5
+ * - `flat` every argument flattened into one list, ranges expanded. What
6
+ * SUM and COUNT want.
7
+ * - `args` one list per argument, so a function can tell `SUM(A1:A3, 5)`
8
+ * from `SUM(A1:A3)` and `SUMIF` can line a range up against a
9
+ * parallel one.
10
+ * - `grids` the 2-D shape of any range argument, kept for VLOOKUP / INDEX /
11
+ * MATCH, which lose meaning once flattened.
12
+ *
13
+ * Functions that must NOT evaluate every argument (IF, IFERROR, AND, OR with
14
+ * short-circuit semantics) are handled in the evaluator instead, because by the
15
+ * time a table entry runs, evaluation has already happened.
16
+ */
17
+ import { isError, type CellValue } from './ast.js';
18
+ export type FnArgs = {
19
+ flat: ReadonlyArray<CellValue>;
20
+ args: ReadonlyArray<ReadonlyArray<CellValue>>;
21
+ grids: ReadonlyArray<ReadonlyArray<ReadonlyArray<CellValue>> | null>;
22
+ };
23
+ export type SheetFunction = (a: FnArgs) => CellValue;
24
+ export declare const FUNCTIONS: Record<string, SheetFunction>;
25
+ /** Merge caller-supplied functions over the built-ins. Keys are uppercased so
26
+ * a consumer can register `myFn` and write `=MYFN()`. */
27
+ export declare function withCustomFunctions(custom: Record<string, SheetFunction> | undefined): Record<string, SheetFunction>;
28
+ export { isError };
@@ -0,0 +1,362 @@
1
+ /**
2
+ * The function table.
3
+ *
4
+ * Each entry receives its arguments already evaluated, in two shapes:
5
+ * - `flat` every argument flattened into one list, ranges expanded. What
6
+ * SUM and COUNT want.
7
+ * - `args` one list per argument, so a function can tell `SUM(A1:A3, 5)`
8
+ * from `SUM(A1:A3)` and `SUMIF` can line a range up against a
9
+ * parallel one.
10
+ * - `grids` the 2-D shape of any range argument, kept for VLOOKUP / INDEX /
11
+ * MATCH, which lose meaning once flattened.
12
+ *
13
+ * Functions that must NOT evaluate every argument (IF, IFERROR, AND, OR with
14
+ * short-circuit semantics) are handled in the evaluator instead, because by the
15
+ * time a table entry runs, evaluation has already happened.
16
+ */
17
+ import { FormulaError, isError, err } from './ast.js';
18
+ import { toNumber, toBool, toText, looseEquals, compare, numericOnly, isBlank, matchesCriterion, } from './coerce.js';
19
+ const first = (a) => a.flat[0] ?? '';
20
+ const nth = (a, i) => a.args[i]?.[0] ?? '';
21
+ function sum(values) {
22
+ return numericOnly(values).reduce((x, y) => x + y, 0);
23
+ }
24
+ function average(values) {
25
+ const ns = numericOnly(values);
26
+ if (ns.length === 0)
27
+ return err('#DIV/0!');
28
+ return ns.reduce((x, y) => x + y, 0) / ns.length;
29
+ }
30
+ function roundTo(value, digits) {
31
+ const f = Math.pow(10, digits);
32
+ // Scale, round, unscale. The epsilon nudge keeps 1.005 -> 1.01 rather than
33
+ // 1.00, which is the binary-float surprise users report as a bug.
34
+ return Math.round((value * f) * (1 + Number.EPSILON)) / f;
35
+ }
36
+ function toDate(v) {
37
+ if (typeof v === 'number') {
38
+ // Excel serial: day 1 is 1900-01-01, with the famous phantom leap day.
39
+ return new Date(Date.UTC(1899, 11, 30) + v * 86400000);
40
+ }
41
+ const d = new Date(toText(v));
42
+ if (Number.isNaN(d.getTime()))
43
+ throw new FormulaError('#VALUE!');
44
+ return d;
45
+ }
46
+ const iso = (d) => d.toISOString().slice(0, 10);
47
+ /** Sum / count / average over a criterion range, optionally summing a parallel
48
+ * range. The three IF functions differ only in what they do with the hits. */
49
+ function criteriaHits(range, criterion) {
50
+ const out = [];
51
+ for (let i = 0; i < range.length; i += 1) {
52
+ if (matchesCriterion(range[i], criterion))
53
+ out.push(i);
54
+ }
55
+ return out;
56
+ }
57
+ /** SUMIFS / COUNTIFS: every (range, criterion) pair must match at an index. */
58
+ function multiCriteriaHits(pairs) {
59
+ const firstPair = pairs[0];
60
+ if (!firstPair)
61
+ return [];
62
+ const out = [];
63
+ for (let i = 0; i < firstPair[0].length; i += 1) {
64
+ if (pairs.every(([range, crit]) => matchesCriterion(range[i] ?? '', crit)))
65
+ out.push(i);
66
+ }
67
+ return out;
68
+ }
69
+ export const FUNCTIONS = {
70
+ // ---- Math and aggregation -------------------------------------------
71
+ SUM: (a) => sum(a.flat),
72
+ AVERAGE: (a) => average(a.flat),
73
+ AVG: (a) => average(a.flat),
74
+ MIN: (a) => { const n = numericOnly(a.flat); return n.length ? Math.min(...n) : 0; },
75
+ MAX: (a) => { const n = numericOnly(a.flat); return n.length ? Math.max(...n) : 0; },
76
+ COUNT: (a) => a.flat.filter((v) => typeof v === 'number').length,
77
+ COUNTA: (a) => a.flat.filter((v) => !isBlank(v)).length,
78
+ COUNTBLANK: (a) => a.flat.filter((v) => isBlank(v)).length,
79
+ ABS: (a) => Math.abs(toNumber(first(a))),
80
+ INT: (a) => Math.floor(toNumber(first(a))),
81
+ MOD: (a) => {
82
+ const d = toNumber(nth(a, 1));
83
+ if (d === 0)
84
+ return err('#DIV/0!');
85
+ // Excel's MOD follows the sign of the divisor, unlike JavaScript's %.
86
+ const n = toNumber(nth(a, 0));
87
+ return n - d * Math.floor(n / d);
88
+ },
89
+ POWER: (a) => Math.pow(toNumber(nth(a, 0)), toNumber(nth(a, 1))),
90
+ SQRT: (a) => {
91
+ const n = toNumber(first(a));
92
+ return n < 0 ? err('#NUM!') : Math.sqrt(n);
93
+ },
94
+ ROUND: (a) => roundTo(toNumber(nth(a, 0)), Math.round(toNumber(nth(a, 1) || 0))),
95
+ ROUNDUP: (a) => {
96
+ const d = Math.round(toNumber(nth(a, 1) || 0));
97
+ const f = Math.pow(10, d);
98
+ const v = toNumber(nth(a, 0));
99
+ return (v < 0 ? -Math.ceil(-v * f) : Math.ceil(v * f)) / f;
100
+ },
101
+ ROUNDDOWN: (a) => {
102
+ const d = Math.round(toNumber(nth(a, 1) || 0));
103
+ const f = Math.pow(10, d);
104
+ const v = toNumber(nth(a, 0));
105
+ return (v < 0 ? -Math.floor(-v * f) : Math.floor(v * f)) / f;
106
+ },
107
+ MEDIAN: (a) => {
108
+ const n = numericOnly(a.flat).sort((x, y) => x - y);
109
+ if (!n.length)
110
+ return err('#NUM!');
111
+ const mid = Math.floor(n.length / 2);
112
+ return n.length % 2 ? n[mid] : (n[mid - 1] + n[mid]) / 2;
113
+ },
114
+ STDEV: (a) => {
115
+ const n = numericOnly(a.flat);
116
+ if (n.length < 2)
117
+ return err('#DIV/0!');
118
+ const mean = n.reduce((x, y) => x + y, 0) / n.length;
119
+ const variance = n.reduce((acc, v) => acc + (v - mean) ** 2, 0) / (n.length - 1);
120
+ return Math.sqrt(variance);
121
+ },
122
+ RANK: (a) => {
123
+ const value = toNumber(nth(a, 0));
124
+ const pool = numericOnly(a.args[1] ?? []);
125
+ const ascending = a.args[2] !== undefined && toBool(nth(a, 2));
126
+ const sorted = pool.slice().sort((x, y) => (ascending ? x - y : y - x));
127
+ const at = sorted.indexOf(value);
128
+ return at < 0 ? err('#N/A') : at + 1;
129
+ },
130
+ // ---- Conditional aggregation ----------------------------------------
131
+ SUMIF: (a) => {
132
+ const range = a.args[0] ?? [];
133
+ const hits = criteriaHits(range, nth(a, 1));
134
+ // The optional third argument is the range actually summed.
135
+ const target = a.args[2] ?? range;
136
+ return sum(hits.map((i) => target[i] ?? ''));
137
+ },
138
+ COUNTIF: (a) => criteriaHits(a.args[0] ?? [], nth(a, 1)).length,
139
+ AVERAGEIF: (a) => {
140
+ const range = a.args[0] ?? [];
141
+ const hits = criteriaHits(range, nth(a, 1));
142
+ const target = a.args[2] ?? range;
143
+ return average(hits.map((i) => target[i] ?? ''));
144
+ },
145
+ SUMIFS: (a) => {
146
+ const target = a.args[0] ?? [];
147
+ const pairs = [];
148
+ for (let i = 1; i + 1 < a.args.length + 1; i += 2) {
149
+ const range = a.args[i];
150
+ if (!range)
151
+ break;
152
+ pairs.push([range, a.args[i + 1]?.[0] ?? '']);
153
+ }
154
+ return sum(multiCriteriaHits(pairs).map((i) => target[i] ?? ''));
155
+ },
156
+ COUNTIFS: (a) => {
157
+ const pairs = [];
158
+ for (let i = 0; i < a.args.length; i += 2) {
159
+ const range = a.args[i];
160
+ if (!range)
161
+ break;
162
+ pairs.push([range, a.args[i + 1]?.[0] ?? '']);
163
+ }
164
+ return multiCriteriaHits(pairs).length;
165
+ },
166
+ // ---- Logical ---------------------------------------------------------
167
+ NOT: (a) => !toBool(first(a)),
168
+ AND: (a) => a.flat.every((v) => toBool(v)),
169
+ OR: (a) => a.flat.some((v) => toBool(v)),
170
+ XOR: (a) => a.flat.filter((v) => toBool(v)).length % 2 === 1,
171
+ // ---- Information -----------------------------------------------------
172
+ // What a value IS, not what it can be coerced to: "12" typed as text is
173
+ // text here, the way Excel answers, and a blank is neither.
174
+ ISNUMBER: (a) => typeof first(a) === 'number',
175
+ ISTEXT: (a) => typeof first(a) === 'string' && first(a) !== '',
176
+ ISLOGICAL: (a) => typeof first(a) === 'boolean',
177
+ ISBLANK: (a) => first(a) === '',
178
+ // ---- Text ------------------------------------------------------------
179
+ LEN: (a) => toText(first(a)).length,
180
+ LEFT: (a) => toText(nth(a, 0)).slice(0, Math.max(0, Math.round(toNumber(a.args[1] ? nth(a, 1) : 1)))),
181
+ RIGHT: (a) => {
182
+ const s = toText(nth(a, 0));
183
+ const n = Math.max(0, Math.round(toNumber(a.args[1] ? nth(a, 1) : 1)));
184
+ return n >= s.length ? s : s.slice(s.length - n);
185
+ },
186
+ MID: (a) => {
187
+ const s = toText(nth(a, 0));
188
+ const start = Math.round(toNumber(nth(a, 1)));
189
+ if (start < 1)
190
+ return err('#VALUE!');
191
+ return s.slice(start - 1, start - 1 + Math.max(0, Math.round(toNumber(nth(a, 2)))));
192
+ },
193
+ UPPER: (a) => toText(first(a)).toUpperCase(),
194
+ LOWER: (a) => toText(first(a)).toLowerCase(),
195
+ TRIM: (a) => toText(first(a)).trim().replace(/\s+/g, ' '),
196
+ CONCAT: (a) => a.flat.map((v) => toText(v)).join(''),
197
+ CONCATENATE: (a) => a.flat.map((v) => toText(v)).join(''),
198
+ TEXTJOIN: (a) => {
199
+ const sep = toText(nth(a, 0));
200
+ const skipEmpty = toBool(nth(a, 1));
201
+ const rest = a.args.slice(2).flat();
202
+ return rest.filter((v) => !skipEmpty || !isBlank(v)).map((v) => toText(v)).join(sep);
203
+ },
204
+ SUBSTITUTE: (a) => {
205
+ const s = toText(nth(a, 0));
206
+ const find = toText(nth(a, 1));
207
+ const replace = toText(nth(a, 2));
208
+ if (find === '')
209
+ return s;
210
+ return s.split(find).join(replace);
211
+ },
212
+ FIND: (a) => {
213
+ // Case sensitive, 1-based, #VALUE! when absent. SEARCH is its
214
+ // case-insensitive twin.
215
+ const at = toText(nth(a, 1)).indexOf(toText(nth(a, 0)));
216
+ return at < 0 ? err('#VALUE!') : at + 1;
217
+ },
218
+ SEARCH: (a) => {
219
+ const at = toText(nth(a, 1)).toLowerCase().indexOf(toText(nth(a, 0)).toLowerCase());
220
+ return at < 0 ? err('#VALUE!') : at + 1;
221
+ },
222
+ TEXT: (a) => {
223
+ // Minimal: the full Excel format grammar arrives with per-cell number
224
+ // formats. Until then this covers the common fixed-decimal case.
225
+ const v = toNumber(nth(a, 0));
226
+ const pattern = toText(nth(a, 1));
227
+ const decimals = /\.(0+)/.exec(pattern)?.[1]?.length ?? 0;
228
+ const body = v.toFixed(decimals);
229
+ if (pattern.includes(',')) {
230
+ const [int = '', frac] = body.split('.');
231
+ const grouped = int.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
232
+ return frac ? `${grouped}.${frac}` : grouped;
233
+ }
234
+ return body;
235
+ },
236
+ // ---- Date ------------------------------------------------------------
237
+ TODAY: () => iso(new Date()),
238
+ NOW: () => new Date().toISOString().slice(0, 19).replace('T', ' '),
239
+ YEAR: (a) => toDate(first(a)).getUTCFullYear(),
240
+ MONTH: (a) => toDate(first(a)).getUTCMonth() + 1,
241
+ DAY: (a) => toDate(first(a)).getUTCDate(),
242
+ DATE: (a) => iso(new Date(Date.UTC(Math.round(toNumber(nth(a, 0))), Math.round(toNumber(nth(a, 1))) - 1, Math.round(toNumber(nth(a, 2)))))),
243
+ EOMONTH: (a) => {
244
+ const d = toDate(nth(a, 0));
245
+ const months = Math.round(toNumber(nth(a, 1)));
246
+ // Day 0 of the following month is the last day of the target month.
247
+ return iso(new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth() + months + 1, 0)));
248
+ },
249
+ // DAYS(end, start): whole days, negative when the end comes first.
250
+ DAYS: (a) => Math.round((toDate(nth(a, 0)).getTime() - toDate(nth(a, 1)).getTime()) / 86400000),
251
+ // DATEDIF(start, end, unit): Excel's "d", "m" and "y", completed units
252
+ // only, and #NUM! when the start comes after the end, as Excel gives.
253
+ DATEDIF: (a) => {
254
+ const start = toDate(nth(a, 0));
255
+ const end = toDate(nth(a, 1));
256
+ if (end.getTime() < start.getTime())
257
+ return err('#NUM!');
258
+ const unit = toText(nth(a, 2)).toUpperCase();
259
+ if (unit === 'D')
260
+ return Math.floor((end.getTime() - start.getTime()) / 86400000);
261
+ let months = (end.getUTCFullYear() - start.getUTCFullYear()) * 12 + (end.getUTCMonth() - start.getUTCMonth());
262
+ if (end.getUTCDate() < start.getUTCDate())
263
+ months -= 1;
264
+ if (unit === 'M')
265
+ return months;
266
+ if (unit === 'Y')
267
+ return Math.floor(months / 12);
268
+ return err('#NUM!');
269
+ },
270
+ // ---- Lookup ----------------------------------------------------------
271
+ VLOOKUP: (a) => {
272
+ const needle = nth(a, 0);
273
+ const grid = a.grids[1];
274
+ if (!grid)
275
+ return err('#REF!');
276
+ const col = Math.round(toNumber(nth(a, 2)));
277
+ if (col < 1)
278
+ return err('#VALUE!');
279
+ for (const row of grid) {
280
+ if (row[0] !== undefined && looseEquals(row[0], needle)) {
281
+ const cell = row[col - 1];
282
+ return cell === undefined ? err('#REF!') : cell;
283
+ }
284
+ }
285
+ return err('#N/A');
286
+ },
287
+ HLOOKUP: (a) => {
288
+ const needle = nth(a, 0);
289
+ const grid = a.grids[1];
290
+ if (!grid)
291
+ return err('#REF!');
292
+ const rowIndex = Math.round(toNumber(nth(a, 2)));
293
+ if (rowIndex < 1)
294
+ return err('#VALUE!');
295
+ const header = grid[0] ?? [];
296
+ for (let c = 0; c < header.length; c += 1) {
297
+ if (looseEquals(header[c], needle)) {
298
+ const cell = grid[rowIndex - 1]?.[c];
299
+ return cell === undefined ? err('#REF!') : cell;
300
+ }
301
+ }
302
+ return err('#N/A');
303
+ },
304
+ MATCH: (a) => {
305
+ const needle = nth(a, 0);
306
+ const pool = a.args[1] ?? [];
307
+ const mode = a.args[2] ? Math.round(toNumber(nth(a, 2))) : 1;
308
+ if (mode === 0) {
309
+ const at = pool.findIndex((v) => looseEquals(v, needle));
310
+ return at < 0 ? err('#N/A') : at + 1;
311
+ }
312
+ // Ordered search: the last value not past the needle.
313
+ let best = -1;
314
+ for (let i = 0; i < pool.length; i += 1) {
315
+ const cmp = compare(pool[i], needle);
316
+ if (mode === 1 ? cmp <= 0 : cmp >= 0)
317
+ best = i;
318
+ }
319
+ return best < 0 ? err('#N/A') : best + 1;
320
+ },
321
+ INDEX: (a) => {
322
+ const grid = a.grids[0];
323
+ if (!grid) {
324
+ const at = Math.round(toNumber(nth(a, 1)));
325
+ const v = (a.args[0] ?? [])[at - 1];
326
+ return v === undefined ? err('#REF!') : v;
327
+ }
328
+ const given = Math.round(toNumber(nth(a, 1)));
329
+ // With one number, a one-column range indexes by row and a one-row range
330
+ // by column, as Excel does: =INDEX(B4:D4, 2) is the second scenario
331
+ // heading, not #REF!.
332
+ const oneRow = grid.length === 1 && !a.args[2];
333
+ const rowIndex = oneRow ? 1 : given;
334
+ const colIndex = oneRow ? given : a.args[2] ? Math.round(toNumber(nth(a, 2))) : 1;
335
+ const row = grid[rowIndex - 1];
336
+ if (!row)
337
+ return err('#REF!');
338
+ const cell = row[colIndex - 1];
339
+ return cell === undefined ? err('#REF!') : cell;
340
+ },
341
+ XLOOKUP: (a) => {
342
+ const needle = nth(a, 0);
343
+ const haystack = a.args[1] ?? [];
344
+ const results = a.args[2] ?? [];
345
+ const at = haystack.findIndex((v) => looseEquals(v, needle));
346
+ if (at < 0)
347
+ return a.args[3] ? nth(a, 3) : err('#N/A');
348
+ const cell = results[at];
349
+ return cell === undefined ? err('#REF!') : cell;
350
+ },
351
+ };
352
+ /** Merge caller-supplied functions over the built-ins. Keys are uppercased so
353
+ * a consumer can register `myFn` and write `=MYFN()`. */
354
+ export function withCustomFunctions(custom) {
355
+ if (!custom)
356
+ return FUNCTIONS;
357
+ const out = { ...FUNCTIONS };
358
+ for (const [name, fn] of Object.entries(custom))
359
+ out[name.toUpperCase()] = fn;
360
+ return out;
361
+ }
362
+ export { isError };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Goal Seek: find the input value that makes a formula cell hit a target.
3
+ *
4
+ * "What interest rate makes the monthly payment 1500?" You know the answer
5
+ * you want and one cell you are willing to change; the solver finds it.
6
+ *
7
+ * The method is secant with a bisection fallback, not Newton. Newton needs a
8
+ * derivative, and the function here is "recalculate a spreadsheet", which has
9
+ * no analytic one. Secant approximates the slope from two evaluations, which
10
+ * is the same information a numerical derivative would cost anyway.
11
+ *
12
+ * Bisection is the fallback because secant is fast but not safe: it can step
13
+ * to infinity on a flat stretch or oscillate on a kink. When a bracket is
14
+ * known - two inputs whose results straddle the target - bisection cannot
15
+ * fail, only be slow. Trying secant first and falling back keeps the common
16
+ * case quick and the awkward case terminating.
17
+ */
18
+ export type GoalSeekOptions = {
19
+ /** Stop once the result is this close to the target. */
20
+ tolerance?: number;
21
+ /** Give up after this many recalculations. */
22
+ maxIterations?: number;
23
+ /** Where to start looking. Defaults to the input cell's current value. */
24
+ initialGuess?: number;
25
+ /** Keep the answer inside these bounds. A rate solver wants [0, 1]. */
26
+ min?: number;
27
+ max?: number;
28
+ };
29
+ export type GoalSeekResult = {
30
+ /** Whether the target was reached within tolerance. */
31
+ converged: boolean;
32
+ /** The input value found. Present even when it did not converge, so a
33
+ * caller can show the closest attempt rather than nothing. */
34
+ value: number;
35
+ /** What the formula produced at that input. */
36
+ result: number;
37
+ iterations: number;
38
+ /** Why it stopped, when it did not converge. */
39
+ reason?: 'maxIterations' | 'notNumeric' | 'flat' | 'outOfBounds';
40
+ };
41
+ /**
42
+ * Solve `evaluate(input) = target` for `input`.
43
+ *
44
+ * `evaluate` sets the input cell, recalculates, and returns the formula
45
+ * cell's value. It is called many times, so it should be the workbook's own
46
+ * recalculation rather than anything that touches the DOM.
47
+ *
48
+ * The caller owns the input cell: this never writes. It reports the value it
49
+ * found and lets the caller decide whether to keep it, which is what makes
50
+ * Excel's "Goal Seek found a solution / OK or Cancel" dialog possible.
51
+ */
52
+ export declare function goalSeek(evaluate: (input: number) => unknown, target: number, start: number, options?: GoalSeekOptions): GoalSeekResult;
53
+ /** What `goalSeekCell` needs of a workbook. */
54
+ export type GoalSeekSheet = {
55
+ getRaw(sheet: string, row: number, col: number): string;
56
+ setRaw(sheet: string, row: number, col: number, text: string): void;
57
+ getValue(sheet: string, row: number, col: number): unknown;
58
+ };
59
+ export type CellAddress = {
60
+ sheet: string;
61
+ row: number;
62
+ col: number;
63
+ };
64
+ /**
65
+ * Goal Seek over a workbook: change `input` until `formula` reads `target`.
66
+ *
67
+ * The input cell is RESTORED before returning, whatever the outcome. The
68
+ * solver writes to it dozens of times while searching, and leaving the last
69
+ * probe behind would be worse than not running: Excel shows you the answer
70
+ * and asks before keeping it, which it cannot do if the sheet has already
71
+ * moved. Apply `result.value` yourself once the user says yes.
72
+ */
73
+ export declare function goalSeekCell(book: GoalSeekSheet, formula: CellAddress, input: CellAddress, target: number, options?: GoalSeekOptions): GoalSeekResult;