@svgrid/enterprise 3.0.2 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (364) hide show
  1. package/LICENSE +94 -24
  2. package/README.md +36 -4
  3. package/dist/SvAdvancedFilter.svelte +1 -1
  4. package/dist/SvAlertsManager.svelte +2 -1
  5. package/dist/SvBoard.svelte +2 -1
  6. package/dist/SvExportMenu.svelte +4 -1
  7. package/dist/SvExportMenu.svelte.d.ts +0 -13
  8. package/dist/SvExpressionEditor.svelte +3 -3
  9. package/dist/SvFormulaBar.svelte +94 -20
  10. package/dist/SvFormulaBar.svelte.d.ts +7 -0
  11. package/dist/SvGridAlerts.svelte +49 -9
  12. package/dist/SvGridBoard.svelte +13 -8
  13. package/dist/SvGridBulkEditDrawer.svelte +26 -2
  14. package/dist/SvGridEditPanel.svelte +3 -0
  15. package/dist/SvGridScheduler.svelte +69 -40
  16. package/dist/SvGridSelectionBar.svelte +10 -3
  17. package/dist/SvPivotDesigner.svelte +198 -40
  18. package/dist/SvPivotDesigner.svelte.d.ts +27 -20
  19. package/dist/SvSheet.svelte +4043 -243
  20. package/dist/SvSheet.svelte.d.ts +76 -3
  21. package/dist/SvSheetChartSetup.svelte +151 -0
  22. package/dist/SvSheetChartSetup.svelte.d.ts +18 -0
  23. package/dist/SvSheetComment.svelte +216 -31
  24. package/dist/SvSheetComment.svelte.d.ts +11 -11
  25. package/dist/SvSheetConditionalFormat.svelte +28 -31
  26. package/dist/SvSheetDataValidation.svelte +66 -42
  27. package/dist/SvSheetEditRanges.svelte +217 -0
  28. package/dist/SvSheetEditRanges.svelte.d.ts +15 -0
  29. package/dist/SvSheetErrors.svelte +125 -0
  30. package/dist/SvSheetErrors.svelte.d.ts +20 -0
  31. package/dist/SvSheetEvaluate.svelte +133 -0
  32. package/dist/SvSheetEvaluate.svelte.d.ts +15 -0
  33. package/dist/SvSheetFilterMenu.svelte +137 -34
  34. package/dist/SvSheetFilterMenu.svelte.d.ts +5 -0
  35. package/dist/SvSheetFindReplace.svelte +19 -19
  36. package/dist/SvSheetFormatCells.svelte +125 -81
  37. package/dist/SvSheetGoalSeek.svelte +17 -16
  38. package/dist/SvSheetInsertFunction.svelte +15 -13
  39. package/dist/SvSheetIteration.svelte +81 -0
  40. package/dist/SvSheetIteration.svelte.d.ts +10 -0
  41. package/dist/SvSheetLink.svelte +99 -0
  42. package/dist/SvSheetLink.svelte.d.ts +17 -0
  43. package/dist/SvSheetListPicker.svelte +4 -2
  44. package/dist/SvSheetListPicker.svelte.d.ts +0 -6
  45. package/dist/SvSheetManageRules.svelte +20 -18
  46. package/dist/SvSheetNameManager.svelte +17 -15
  47. package/dist/SvSheetPageSetup.svelte +159 -0
  48. package/dist/SvSheetPageSetup.svelte.d.ts +13 -0
  49. package/dist/SvSheetPasteSpecial.svelte +22 -20
  50. package/dist/SvSheetPivot.svelte +220 -0
  51. package/dist/SvSheetPivot.svelte.d.ts +21 -0
  52. package/dist/SvSheetProtectSheet.svelte +81 -0
  53. package/dist/SvSheetProtectSheet.svelte.d.ts +11 -0
  54. package/dist/SvSheetRemoveDuplicates.svelte +13 -10
  55. package/dist/SvSheetRibbon.svelte +104 -51
  56. package/dist/SvSheetSizeDialog.svelte +4 -2
  57. package/dist/SvSheetSort.svelte +218 -0
  58. package/dist/SvSheetSort.svelte.d.ts +28 -0
  59. package/dist/SvSheetSparklines.svelte +135 -0
  60. package/dist/SvSheetSparklines.svelte.d.ts +14 -0
  61. package/dist/SvSheetTable.svelte +160 -0
  62. package/dist/SvSheetTable.svelte.d.ts +24 -0
  63. package/dist/SvSheetTabs.svelte +161 -31
  64. package/dist/SvSheetTabs.svelte.d.ts +22 -8
  65. package/dist/SvSheetTextToColumns.svelte +20 -20
  66. package/dist/SvSheetValidationAlert.svelte +8 -6
  67. package/dist/advanced-filter-enable.js +1 -1
  68. package/dist/alerts/alert-engine.d.ts +6 -0
  69. package/dist/alerts/alert-engine.js +21 -4
  70. package/dist/alerts/alert-formats.js +2 -0
  71. package/dist/alerts/alert-types.d.ts +1 -1
  72. package/dist/alerts.d.ts +1 -1
  73. package/dist/alerts.js +2 -2
  74. package/dist/board.js +2 -2
  75. package/dist/bulk-edit.d.ts +3 -1
  76. package/dist/bulk-edit.js +1 -1
  77. package/dist/cdn/svgrid-enterprise.svelte-external.js +39827 -16429
  78. package/dist/designer/assets/GridMenus-8gTNssgV.js +8 -0
  79. package/dist/designer/assets/{SvChartMenu-D9hEeHar.js → SvChartMenu-BDoeqGz6.js} +1 -1
  80. package/dist/designer/assets/{SvDateTimePicker-DARvKUL2.js → SvDateTimePicker-DCPg7WGN.js} +1 -1
  81. package/dist/designer/assets/SvGridCellEditor-DMoWJjEI.js +4 -0
  82. package/dist/designer/assets/{SvGridChart-B8j1SSy3.js → SvGridChart-Cy1ATrWh.js} +2 -2
  83. package/dist/designer/assets/SvGridChartBuilder-eQ3mn0L9.js +1 -0
  84. package/dist/designer/assets/{SvGridChartPanel-pT6ITc2P.js → SvGridChartPanel-CATdVc9X.js} +3 -3
  85. package/dist/designer/assets/{SvGridChartView-bg281UA1.js → SvGridChartView-CmsZtCED.js} +1 -1
  86. package/dist/designer/assets/SvGridDropdown-Cjz0H-fI.js +1 -0
  87. package/dist/designer/assets/{SvTabs-UFCMTHXS.js → SvTabs-2mHC6oaz.js} +1 -1
  88. package/dist/designer/assets/cell-formatting-BbubJTVz.js +1 -0
  89. package/dist/designer/assets/{chart-cIPUsbM5.js → chart-Cn7MnNqA.js} +1 -1
  90. package/dist/designer/assets/{chart-panel-messages-DtTxpBUU.js → chart-panel-messages-Dz7PTIqT.js} +1 -1
  91. package/dist/designer/assets/{chart-summary-Czu_5epb.js → chart-summary-BD1qYB2R.js} +1 -1
  92. package/dist/designer/assets/{chart-trend-D5I5VEe8.js → chart-trend-B8xr5LuD.js} +1 -1
  93. package/dist/designer/assets/{dismissable-BO547MH9.js → dismissable-ChWRPkoa.js} +1 -1
  94. package/dist/designer/assets/{export-format-D-eP4b2l.js → export-format-DGckmgKr.js} +1 -1
  95. package/dist/designer/assets/{focus-trap-CAreAhlU.js → focus-trap-V2-6Fy9I.js} +1 -1
  96. package/dist/designer/assets/{index-DwU7CAMm.js → index-D5bVbuzI.js} +317 -315
  97. package/dist/designer/assets/index-_JVFxt02.css +1 -0
  98. package/dist/designer/assets/row-resize-BInFWCpr.js +1 -0
  99. package/dist/designer/assets/server-block-cache-CXJKkJpy.js +1 -0
  100. package/dist/designer/assets/src-DUQ4xE3x.js +58 -0
  101. package/dist/designer/assets/validate-C3B8QKsM.js +1 -0
  102. package/dist/designer/index.html +17 -16
  103. package/dist/export-pdf.d.ts +75 -0
  104. package/dist/export-pdf.js +216 -15
  105. package/dist/export.js +10 -2
  106. package/dist/gantt/SvGridGantt.svelte +2890 -0
  107. package/dist/gantt/SvGridGantt.svelte.d.ts +30 -0
  108. package/dist/gantt/gantt-config.d.ts +73 -0
  109. package/dist/gantt/gantt-config.js +1 -0
  110. package/dist/gantt/gantt-critical-path.d.ts +67 -0
  111. package/dist/gantt/gantt-critical-path.js +207 -0
  112. package/dist/gantt/gantt-model.d.ts +257 -0
  113. package/dist/gantt/gantt-model.js +651 -0
  114. package/dist/gantt/gantt-resources.d.ts +59 -0
  115. package/dist/gantt/gantt-resources.js +71 -0
  116. package/dist/gantt/gantt.d.ts +7 -0
  117. package/dist/gantt/gantt.js +36 -0
  118. package/dist/gantt/index.d.ts +15 -0
  119. package/dist/gantt/index.js +22 -0
  120. package/dist/gantt/timeline-arrows.d.ts +102 -0
  121. package/dist/gantt/timeline-arrows.js +181 -0
  122. package/dist/import.d.ts +2 -2
  123. package/dist/import.js +1 -1
  124. package/dist/index.d.ts +34 -7
  125. package/dist/index.js +44 -7
  126. package/dist/install.js +8 -1
  127. package/dist/license-core.d.ts +17 -1
  128. package/dist/license-core.js +16 -5
  129. package/dist/license.d.ts +18 -2
  130. package/dist/license.js +71 -6
  131. package/dist/node/studio.js +140 -8
  132. package/dist/pivot-enable.js +2 -2
  133. package/dist/scheduler-dependencies.d.ts +35 -0
  134. package/dist/scheduler-dependencies.js +36 -1
  135. package/dist/scheduler.js +2 -2
  136. package/dist/selection-bar.js +2 -2
  137. package/dist/server/SvGroupCell.svelte +213 -0
  138. package/dist/server/SvGroupCell.svelte.d.ts +62 -0
  139. package/dist/server/SvRowGroupPanel.svelte +322 -0
  140. package/dist/server/SvRowGroupPanel.svelte.d.ts +37 -0
  141. package/dist/server/enable.d.ts +17 -0
  142. package/dist/server/enable.js +49 -0
  143. package/dist/server/index.d.ts +22 -0
  144. package/dist/server/index.js +24 -0
  145. package/dist/server/messages.d.ts +45 -0
  146. package/dist/server/messages.js +35 -0
  147. package/dist/server/server-group-model.d.ts +104 -0
  148. package/dist/server/server-group-model.js +272 -0
  149. package/dist/server/server-pivot.d.ts +46 -0
  150. package/dist/server/server-pivot.js +57 -0
  151. package/dist/server/server-row-model.d.ts +547 -0
  152. package/dist/server/server-row-model.js +1551 -0
  153. package/dist/server/server-selection.d.ts +99 -0
  154. package/dist/server/server-selection.js +215 -0
  155. package/dist/server/svgrid-adapter.d.ts +155 -0
  156. package/dist/server/svgrid-adapter.js +202 -0
  157. package/dist/sheet/ast.d.ts +45 -1
  158. package/dist/sheet/ast.js +14 -0
  159. package/dist/sheet/auto-filter.d.ts +58 -4
  160. package/dist/sheet/auto-filter.js +159 -11
  161. package/dist/sheet/autocomplete.d.ts +9 -0
  162. package/dist/sheet/autocomplete.js +90 -4
  163. package/dist/sheet/cell-images.d.ts +39 -0
  164. package/dist/sheet/cell-images.js +90 -0
  165. package/dist/sheet/cell-types.d.ts +58 -0
  166. package/dist/sheet/cell-types.js +96 -0
  167. package/dist/sheet/coerce.d.ts +40 -0
  168. package/dist/sheet/coerce.js +170 -3
  169. package/dist/sheet/comments.d.ts +43 -9
  170. package/dist/sheet/comments.js +85 -27
  171. package/dist/sheet/conditional-formats.d.ts +29 -6
  172. package/dist/sheet/conditional-formats.js +37 -12
  173. package/dist/sheet/csv.d.ts +32 -0
  174. package/dist/sheet/csv.js +158 -0
  175. package/dist/sheet/culture.d.ts +87 -0
  176. package/dist/sheet/culture.js +247 -0
  177. package/dist/sheet/delta.d.ts +102 -0
  178. package/dist/sheet/delta.js +203 -0
  179. package/dist/sheet/deps.d.ts +45 -1
  180. package/dist/sheet/deps.js +77 -2
  181. package/dist/sheet/document.d.ts +106 -4
  182. package/dist/sheet/document.js +204 -3
  183. package/dist/sheet/engine.d.ts +67 -0
  184. package/dist/sheet/engine.js +19 -0
  185. package/dist/sheet/entry.d.ts +8 -4
  186. package/dist/sheet/entry.js +171 -21
  187. package/dist/sheet/error-check.d.ts +49 -0
  188. package/dist/sheet/error-check.js +83 -0
  189. package/dist/sheet/evaluate-steps.d.ts +48 -0
  190. package/dist/sheet/evaluate-steps.js +196 -0
  191. package/dist/sheet/evaluate.d.ts +67 -0
  192. package/dist/sheet/evaluate.js +725 -13
  193. package/dist/sheet/filter-files.d.ts +37 -0
  194. package/dist/sheet/filter-files.js +465 -0
  195. package/dist/sheet/format-store.d.ts +15 -0
  196. package/dist/sheet/format-store.js +11 -1
  197. package/dist/sheet/from-rows.d.ts +14 -0
  198. package/dist/sheet/from-rows.js +50 -0
  199. package/dist/sheet/function-catalog.d.ts +1 -1
  200. package/dist/sheet/function-catalog.js +296 -5
  201. package/dist/sheet/functions.js +363 -91
  202. package/dist/sheet/index.d.ts +35 -8
  203. package/dist/sheet/index.js +35 -8
  204. package/dist/sheet/links.d.ts +57 -0
  205. package/dist/sheet/links.js +174 -0
  206. package/dist/sheet/messages.d.ts +778 -0
  207. package/dist/sheet/messages.js +806 -0
  208. package/dist/sheet/number-format.d.ts +52 -5
  209. package/dist/sheet/number-format.js +465 -68
  210. package/dist/sheet/objects.d.ts +106 -0
  211. package/dist/sheet/objects.js +149 -0
  212. package/dist/sheet/ods-document.d.ts +44 -0
  213. package/dist/sheet/ods-document.js +1275 -0
  214. package/dist/sheet/open-file.d.ts +26 -0
  215. package/dist/sheet/open-file.js +56 -0
  216. package/dist/sheet/outline.d.ts +82 -0
  217. package/dist/sheet/outline.js +228 -0
  218. package/dist/sheet/packs/array.d.ts +16 -0
  219. package/dist/sheet/packs/array.js +172 -0
  220. package/dist/sheet/packs/database.d.ts +42 -0
  221. package/dist/sheet/packs/database.js +142 -0
  222. package/dist/sheet/packs/engineering.d.ts +2 -0
  223. package/dist/sheet/packs/engineering.js +296 -0
  224. package/dist/sheet/packs/financial.d.ts +5 -0
  225. package/dist/sheet/packs/financial.js +220 -0
  226. package/dist/sheet/packs/math-stats.d.ts +2 -0
  227. package/dist/sheet/packs/math-stats.js +372 -0
  228. package/dist/sheet/packs/special.d.ts +44 -0
  229. package/dist/sheet/packs/special.js +187 -0
  230. package/dist/sheet/packs/stats-dist.d.ts +2 -0
  231. package/dist/sheet/packs/stats-dist.js +785 -0
  232. package/dist/sheet/packs/text-date.d.ts +2 -0
  233. package/dist/sheet/packs/text-date.js +332 -0
  234. package/dist/sheet/packs/trig.d.ts +2 -0
  235. package/dist/sheet/packs/trig.js +73 -0
  236. package/dist/sheet/page-setup.d.ts +73 -0
  237. package/dist/sheet/page-setup.js +73 -0
  238. package/dist/sheet/parse.js +42 -10
  239. package/dist/sheet/paste-special.d.ts +22 -0
  240. package/dist/sheet/paste-special.js +14 -5
  241. package/dist/sheet/pivot-range.d.ts +160 -0
  242. package/dist/sheet/pivot-range.js +333 -0
  243. package/dist/sheet/presence.d.ts +73 -0
  244. package/dist/sheet/presence.js +79 -0
  245. package/dist/sheet/print.d.ts +104 -0
  246. package/dist/sheet/print.js +169 -0
  247. package/dist/sheet/protection.d.ts +55 -1
  248. package/dist/sheet/protection.js +55 -2
  249. package/dist/sheet/rects.d.ts +1 -1
  250. package/dist/sheet/refs.d.ts +48 -0
  251. package/dist/sheet/refs.js +155 -8
  252. package/dist/sheet/ribbon-icons.d.ts +1 -1
  253. package/dist/sheet/ribbon-icons.js +186 -0
  254. package/dist/sheet/ribbon.d.ts +1 -1
  255. package/dist/sheet/ribbon.js +324 -23
  256. package/dist/sheet/sheet-kinds.d.ts +74 -0
  257. package/dist/sheet/sheet-kinds.js +91 -0
  258. package/dist/sheet/shortcuts.d.ts +13 -3
  259. package/dist/sheet/shortcuts.js +63 -12
  260. package/dist/sheet/sort.d.ts +51 -0
  261. package/dist/sheet/sort.js +107 -0
  262. package/dist/sheet/sparklines.d.ts +111 -0
  263. package/dist/sheet/sparklines.js +204 -0
  264. package/dist/sheet/table-styles.d.ts +74 -0
  265. package/dist/sheet/table-styles.js +152 -0
  266. package/dist/sheet/tables.d.ts +19 -0
  267. package/dist/sheet/tables.js +31 -0
  268. package/dist/sheet/tokenize.d.ts +18 -1
  269. package/dist/sheet/tokenize.js +60 -9
  270. package/dist/sheet/validation.d.ts +16 -0
  271. package/dist/sheet/validation.js +37 -0
  272. package/dist/sheet/workbook.d.ts +148 -3
  273. package/dist/sheet/workbook.js +742 -31
  274. package/dist/sheet/xls-cfb.d.ts +32 -0
  275. package/dist/sheet/xls-cfb.js +290 -0
  276. package/dist/sheet/xls-document.d.ts +10 -0
  277. package/dist/sheet/xls-document.js +1243 -0
  278. package/dist/sheet/xls-formula.d.ts +40 -0
  279. package/dist/sheet/xls-formula.js +569 -0
  280. package/dist/sheet/xlsx-document.d.ts +108 -0
  281. package/dist/sheet/xlsx-document.js +1849 -0
  282. package/dist/sheet/xlsx-drawing.d.ts +99 -0
  283. package/dist/sheet/xlsx-drawing.js +420 -0
  284. package/dist/sheet-enable.js +6 -7
  285. package/dist/sheet-text.d.ts +7 -0
  286. package/dist/sheet-text.js +29 -0
  287. package/dist/sources/auth-supabase.js +2 -2
  288. package/dist/sources/realtime-supabase.js +2 -2
  289. package/dist/sources/rest.d.ts +6 -2
  290. package/dist/sources/rest.js +42 -7
  291. package/dist/sources/supabase.d.ts +10 -1
  292. package/dist/sources/supabase.js +73 -40
  293. package/dist/studio/emit-project.js +14 -1
  294. package/dist/studio/index.js +1 -1
  295. package/dist/studio/project.d.ts +11 -2
  296. package/dist/studio/project.js +5 -2
  297. package/dist/studio/ui-components.generated.js +107 -2
  298. package/dist/sveltekit/in-memory.d.ts +2 -2
  299. package/dist/sveltekit/in-memory.js +125 -4
  300. package/dist/sveltekit/index.d.ts +1 -1
  301. package/dist/sveltekit/index.js +1 -1
  302. package/dist/sveltekit/query-plan.d.ts +50 -4
  303. package/dist/sveltekit/query-plan.js +25 -3
  304. package/dist/sveltekit/sql-source.d.ts +6 -0
  305. package/dist/sveltekit/sql-source.js +34 -6
  306. package/dist/sveltekit/sql.d.ts +31 -0
  307. package/dist/sveltekit/sql.js +135 -25
  308. package/dist/sveltekit/transport.d.ts +10 -2
  309. package/dist/sveltekit/transport.js +30 -6
  310. package/dist/upgrade-prompt.d.ts +1 -1
  311. package/dist/version.d.ts +1 -1
  312. package/dist/version.js +1 -1
  313. package/dist/watermark.js +35 -2
  314. package/dist/wc/GridMenus-By9vPuq0.js +1088 -0
  315. package/dist/wc/SvChartMenu-CQNrQGT2.js +308 -0
  316. package/dist/wc/SvDateRangeInput-DR6m7bSM.js +199 -0
  317. package/dist/wc/SvDateTimePicker-D-vRnaMo.js +771 -0
  318. package/dist/wc/SvField-B_kurx_P.js +149 -0
  319. package/dist/wc/SvGrid.helpers-BdVDtjUm.js +135 -0
  320. package/dist/wc/SvGridCellEditor-Bnf1Kr5C.js +560 -0
  321. package/dist/wc/SvGridChart-BqUJh2pG.js +3572 -0
  322. package/dist/wc/SvGridChartBuilder-CGycC5cn.js +988 -0
  323. package/dist/wc/SvGridChartPanel-CRnizsHD.js +1746 -0
  324. package/dist/wc/SvGridChartView-D1pa_xMy.js +47 -0
  325. package/dist/wc/SvGridDropdown-45WsObLL.js +259 -0
  326. package/dist/wc/SvModal-DrfOYYyX.js +189 -0
  327. package/dist/wc/cell-formatting-CBfgahv1.js +86 -0
  328. package/dist/wc/chart-6OXlybVT.js +4341 -0
  329. package/dist/wc/chart-export-CeSADGfi.js +135 -0
  330. package/dist/wc/chart-export-pdf-BGko7MER.js +104 -0
  331. package/dist/wc/chart-summary-2m3ia1-n.js +137 -0
  332. package/dist/wc/chart-trend-CQOQtTMl.js +50 -0
  333. package/dist/wc/chart-validate-CD6ptiwg.js +180 -0
  334. package/dist/wc/client-DQIzjDBG.js +3064 -0
  335. package/dist/wc/column-resize-DUPgynvc.js +101 -0
  336. package/dist/wc/date-format-DS-z_h9v.js +1130 -0
  337. package/dist/wc/dismissable-CQ6XFXsk.js +45 -0
  338. package/dist/wc/editor-contract-peBDxir_.js +22 -0
  339. package/dist/wc/editor-registry-DxGKqcvx.js +24 -0
  340. package/dist/wc/focus-trap-Dbb2tJxb.js +65 -0
  341. package/dist/wc/list-option-DrRyivWp.js +82 -0
  342. package/dist/wc/popover-WsGlvtQv.js +69 -0
  343. package/dist/wc/positioning-BiKLfu1E.js +112 -0
  344. package/dist/wc/react.d.ts +41 -0
  345. package/dist/wc/react.js +90 -0
  346. package/dist/wc/rolldown-runtime-Dy4uBu1J.js +11 -0
  347. package/dist/wc/row-drag-touch-CycRR65n.js +93 -0
  348. package/dist/wc/row-resize-limG_N1z.js +111 -0
  349. package/dist/wc/sv-sheet-element.d.ts +97 -0
  350. package/dist/wc/sv-sheet-element.js +44213 -0
  351. package/dist/wc/svelte-virtualizer.svelte-CXtQy2TQ.js +530 -0
  352. package/dist/wc/validate-BqDthkNr.js +88 -0
  353. package/dist/wc/vue.d.ts +31 -0
  354. package/dist/wc/vue.js +75 -0
  355. package/package.json +30 -5
  356. package/dist/designer/assets/GridMenus-BlsvL_aU.js +0 -8
  357. package/dist/designer/assets/SvGridCellEditor-C7uQXYds.js +0 -4
  358. package/dist/designer/assets/SvGridChartBuilder-kvyIU_Rl.js +0 -1
  359. package/dist/designer/assets/SvGridDropdown-Bb3HH2Aj.js +0 -1
  360. package/dist/designer/assets/cell-formatting-wr5wm7US.js +0 -1
  361. package/dist/designer/assets/index-CMFgAoVV.css +0 -1
  362. package/dist/designer/assets/row-resize-DLktcqUK.js +0 -1
  363. package/dist/designer/assets/src-EdI3Xqds.js +0 -58
  364. package/dist/designer/assets/validate-h-aslRV9.js +0 -1
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Eight colours that read as different people rather than as a heat map,
3
+ * stay legible as a thin box over a white sheet and over a dark one, and
4
+ * each carry a white name at 11px at 4.5:1 or better, so every tag wears
5
+ * the same white ink. The first set had five a shade too light for that.
6
+ */
7
+ export const PRESENCE_COLOURS = [
8
+ '#e11d48', '#2563eb', '#15803d', '#7e22ce',
9
+ '#c2410c', '#0e7490', '#a16207', '#db2777',
10
+ ];
11
+ /** A colour for an id: the same person gets the same one every session. */
12
+ export function presenceColour(id) {
13
+ let hash = 0;
14
+ for (let i = 0; i < id.length; i += 1)
15
+ hash = (hash * 31 + id.charCodeAt(i)) >>> 0;
16
+ return PRESENCE_COLOURS[hash % PRESENCE_COLOURS.length];
17
+ }
18
+ /**
19
+ * The ink for a name tag on a person's colour: black or white, whichever
20
+ * contrasts more. White on every colour was the first version, and white
21
+ * on the first set's green, orange or yellow was a little over 3:1, under
22
+ * the 4.5:1 an 11px name needs. The built-in set is dark enough now, but a
23
+ * collaborator's own colour can be anything, so the tag still asks.
24
+ * A colour that is not a hex triplet gets white, the way it always did.
25
+ */
26
+ export function presenceInk(colour) {
27
+ const hex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(colour.trim());
28
+ if (!hex)
29
+ return '#fff';
30
+ const digits = hex[1].length === 3 ? [...hex[1]].map((d) => d + d).join('') : hex[1];
31
+ const channel = (at) => {
32
+ const c = parseInt(digits.slice(at, at + 2), 16) / 255;
33
+ return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
34
+ };
35
+ const luminance = 0.2126 * channel(0) + 0.7152 * channel(2) + 0.0722 * channel(4);
36
+ // Contrast against white is (1.05 / (L + 0.05)); against black, (L + 0.05) / 0.05.
37
+ return 1.05 / (luminance + 0.05) >= (luminance + 0.05) / 0.05 ? '#fff' : '#000';
38
+ }
39
+ /** Two initials for the tag when the box is too small for a name. */
40
+ export function presenceInitials(name) {
41
+ const words = name.trim().split(/\s+/).filter(Boolean);
42
+ if (words.length === 0)
43
+ return '?';
44
+ if (words.length === 1)
45
+ return words[0].slice(0, 2).toUpperCase();
46
+ return `${words[0][0]}${words[words.length - 1][0]}`.toUpperCase();
47
+ }
48
+ /**
49
+ * The peers still here: the newest entry per person, anyone quiet for
50
+ * longer than `timeoutMs` dropped.
51
+ *
52
+ * A network gives no "goodbye" when a tab is closed, so the only honest
53
+ * answer to "is this person still here" is how long ago they last said
54
+ * anything. Fifteen seconds is the grid's own answer, and this keeps to it.
55
+ */
56
+ export function livePresence(list, now = Date.now(), timeoutMs = 15000) {
57
+ const newest = new Map();
58
+ for (const person of list) {
59
+ if (now - (person.at ?? now) > timeoutMs)
60
+ continue;
61
+ const had = newest.get(person.id);
62
+ if (!had || (person.at ?? now) >= (had.at ?? now))
63
+ newest.set(person.id, person);
64
+ }
65
+ return [...newest.values()];
66
+ }
67
+ /** The peers on one sheet, in a stable order so the boxes do not swap. */
68
+ export function presenceOnSheet(list, sheet) {
69
+ return list
70
+ .filter((person) => person.sheet.toLowerCase() === sheet.toLowerCase())
71
+ .sort((a, b) => a.id.localeCompare(b.id));
72
+ }
73
+ /** Where the tag goes: the cell named, or the top-left of the selection. */
74
+ export function presenceAnchor(person) {
75
+ if (person.active)
76
+ return person.active;
77
+ const [r1, c1] = person.rect;
78
+ return { row: r1, col: c1 };
79
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * A sheet as the page File > Print opens: one standalone HTML document the
3
+ * browser's own print engine lays out, so fonts, CJK and RTL come out
4
+ * right and nothing is bundled. The print area (or the used range) as a
5
+ * table, column widths and row heights as the sheet shows them, hidden
6
+ * lines left out, merges as spans, every cell with its format and its
7
+ * conditional style, the title rows in a `<thead>` so they repeat on each
8
+ * page, gridlines and headings when the setup asks, and `@page` carrying
9
+ * the orientation, paper and margins. Pure: the shell hands in what a cell
10
+ * shows and where; a test reads the HTML back.
11
+ */
12
+ import type { CellFormatEntry, Rect } from './format-store.js';
13
+ import type { CfStyle } from './conditional-formats.js';
14
+ import { type PageSetup } from './page-setup.js';
15
+ export type SheetPrintCell = {
16
+ /** What the cell shows. */
17
+ text: string;
18
+ /**
19
+ * The sparkline drawn in this cell, as SVG markup ready to place. Placed
20
+ * behind the text, as it is on screen, so a label typed over one still
21
+ * reads on the page.
22
+ */
23
+ sparkline?: string;
24
+ /**
25
+ * The picture an `IMAGE` cell shows, as markup ready to place. Fitted
26
+ * inside the cell, as it is on screen.
27
+ */
28
+ image?: string;
29
+ /**
30
+ * The table's look on this cell, where it is inside one: Excel prints a
31
+ * table banded, and the shell draws the look rather than writing it into
32
+ * the cells, so it has to be handed in here or the page comes out plain.
33
+ * Laid under the cell's own format, as it is on screen.
34
+ */
35
+ table?: {
36
+ fill?: string;
37
+ color?: string;
38
+ bold?: boolean;
39
+ borderTop?: string;
40
+ borderBottom?: string;
41
+ };
42
+ /** An error's colour, as the sheet paints it. */
43
+ color?: string;
44
+ /** Numbers right, text left, unless the format says. */
45
+ align?: 'left' | 'center' | 'right';
46
+ entry?: CellFormatEntry;
47
+ cf?: CfStyle;
48
+ };
49
+ export type SheetPrintInput = {
50
+ /** The sheet's name, the page's title. */
51
+ name: string;
52
+ /** The used range: rows and columns with anything in them. */
53
+ rowCount: number;
54
+ colCount: number;
55
+ cellAt: (r: number, c: number) => SheetPrintCell;
56
+ widths: Readonly<Record<string, number>>;
57
+ defaultWidth: number;
58
+ heights: ReadonlyMap<number, number>;
59
+ defaultHeight: number;
60
+ hidden: {
61
+ rows: ReadonlySet<number>;
62
+ cols: ReadonlySet<number>;
63
+ };
64
+ merges: ReadonlyArray<Rect>;
65
+ setup: PageSetup;
66
+ /**
67
+ * The charts and pictures over the cells, each as markup ready to place:
68
+ * an `<img>`, or a chart already drawn to `<svg>`.
69
+ *
70
+ * An object is placed against its ANCHOR CELL with the offset and size it
71
+ * has on the sheet, so the printed page puts it where the sheet does
72
+ * without the print builder knowing anything about layout. One anchored
73
+ * outside the printed area, or to a hidden line, is left out: there is no
74
+ * cell on the page to hang it from.
75
+ */
76
+ objects?: ReadonlyArray<SheetPrintObject>;
77
+ };
78
+ export type SheetPrintObject = {
79
+ /** The cell it hangs from. */
80
+ row: number;
81
+ col: number;
82
+ /** Its offset inside that cell, and its size, in pixels. */
83
+ dx: number;
84
+ dy: number;
85
+ width: number;
86
+ height: number;
87
+ /** The markup, placed as it stands. The caller has escaped it. */
88
+ html: string;
89
+ };
90
+ /** The rectangles that print: the setup's area, or the whole used range. */
91
+ export declare function printAreas(input: Pick<SheetPrintInput, 'rowCount' | 'colCount' | 'setup'>): Rect[];
92
+ /**
93
+ * The used range grown to hold what floats over it.
94
+ *
95
+ * A chart is almost always anchored BELOW the numbers it reads, which is
96
+ * past the last row with anything typed in it. Printing the used range and
97
+ * nothing else would drop it, so the default area grows to cover each
98
+ * object's cells, walking the widths and heights out from its anchor until
99
+ * the object is covered. An explicit print area is left exactly as it is:
100
+ * someone who named a block meant that block.
101
+ */
102
+ export declare function areasWithObjects(input: SheetPrintInput): Rect[];
103
+ /** One printable HTML document for the sheet. */
104
+ export declare function sheetPrintHtml(input: SheetPrintInput): string;
@@ -0,0 +1,169 @@
1
+ import { entryToStyle } from './format-store.js';
2
+ import { colToLetters } from './address.js';
3
+ import { mergeAt, isCoveredCell } from './merges.js';
4
+ import { marginsCss, PAPER_SIZES } from './page-setup.js';
5
+ const HTML_ESCAPE = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
6
+ const esc = (s) => s.replace(/[&<>"']/g, (c) => HTML_ESCAPE[c]);
7
+ /** The rectangles that print: the setup's area, or the whole used range. */
8
+ export function printAreas(input) {
9
+ if (input.setup.printArea?.length)
10
+ return input.setup.printArea;
11
+ return [[0, 0, Math.max(0, input.rowCount - 1), Math.max(0, input.colCount - 1)]];
12
+ }
13
+ /**
14
+ * The used range grown to hold what floats over it.
15
+ *
16
+ * A chart is almost always anchored BELOW the numbers it reads, which is
17
+ * past the last row with anything typed in it. Printing the used range and
18
+ * nothing else would drop it, so the default area grows to cover each
19
+ * object's cells, walking the widths and heights out from its anchor until
20
+ * the object is covered. An explicit print area is left exactly as it is:
21
+ * someone who named a block meant that block.
22
+ */
23
+ export function areasWithObjects(input) {
24
+ const areas = printAreas(input);
25
+ if (input.setup.printArea?.length || !input.objects?.length)
26
+ return areas;
27
+ const area = areas[0];
28
+ let [r1, c1, r2, c2] = area;
29
+ for (const object of input.objects) {
30
+ let row = object.row;
31
+ for (let covered = -object.dy; covered < object.height; row += 1) {
32
+ covered += input.heights.get(row) ?? input.defaultHeight;
33
+ }
34
+ let col = object.col;
35
+ for (let covered = -object.dx; covered < object.width; col += 1) {
36
+ covered += input.widths[colToLetters(col)] ?? input.defaultWidth;
37
+ }
38
+ r1 = Math.min(r1, object.row);
39
+ c1 = Math.min(c1, object.col);
40
+ r2 = Math.max(r2, row - 1);
41
+ c2 = Math.max(c2, col - 1);
42
+ }
43
+ return [[r1, c1, r2, c2]];
44
+ }
45
+ /** One printable HTML document for the sheet. */
46
+ export function sheetPrintHtml(input) {
47
+ const { setup } = input;
48
+ /** The objects hanging from each cell, so a cell is one lookup. */
49
+ const byAnchor = new Map();
50
+ for (const object of input.objects ?? []) {
51
+ const key = `${object.row},${object.col}`;
52
+ const list = byAnchor.get(key);
53
+ if (list)
54
+ list.push(object);
55
+ else
56
+ byAnchor.set(key, [object]);
57
+ }
58
+ const visibleRows = (r1, r2) => { const out = []; for (let r = r1; r <= r2; r += 1)
59
+ if (!input.hidden.rows.has(r))
60
+ out.push(r); return out; };
61
+ const visibleCols = (c1, c2) => { const out = []; for (let c = c1; c <= c2; c += 1)
62
+ if (!input.hidden.cols.has(c))
63
+ out.push(c); return out; };
64
+ const cellHtml = (r, c, area, tag = 'td') => {
65
+ if (isCoveredCell(input.merges, r, c))
66
+ return '';
67
+ const cell = input.cellAt(r, c);
68
+ const merge = mergeAt(input.merges, r, c);
69
+ let span = '';
70
+ if (merge) {
71
+ const cols = visibleCols(Math.max(merge[1], area[1]), Math.min(merge[3], area[3])).length;
72
+ const rows = visibleRows(Math.max(merge[0], area[0]), Math.min(merge[2], area[2])).length;
73
+ if (cols > 1)
74
+ span += ` colspan="${cols}"`;
75
+ if (rows > 1)
76
+ span += ` rowspan="${rows}"`;
77
+ }
78
+ const styles = [];
79
+ const align = cell.entry?.align ?? cell.align;
80
+ if (align && align !== 'left')
81
+ styles.push(`text-align:${align}`);
82
+ // The table's bands go in first, so a fill or a colour written on the
83
+ // cell still wins, which is the order the screen draws them in.
84
+ if (cell.table) {
85
+ if (cell.table.fill)
86
+ styles.push(`background:${cell.table.fill}`);
87
+ if (cell.table.color)
88
+ styles.push(`color:${cell.table.color}`);
89
+ if (cell.table.bold)
90
+ styles.push('font-weight:600');
91
+ if (cell.table.borderTop)
92
+ styles.push(`border-top:1px solid ${cell.table.borderTop}`);
93
+ if (cell.table.borderBottom)
94
+ styles.push(`border-bottom:1px solid ${cell.table.borderBottom}`);
95
+ }
96
+ const own = entryToStyle(cell.entry);
97
+ if (own)
98
+ styles.push(own);
99
+ if (cell.cf)
100
+ styles.push(entryToStyle(cell.cf));
101
+ if (cell.color)
102
+ styles.push(`color:${cell.color}`);
103
+ const style = styles.length ? ` style="${esc(styles.filter(Boolean).join(';'))}"` : '';
104
+ // A sparkline goes behind the text; an object hangs from the cell and is
105
+ // allowed to overflow it, which is what makes a chart bigger than one
106
+ // cell print as a chart rather than as a sliver.
107
+ const spark = cell.sparkline ? `<span class="sp">${cell.sparkline}</span>` : '';
108
+ const picture = cell.image ? `<span class="im">${cell.image}</span>` : '';
109
+ const objects = (byAnchor.get(`${r},${c}`) ?? [])
110
+ .map((o) => `<span class="ob" style="inset-inline-start:${o.dx}px;top:${o.dy}px;width:${o.width}px;height:${o.height}px">${o.html}</span>`)
111
+ .join('');
112
+ const classes = [spark || picture ? 'sp-cell' : '', objects ? 'ob-cell' : ''].filter(Boolean).join(' ');
113
+ const cls = classes ? ` class="${classes}"` : '';
114
+ // A cell past the written area has nothing to say, and a caller reading
115
+ // one is not a reason to throw during a print.
116
+ const text = esc(cell.text ?? '');
117
+ const body = spark || picture || objects
118
+ ? `${spark}${picture}${objects}<span class="tx">${cell.image ? '' : text}</span>`
119
+ : text;
120
+ return `<${tag}${span}${cls}${style}>${body}</${tag}>`;
121
+ };
122
+ const rowHtml = (r, cols, area, head = false) => {
123
+ const h = input.heights.get(r) ?? input.defaultHeight;
124
+ const heading = setup.headings ? `<th class="rh">${r + 1}</th>` : '';
125
+ return `<tr style="height:${h}px">${heading}${cols.map((c) => cellHtml(r, c, area, head ? 'th' : 'td')).join('')}</tr>`;
126
+ };
127
+ const tables = areasWithObjects(input).map((area) => {
128
+ const cols = visibleCols(area[1], area[3]);
129
+ const rows = visibleRows(area[0], area[2]);
130
+ const colgroup = `<colgroup>${setup.headings ? '<col style="width:40px">' : ''}${cols.map((c) => `<col style="width:${input.widths[colToLetters(c)] ?? input.defaultWidth}px">`).join('')}</colgroup>`;
131
+ const headings = setup.headings ? `<tr class="ch"><th class="corner"></th>${cols.map((c) => `<th>${colToLetters(c)}</th>`).join('')}</tr>` : '';
132
+ // The title rows repeat on every page when they sit above or inside the area.
133
+ const titles = setup.printTitleRows;
134
+ const titleRows = titles && titles[0] <= area[2] ? visibleRows(titles[0], Math.min(titles[1], area[2])).filter((r) => r < area[0] || r <= area[2]) : [];
135
+ const bodyRows = rows.filter((r) => !titleRows.includes(r));
136
+ const thead = headings || titleRows.length
137
+ ? `<thead>${headings}${titleRows.map((r) => rowHtml(r, cols, [Math.min(r, area[0]), area[1], area[2], area[3]], true)).join('')}</thead>`
138
+ : '';
139
+ return `<table>${colgroup}${thead}<tbody>${bodyRows.map((r) => rowHtml(r, cols, area)).join('')}</tbody></table>`;
140
+ });
141
+ const paper = PAPER_SIZES[setup.paper]?.css ?? 'A4';
142
+ const grid = setup.gridlines ? 'td, th { border: 1px solid #d0d0d0; }' : 'td, th { border: 1px solid transparent; }';
143
+ return `<!DOCTYPE html>
144
+ <html><head><meta charset="utf-8"><title>${esc(input.name)}</title>
145
+ <style>
146
+ @page { size: ${paper} ${setup.orientation}; margin: ${marginsCss(setup.margins)}; }
147
+ @media print { body { -webkit-print-color-adjust: exact; print-color-adjust: exact; } }
148
+ body { font-family: Calibri, "Segoe UI", -apple-system, Roboto, sans-serif; font-size: 11pt; color: #000; margin: 0; }
149
+ table { border-collapse: collapse; table-layout: fixed; zoom: ${setup.scale / 100}; }
150
+ table + table { break-before: page; }
151
+ thead { display: table-header-group; }
152
+ tr { break-inside: avoid; }
153
+ ${grid}
154
+ td, th { padding: 1px 4px; overflow: hidden; white-space: nowrap; text-overflow: clip; text-align: left; font-weight: 400; vertical-align: bottom; }
155
+ th.rh, tr.ch th { background: #f2f2f2; color: #444; text-align: center; font-size: 9pt; border: 1px solid #c8c8c8; }
156
+ td.sp-cell, td.ob-cell { position: relative; }
157
+ td.ob-cell { overflow: visible; }
158
+ td .sp { position: absolute; inset: 1px 4px; display: block; }
159
+ td .sp svg { width: 100%; height: 100%; }
160
+ td .im { position: absolute; inset: 1px 2px; display: block; }
161
+ td .im img { width: 100%; height: 100%; object-fit: contain; }
162
+ td .ob { position: absolute; display: block; overflow: hidden; }
163
+ td .ob img, td .ob svg { width: 100%; height: 100%; object-fit: contain; }
164
+ td .tx { position: relative; }
165
+ </style></head>
166
+ <body>
167
+ ${tables.join('\n ')}
168
+ </body></html>`;
169
+ }
@@ -3,19 +3,73 @@
3
3
  * Format Cells > Protection unlocks the ones that may change, and Protect
4
4
  * Sheet turns the flags on. Until then a locked cell is an ordinary cell.
5
5
  *
6
+ * Two refinements ride beside the flag, as they do in Excel. The "allow
7
+ * all users of this worksheet to" list of the Protect Sheet dialog says
8
+ * which kinds of change stay open while the sheet is protected (format
9
+ * cells, size and hide lines, insert and delete, sort, filter); and Allow
10
+ * Edit Ranges names blocks that take an edit on a protected sheet whether
11
+ * their cells are locked or not. There is no password.
12
+ *
6
13
  * The rules live here so the shell, the ribbon and the commands agree on
7
14
  * them without each reading the format entry its own way.
8
15
  */
9
16
  import type { CellAddressLookup, CellFormatEntry, Rect, SheetFormatStore } from './format-store.js';
10
17
  /** What the sheet says when a protected cell is asked to change. */
11
18
  export declare const PROTECTED_MESSAGE = "The cell you're trying to change is on a protected sheet. To make a change, unprotect the sheet.";
19
+ /**
20
+ * What stays allowed on a protected sheet: Excel's Protect Sheet list, the
21
+ * entries the shell has something behind. An absent key is not allowed.
22
+ */
23
+ export type ProtectionAllow = {
24
+ /** Format Cells, the Home > Font / Alignment / Number buttons, merges, Lock Cell. */
25
+ formatCells?: boolean;
26
+ /** Column width, AutoFit, hide and unhide columns, the resize handle. */
27
+ formatColumns?: boolean;
28
+ /** Row height, AutoFit, hide and unhide rows, the resize handle. */
29
+ formatRows?: boolean;
30
+ insertColumns?: boolean;
31
+ insertRows?: boolean;
32
+ deleteColumns?: boolean;
33
+ deleteRows?: boolean;
34
+ /** Sort, of a block with no locked cell: Excel refuses one with, whatever this says. */
35
+ sort?: boolean;
36
+ /** Filter on and off, and the arrows' menus. */
37
+ autoFilter?: boolean;
38
+ };
39
+ export type ProtectionPermission = keyof ProtectionAllow;
40
+ /** The list in the order Excel's dialog shows it. */
41
+ export declare const PROTECTION_PERMISSIONS: ReadonlyArray<ProtectionPermission>;
42
+ /** Excel's Allow Users to Edit Ranges entry: a name over some cells. */
43
+ export type EditRange = {
44
+ id: string;
45
+ title: string;
46
+ rects: Rect[];
47
+ };
48
+ /** What a sheet keeps beside its `protected` flag. */
49
+ export type SheetProtection = {
50
+ allow: ProtectionAllow;
51
+ ranges: EditRange[];
52
+ };
53
+ export declare const defaultProtection: () => SheetProtection;
12
54
  /** A cell is locked unless its format says otherwise. */
13
55
  export declare function isLocked(entry: CellFormatEntry | undefined): boolean;
56
+ /** Whether (r, c) lies in one of the ranges that stay editable. */
57
+ export declare function inEditRange(ranges: ReadonlyArray<EditRange>, r: number, c: number): boolean;
58
+ /** Whether the cell holds on a protected sheet: locked, and in no edit range. */
59
+ export declare function cellLocked(entry: CellFormatEntry | undefined, ranges: ReadonlyArray<EditRange>, r: number, c: number): boolean;
14
60
  /**
15
61
  * Whether any cell of the rectangles is locked. A protected sheet refuses
16
62
  * a change that touches one locked cell rather than doing the rest, which
17
63
  * is what Excel does and what keeps an undo step whole.
18
64
  */
19
- export declare function rectsHaveLocked(store: SheetFormatStore, lookup: CellAddressLookup, rects: ReadonlyArray<Rect>): boolean;
65
+ export declare function rectsHaveLocked(store: SheetFormatStore, lookup: CellAddressLookup, rects: ReadonlyArray<Rect>, ranges?: ReadonlyArray<EditRange>): boolean;
20
66
  /** Whether the rectangles hold both locked and unlocked cells. */
21
67
  export declare function rectsMixLocked(store: SheetFormatStore, lookup: CellAddressLookup, rects: ReadonlyArray<Rect>): boolean;
68
+ /** A copy safe to hand out or save. */
69
+ export declare function copyProtection(protection: SheetProtection): SheetProtection;
70
+ /** An id no other range of this session carries. */
71
+ export declare const newEditRangeId: () => string;
72
+ /** `B2:B10, A1 C3:C5` as rectangles; null when any piece is not a cell or a range. */
73
+ export declare function parseRangeText(text: string): Rect[] | null;
74
+ /** Rectangles as `B2:B10, A1`, the way the dialog lists them. */
75
+ export declare function rangeText(rects: ReadonlyArray<Rect>): string;
@@ -1,15 +1,34 @@
1
+ import { colToLetters, parseA1 } from './address.js';
1
2
  /** What the sheet says when a protected cell is asked to change. */
2
3
  export const PROTECTED_MESSAGE = "The cell you're trying to change is on a protected sheet. To make a change, unprotect the sheet.";
4
+ /** The list in the order Excel's dialog shows it. */
5
+ export const PROTECTION_PERMISSIONS = [
6
+ 'formatCells', 'formatColumns', 'formatRows', 'insertColumns', 'insertRows', 'deleteColumns', 'deleteRows', 'sort', 'autoFilter',
7
+ ];
8
+ export const defaultProtection = () => ({ allow: {}, ranges: [] });
3
9
  /** A cell is locked unless its format says otherwise. */
4
10
  export function isLocked(entry) {
5
11
  return entry?.locked !== false;
6
12
  }
13
+ /** Whether (r, c) lies in one of the ranges that stay editable. */
14
+ export function inEditRange(ranges, r, c) {
15
+ for (const range of ranges) {
16
+ for (const [r1, c1, r2, c2] of range.rects)
17
+ if (r >= r1 && r <= r2 && c >= c1 && c <= c2)
18
+ return true;
19
+ }
20
+ return false;
21
+ }
22
+ /** Whether the cell holds on a protected sheet: locked, and in no edit range. */
23
+ export function cellLocked(entry, ranges, r, c) {
24
+ return isLocked(entry) && !inEditRange(ranges, r, c);
25
+ }
7
26
  /**
8
27
  * Whether any cell of the rectangles is locked. A protected sheet refuses
9
28
  * a change that touches one locked cell rather than doing the rest, which
10
29
  * is what Excel does and what keeps an undo step whole.
11
30
  */
12
- export function rectsHaveLocked(store, lookup, rects) {
31
+ export function rectsHaveLocked(store, lookup, rects, ranges = []) {
13
32
  for (const [minRow, minCol, maxRow, maxCol] of rects) {
14
33
  for (let r = minRow; r <= maxRow; r += 1) {
15
34
  for (let c = minCol; c <= maxCol; c += 1) {
@@ -17,7 +36,7 @@ export function rectsHaveLocked(store, lookup, rects) {
17
36
  const columnId = lookup.columnIdAt(c);
18
37
  if (rowId == null || columnId == null)
19
38
  continue;
20
- if (isLocked(store.get(rowId, columnId)))
39
+ if (cellLocked(store.get(rowId, columnId), ranges, r, c))
21
40
  return true;
22
41
  }
23
42
  }
@@ -46,3 +65,37 @@ export function rectsMixLocked(store, lookup, rects) {
46
65
  }
47
66
  return false;
48
67
  }
68
+ /** A copy safe to hand out or save. */
69
+ export function copyProtection(protection) {
70
+ return {
71
+ allow: { ...protection.allow },
72
+ ranges: protection.ranges.map((range) => ({ ...range, rects: range.rects.map(([r1, c1, r2, c2]) => [r1, c1, r2, c2]) })),
73
+ };
74
+ }
75
+ let nextRangeId = 1;
76
+ /** An id no other range of this session carries. */
77
+ export const newEditRangeId = () => `range-${Date.now().toString(36)}-${(nextRangeId += 1).toString(36)}`;
78
+ /** `B2:B10, A1 C3:C5` as rectangles; null when any piece is not a cell or a range. */
79
+ export function parseRangeText(text) {
80
+ const pieces = text.split(/[,\s]+/).map((p) => p.trim().replace(/^=/, '')).filter(Boolean);
81
+ if (!pieces.length)
82
+ return null;
83
+ const out = [];
84
+ for (const piece of pieces) {
85
+ const [first, last] = piece.split(':');
86
+ const a = parseA1(first ?? '');
87
+ const b = last === undefined ? a : parseA1(last);
88
+ if (!a || !b || a.row === null || b.row === null)
89
+ return null;
90
+ out.push([Math.min(a.row, b.row), Math.min(a.col, b.col), Math.max(a.row, b.row), Math.max(a.col, b.col)]);
91
+ }
92
+ return out;
93
+ }
94
+ /** Rectangles as `B2:B10, A1`, the way the dialog lists them. */
95
+ export function rangeText(rects) {
96
+ return rects.map(([r1, c1, r2, c2]) => {
97
+ const a = `${colToLetters(c1)}${r1 + 1}`;
98
+ const b = `${colToLetters(c2)}${r2 + 1}`;
99
+ return a === b ? a : `${a}:${b}`;
100
+ }).join(', ');
101
+ }
@@ -40,6 +40,6 @@ export type NotesMap = Record<string, Record<string, string>>;
40
40
  * is after the edit, or null when the edit deleted it, which drops its
41
41
  * notes with it.
42
42
  */
43
- export declare function remapNotes(notes: NotesMap, axis: 'rows' | 'cols', shift: (index: number) => number | null): NotesMap;
43
+ export declare function remapNotes<T = string>(notes: Record<string, Record<string, T>>, axis: 'rows' | 'cols', shift: (index: number) => number | null): Record<string, Record<string, T>>;
44
44
  /** The shift function a structural edit implies, shared by every keyed part. */
45
45
  export declare function lineShift(edit: StructuralEdit): (index: number) => number | null;
@@ -24,6 +24,25 @@ export declare function formatFormula(node: Node): string;
24
24
  * whole column of mixed literals and formulas through it.
25
25
  */
26
26
  export declare function translateFormula(text: unknown, dRow: number, dCol: number): unknown;
27
+ /**
28
+ * A formula for a cell that a transposed paste moves from `source` to
29
+ * `dest`, its relative references turned with it.
30
+ *
31
+ * Excel rotates a relative offset on a transpose: a reference `dr` rows
32
+ * and `dc` columns away becomes `dc` rows and `dr` columns away. A cell
33
+ * inside the block moved the same way, so a formula that read the price
34
+ * beside it still reads that price, now above it, which is what makes a
35
+ * transposed totals column still total. A reference outside the block is
36
+ * turned too, as Excel turns it. Absolute parts stay where they point.
37
+ * A column-only reference has no row to turn and is left as it is.
38
+ */
39
+ export declare function transposeFormula(text: unknown, source: {
40
+ row: number;
41
+ col: number;
42
+ }, dest: {
43
+ row: number;
44
+ col: number;
45
+ }): unknown;
27
46
  /**
28
47
  * Point every reference that names sheet `from` at `to` instead: what a
29
48
  * sheet rename owes the formulas on the other sheets and the defined
@@ -32,6 +51,35 @@ export declare function translateFormula(text: unknown, dRow: number, dCol: numb
32
51
  * name is left alone and a new name with a space comes out quoted. A
33
52
  * formula that names no such sheet is returned as it was, untouched.
34
53
  */
54
+ /**
55
+ * A block of cells that has MOVED: cut and pasted somewhere else, or dragged
56
+ * there. `sheet` is where it was, `toSheet` where it landed, and the rect is
57
+ * the block's old position, zero-based and inclusive.
58
+ */
59
+ export type CellMove = {
60
+ sheet: string;
61
+ toSheet: string;
62
+ top: number;
63
+ left: number;
64
+ bottom: number;
65
+ right: number;
66
+ dRow: number;
67
+ dCol: number;
68
+ };
69
+ /**
70
+ * Point every reference to a moved cell at where the cell now is.
71
+ *
72
+ * This is what a cut and paste owes the rest of the workbook, and Excel does
73
+ * it: moving A1 to D1 rewrites `=A1*2` as `=D1*2` rather than leaving it
74
+ * reading an emptied cell. A `$` makes no difference - the cell moved, so
75
+ * every way of naming it moves - and a RANGE only follows when the whole of
76
+ * it moved, which is why `=SUM(A1:A2)` stays as it is when only A1 goes.
77
+ *
78
+ * `self` is the sheet the formula lives on, so an unqualified reference is
79
+ * read against the right geometry; a reference that lands on another sheet
80
+ * takes that sheet's name, as Excel writes it.
81
+ */
82
+ export declare function repointReferences(text: unknown, move: CellMove, self: string | null): unknown;
35
83
  /**
36
84
  * Excel's reference colours: the A1 references in a formula being typed,
37
85
  * each occurrence with the colour of its range, so the cells a formula