@rowsncolumns/spreadsheet-state 28.0.72 → 28.0.74

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 (185) hide show
  1. package/dist/cjs/api/advanced-filter.d.ts +72 -0
  2. package/dist/cjs/api/advanced-filter.d.ts.map +1 -0
  3. package/dist/cjs/api/advanced-filter.js +0 -0
  4. package/dist/cjs/api/goal-seek.d.ts +29 -0
  5. package/dist/cjs/api/goal-seek.d.ts.map +1 -0
  6. package/dist/cjs/api/goal-seek.js +131 -0
  7. package/dist/cjs/api/immer-utils.d.ts.map +1 -1
  8. package/dist/cjs/api/immer-utils.js +2 -0
  9. package/dist/cjs/api/paint-format.d.ts +41 -0
  10. package/dist/cjs/api/paint-format.d.ts.map +1 -0
  11. package/dist/cjs/api/paint-format.js +115 -0
  12. package/dist/cjs/api/paste-special.d.ts +48 -0
  13. package/dist/cjs/api/paste-special.d.ts.map +1 -0
  14. package/dist/cjs/api/paste-special.js +229 -0
  15. package/dist/cjs/api/split-text.d.ts +12 -0
  16. package/dist/cjs/api/split-text.d.ts.map +1 -1
  17. package/dist/cjs/api/split-text.js +41 -0
  18. package/dist/cjs/api/subtotal.d.ts +85 -0
  19. package/dist/cjs/api/subtotal.d.ts.map +1 -0
  20. package/dist/cjs/api/subtotal.js +250 -0
  21. package/dist/cjs/commands.d.ts +13 -0
  22. package/dist/cjs/commands.d.ts.map +1 -1
  23. package/dist/cjs/components/editors/data-validation-rule-editor.d.ts.map +1 -1
  24. package/dist/cjs/components/editors/data-validation-rule-editor.js +83 -16
  25. package/dist/cjs/components/editors/table-editor.js +7 -2
  26. package/dist/cjs/hooks/use-calculation-worker.d.ts.map +1 -1
  27. package/dist/cjs/hooks/use-calculation-worker.js +39 -8
  28. package/dist/cjs/hooks/use-calculation.d.ts +12 -2
  29. package/dist/cjs/hooks/use-calculation.d.ts.map +1 -1
  30. package/dist/cjs/hooks/use-calculation.js +71 -35
  31. package/dist/cjs/hooks/use-on-advanced-filter.d.ts +21 -0
  32. package/dist/cjs/hooks/use-on-advanced-filter.d.ts.map +1 -0
  33. package/dist/cjs/hooks/use-on-advanced-filter.js +42 -0
  34. package/dist/cjs/hooks/use-on-goal-seek.d.ts +30 -0
  35. package/dist/cjs/hooks/use-on-goal-seek.d.ts.map +1 -0
  36. package/dist/cjs/hooks/use-on-goal-seek.js +140 -0
  37. package/dist/cjs/hooks/use-on-import-excel.d.ts +10 -1
  38. package/dist/cjs/hooks/use-on-import-excel.d.ts.map +1 -1
  39. package/dist/cjs/hooks/use-on-import-excel.js +8 -4
  40. package/dist/cjs/hooks/use-on-merge-unmerge-cells.d.ts.map +1 -1
  41. package/dist/cjs/hooks/use-on-merge-unmerge-cells.js +53 -34
  42. package/dist/cjs/hooks/use-on-paste.d.ts.map +1 -1
  43. package/dist/cjs/hooks/use-on-paste.js +82 -52
  44. package/dist/cjs/hooks/use-on-remove-duplicates.d.ts +2 -1
  45. package/dist/cjs/hooks/use-on-remove-duplicates.d.ts.map +1 -1
  46. package/dist/cjs/hooks/use-on-remove-duplicates.js +5 -3
  47. package/dist/cjs/hooks/use-on-show-column.d.ts.map +1 -1
  48. package/dist/cjs/hooks/use-on-show-column.js +2 -0
  49. package/dist/cjs/hooks/use-on-show-row.d.ts.map +1 -1
  50. package/dist/cjs/hooks/use-on-show-row.js +2 -0
  51. package/dist/cjs/hooks/use-on-subtotal.d.ts +26 -0
  52. package/dist/cjs/hooks/use-on-subtotal.d.ts.map +1 -0
  53. package/dist/cjs/hooks/use-on-subtotal.js +53 -0
  54. package/dist/cjs/hooks/use-paint-format.d.ts +19 -3
  55. package/dist/cjs/hooks/use-paint-format.d.ts.map +1 -1
  56. package/dist/cjs/hooks/use-paint-format.js +85 -31
  57. package/dist/cjs/hooks/use-sheet-properties.d.ts +3 -0
  58. package/dist/cjs/hooks/use-sheet-properties.d.ts.map +1 -1
  59. package/dist/cjs/hooks/use-sheet-properties.js +8 -0
  60. package/dist/cjs/hooks/use-split-text-to-columns.d.ts +2 -1
  61. package/dist/cjs/hooks/use-split-text-to-columns.d.ts.map +1 -1
  62. package/dist/cjs/hooks/use-split-text-to-columns.js +3 -2
  63. package/dist/cjs/hooks/use-spreadsheet-state.d.ts +50 -36
  64. package/dist/cjs/hooks/use-spreadsheet-state.d.ts.map +1 -1
  65. package/dist/cjs/hooks/use-spreadsheet-state.js +98 -18
  66. package/dist/cjs/index.d.ts +9 -0
  67. package/dist/cjs/index.d.ts.map +1 -1
  68. package/dist/cjs/index.js +9 -0
  69. package/dist/cjs/interface/calculation-interface.d.ts.map +1 -1
  70. package/dist/cjs/interface/calculation-interface.js +5 -0
  71. package/dist/cjs/interface/change-batch-stream.d.ts.map +1 -1
  72. package/dist/cjs/interface/change-batch-stream.js +12 -6
  73. package/dist/cjs/interface/change-batch.d.ts.map +1 -1
  74. package/dist/cjs/interface/change-batch.js +17 -9
  75. package/dist/cjs/interface/change-formatting.d.ts.map +1 -1
  76. package/dist/cjs/interface/change-formatting.js +30 -11
  77. package/dist/cjs/interface/hide-column.d.ts.map +1 -1
  78. package/dist/cjs/interface/hide-column.js +4 -0
  79. package/dist/cjs/interface/hide-row.d.ts.map +1 -1
  80. package/dist/cjs/interface/hide-row.js +4 -0
  81. package/dist/cjs/interface/remove-duplicates.d.ts +3 -2
  82. package/dist/cjs/interface/remove-duplicates.d.ts.map +1 -1
  83. package/dist/cjs/interface/remove-duplicates.js +41 -7
  84. package/dist/cjs/interface/split-text.d.ts +2 -1
  85. package/dist/cjs/interface/split-text.d.ts.map +1 -1
  86. package/dist/cjs/interface/split-text.js +7 -3
  87. package/dist/cjs/interface/spreadsheet-interface.d.ts +2 -1
  88. package/dist/cjs/interface/spreadsheet-interface.d.ts.map +1 -1
  89. package/dist/cjs/interface/spreadsheet-interface.js +5 -5
  90. package/dist/cjs/sheet-cell.d.ts.map +1 -1
  91. package/dist/cjs/sheet-cell.js +7 -0
  92. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  93. package/dist/esm/api/advanced-filter.d.ts +72 -0
  94. package/dist/esm/api/advanced-filter.d.ts.map +1 -0
  95. package/dist/esm/api/advanced-filter.js +0 -0
  96. package/dist/esm/api/goal-seek.d.ts +29 -0
  97. package/dist/esm/api/goal-seek.d.ts.map +1 -0
  98. package/dist/esm/api/goal-seek.js +108 -0
  99. package/dist/esm/api/immer-utils.d.ts.map +1 -1
  100. package/dist/esm/api/immer-utils.js +2 -0
  101. package/dist/esm/api/paint-format.d.ts +41 -0
  102. package/dist/esm/api/paint-format.d.ts.map +1 -0
  103. package/dist/esm/api/paint-format.js +77 -0
  104. package/dist/esm/api/paste-special.d.ts +48 -0
  105. package/dist/esm/api/paste-special.d.ts.map +1 -0
  106. package/dist/esm/api/paste-special.js +220 -0
  107. package/dist/esm/api/split-text.d.ts +12 -0
  108. package/dist/esm/api/split-text.d.ts.map +1 -1
  109. package/dist/esm/api/split-text.js +28 -0
  110. package/dist/esm/api/subtotal.d.ts +85 -0
  111. package/dist/esm/api/subtotal.d.ts.map +1 -0
  112. package/dist/esm/api/subtotal.js +181 -0
  113. package/dist/esm/commands.d.ts +13 -0
  114. package/dist/esm/commands.d.ts.map +1 -1
  115. package/dist/esm/components/editors/data-validation-rule-editor.d.ts.map +1 -1
  116. package/dist/esm/components/editors/data-validation-rule-editor.js +52 -4
  117. package/dist/esm/components/editors/table-editor.js +7 -4
  118. package/dist/esm/hooks/use-calculation-worker.d.ts.map +1 -1
  119. package/dist/esm/hooks/use-calculation-worker.js +20 -2
  120. package/dist/esm/hooks/use-calculation.d.ts +12 -2
  121. package/dist/esm/hooks/use-calculation.d.ts.map +1 -1
  122. package/dist/esm/hooks/use-calculation.js +38 -7
  123. package/dist/esm/hooks/use-on-advanced-filter.d.ts +21 -0
  124. package/dist/esm/hooks/use-on-advanced-filter.d.ts.map +1 -0
  125. package/dist/esm/hooks/use-on-advanced-filter.js +41 -0
  126. package/dist/esm/hooks/use-on-goal-seek.d.ts +30 -0
  127. package/dist/esm/hooks/use-on-goal-seek.d.ts.map +1 -0
  128. package/dist/esm/hooks/use-on-goal-seek.js +82 -0
  129. package/dist/esm/hooks/use-on-import-excel.d.ts +10 -1
  130. package/dist/esm/hooks/use-on-import-excel.d.ts.map +1 -1
  131. package/dist/esm/hooks/use-on-import-excel.js +8 -4
  132. package/dist/esm/hooks/use-on-merge-unmerge-cells.d.ts.map +1 -1
  133. package/dist/esm/hooks/use-on-merge-unmerge-cells.js +13 -13
  134. package/dist/esm/hooks/use-on-paste.d.ts.map +1 -1
  135. package/dist/esm/hooks/use-on-paste.js +49 -14
  136. package/dist/esm/hooks/use-on-remove-duplicates.d.ts +2 -1
  137. package/dist/esm/hooks/use-on-remove-duplicates.d.ts.map +1 -1
  138. package/dist/esm/hooks/use-on-remove-duplicates.js +5 -3
  139. package/dist/esm/hooks/use-on-show-column.d.ts.map +1 -1
  140. package/dist/esm/hooks/use-on-show-column.js +2 -0
  141. package/dist/esm/hooks/use-on-show-row.d.ts.map +1 -1
  142. package/dist/esm/hooks/use-on-show-row.js +2 -0
  143. package/dist/esm/hooks/use-on-subtotal.d.ts +26 -0
  144. package/dist/esm/hooks/use-on-subtotal.d.ts.map +1 -0
  145. package/dist/esm/hooks/use-on-subtotal.js +48 -0
  146. package/dist/esm/hooks/use-paint-format.d.ts +19 -3
  147. package/dist/esm/hooks/use-paint-format.d.ts.map +1 -1
  148. package/dist/esm/hooks/use-paint-format.js +71 -29
  149. package/dist/esm/hooks/use-sheet-properties.d.ts +3 -0
  150. package/dist/esm/hooks/use-sheet-properties.d.ts.map +1 -1
  151. package/dist/esm/hooks/use-sheet-properties.js +8 -0
  152. package/dist/esm/hooks/use-split-text-to-columns.d.ts +2 -1
  153. package/dist/esm/hooks/use-split-text-to-columns.d.ts.map +1 -1
  154. package/dist/esm/hooks/use-split-text-to-columns.js +3 -2
  155. package/dist/esm/hooks/use-spreadsheet-state.d.ts +50 -36
  156. package/dist/esm/hooks/use-spreadsheet-state.d.ts.map +1 -1
  157. package/dist/esm/hooks/use-spreadsheet-state.js +89 -16
  158. package/dist/esm/index.d.ts +9 -0
  159. package/dist/esm/index.d.ts.map +1 -1
  160. package/dist/esm/index.js +9 -0
  161. package/dist/esm/interface/calculation-interface.d.ts.map +1 -1
  162. package/dist/esm/interface/calculation-interface.js +3 -0
  163. package/dist/esm/interface/change-batch-stream.d.ts.map +1 -1
  164. package/dist/esm/interface/change-batch-stream.js +12 -6
  165. package/dist/esm/interface/change-batch.d.ts.map +1 -1
  166. package/dist/esm/interface/change-batch.js +15 -9
  167. package/dist/esm/interface/change-formatting.d.ts.map +1 -1
  168. package/dist/esm/interface/change-formatting.js +28 -11
  169. package/dist/esm/interface/hide-column.d.ts.map +1 -1
  170. package/dist/esm/interface/hide-column.js +4 -0
  171. package/dist/esm/interface/hide-row.d.ts.map +1 -1
  172. package/dist/esm/interface/hide-row.js +4 -0
  173. package/dist/esm/interface/remove-duplicates.d.ts +3 -2
  174. package/dist/esm/interface/remove-duplicates.d.ts.map +1 -1
  175. package/dist/esm/interface/remove-duplicates.js +37 -6
  176. package/dist/esm/interface/split-text.d.ts +2 -1
  177. package/dist/esm/interface/split-text.d.ts.map +1 -1
  178. package/dist/esm/interface/split-text.js +6 -3
  179. package/dist/esm/interface/spreadsheet-interface.d.ts +2 -1
  180. package/dist/esm/interface/spreadsheet-interface.d.ts.map +1 -1
  181. package/dist/esm/interface/spreadsheet-interface.js +5 -5
  182. package/dist/esm/sheet-cell.d.ts.map +1 -1
  183. package/dist/esm/sheet-cell.js +7 -0
  184. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  185. package/package.json +18 -18
@@ -1 +1 @@
1
- {"version":3,"file":"immer-utils.d.ts","sourceRoot":"","sources":["../../../api/immer-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"immer-utils.d.ts","sourceRoot":"","sources":["../../../api/immer-utils.ts"],"names":[],"mappings":"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"}
@@ -67,6 +67,8 @@ const formatDerivationRules = {
67
67
  UNIQUE: { type: "fixed_index", index: 0 },
68
68
  TAKE: { type: "fixed_index", index: 0 },
69
69
  DROP: { type: "fixed_index", index: 0 },
70
+ TRIMRANGE: { type: "fixed_index", index: 0 },
71
+ EXPAND: { type: "fixed_index", index: 0 },
70
72
  TOCOL: { type: "fixed_index", index: 0 },
71
73
  TOROW: { type: "fixed_index", index: 0 },
72
74
  WRAPROWS: { type: "fixed_index", index: 0 },
@@ -0,0 +1,41 @@
1
+ import type { CellFormat, GridRange } from "@rowsncolumns/common-types";
2
+ /**
3
+ * Format-painter pattern shared by both engines: the captured 2-D format grid plus the
4
+ * source block's merge configuration, re-based to the block's top-left so it can be tiled
5
+ * onto any target (Google Sheets copies merges with the format; Excel's painter does too).
6
+ */
7
+ export type PaintPattern = {
8
+ formats: (CellFormat | null | undefined)[][];
9
+ /** Merges fully inside the source block, as 0-based offsets from its top-left. */
10
+ merges: GridRange[];
11
+ /** Source block size — the tiling period. */
12
+ rows: number;
13
+ cols: number;
14
+ };
15
+ /**
16
+ * The merges the painter carries from a source block: every merge that lies FULLY inside
17
+ * `source`, re-based to 0-based offsets from the block's top-left. A merge reaching outside the
18
+ * block is not part of its pattern (Sheets/Excel behave the same — the painter copies the look of
19
+ * the selected cells, not of the cells around them).
20
+ */
21
+ export declare const collectPaintMerges: (merges: GridRange[] | null | undefined, source: GridRange) => GridRange[];
22
+ /**
23
+ * Tile a pattern's relative merges across `target` with the pattern's period (`rows` × `cols`),
24
+ * the same way the format grid itself is tiled by the formatting applier. A merge that a partial
25
+ * trailing tile would push past the target's edge is dropped — the painter never creates a merge
26
+ * that the user did not drag over.
27
+ */
28
+ export declare const tilePaintMerges: (relativeMerges: GridRange[], rows: number, cols: number, target: GridRange) => GridRange[];
29
+ /**
30
+ * The banded (table stripe / alternating-colour) format the grid paints under a cell, looked up
31
+ * in the map `getBandedCells` builds for a sheet.
32
+ */
33
+ export declare const getBandedCellFormat: (bandedCells: Map<string, CellFormat> | undefined | null, rowIndex: number, columnIndex: number) => CellFormat | undefined;
34
+ /**
35
+ * Layer a cell's explicit format over the banded format the grid would paint beneath it, so the
36
+ * captured pattern carries the VISIBLE look (Sheets copies the alternating colours as static cell
37
+ * fills — it does not create a table or banding at the target). Explicit keys win; an explicit
38
+ * `undefined` never clobbers a banded value.
39
+ */
40
+ export declare const layerBandedFormat: (explicit: CellFormat | null | undefined, banded: CellFormat | undefined) => CellFormat | null | undefined;
41
+ //# sourceMappingURL=paint-format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paint-format.d.ts","sourceRoot":"","sources":["../../../api/paint-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAGxE;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EAAE,CAAC;IAC7C,kFAAkF;IAClF,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAQF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,SAAS,EAAE,GAAG,IAAI,GAAG,SAAS,EACtC,QAAQ,SAAS,KAChB,SAAS,EAaX,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,gBAAgB,SAAS,EAAE,EAC3B,MAAM,MAAM,EACZ,MAAM,MAAM,EACZ,QAAQ,SAAS,KAChB,SAAS,EAqBX,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAC9B,aAAa,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,SAAS,GAAG,IAAI,EACvD,UAAU,MAAM,EAChB,aAAa,MAAM,KAClB,UAAU,GAAG,SACyC,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAU,UAAU,GAAG,IAAI,GAAG,SAAS,EACvC,QAAQ,UAAU,GAAG,SAAS,KAC7B,UAAU,GAAG,IAAI,GAAG,SAWtB,CAAC"}
@@ -0,0 +1,77 @@
1
+ import { cellIdentifier } from "@rowsncolumns/grid";
2
+ const rangeContains = (outer, inner) => inner.startRowIndex >= outer.startRowIndex &&
3
+ inner.endRowIndex <= outer.endRowIndex &&
4
+ inner.startColumnIndex >= outer.startColumnIndex &&
5
+ inner.endColumnIndex <= outer.endColumnIndex;
6
+ /**
7
+ * The merges the painter carries from a source block: every merge that lies FULLY inside
8
+ * `source`, re-based to 0-based offsets from the block's top-left. A merge reaching outside the
9
+ * block is not part of its pattern (Sheets/Excel behave the same — the painter copies the look of
10
+ * the selected cells, not of the cells around them).
11
+ */
12
+ export const collectPaintMerges = (merges, source) => {
13
+ if (!merges?.length)
14
+ return [];
15
+ const out = [];
16
+ for (const merge of merges) {
17
+ if (!rangeContains(source, merge))
18
+ continue;
19
+ out.push({
20
+ startRowIndex: merge.startRowIndex - source.startRowIndex,
21
+ endRowIndex: merge.endRowIndex - source.startRowIndex,
22
+ startColumnIndex: merge.startColumnIndex - source.startColumnIndex,
23
+ endColumnIndex: merge.endColumnIndex - source.startColumnIndex,
24
+ });
25
+ }
26
+ return out;
27
+ };
28
+ /**
29
+ * Tile a pattern's relative merges across `target` with the pattern's period (`rows` × `cols`),
30
+ * the same way the format grid itself is tiled by the formatting applier. A merge that a partial
31
+ * trailing tile would push past the target's edge is dropped — the painter never creates a merge
32
+ * that the user did not drag over.
33
+ */
34
+ export const tilePaintMerges = (relativeMerges, rows, cols, target) => {
35
+ if (!relativeMerges.length || rows <= 0 || cols <= 0)
36
+ return [];
37
+ const out = [];
38
+ for (let top = target.startRowIndex; top <= target.endRowIndex; top += rows) {
39
+ for (let left = target.startColumnIndex; left <= target.endColumnIndex; left += cols) {
40
+ for (const merge of relativeMerges) {
41
+ const placed = {
42
+ startRowIndex: top + merge.startRowIndex,
43
+ endRowIndex: top + merge.endRowIndex,
44
+ startColumnIndex: left + merge.startColumnIndex,
45
+ endColumnIndex: left + merge.endColumnIndex,
46
+ };
47
+ if (rangeContains(target, placed))
48
+ out.push(placed);
49
+ }
50
+ }
51
+ }
52
+ return out;
53
+ };
54
+ /**
55
+ * The banded (table stripe / alternating-colour) format the grid paints under a cell, looked up
56
+ * in the map `getBandedCells` builds for a sheet.
57
+ */
58
+ export const getBandedCellFormat = (bandedCells, rowIndex, columnIndex) => bandedCells?.get(cellIdentifier(rowIndex, columnIndex));
59
+ /**
60
+ * Layer a cell's explicit format over the banded format the grid would paint beneath it, so the
61
+ * captured pattern carries the VISIBLE look (Sheets copies the alternating colours as static cell
62
+ * fills — it does not create a table or banding at the target). Explicit keys win; an explicit
63
+ * `undefined` never clobbers a banded value.
64
+ */
65
+ export const layerBandedFormat = (explicit, banded) => {
66
+ if (!banded)
67
+ return explicit;
68
+ const merged = { ...banded };
69
+ if (explicit) {
70
+ for (const [key, value] of Object.entries(explicit)) {
71
+ if (value !== undefined) {
72
+ merged[key] = value;
73
+ }
74
+ }
75
+ }
76
+ return merged;
77
+ };
@@ -0,0 +1,48 @@
1
+ import type { CellData, PasteSpecialOperation, PasteSpecialOptions, PasteSpecialType } from "@rowsncolumns/spreadsheet";
2
+ /** Synthetic clipboard key carrying the legacy single-mode `PasteSpecialType`. */
3
+ export declare const PASTE_SPECIAL_TYPE_KEY = "pasteSpecialType";
4
+ /** Synthetic clipboard key carrying a JSON-encoded `PasteSpecialOptions`. */
5
+ export declare const PASTE_SPECIAL_OPTIONS_KEY = "pasteSpecialOptions";
6
+ export type ResolvedPasteSpecialOptions = {
7
+ paste: NonNullable<PasteSpecialOptions["paste"]>;
8
+ operation?: PasteSpecialOperation;
9
+ skipBlanks: boolean;
10
+ transpose: boolean;
11
+ /** True when any Paste Special mode is active (the destination is not a plain overwrite). */
12
+ isSpecial: boolean;
13
+ };
14
+ /**
15
+ * Normalize a `PasteSpecialOptions` (or the legacy single-mode string) into
16
+ * the flags the paste pipelines branch on.
17
+ */
18
+ export declare const normalizePasteSpecialOptions: (input: PasteSpecialOptions | PasteSpecialType | null | undefined) => ResolvedPasteSpecialOptions;
19
+ /**
20
+ * Read the Paste Special request the grid stashed on the clipboard event
21
+ * (`pasteSpecialOptions` JSON wins over the legacy `pasteSpecialType`).
22
+ */
23
+ export declare const resolvePasteSpecialOptions: (clipboardData: Pick<DataTransfer, "getData"> | null | undefined) => ResolvedPasteSpecialOptions;
24
+ /**
25
+ * A clipboard cell that carries no value: Paste Special "Skip blanks" leaves
26
+ * the destination untouched for these. A shared-string reference counts as a
27
+ * value.
28
+ */
29
+ export declare const isBlankClipboardCell: (cell: CellData | null | undefined) => boolean;
30
+ /**
31
+ * Excel Paste Special → Operation. Combines one clipboard cell with the
32
+ * destination cell it lands on and returns the cell data to write there:
33
+ *
34
+ * - number ⊕ number → the arithmetic result (blank destination counts as 0,
35
+ * numeric text is coerced; a non-finite result such as `x/0` is written as
36
+ * the formula `=x/0` so the cell shows `#DIV/0!`).
37
+ * - a formula on either side → a combined formula (`=(dest)+(source)`), the
38
+ * source formula already relocated to the destination by the paste.
39
+ * - blank source → the destination is left as it is (Excel: `d + 0`; the
40
+ * classic "paste-add a blank cell" trick still coerces numeric text).
41
+ * - non-numeric text destination → left as it is.
42
+ * - non-numeric text source → `=dest+"text"` (Excel's `#VALUE!`).
43
+ *
44
+ * `paste: "values"` callers pre-resolve the source to values with
45
+ * `pickValue`, so the source side is never a formula there.
46
+ */
47
+ export declare const applyPasteOperation: <T extends CellData>(source: T | CellData | null | undefined, destination: CellData | null | undefined, operation: PasteSpecialOperation, sheetId: number, locale?: string) => CellData;
48
+ //# sourceMappingURL=paste-special.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paste-special.d.ts","sourceRoot":"","sources":["../../../api/paste-special.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AAanC,kFAAkF;AAClF,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,6EAA6E;AAC7E,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,EAAE,WAAW,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,6FAA6F;IAC7F,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AA+BF;;;GAGG;AACH,eAAO,MAAM,4BAA4B,GACvC,OAAO,mBAAmB,GAAG,gBAAgB,GAAG,IAAI,GAAG,SAAS,KAC/D,2BAsBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,GACrC,eAAe,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,KAC9D,2BAkBF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,SAAS,KAChC,OAWF,CAAC;AA8FF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,QAAQ,EACpD,QAAQ,CAAC,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,EACvC,aAAa,QAAQ,GAAG,IAAI,GAAG,SAAS,EACxC,WAAW,qBAAqB,EAChC,SAAS,MAAM,EACf,SAAS,MAAM,KACd,QAmCF,CAAC"}
@@ -0,0 +1,220 @@
1
+ import { getCellUserEnteredValue, getExtendedValueBool, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, isNil, } from "@rowsncolumns/utils";
2
+ import { SheetCell } from "../sheet-cell";
3
+ import { convertToNumber, isNumber } from "./datatype";
4
+ /** Synthetic clipboard key carrying the legacy single-mode `PasteSpecialType`. */
5
+ export const PASTE_SPECIAL_TYPE_KEY = "pasteSpecialType";
6
+ /** Synthetic clipboard key carrying a JSON-encoded `PasteSpecialOptions`. */
7
+ export const PASTE_SPECIAL_OPTIONS_KEY = "pasteSpecialOptions";
8
+ const PLAIN_PASTE = {
9
+ paste: "all",
10
+ skipBlanks: false,
11
+ transpose: false,
12
+ isSpecial: false,
13
+ };
14
+ const LEGACY_TYPE_TO_OPTIONS = {
15
+ Transposed: { transpose: true },
16
+ Formatting: { paste: "formats" },
17
+ Formula: { paste: "formulas" },
18
+ Value: { paste: "values" },
19
+ Link: {},
20
+ };
21
+ const isOperation = (value) => value === "add" ||
22
+ value === "subtract" ||
23
+ value === "multiply" ||
24
+ value === "divide";
25
+ const isPasteMode = (value) => value === "all" ||
26
+ value === "values" ||
27
+ value === "formulas" ||
28
+ value === "formats";
29
+ /**
30
+ * Normalize a `PasteSpecialOptions` (or the legacy single-mode string) into
31
+ * the flags the paste pipelines branch on.
32
+ */
33
+ export const normalizePasteSpecialOptions = (input) => {
34
+ if (!input)
35
+ return PLAIN_PASTE;
36
+ const options = typeof input === "string" ? LEGACY_TYPE_TO_OPTIONS[input] ?? {} : input;
37
+ const paste = isPasteMode(options.paste) ? options.paste : "all";
38
+ // Excel greys Operation out under Paste → Formats: a formats paste never
39
+ // touches destination values, so an operation is dropped here for both
40
+ // pipelines rather than each guarding separately.
41
+ const operation = paste !== "formats" && isOperation(options.operation)
42
+ ? options.operation
43
+ : undefined;
44
+ const skipBlanks = Boolean(options.skipBlanks);
45
+ const transpose = Boolean(options.transpose);
46
+ return {
47
+ paste,
48
+ operation,
49
+ skipBlanks,
50
+ transpose,
51
+ isSpecial: paste !== "all" || operation !== undefined || skipBlanks || transpose,
52
+ };
53
+ };
54
+ /**
55
+ * Read the Paste Special request the grid stashed on the clipboard event
56
+ * (`pasteSpecialOptions` JSON wins over the legacy `pasteSpecialType`).
57
+ */
58
+ export const resolvePasteSpecialOptions = (clipboardData) => {
59
+ if (!clipboardData)
60
+ return PLAIN_PASTE;
61
+ const encoded = clipboardData.getData(PASTE_SPECIAL_OPTIONS_KEY);
62
+ if (encoded) {
63
+ try {
64
+ const parsed = JSON.parse(encoded);
65
+ if (parsed && typeof parsed === "object") {
66
+ return normalizePasteSpecialOptions(parsed);
67
+ }
68
+ }
69
+ catch {
70
+ // Fall through to the legacy key
71
+ }
72
+ }
73
+ const legacy = clipboardData.getData(PASTE_SPECIAL_TYPE_KEY);
74
+ return normalizePasteSpecialOptions(legacy || undefined);
75
+ };
76
+ /**
77
+ * A clipboard cell that carries no value: Paste Special "Skip blanks" leaves
78
+ * the destination untouched for these. A shared-string reference counts as a
79
+ * value.
80
+ */
81
+ export const isBlankClipboardCell = (cell) => {
82
+ if (isNil(cell))
83
+ return true;
84
+ if (!isNil(cell.ss))
85
+ return false;
86
+ const ue = getCellUserEnteredValue(cell);
87
+ if (isNil(ue))
88
+ return true;
89
+ return (isNil(getExtendedValueFormula(ue)) &&
90
+ isNil(getExtendedValueNumber(ue)) &&
91
+ isNil(getExtendedValueString(ue)) &&
92
+ isNil(getExtendedValueBool(ue)));
93
+ };
94
+ const classifyOperand = (cell, locale) => {
95
+ if (isNil(cell))
96
+ return { kind: "blank" };
97
+ const ue = getCellUserEnteredValue(cell);
98
+ const formula = getExtendedValueFormula(ue);
99
+ if (!isNil(formula)) {
100
+ const body = formula.trim().replace(/^=/, "");
101
+ return body ? { kind: "formula", body } : { kind: "blank" };
102
+ }
103
+ const nv = getExtendedValueNumber(ue);
104
+ if (!isNil(nv))
105
+ return { kind: "number", value: nv };
106
+ const bv = getExtendedValueBool(ue);
107
+ if (!isNil(bv))
108
+ return { kind: "number", value: bv ? 1 : 0 };
109
+ const sv = getExtendedValueString(ue);
110
+ if (isNil(sv) || sv === "")
111
+ return { kind: "blank" };
112
+ if (isNumber(sv, locale)) {
113
+ return { kind: "number", value: convertToNumber(sv, locale) };
114
+ }
115
+ return { kind: "text", value: sv };
116
+ };
117
+ const OPERATOR = {
118
+ add: "+",
119
+ subtract: "-",
120
+ multiply: "*",
121
+ divide: "/",
122
+ };
123
+ const compute = (operation, left, right) => {
124
+ switch (operation) {
125
+ case "add":
126
+ return left + right;
127
+ case "subtract":
128
+ return left - right;
129
+ case "multiply":
130
+ return left * right;
131
+ case "divide":
132
+ return left / right;
133
+ }
134
+ };
135
+ const numberLiteral = (value) => value < 0 ? `(${String(value)})` : String(value);
136
+ /** Render an operand as a formula fragment (a formula body is parenthesized). */
137
+ const toFormulaFragment = (operand) => {
138
+ switch (operand.kind) {
139
+ case "blank":
140
+ return "0";
141
+ case "number":
142
+ return numberLiteral(operand.value);
143
+ case "formula":
144
+ return `(${operand.body})`;
145
+ case "text":
146
+ return `"${operand.value.replace(/"/g, '""')}"`;
147
+ }
148
+ };
149
+ /**
150
+ * Strip every value facet from a clipboard cell, keeping its formatting so a
151
+ * "Paste all + operation" still carries the source formats.
152
+ */
153
+ const withoutValue = (cell) => {
154
+ if (isNil(cell))
155
+ return {};
156
+ const { ue: _ue, ev: _ev, fv: _fv, ss: _ss, userEnteredValue: _userEnteredValue, effectiveValue: _effectiveValue, formattedValue: _formattedValue, ...rest } = cell;
157
+ return rest;
158
+ };
159
+ /**
160
+ * Excel Paste Special → Operation. Combines one clipboard cell with the
161
+ * destination cell it lands on and returns the cell data to write there:
162
+ *
163
+ * - number ⊕ number → the arithmetic result (blank destination counts as 0,
164
+ * numeric text is coerced; a non-finite result such as `x/0` is written as
165
+ * the formula `=x/0` so the cell shows `#DIV/0!`).
166
+ * - a formula on either side → a combined formula (`=(dest)+(source)`), the
167
+ * source formula already relocated to the destination by the paste.
168
+ * - blank source → the destination is left as it is (Excel: `d + 0`; the
169
+ * classic "paste-add a blank cell" trick still coerces numeric text).
170
+ * - non-numeric text destination → left as it is.
171
+ * - non-numeric text source → `=dest+"text"` (Excel's `#VALUE!`).
172
+ *
173
+ * `paste: "values"` callers pre-resolve the source to values with
174
+ * `pickValue`, so the source side is never a formula there.
175
+ */
176
+ export const applyPasteOperation = (source, destination, operation, sheetId, locale) => {
177
+ const src = classifyOperand(source, locale);
178
+ const dst = classifyOperand(destination, locale);
179
+ const base = withoutValue(source);
180
+ const keepDestination = () => {
181
+ const destinationValue = getCellUserEnteredValue(destination);
182
+ return isNil(destinationValue) ? base : { ...base, ue: destinationValue };
183
+ };
184
+ if (dst.kind === "text") {
185
+ return keepDestination();
186
+ }
187
+ if (src.kind === "blank") {
188
+ if (dst.kind === "number" &&
189
+ (operation === "add" || operation === "subtract")) {
190
+ // `d + 0` — the destination's numeric text becomes a number.
191
+ return writeValue(base, dst.value, sheetId, locale);
192
+ }
193
+ return keepDestination();
194
+ }
195
+ const leftIsNumeric = dst.kind === "blank" || dst.kind === "number";
196
+ if (leftIsNumeric && src.kind === "number") {
197
+ const left = dst.kind === "number" ? dst.value : 0;
198
+ const result = compute(operation, left, src.value);
199
+ if (Number.isFinite(result)) {
200
+ return writeValue(base, result, sheetId, locale);
201
+ }
202
+ }
203
+ const formula = `=${toFormulaFragment(dst)}${OPERATOR[operation]}${toFormulaFragment(src)}`;
204
+ return writeValue(base, formula, sheetId, locale);
205
+ };
206
+ const writeValue = (base, value, sheetId, locale) => {
207
+ const sheetCell = new SheetCell();
208
+ sheetCell.setLocale(locale);
209
+ sheetCell.assign(sheetId, undefined, base);
210
+ sheetCell.setUserEnteredValue(value);
211
+ const result = sheetCell.getCellData() ?? { ...base };
212
+ // Typing a number stamps an inferred `uf.numberFormat`; an unformatted
213
+ // source (values-only paste) must stay unformatted so the destination's
214
+ // own format survives the merge.
215
+ if (!base.uf && result.uf) {
216
+ const { uf: _uf, ...rest } = result;
217
+ return rest;
218
+ }
219
+ return result;
220
+ };
@@ -1,2 +1,14 @@
1
+ import type { SplitTextOptions } from "@rowsncolumns/spreadsheet";
1
2
  export declare const splitTextToColumns: (values: (string | null | undefined)[], delimiter?: string) => string[][];
3
+ export type { SplitTextOptions };
4
+ /** Normalized, ascending, de-duplicated positive break positions. */
5
+ export declare const normalizeColumnBreaks: (columnBreaks: number[]) => number[];
6
+ /**
7
+ * Excel's Text to Columns → Fixed width: cut each cell at the given
8
+ * character positions. Fields are trimmed like the delimited path (Excel's
9
+ * General column data format drops the padding spaces fixed-width data is
10
+ * aligned with). Cells without breaks inside their text still split — the
11
+ * trailing fields are empty — so the resulting block is rectangular.
12
+ */
13
+ export declare const splitTextFixedWidth: (values: (string | null | undefined)[], columnBreaks: number[]) => string[][];
2
14
  //# sourceMappingURL=split-text.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"split-text.d.ts","sourceRoot":"","sources":["../../../api/split-text.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,YAAW,MAAY,KACtB,MAAM,EAAE,EAwBV,CAAC"}
1
+ {"version":3,"file":"split-text.d.ts","sourceRoot":"","sources":["../../../api/split-text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,YAAW,MAAY,KACtB,MAAM,EAAE,EAwBV,CAAC;AAEF,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,GAAI,cAAc,MAAM,EAAE,KAAG,MAAM,EAG3C,CAAC;AAE3B;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACrC,cAAc,MAAM,EAAE,KACrB,MAAM,EAAE,EAgBV,CAAC"}
@@ -22,3 +22,31 @@ export const splitTextToColumns = (values, delimiter = ",") => {
22
22
  return trimmedParts;
23
23
  });
24
24
  };
25
+ /** Normalized, ascending, de-duplicated positive break positions. */
26
+ export const normalizeColumnBreaks = (columnBreaks) => [...new Set(columnBreaks)]
27
+ .filter((position) => Number.isInteger(position) && position > 0)
28
+ .sort((a, b) => a - b);
29
+ /**
30
+ * Excel's Text to Columns → Fixed width: cut each cell at the given
31
+ * character positions. Fields are trimmed like the delimited path (Excel's
32
+ * General column data format drops the padding spaces fixed-width data is
33
+ * aligned with). Cells without breaks inside their text still split — the
34
+ * trailing fields are empty — so the resulting block is rectangular.
35
+ */
36
+ export const splitTextFixedWidth = (values, columnBreaks) => {
37
+ const breaks = normalizeColumnBreaks(columnBreaks);
38
+ return values.map((cell) => {
39
+ if (isNil(cell)) {
40
+ return [""];
41
+ }
42
+ const text = String(cell);
43
+ const parts = [];
44
+ let start = 0;
45
+ for (const position of breaks) {
46
+ parts.push(text.slice(start, position).trim());
47
+ start = position;
48
+ }
49
+ parts.push(text.slice(start).trim());
50
+ return parts;
51
+ });
52
+ };
@@ -0,0 +1,85 @@
1
+ import type { GridRange } from "@rowsncolumns/common-types";
2
+ import { SUBTOTAL_FUNCTIONS, type SubtotalFunction, type SubtotalOptions } from "@rowsncolumns/spreadsheet";
3
+ export { SUBTOTAL_FUNCTIONS };
4
+ export type { SubtotalFunction, SubtotalOptions };
5
+ /**
6
+ * The `SUBTOTAL(function_num, …)` code each "Use function" entry writes.
7
+ * Codes 1–11 (not 101–111): the subtotal rows Excel inserts count manually
8
+ * hidden rows.
9
+ */
10
+ export declare const SUBTOTAL_FUNCTION_NUMBERS: Record<SubtotalFunction, number>;
11
+ /** Excel's total-row labels: "<group> Total" per group, "Grand Total" at the bottom. */
12
+ export declare const SUBTOTAL_GRAND_TOTAL_LABEL = "Grand Total";
13
+ export declare const subtotalGroupLabel: (groupValue: string) => string;
14
+ /**
15
+ * Reads a cell of the data range. `getValue` should return the DISPLAYED text
16
+ * when the host has one (Excel groups and labels on what the cells show —
17
+ * `1/1/2024 Total`, not `45292 Total`). `getFormula` returns the `=…` text for
18
+ * a formula cell. `getOutlineLevel` returns a row's current outline level so
19
+ * "Replace current subtotals" can rebuild the outline from level 0.
20
+ */
21
+ export type SubtotalReader = {
22
+ getValue: (rowIndex: number, columnIndex: number) => string | number | boolean | null | undefined;
23
+ getFormula: (rowIndex: number, columnIndex: number) => string | undefined;
24
+ getOutlineLevel?: (rowIndex: number) => number | undefined;
25
+ };
26
+ /** One `change-batch` write: a single row segment at final coordinates. */
27
+ export type SubtotalWrite = {
28
+ rowIndex: number;
29
+ startColumnIndex: number;
30
+ values: (string | null)[];
31
+ };
32
+ /**
33
+ * The plan applies in this order, every index already in FINAL coordinates
34
+ * (the sheet after all removals and insertions):
35
+ * 1. `deleteRows` (descending original indexes — existing subtotal rows),
36
+ * 2. `insertRows` ascending: inserting at final row `r` shifts the not-yet
37
+ * final rows below it, so ascending order lands each new row exactly
38
+ * where the plan expects it,
39
+ * 3. `writes` (labels + SUBTOTAL formulas),
40
+ * 4. `ungroupRows`: one `ungroup-rows` call per entry — the outline reset of
41
+ * "Replace current subtotals". Group / ungroup are ±1 steps in both
42
+ * engines, so pass `k` lists the surviving data rows that were deeper
43
+ * than level `k`; after the passes every row of the range is back at
44
+ * level 0 (empty when nothing was outlined or when not replacing), then
45
+ * 5. `outlineGroups`: one `group-rows` call per entry (Excel's levels — the
46
+ * first spans every row above the grand total, the second the detail
47
+ * rows of each group, so detail rows end at level 2 and subtotal rows
48
+ * at level 1 — the same three-level outline on every re-apply).
49
+ */
50
+ export type SubtotalPlan = {
51
+ deleteRows: number[];
52
+ insertRows: number[];
53
+ writes: SubtotalWrite[];
54
+ ungroupRows: number[][];
55
+ outlineGroups: number[][];
56
+ /** Number of groups found. */
57
+ groupCount: number;
58
+ /** The range after the plan is applied (header row included when present). */
59
+ resultRange: GridRange;
60
+ };
61
+ /**
62
+ * Plans Excel's Subtotal command over `options.range`. Consecutive rows with
63
+ * the same group-column value form a group (Excel does not sort — it expects
64
+ * the data sorted and totals each run of equal values). Each group gets a
65
+ * total row right below it holding "<value> Total" in the group column and
66
+ * `=SUBTOTAL(n, first:last)` over the group's data rows in every aggregate
67
+ * column; a grand-total row closes the range with `SUBTOTAL` over the whole
68
+ * data block (SUBTOTAL ignores the nested subtotal rows, like Excel). With
69
+ * `replaceCurrent` the range's existing outline is cleared too, so a re-apply
70
+ * yields Excel's fresh detail 2 / subtotal 1 / grand total 0 levels instead
71
+ * of nesting deeper; without it the new levels stack on the old ones (Excel's
72
+ * nested subtotals). Returns `undefined` when the range has no data rows.
73
+ */
74
+ export declare const planSubtotals: (options: SubtotalOptions, reader: SubtotalReader) => SubtotalPlan | undefined;
75
+ /** The state callbacks a plan is applied through — the same in both engines. */
76
+ export type SubtotalPlanExecutor = {
77
+ onDeleteRow: (sheetId: number, rowIndexes: number[]) => void;
78
+ onInsertRow: (sheetId: number, referenceRowIndex: number, numRows?: number) => void;
79
+ onChangeBatch: (sheetId: number, range: GridRange, values: (string | null)[][]) => void;
80
+ onGroupRows: (sheetId: number, rowIndexes: number[]) => void;
81
+ onUngroupRows: (sheetId: number, rowIndexes: number[]) => void;
82
+ };
83
+ /** Applies a {@link SubtotalPlan} in its documented order. */
84
+ export declare const applySubtotalPlan: (sheetId: number, plan: SubtotalPlan, executor: SubtotalPlanExecutor) => void;
85
+ //# sourceMappingURL=subtotal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subtotal.d.ts","sourceRoot":"","sources":["../../../api/subtotal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EACL,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAC9B,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAYtE,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,0BAA0B,gBAAgB,CAAC;AACxD,eAAO,MAAM,kBAAkB,GAAI,YAAY,MAAM,WACP,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;IAClG,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC1E,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC5D,CAAC;AAEF,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC;IAC1B,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,WAAW,EAAE,SAAS,CAAC;CACxB,CAAC;AAcF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,GACxB,SAAS,eAAe,EACxB,QAAQ,cAAc,KACrB,YAAY,GAAG,SAyHjB,CAAC;AAEF,gFAAgF;AAChF,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7D,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpF,aAAa,EAAE,CACb,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EAAE,KACxB,IAAI,CAAC;IACV,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7D,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAChE,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,EACf,MAAM,YAAY,EAClB,UAAU,oBAAoB,SAwB/B,CAAC"}