@dou-ui/sheet 0.0.0-stage → 0.1.0-alpha.0

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 (262) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/dist/cell-types.js +20 -0
  4. package/dist/cell-types.js.map +1 -0
  5. package/dist/code/code-formula-bar.js +6 -0
  6. package/dist/code/code-formula-bar.js.map +1 -0
  7. package/dist/code/code-formula-bar.vue_vue_type_script_setup_true_lang.js +192 -0
  8. package/dist/code/code-formula-bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  9. package/dist/code/index.js +12 -0
  10. package/dist/code/index.js.map +1 -0
  11. package/dist/code/language.js +51 -0
  12. package/dist/code/language.js.map +1 -0
  13. package/dist/code/style.d.ts +1 -0
  14. package/dist/code/style.js +2 -0
  15. package/dist/collaboration/anchor.js +143 -0
  16. package/dist/collaboration/anchor.js.map +1 -0
  17. package/dist/collaboration/index.js +770 -0
  18. package/dist/collaboration/index.js.map +1 -0
  19. package/dist/collaboration/peers.js +87 -0
  20. package/dist/collaboration/peers.js.map +1 -0
  21. package/dist/collaboration/shared.js +450 -0
  22. package/dist/collaboration/shared.js.map +1 -0
  23. package/dist/components/cell-panel.js +6 -0
  24. package/dist/components/cell-panel.js.map +1 -0
  25. package/dist/components/cell-panel.vue_vue_type_script_setup_true_lang.js +70 -0
  26. package/dist/components/cell-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  27. package/dist/components/cell-renders.js +40 -0
  28. package/dist/components/cell-renders.js.map +1 -0
  29. package/dist/components/date-panel.js +6 -0
  30. package/dist/components/date-panel.js.map +1 -0
  31. package/dist/components/date-panel.vue_vue_type_script_setup_true_lang.js +48 -0
  32. package/dist/components/date-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  33. package/dist/components/filter-panel.js +6 -0
  34. package/dist/components/filter-panel.js.map +1 -0
  35. package/dist/components/filter-panel.vue_vue_type_script_setup_true_lang.js +259 -0
  36. package/dist/components/filter-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  37. package/dist/components/format-dialog.js +6 -0
  38. package/dist/components/format-dialog.js.map +1 -0
  39. package/dist/components/format-dialog.vue_vue_type_script_setup_true_lang.js +432 -0
  40. package/dist/components/format-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  41. package/dist/components/format-list.js +6 -0
  42. package/dist/components/format-list.js.map +1 -0
  43. package/dist/components/format-list.vue_vue_type_script_setup_true_lang.js +187 -0
  44. package/dist/components/format-list.vue_vue_type_script_setup_true_lang.js.map +1 -0
  45. package/dist/components/format-presets.js +97 -0
  46. package/dist/components/format-presets.js.map +1 -0
  47. package/dist/components/option-panel.js +6 -0
  48. package/dist/components/option-panel.js.map +1 -0
  49. package/dist/components/option-panel.vue_vue_type_script_setup_true_lang.js +117 -0
  50. package/dist/components/option-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  51. package/dist/components/sheet-comment.js +6 -0
  52. package/dist/components/sheet-comment.js.map +1 -0
  53. package/dist/components/sheet-comment.vue_vue_type_script_setup_true_lang.js +104 -0
  54. package/dist/components/sheet-comment.vue_vue_type_script_setup_true_lang.js.map +1 -0
  55. package/dist/components/sheet-formula-bar.js +6 -0
  56. package/dist/components/sheet-formula-bar.js.map +1 -0
  57. package/dist/components/sheet-formula-bar.vue_vue_type_script_setup_true_lang.js +124 -0
  58. package/dist/components/sheet-formula-bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  59. package/dist/components/sheet-link.js +6 -0
  60. package/dist/components/sheet-link.js.map +1 -0
  61. package/dist/components/sheet-link.vue_vue_type_script_setup_true_lang.js +249 -0
  62. package/dist/components/sheet-link.vue_vue_type_script_setup_true_lang.js.map +1 -0
  63. package/dist/components/sheet-menu.js +6 -0
  64. package/dist/components/sheet-menu.js.map +1 -0
  65. package/dist/components/sheet-menu.vue_vue_type_script_setup_true_lang.js +115 -0
  66. package/dist/components/sheet-menu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  67. package/dist/components/sheet-name-box.js +6 -0
  68. package/dist/components/sheet-name-box.js.map +1 -0
  69. package/dist/components/sheet-name-box.vue_vue_type_script_setup_true_lang.js +91 -0
  70. package/dist/components/sheet-name-box.vue_vue_type_script_setup_true_lang.js.map +1 -0
  71. package/dist/components/sheet-note.js +6 -0
  72. package/dist/components/sheet-note.js.map +1 -0
  73. package/dist/components/sheet-note.vue_vue_type_script_setup_true_lang.js +146 -0
  74. package/dist/components/sheet-note.vue_vue_type_script_setup_true_lang.js.map +1 -0
  75. package/dist/components/sheet-outline.js +6 -0
  76. package/dist/components/sheet-outline.js.map +1 -0
  77. package/dist/components/sheet-outline.vue_vue_type_script_setup_true_lang.js +237 -0
  78. package/dist/components/sheet-outline.vue_vue_type_script_setup_true_lang.js.map +1 -0
  79. package/dist/components/sheet-tabs.js +6 -0
  80. package/dist/components/sheet-tabs.js.map +1 -0
  81. package/dist/components/sheet-tabs.vue_vue_type_script_setup_true_lang.js +487 -0
  82. package/dist/components/sheet-tabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
  83. package/dist/components/sheet-toolbar.js +6 -0
  84. package/dist/components/sheet-toolbar.js.map +1 -0
  85. package/dist/components/sheet-toolbar.vue_vue_type_script_setup_true_lang.js +1562 -0
  86. package/dist/components/sheet-toolbar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  87. package/dist/components/validation-dialog.js +6 -0
  88. package/dist/components/validation-dialog.js.map +1 -0
  89. package/dist/components/validation-dialog.vue_vue_type_script_setup_true_lang.js +370 -0
  90. package/dist/components/validation-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  91. package/dist/context.js +12 -0
  92. package/dist/context.js.map +1 -0
  93. package/dist/core/address.js +256 -0
  94. package/dist/core/address.js.map +1 -0
  95. package/dist/core/axis.js +72 -0
  96. package/dist/core/axis.js.map +1 -0
  97. package/dist/core/cell-type.js +30 -0
  98. package/dist/core/cell-type.js.map +1 -0
  99. package/dist/core/clipboard.js +141 -0
  100. package/dist/core/clipboard.js.map +1 -0
  101. package/dist/core/commands.js +63 -0
  102. package/dist/core/commands.js.map +1 -0
  103. package/dist/core/comments.js +74 -0
  104. package/dist/core/comments.js.map +1 -0
  105. package/dist/core/conditional.js +362 -0
  106. package/dist/core/conditional.js.map +1 -0
  107. package/dist/core/csv.js +191 -0
  108. package/dist/core/csv.js.map +1 -0
  109. package/dist/core/data.js +118 -0
  110. package/dist/core/data.js.map +1 -0
  111. package/dist/core/document.js +187 -0
  112. package/dist/core/document.js.map +1 -0
  113. package/dist/core/extension.js +60 -0
  114. package/dist/core/extension.js.map +1 -0
  115. package/dist/core/file.js +336 -0
  116. package/dist/core/file.js.map +1 -0
  117. package/dist/core/fill.js +153 -0
  118. package/dist/core/fill.js.map +1 -0
  119. package/dist/core/find.js +42 -0
  120. package/dist/core/find.js.map +1 -0
  121. package/dist/core/format.js +404 -0
  122. package/dist/core/format.js.map +1 -0
  123. package/dist/core/group.js +134 -0
  124. package/dist/core/group.js.map +1 -0
  125. package/dist/core/history.js +68 -0
  126. package/dist/core/history.js.map +1 -0
  127. package/dist/core/index.js +17 -0
  128. package/dist/core/link.js +34 -0
  129. package/dist/core/link.js.map +1 -0
  130. package/dist/core/merge.js +105 -0
  131. package/dist/core/merge.js.map +1 -0
  132. package/dist/core/model.js +48 -0
  133. package/dist/core/model.js.map +1 -0
  134. package/dist/core/nav.js +44 -0
  135. package/dist/core/nav.js.map +1 -0
  136. package/dist/core/paint.js +106 -0
  137. package/dist/core/paint.js.map +1 -0
  138. package/dist/core/plain-cell-types.js +54 -0
  139. package/dist/core/plain-cell-types.js.map +1 -0
  140. package/dist/core/protect.js +246 -0
  141. package/dist/core/protect.js.map +1 -0
  142. package/dist/core/selection.js +37 -0
  143. package/dist/core/selection.js.map +1 -0
  144. package/dist/core/transaction.js +1582 -0
  145. package/dist/core/transaction.js.map +1 -0
  146. package/dist/core/validation.js +135 -0
  147. package/dist/core/validation.js.map +1 -0
  148. package/dist/core/versions.js +161 -0
  149. package/dist/core/versions.js.map +1 -0
  150. package/dist/export/color.js +36 -0
  151. package/dist/export/color.js.map +1 -0
  152. package/dist/export/draw.js +316 -0
  153. package/dist/export/draw.js.map +1 -0
  154. package/dist/export/index.js +390 -0
  155. package/dist/export/index.js.map +1 -0
  156. package/dist/formula/edit.js +210 -0
  157. package/dist/formula/edit.js.map +1 -0
  158. package/dist/formula/engine.js +526 -0
  159. package/dist/formula/engine.js.map +1 -0
  160. package/dist/formula/error.js +39 -0
  161. package/dist/formula/error.js.map +1 -0
  162. package/dist/formula/functions.js +1493 -0
  163. package/dist/formula/functions.js.map +1 -0
  164. package/dist/formula/help.js +408 -0
  165. package/dist/formula/help.js.map +1 -0
  166. package/dist/formula/index.js +7 -0
  167. package/dist/formula/parse.js +369 -0
  168. package/dist/formula/parse.js.map +1 -0
  169. package/dist/formula/values.js +123 -0
  170. package/dist/formula/values.js.map +1 -0
  171. package/dist/formulas.js +30 -0
  172. package/dist/formulas.js.map +1 -0
  173. package/dist/index.js +39 -0
  174. package/dist/index.js.map +1 -0
  175. package/dist/locale.js +1312 -0
  176. package/dist/locale.js.map +1 -0
  177. package/dist/sheet.js +6 -0
  178. package/dist/sheet.js.map +1 -0
  179. package/dist/sheet.vue_vue_type_script_setup_true_lang.js +7166 -0
  180. package/dist/sheet.vue_vue_type_script_setup_true_lang.js.map +1 -0
  181. package/dist/style.css +1 -0
  182. package/dist/style.d.ts +1 -0
  183. package/dist/style.js +17 -0
  184. package/dist/types/cell-types.d.ts +2 -0
  185. package/dist/types/code/code-formula-bar.vue.d.ts +3 -0
  186. package/dist/types/code/index.d.ts +12 -0
  187. package/dist/types/code/language.d.ts +13 -0
  188. package/dist/types/collaboration/anchor.d.ts +65 -0
  189. package/dist/types/collaboration/index.d.ts +59 -0
  190. package/dist/types/collaboration/peers.d.ts +21 -0
  191. package/dist/types/collaboration/shared.d.ts +75 -0
  192. package/dist/types/components/cell-panel.vue.d.ts +20 -0
  193. package/dist/types/components/cell-renders.d.ts +9 -0
  194. package/dist/types/components/date-panel.vue.d.ts +9 -0
  195. package/dist/types/components/filter-panel.vue.d.ts +21 -0
  196. package/dist/types/components/format-dialog.vue.d.ts +24 -0
  197. package/dist/types/components/format-list.vue.d.ts +25 -0
  198. package/dist/types/components/format-presets.d.ts +30 -0
  199. package/dist/types/components/option-panel.vue.d.ts +13 -0
  200. package/dist/types/components/sheet-comment.vue.d.ts +29 -0
  201. package/dist/types/components/sheet-formula-bar.vue.d.ts +3 -0
  202. package/dist/types/components/sheet-link.vue.d.ts +32 -0
  203. package/dist/types/components/sheet-menu.vue.d.ts +20 -0
  204. package/dist/types/components/sheet-name-box.vue.d.ts +3 -0
  205. package/dist/types/components/sheet-note.vue.d.ts +22 -0
  206. package/dist/types/components/sheet-outline.vue.d.ts +36 -0
  207. package/dist/types/components/sheet-tabs.vue.d.ts +9 -0
  208. package/dist/types/components/sheet-toolbar.vue.d.ts +11 -0
  209. package/dist/types/components/validation-dialog.vue.d.ts +25 -0
  210. package/dist/types/context.d.ts +189 -0
  211. package/dist/types/core/address.d.ts +109 -0
  212. package/dist/types/core/axis.d.ts +23 -0
  213. package/dist/types/core/cell-type.d.ts +157 -0
  214. package/dist/types/core/clipboard.d.ts +48 -0
  215. package/dist/types/core/commands.d.ts +76 -0
  216. package/dist/types/core/comments.d.ts +22 -0
  217. package/dist/types/core/conditional.d.ts +114 -0
  218. package/dist/types/core/csv.d.ts +93 -0
  219. package/dist/types/core/data.d.ts +26 -0
  220. package/dist/types/core/document.d.ts +49 -0
  221. package/dist/types/core/extension.d.ts +177 -0
  222. package/dist/types/core/file.d.ts +301 -0
  223. package/dist/types/core/fill.d.ts +23 -0
  224. package/dist/types/core/find.d.ts +39 -0
  225. package/dist/types/core/format.d.ts +47 -0
  226. package/dist/types/core/group.d.ts +76 -0
  227. package/dist/types/core/history.d.ts +27 -0
  228. package/dist/types/core/index.d.ts +33 -0
  229. package/dist/types/core/link.d.ts +14 -0
  230. package/dist/types/core/merge.d.ts +26 -0
  231. package/dist/types/core/model.d.ts +363 -0
  232. package/dist/types/core/nav.d.ts +15 -0
  233. package/dist/types/core/paint.d.ts +19 -0
  234. package/dist/types/core/plain-cell-types.d.ts +6 -0
  235. package/dist/types/core/protect.d.ts +34 -0
  236. package/dist/types/core/selection.d.ts +25 -0
  237. package/dist/types/core/transaction.d.ts +470 -0
  238. package/dist/types/core/validation.d.ts +55 -0
  239. package/dist/types/core/versions.d.ts +38 -0
  240. package/dist/types/export/color.d.ts +7 -0
  241. package/dist/types/export/draw.d.ts +98 -0
  242. package/dist/types/export/index.d.ts +47 -0
  243. package/dist/types/formula/edit.d.ts +62 -0
  244. package/dist/types/formula/engine.d.ts +99 -0
  245. package/dist/types/formula/error.d.ts +30 -0
  246. package/dist/types/formula/functions.d.ts +62 -0
  247. package/dist/types/formula/help.d.ts +12 -0
  248. package/dist/types/formula/index.d.ts +13 -0
  249. package/dist/types/formula/parse.d.ts +92 -0
  250. package/dist/types/formula/values.d.ts +65 -0
  251. package/dist/types/formulas.d.ts +32 -0
  252. package/dist/types/index.d.ts +225 -0
  253. package/dist/types/locale.d.ts +531 -0
  254. package/dist/types/sheet.vue.d.ts +60 -0
  255. package/dist/types/types.d.ts +498 -0
  256. package/dist/types/use-comments.d.ts +47 -0
  257. package/dist/types/use-messages.d.ts +7 -0
  258. package/dist/use-comments.js +130 -0
  259. package/dist/use-comments.js.map +1 -0
  260. package/dist/use-messages.js +29 -0
  261. package/dist/use-messages.js.map +1 -0
  262. package/package.json +93 -4
@@ -0,0 +1,36 @@
1
+ // src/export/color.ts
2
+ var normalizer;
3
+ var SRGB = /^(#|rgba?\()/;
4
+ /**
5
+ * A computed color as `#rrggbb` or `rgba(…)`, which every SVG reader
6
+ * understands. A canvas converts most colors as it parses them; colors
7
+ * it keeps in another space (`oklab(…)`, `color(…)`) are painted on a
8
+ * pixel and read back.
9
+ */
10
+ function plainColor(color) {
11
+ if (SRGB.test(color)) return color;
12
+ if (normalizer === void 0) try {
13
+ const canvas = document.createElement("canvas");
14
+ canvas.width = canvas.height = 1;
15
+ normalizer = canvas.getContext("2d", { willReadFrequently: true });
16
+ } catch {
17
+ normalizer = null;
18
+ }
19
+ if (!normalizer) return color;
20
+ normalizer.fillStyle = "#000";
21
+ normalizer.fillStyle = color;
22
+ const parsed = String(normalizer.fillStyle);
23
+ if (SRGB.test(parsed)) return parsed;
24
+ normalizer.clearRect(0, 0, 1, 1);
25
+ normalizer.fillRect(0, 0, 1, 1);
26
+ const [r, g, b, a] = normalizer.getImageData(0, 0, 1, 1).data;
27
+ if (a === 255) return `#${[
28
+ r,
29
+ g,
30
+ b
31
+ ].map((v) => v.toString(16).padStart(2, "0")).join("")}`;
32
+ return `rgba(${r}, ${g}, ${b}, ${Math.round(a / 255 * 1e3) / 1e3})`;
33
+ }
34
+ export { plainColor };
35
+
36
+ //# sourceMappingURL=color.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color.js","names":[],"sources":["../../src/export/color.ts"],"sourcesContent":["let normalizer: CanvasRenderingContext2D | null | undefined\n\nconst SRGB = /^(#|rgba?\\()/\n\n/**\n * A computed color as `#rrggbb` or `rgba(…)`, which every SVG reader\n * understands. A canvas converts most colors as it parses them; colors\n * it keeps in another space (`oklab(…)`, `color(…)`) are painted on a\n * pixel and read back.\n */\nexport function plainColor(color: string) {\n if (SRGB.test(color)) return color\n if (normalizer === undefined)\n try {\n const canvas = document.createElement('canvas')\n canvas.width = canvas.height = 1\n normalizer = canvas.getContext('2d', { willReadFrequently: true })\n } catch {\n normalizer = null\n }\n if (!normalizer) return color\n normalizer.fillStyle = '#000'\n normalizer.fillStyle = color\n const parsed = String(normalizer.fillStyle)\n if (SRGB.test(parsed)) return parsed\n normalizer.clearRect(0, 0, 1, 1)\n normalizer.fillRect(0, 0, 1, 1)\n const [r, g, b, a] = normalizer.getImageData(0, 0, 1, 1).data\n if (a === 255) return `#${[r, g, b].map((v) => v!.toString(16).padStart(2, '0')).join('')}`\n return `rgba(${r}, ${g}, ${b}, ${Math.round((a! / 255) * 1000) / 1000})`\n}\n"],"mappings":";AAAA,IAAI;AAEJ,IAAM,OAAO;;;;;;;AAQb,SAAgB,WAAW,OAAe;CACxC,IAAI,KAAK,KAAK,KAAK,GAAG,OAAO;CAC7B,IAAI,eAAe,KAAA,GACjB,IAAI;EACF,MAAM,SAAS,SAAS,cAAc,QAAQ;EAC9C,OAAO,QAAQ,OAAO,SAAS;EAC/B,aAAa,OAAO,WAAW,MAAM,EAAE,oBAAoB,KAAK,CAAC;CACnE,QAAQ;EACN,aAAa;CACf;CACF,IAAI,CAAC,YAAY,OAAO;CACxB,WAAW,YAAY;CACvB,WAAW,YAAY;CACvB,MAAM,SAAS,OAAO,WAAW,SAAS;CAC1C,IAAI,KAAK,KAAK,MAAM,GAAG,OAAO;CAC9B,WAAW,UAAU,GAAG,GAAG,GAAG,CAAC;CAC/B,WAAW,SAAS,GAAG,GAAG,GAAG,CAAC;CAC9B,MAAM,CAAC,GAAG,GAAG,GAAG,KAAK,WAAW,aAAa,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC;CACzD,IAAI,MAAM,KAAK,OAAO,IAAI;EAAC;EAAG;EAAG;CAAC,CAAC,CAAC,KAAK,MAAM,EAAG,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;CACxF,OAAO,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,MAAO,IAAK,MAAO,GAAI,IAAI,IAAK;AACxE"}
@@ -0,0 +1,316 @@
1
+ // src/export/draw.ts
2
+ var PAD = 8;
3
+ var LINE_HEIGHT = 1.4;
4
+ var XML_SPECIAL = /[&<>"]/;
5
+ var XML_ESCAPES = {
6
+ "&": "&amp;",
7
+ "<": "&lt;",
8
+ ">": "&gt;",
9
+ "\"": "&quot;"
10
+ };
11
+ var escapeXML = (text) => XML_SPECIAL.test(text) ? text.replace(/[&<>"]/g, (c) => XML_ESCAPES[c]) : text;
12
+ var n = (value) => String(Math.round(value * 100) / 100);
13
+ /**
14
+ * Breaks text into lines no wider than `width`: at spaces where it can,
15
+ * between any two characters of CJK text, and inside a word too long
16
+ * for a line.
17
+ */
18
+ function wrapLines(text, width, measure) {
19
+ const lines = [];
20
+ for (const paragraph of text.split("\n")) {
21
+ const pieces = paragraph.match(/[⺀-鿿豈-﫿＀-￯]|[^\s⺀-鿿豈-﫿＀-￯]+\s*|\s+/g) ?? [""];
22
+ let line = "";
23
+ for (const piece of pieces) {
24
+ const next = line + piece;
25
+ if (!line || measure(next.trimEnd()) <= width) {
26
+ line = next;
27
+ continue;
28
+ }
29
+ lines.push(line.trimEnd());
30
+ line = piece.trimStart();
31
+ }
32
+ while (line && measure(line.trimEnd()) > width && line.length > 1) {
33
+ let cut = line.length - 1;
34
+ while (cut > 1 && measure(line.slice(0, cut)) > width) cut--;
35
+ lines.push(line.slice(0, cut));
36
+ line = line.slice(cut);
37
+ }
38
+ lines.push(line.trimEnd());
39
+ }
40
+ return lines;
41
+ }
42
+ /** The sheet as an SVG document. */
43
+ /** The size of the image a drawing makes, in CSS px. */
44
+ function drawingSize(drawing) {
45
+ let width = drawing.headerWidth;
46
+ for (const w of drawing.colWidths) width += w;
47
+ let height = drawing.headerHeight;
48
+ for (const h of drawing.rowHeights) height += h;
49
+ return {
50
+ width,
51
+ height
52
+ };
53
+ }
54
+ function drawSheet(drawing, measure) {
55
+ const { theme, colWidths, rowHeights, headerWidth: hx, headerHeight: hy } = drawing;
56
+ const xs = [hx];
57
+ for (const w of colWidths) xs.push(xs[xs.length - 1] + w);
58
+ const ys = [hy];
59
+ for (const h of rowHeights) ys.push(ys[ys.length - 1] + h);
60
+ const width = xs[xs.length - 1];
61
+ const height = ys[ys.length - 1];
62
+ const font = (bold, italic) => `${italic ? "italic " : ""}${bold ? theme.boldWeight : "400"} ${theme.fontSize}px ${theme.fontFamily}`;
63
+ const out = [];
64
+ const defs = [];
65
+ let clips = 0;
66
+ if (drawing.background) out.push(`<rect width="${n(width)}" height="${n(height)}" fill="${theme.surface}"/>`);
67
+ for (const cell of drawing.cells) {
68
+ const x = hx + cell.x;
69
+ const y = hy + cell.y;
70
+ if (cell.look.background) out.push(`<rect x="${n(x)}" y="${n(y)}" width="${n(cell.width)}" height="${n(cell.height)}" fill="${cell.look.background}"/>`);
71
+ if (cell.bar) {
72
+ const inner = cell.width - 6;
73
+ out.push(`<rect x="${n(x + 3 + inner * cell.bar.from)}" y="${n(y + 5)}" width="${n(Math.max(0, inner * (cell.bar.to - cell.bar.from)))}" height="${n(Math.max(0, cell.height - 10))}" fill="${cell.bar.color}"/>`);
74
+ }
75
+ }
76
+ const lines = [];
77
+ if (drawing.gridlines) {
78
+ const covered = coveredEdges(drawing);
79
+ for (let i = 1; i < xs.length; i++) {
80
+ if (i === drawing.frozenCols) continue;
81
+ for (const [top, bottom] of openRuns(ys, covered.cols.get(i - 1))) lines.push(`M${n(xs[i] - .5)} ${n(top)}V${n(bottom)}`);
82
+ }
83
+ for (let i = 1; i < ys.length; i++) {
84
+ if (i === drawing.frozenRows) continue;
85
+ for (const [left, right] of openRuns(xs, covered.rows.get(i - 1))) lines.push(`M${n(left)} ${n(ys[i] - .5)}H${n(right)}`);
86
+ }
87
+ }
88
+ if (drawing.gridlines && xs.length > 1 && ys.length > 1) {
89
+ if (!hy) lines.push(`M${n(hx)} 0.5H${n(width)}`);
90
+ if (!hx) lines.push(`M0.5 ${n(hy)}V${n(height)}`);
91
+ }
92
+ if (lines.length) out.push(`<path d="${lines.join("")}" stroke="${theme.line}" fill="none"/>`);
93
+ const own = /* @__PURE__ */ new Map();
94
+ if (drawing.gridlines) for (const cell of drawing.cells) {
95
+ const color = cell.look.line;
96
+ if (!color || color === theme.line) continue;
97
+ const right = hx + cell.x + cell.width - .5;
98
+ const bottom = hy + cell.y + cell.height - .5;
99
+ const path = `M${n(right)} ${n(hy + cell.y)}V${n(bottom + .5)}M${n(hx + cell.x)} ${n(bottom)}H${n(right)}`;
100
+ const list = own.get(color);
101
+ if (list) list.push(path);
102
+ else own.set(color, [path]);
103
+ }
104
+ for (const [color, paths] of own) out.push(`<path d="${paths.join("")}" stroke="${color}" fill="none"/>`);
105
+ const freeze = [];
106
+ if (drawing.frozenCols > 0 && drawing.frozenCols < xs.length) freeze.push(`M${n(xs[drawing.frozenCols] - .5)} ${n(hy)}V${n(height)}`);
107
+ if (drawing.frozenRows > 0 && drawing.frozenRows < ys.length) freeze.push(`M${n(hx)} ${n(ys[drawing.frozenRows] - .5)}H${n(width)}`);
108
+ if (freeze.length) out.push(`<path d="${freeze.join("")}" stroke="${theme.freezeLine}" fill="none"/>`);
109
+ const text = mostCommon(drawing.cells.map((cell) => cell.look.color)) ?? theme.headerText;
110
+ const words = [];
111
+ for (const cell of drawing.cells) {
112
+ const x = hx + cell.x;
113
+ const y = hy + cell.y;
114
+ const { look } = cell;
115
+ if (cell.draw) {
116
+ const markup = cell.draw(drawContext(cell, drawing, measure));
117
+ if (!markup) continue;
118
+ const id = `c${clips++}`;
119
+ defs.push(`<clipPath id="${id}"><rect width="${n(cell.width)}" height="${n(cell.height)}"/></clipPath>`);
120
+ out.push(`<g transform="translate(${n(x)} ${n(y)})" clip-path="url(#${id})">${markup}</g>`);
121
+ continue;
122
+ }
123
+ if (cell.check !== void 0) {
124
+ const size = 14;
125
+ const bx = alignX(look.align, x, cell.width, size);
126
+ const by = alignY(look.valign, y, cell.height, size);
127
+ out.push(`<rect x="${n(bx + .5)}" y="${n(by + .5)}" width="13" height="13" rx="3.5" fill="${cell.check ? theme.checkOnBg : theme.checkBg}" stroke="${cell.check ? theme.checkOnBg : theme.checkBorder}"/>`);
128
+ if (cell.check) out.push(`<path d="M${n(bx + 3.5)} ${n(by + 7.2)}l2.4 2.4 4.6-5" fill="none" stroke="${theme.checkOn}" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>`);
129
+ continue;
130
+ }
131
+ if (!cell.text) continue;
132
+ const f = font(look.bold, look.italic);
133
+ const room = cell.width - 16;
134
+ const lineHeight = Math.round(theme.fontSize * LINE_HEIGHT);
135
+ if (cell.tag) {
136
+ const textWidth = Math.min(measure(cell.text, f), room - 12);
137
+ const tagWidth = textWidth + 12;
138
+ const tagHeight = 20;
139
+ const tx = alignX(look.align, x, cell.width, tagWidth);
140
+ const ty = alignY(look.valign, y, cell.height, tagHeight);
141
+ const id = `c${clips++}`;
142
+ defs.push(`<clipPath id="${id}"><rect x="${n(tx + 6)}" y="${n(ty)}" width="${n(textWidth)}" height="${tagHeight}"/></clipPath>`);
143
+ out.push(`<rect x="${n(tx + .5)}" y="${n(ty + .5)}" width="${n(tagWidth - 1)}" height="19" rx="3.5" fill="${cell.tag.background}" stroke="${cell.tag.border}"/>`, `<text x="${n(tx + 6)}" y="${n(ty + tagHeight / 2)}" dominant-baseline="central" fill="${cell.tag.color}" clip-path="url(#${id})"${textAttrs(look)}>${escapeXML(cell.text)}</text>`);
144
+ continue;
145
+ }
146
+ const single = !look.wrap;
147
+ const texts = single ? [firstLine(cell.text)] : wrapLines(cell.text, room, (t) => measure(t, f));
148
+ const widest = single && texts[0].length * theme.fontSize <= room ? 0 : Math.max(...texts.map((t) => measure(t, f)));
149
+ const blockHeight = texts.length * lineHeight;
150
+ const top = look.wrap ? y + 4 : look.valign === "top" ? y + 4 : look.valign === "bottom" ? y + cell.height - 4 - blockHeight : y + (cell.height - blockHeight) / 2;
151
+ const tx = look.align === "center" ? x + cell.width / 2 : look.align === "right" ? x + cell.width - PAD : x + PAD;
152
+ let attrs = textAttrs(look);
153
+ if (look.align !== "left") attrs += ` text-anchor="${look.align === "center" ? "middle" : "end"}"`;
154
+ if (look.color !== text) attrs += ` fill="${look.color}"`;
155
+ if (widest > room || blockHeight > cell.height - 8) {
156
+ const id = `c${clips++}`;
157
+ defs.push(`<clipPath id="${id}"><rect x="${n(x + 1)}" y="${n(y)}" width="${n(Math.max(0, cell.width - 2))}" height="${n(cell.height - 1)}"/></clipPath>`);
158
+ attrs += ` clip-path="url(#${id})"`;
159
+ }
160
+ if (texts.length === 1) words.push(`<text x="${n(tx)}" y="${n(top + lineHeight / 2)}"${attrs}>${escapeXML(texts[0])}</text>`);
161
+ else words.push(`<text${attrs}>${texts.map((t, i) => `<tspan x="${n(tx)}" y="${n(top + lineHeight * i + lineHeight / 2)}">${escapeXML(t)}</tspan>`).join("")}</text>`);
162
+ }
163
+ if (words.length) out.push(`<g dominant-baseline="central" fill="${text}">${words.join("")}</g>`);
164
+ if (drawing.colNames && hy > 0) {
165
+ out.push(`<rect width="${n(width)}" height="${n(hy)}" fill="${theme.headerBg}"/>`);
166
+ drawing.colNames.forEach((name, i) => out.push(`<text x="${n((xs[i] + xs[i + 1]) / 2)}" y="${n(hy / 2)}" text-anchor="middle" dominant-baseline="central" fill="${theme.headerText}">${escapeXML(name)}</text>`));
167
+ }
168
+ if (drawing.rowNames && hx > 0) {
169
+ out.push(`<rect y="${n(hy)}" width="${n(hx)}" height="${n(height - hy)}" fill="${theme.headerBg}"/>`);
170
+ drawing.rowNames.forEach((name, i) => out.push(`<text x="${n(hx / 2)}" y="${n((ys[i] + ys[i + 1]) / 2)}" text-anchor="middle" dominant-baseline="central" fill="${theme.headerText}">${escapeXML(name)}</text>`));
171
+ }
172
+ if (hx > 0 || hy > 0) {
173
+ const edges = [];
174
+ if (hy > 0) {
175
+ edges.push(`M0 ${n(hy - .5)}H${n(width)}`);
176
+ for (let i = 1; i < xs.length; i++) edges.push(`M${n(xs[i] - .5)} 0V${n(hy)}`);
177
+ }
178
+ if (hx > 0) {
179
+ edges.push(`M${n(hx - .5)} 0V${n(height)}`);
180
+ for (let i = 1; i < ys.length; i++) edges.push(`M0 ${n(ys[i] - .5)}H${n(hx)}`);
181
+ }
182
+ out.push(`<path d="${edges.join("")}" stroke="${theme.headerLine}" fill="none"/>`);
183
+ }
184
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${n(width)}" height="${n(height)}" viewBox="0 0 ${n(width)} ${n(height)}" font-family="${escapeXML(theme.fontFamily)}" font-size="${theme.fontSize}" xml:space="preserve">` + (defs.length ? `<defs>${defs.join("")}</defs>` : "") + out.join("") + `</svg>`;
185
+ }
186
+ var firstLine = (text) => {
187
+ const end = text.indexOf("\n");
188
+ return end === -1 ? text : text.slice(0, end);
189
+ };
190
+ function mostCommon(list) {
191
+ const counts = /* @__PURE__ */ new Map();
192
+ let best;
193
+ let most = 0;
194
+ for (const item of list) {
195
+ const count = (counts.get(item) ?? 0) + 1;
196
+ counts.set(item, count);
197
+ if (count > most) {
198
+ most = count;
199
+ best = item;
200
+ }
201
+ }
202
+ return best;
203
+ }
204
+ /** What a cell type's `draw` gets for a cell. */
205
+ function drawContext(cell, drawing, measure) {
206
+ const { theme } = drawing;
207
+ const look = {
208
+ color: cell.look.color,
209
+ background: cell.look.background,
210
+ align: cell.look.align,
211
+ valign: cell.look.valign,
212
+ bold: cell.look.bold,
213
+ italic: cell.look.italic,
214
+ fontFamily: theme.fontFamily,
215
+ fontSize: theme.fontSize
216
+ };
217
+ const text = (value, box = {
218
+ x: 0,
219
+ y: 0,
220
+ width: cell.width,
221
+ height: cell.height
222
+ }, options = {}) => {
223
+ const line = firstLine(value);
224
+ if (!line) return "";
225
+ const align = options.align ?? look.align;
226
+ const valign = options.valign ?? look.valign;
227
+ const size = options.size ?? look.fontSize;
228
+ const bold = options.bold ?? look.bold;
229
+ const italic = options.italic ?? look.italic;
230
+ const width = measure(line, `${italic ? "italic " : ""}${bold ? theme.boldWeight : "400"} ${size}px ${theme.fontFamily}`);
231
+ const x = alignX(align, box.x, box.width, width);
232
+ const y = alignY(valign, box.y, box.height, size * LINE_HEIGHT) + size * LINE_HEIGHT / 2;
233
+ let attrs = ` fill="${options.color ?? look.color}"`;
234
+ if (size !== theme.fontSize) attrs += ` font-size="${n(size)}"`;
235
+ if (bold) attrs += ` font-weight="bold"`;
236
+ if (italic) attrs += ` font-style="italic"`;
237
+ return `<text x="${n(x)}" y="${n(y)}" dominant-baseline="central"${attrs}>${escapeXML(line)}</text>`;
238
+ };
239
+ return {
240
+ width: cell.width,
241
+ height: cell.height,
242
+ formatted: cell.text,
243
+ look,
244
+ text,
245
+ icon: drawing.icon ?? (() => ""),
246
+ color: drawing.color ?? ((value) => value),
247
+ escape: escapeXML
248
+ };
249
+ }
250
+ function textAttrs(look) {
251
+ let attrs = "";
252
+ if (look.bold) attrs += ` font-weight="bold"`;
253
+ if (look.italic) attrs += ` font-style="italic"`;
254
+ const deco = [look.underline && "underline", look.strike && "line-through"].filter(Boolean);
255
+ if (deco.length) attrs += ` text-decoration="${deco.join(" ")}"`;
256
+ return attrs;
257
+ }
258
+ var alignX = (align, x, width, size) => align === "center" ? x + (width - size) / 2 : align === "right" ? x + width - PAD - size : x + PAD;
259
+ var alignY = (valign, y, height, size) => valign === "top" ? y + 4 : valign === "bottom" ? y + height - 4 - size : y + (height - size) / 2;
260
+ /** Where each line's far edge is, from the first line's near edge: offset → line after it. */
261
+ function edgesOf(sizes) {
262
+ const at = /* @__PURE__ */ new Map([[0, 0]]);
263
+ let sum = 0;
264
+ sizes.forEach((size, i) => at.set(sum += size, i + 1));
265
+ return at;
266
+ }
267
+ /**
268
+ * The grid lines a merge hides: for each column edge (after column `i`)
269
+ * the runs of y it covers, and for each row edge the runs of x.
270
+ */
271
+ function coveredEdges(drawing) {
272
+ const cols = /* @__PURE__ */ new Map();
273
+ const rows = /* @__PURE__ */ new Map();
274
+ const merged = drawing.cells.filter((cell) => cell.merged);
275
+ if (!merged.length) return {
276
+ cols,
277
+ rows
278
+ };
279
+ const xs = edgesOf(drawing.colWidths);
280
+ const ys = edgesOf(drawing.rowHeights);
281
+ for (const cell of merged) {
282
+ const left = xs.get(cell.x);
283
+ const top = ys.get(cell.y);
284
+ const right = xs.get(cell.x + cell.width);
285
+ const bottom = ys.get(cell.y + cell.height);
286
+ if (left === void 0 || top === void 0 || right === void 0 || bottom === void 0) continue;
287
+ for (let i = left + 1; i < right; i++) push(cols, i - 1, [drawing.headerHeight + cell.y, drawing.headerHeight + cell.y + cell.height]);
288
+ for (let i = top + 1; i < bottom; i++) push(rows, i - 1, [drawing.headerWidth + cell.x, drawing.headerWidth + cell.x + cell.width]);
289
+ }
290
+ return {
291
+ cols,
292
+ rows
293
+ };
294
+ }
295
+ function push(map, key, run) {
296
+ const list = map.get(key);
297
+ if (list) list.push(run);
298
+ else map.set(key, [run]);
299
+ }
300
+ /** The parts of a line from the first to the last of `edges` not under any of `covered`. */
301
+ function openRuns(edges, covered) {
302
+ const start = edges[0];
303
+ const end = edges[edges.length - 1];
304
+ if (!covered) return [[start, end]];
305
+ const runs = [];
306
+ let at = start;
307
+ for (const [a, b] of [...covered].sort((p, q) => p[0] - q[0])) {
308
+ if (a > at) runs.push([at, a]);
309
+ at = Math.max(at, b);
310
+ }
311
+ if (at < end) runs.push([at, end]);
312
+ return runs;
313
+ }
314
+ export { drawSheet, drawingSize, escapeXML, wrapLines };
315
+
316
+ //# sourceMappingURL=draw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draw.js","names":[],"sources":["../../src/export/draw.ts"],"sourcesContent":["/*\n * A sheet, or a page of it, drawn as SVG: fills, data bars, grid lines,\n * text and the built-in cell types' marks, the way the grid shows them.\n * Plain SVG that design programs read, without `foreignObject`.\n */\n\nimport type { Component } from 'vue'\nimport type { SheetDrawContext, SheetDrawRect, SheetDrawTextOptions } from '../core/cell-type'\n\n/** The look of a cell's content, in plain colors. */\nexport interface DrawLook {\n color: string\n /** The fill, `null` for none. */\n background: string | null\n bold: boolean\n italic: boolean\n underline: boolean\n strike: boolean\n align: 'left' | 'center' | 'right'\n valign: 'top' | 'middle' | 'bottom'\n wrap: boolean\n /** The cell's own grid line, where it isn't the sheet's, as on a fill. */\n line: string | null\n}\n\n/** A cell to draw, at its place among the lines drawn. */\nexport interface DrawCell {\n x: number\n y: number\n width: number\n height: number\n text: string\n look: DrawLook\n /** A conditional format's bar, as parts of the cell's width. */\n bar?: { from: number; to: number; color: string }\n /** A checkbox cell's box. */\n check?: boolean\n /** A merged cell, which hides the grid lines inside it. */\n merged?: boolean\n /** A select cell's value as a soft tag. */\n tag?: { background: string; color: string; border: string }\n /** A cell type's own drawing, as SVG markup in the cell's own coordinates. */\n draw?: (draw: SheetDrawContext) => string\n}\n\n/** The colors and font of the sheet, read from the page. */\nexport interface DrawTheme {\n fontFamily: string\n fontSize: number\n boldWeight: string\n surface: string\n line: string\n freezeLine: string\n headerBg: string\n headerText: string\n headerLine: string\n checkBorder: string\n checkBg: string\n checkOn: string\n checkOnBg: string\n}\n\nexport interface SheetDrawing {\n /** The widths of the columns drawn, left to right. */\n colWidths: number[]\n /** The heights of the rows drawn, top to bottom. */\n rowHeights: number[]\n /** The column letters and row numbers, when the headers are drawn. */\n colNames?: string[]\n rowNames?: string[]\n headerWidth: number\n headerHeight: number\n /** How many of the rows and columns drawn are frozen, with a firmer line after them. */\n frozenRows: number\n frozenCols: number\n cells: DrawCell[]\n gridlines: boolean\n background: boolean\n theme: DrawTheme\n /** Icons as SVG, for cell types' drawings; none without it. */\n icon?: (icon: Component, box: SheetDrawRect, color: string) => string\n /** CSS colors as SVG takes them, for cell types' drawings; as they are without it. */\n color?: (value: string) => string\n}\n\n/** Measures text in a font, in px. */\nexport type MeasureText = (text: string, font: string) => number\n\nconst PAD = 8\nconst LINE_HEIGHT = 1.4\n\nconst XML_SPECIAL = /[&<>\"]/\nconst XML_ESCAPES: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n}\n\nexport const escapeXML = (text: string) =>\n XML_SPECIAL.test(text) ? text.replace(/[&<>\"]/g, (c) => XML_ESCAPES[c]!) : text\n\nconst n = (value: number) => String(Math.round(value * 100) / 100)\n\n/**\n * Breaks text into lines no wider than `width`: at spaces where it can,\n * between any two characters of CJK text, and inside a word too long\n * for a line.\n */\nexport function wrapLines(text: string, width: number, measure: (text: string) => number) {\n const lines: string[] = []\n for (const paragraph of text.split('\\n')) {\n // words with their space after, and each CJK character on its own\n const pieces = paragraph.match(/[⺀-鿿豈-﫿＀-￯]|[^\\s⺀-鿿豈-﫿＀-￯]+\\s*|\\s+/g) ?? ['']\n let line = ''\n for (const piece of pieces) {\n const next = line + piece\n if (!line || measure(next.trimEnd()) <= width) {\n line = next\n continue\n }\n lines.push(line.trimEnd())\n line = piece.trimStart()\n }\n // a word wider than the line is cut where it fills it\n while (line && measure(line.trimEnd()) > width && line.length > 1) {\n let cut = line.length - 1\n while (cut > 1 && measure(line.slice(0, cut)) > width) cut--\n lines.push(line.slice(0, cut))\n line = line.slice(cut)\n }\n lines.push(line.trimEnd())\n }\n return lines\n}\n\n/** The sheet as an SVG document. */\n/** The size of the image a drawing makes, in CSS px. */\nexport function drawingSize(drawing: SheetDrawing) {\n let width = drawing.headerWidth\n for (const w of drawing.colWidths) width += w\n let height = drawing.headerHeight\n for (const h of drawing.rowHeights) height += h\n return { width, height }\n}\n\nexport function drawSheet(drawing: SheetDrawing, measure: MeasureText) {\n const { theme, colWidths, rowHeights, headerWidth: hx, headerHeight: hy } = drawing\n const xs = [hx]\n for (const w of colWidths) xs.push(xs[xs.length - 1]! + w)\n const ys = [hy]\n for (const h of rowHeights) ys.push(ys[ys.length - 1]! + h)\n const width = xs[xs.length - 1]!\n const height = ys[ys.length - 1]!\n const font = (bold: boolean, italic: boolean) =>\n `${italic ? 'italic ' : ''}${bold ? theme.boldWeight : '400'} ${theme.fontSize}px ${theme.fontFamily}`\n const out: string[] = []\n const defs: string[] = []\n let clips = 0\n\n if (drawing.background)\n out.push(`<rect width=\"${n(width)}\" height=\"${n(height)}\" fill=\"${theme.surface}\"/>`)\n\n // fills and bars first, then the lines over them, then the text\n for (const cell of drawing.cells) {\n const x = hx + cell.x\n const y = hy + cell.y\n if (cell.look.background)\n out.push(\n `<rect x=\"${n(x)}\" y=\"${n(y)}\" width=\"${n(cell.width)}\" height=\"${n(cell.height)}\" fill=\"${cell.look.background}\"/>`,\n )\n if (cell.bar) {\n const inner = cell.width - 6\n out.push(\n `<rect x=\"${n(x + 3 + inner * cell.bar.from)}\" y=\"${n(y + 5)}\" width=\"${n(Math.max(0, inner * (cell.bar.to - cell.bar.from)))}\" height=\"${n(Math.max(0, cell.height - 10))}\" fill=\"${cell.bar.color}\"/>`,\n )\n }\n }\n\n const lines: string[] = []\n if (drawing.gridlines) {\n const covered = coveredEdges(drawing)\n for (let i = 1; i < xs.length; i++) {\n if (i === drawing.frozenCols) continue\n for (const [top, bottom] of openRuns(ys, covered.cols.get(i - 1)))\n lines.push(`M${n(xs[i]! - 0.5)} ${n(top)}V${n(bottom)}`)\n }\n for (let i = 1; i < ys.length; i++) {\n if (i === drawing.frozenRows) continue\n for (const [left, right] of openRuns(xs, covered.rows.get(i - 1)))\n lines.push(`M${n(left)} ${n(ys[i]! - 0.5)}H${n(right)}`)\n }\n }\n // the sheet's outer edges, which the headers draw in the grid\n if (drawing.gridlines && xs.length > 1 && ys.length > 1) {\n if (!hy) lines.push(`M${n(hx)} 0.5H${n(width)}`)\n if (!hx) lines.push(`M0.5 ${n(hy)}V${n(height)}`)\n }\n if (lines.length) out.push(`<path d=\"${lines.join('')}\" stroke=\"${theme.line}\" fill=\"none\"/>`)\n // cells with their own line, such as filled ones, draw their right and bottom edges\n const own = new Map<string, string[]>()\n if (drawing.gridlines)\n for (const cell of drawing.cells) {\n const color = cell.look.line\n if (!color || color === theme.line) continue\n const right = hx + cell.x + cell.width - 0.5\n const bottom = hy + cell.y + cell.height - 0.5\n const path = `M${n(right)} ${n(hy + cell.y)}V${n(bottom + 0.5)}M${n(hx + cell.x)} ${n(bottom)}H${n(right)}`\n const list = own.get(color)\n if (list) list.push(path)\n else own.set(color, [path])\n }\n for (const [color, paths] of own)\n out.push(`<path d=\"${paths.join('')}\" stroke=\"${color}\" fill=\"none\"/>`)\n const freeze: string[] = []\n if (drawing.frozenCols > 0 && drawing.frozenCols < xs.length)\n freeze.push(`M${n(xs[drawing.frozenCols]! - 0.5)} ${n(hy)}V${n(height)}`)\n if (drawing.frozenRows > 0 && drawing.frozenRows < ys.length)\n freeze.push(`M${n(hx)} ${n(ys[drawing.frozenRows]! - 0.5)}H${n(width)}`)\n if (freeze.length)\n out.push(`<path d=\"${freeze.join('')}\" stroke=\"${theme.freezeLine}\" fill=\"none\"/>`)\n\n // the text, in a group with what most of it shares\n const text = mostCommon(drawing.cells.map((cell) => cell.look.color)) ?? theme.headerText\n const words: string[] = []\n for (const cell of drawing.cells) {\n const x = hx + cell.x\n const y = hy + cell.y\n const { look } = cell\n if (cell.draw) {\n const markup = cell.draw(drawContext(cell, drawing, measure))\n if (!markup) continue\n // in the cell's own coordinates, and kept to it as the grid keeps a cell's content\n const id = `c${clips++}`\n defs.push(\n `<clipPath id=\"${id}\"><rect width=\"${n(cell.width)}\" height=\"${n(cell.height)}\"/></clipPath>`,\n )\n out.push(`<g transform=\"translate(${n(x)} ${n(y)})\" clip-path=\"url(#${id})\">${markup}</g>`)\n continue\n }\n if (cell.check !== undefined) {\n const size = 14\n const bx = alignX(look.align, x, cell.width, size)\n const by = alignY(look.valign, y, cell.height, size)\n out.push(\n `<rect x=\"${n(bx + 0.5)}\" y=\"${n(by + 0.5)}\" width=\"${size - 1}\" height=\"${size - 1}\" rx=\"3.5\" fill=\"${cell.check ? theme.checkOnBg : theme.checkBg}\" stroke=\"${cell.check ? theme.checkOnBg : theme.checkBorder}\"/>`,\n )\n if (cell.check)\n out.push(\n `<path d=\"M${n(bx + 3.5)} ${n(by + 7.2)}l2.4 2.4 4.6-5\" fill=\"none\" stroke=\"${theme.checkOn}\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n )\n continue\n }\n if (!cell.text) continue\n const f = font(look.bold, look.italic)\n const room = cell.width - PAD * 2\n const lineHeight = Math.round(theme.fontSize * LINE_HEIGHT)\n if (cell.tag) {\n const textWidth = Math.min(measure(cell.text, f), room - 12)\n const tagWidth = textWidth + 12\n const tagHeight = 20\n const tx = alignX(look.align, x, cell.width, tagWidth)\n const ty = alignY(look.valign, y, cell.height, tagHeight)\n const id = `c${clips++}`\n defs.push(\n `<clipPath id=\"${id}\"><rect x=\"${n(tx + 6)}\" y=\"${n(ty)}\" width=\"${n(textWidth)}\" height=\"${tagHeight}\"/></clipPath>`,\n )\n out.push(\n `<rect x=\"${n(tx + 0.5)}\" y=\"${n(ty + 0.5)}\" width=\"${n(tagWidth - 1)}\" height=\"${tagHeight - 1}\" rx=\"3.5\" fill=\"${cell.tag.background}\" stroke=\"${cell.tag.border}\"/>`,\n `<text x=\"${n(tx + 6)}\" y=\"${n(ty + tagHeight / 2)}\" dominant-baseline=\"central\" fill=\"${cell.tag.color}\" clip-path=\"url(#${id})\"${textAttrs(look)}>${escapeXML(cell.text)}</text>`,\n )\n continue\n }\n const single = !look.wrap\n const texts = single ? [firstLine(cell.text)] : wrapLines(cell.text, room, (t) => measure(t, f))\n // text no wider than a full em a character fits without measuring it\n const widest =\n single && texts[0]!.length * theme.fontSize <= room\n ? 0\n : Math.max(...texts.map((t) => measure(t, f)))\n const blockHeight = texts.length * lineHeight\n const top = look.wrap\n ? y + 4\n : look.valign === 'top'\n ? y + 4\n : look.valign === 'bottom'\n ? y + cell.height - 4 - blockHeight\n : y + (cell.height - blockHeight) / 2\n const tx =\n look.align === 'center'\n ? x + cell.width / 2\n : look.align === 'right'\n ? x + cell.width - PAD\n : x + PAD\n let attrs = textAttrs(look)\n if (look.align !== 'left')\n attrs += ` text-anchor=\"${look.align === 'center' ? 'middle' : 'end'}\"`\n if (look.color !== text) attrs += ` fill=\"${look.color}\"`\n if (widest > room || blockHeight > cell.height - 8) {\n const id = `c${clips++}`\n defs.push(\n `<clipPath id=\"${id}\"><rect x=\"${n(x + 1)}\" y=\"${n(y)}\" width=\"${n(Math.max(0, cell.width - 2))}\" height=\"${n(cell.height - 1)}\"/></clipPath>`,\n )\n attrs += ` clip-path=\"url(#${id})\"`\n }\n if (texts.length === 1)\n words.push(\n `<text x=\"${n(tx)}\" y=\"${n(top + lineHeight / 2)}\"${attrs}>${escapeXML(texts[0]!)}</text>`,\n )\n else\n words.push(\n `<text${attrs}>${texts\n .map(\n (t, i) =>\n `<tspan x=\"${n(tx)}\" y=\"${n(top + lineHeight * i + lineHeight / 2)}\">${escapeXML(t)}</tspan>`,\n )\n .join('')}</text>`,\n )\n }\n if (words.length) out.push(`<g dominant-baseline=\"central\" fill=\"${text}\">${words.join('')}</g>`)\n\n if (drawing.colNames && hy > 0) {\n out.push(`<rect width=\"${n(width)}\" height=\"${n(hy)}\" fill=\"${theme.headerBg}\"/>`)\n drawing.colNames.forEach((name, i) =>\n out.push(\n `<text x=\"${n((xs[i]! + xs[i + 1]!) / 2)}\" y=\"${n(hy / 2)}\" text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"${theme.headerText}\">${escapeXML(name)}</text>`,\n ),\n )\n }\n if (drawing.rowNames && hx > 0) {\n out.push(\n `<rect y=\"${n(hy)}\" width=\"${n(hx)}\" height=\"${n(height - hy)}\" fill=\"${theme.headerBg}\"/>`,\n )\n drawing.rowNames.forEach((name, i) =>\n out.push(\n `<text x=\"${n(hx / 2)}\" y=\"${n((ys[i]! + ys[i + 1]!) / 2)}\" text-anchor=\"middle\" dominant-baseline=\"central\" fill=\"${theme.headerText}\">${escapeXML(name)}</text>`,\n ),\n )\n }\n if (hx > 0 || hy > 0) {\n const edges: string[] = []\n if (hy > 0) {\n edges.push(`M0 ${n(hy - 0.5)}H${n(width)}`)\n for (let i = 1; i < xs.length; i++) edges.push(`M${n(xs[i]! - 0.5)} 0V${n(hy)}`)\n }\n if (hx > 0) {\n edges.push(`M${n(hx - 0.5)} 0V${n(height)}`)\n for (let i = 1; i < ys.length; i++) edges.push(`M0 ${n(ys[i]! - 0.5)}H${n(hx)}`)\n }\n out.push(`<path d=\"${edges.join('')}\" stroke=\"${theme.headerLine}\" fill=\"none\"/>`)\n }\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${n(width)}\" height=\"${n(height)}\" viewBox=\"0 0 ${n(width)} ${n(height)}\"` +\n ` font-family=\"${escapeXML(theme.fontFamily)}\" font-size=\"${theme.fontSize}\" xml:space=\"preserve\">` +\n (defs.length ? `<defs>${defs.join('')}</defs>` : '') +\n out.join('') +\n `</svg>`\n )\n}\n\nconst firstLine = (text: string) => {\n const end = text.indexOf('\\n')\n return end === -1 ? text : text.slice(0, end)\n}\n\nfunction mostCommon(list: string[]) {\n const counts = new Map<string, number>()\n let best: string | undefined\n let most = 0\n for (const item of list) {\n const count = (counts.get(item) ?? 0) + 1\n counts.set(item, count)\n if (count > most) {\n most = count\n best = item\n }\n }\n return best\n}\n\n/** What a cell type's `draw` gets for a cell. */\nfunction drawContext(\n cell: DrawCell,\n drawing: SheetDrawing,\n measure: MeasureText,\n): SheetDrawContext {\n const { theme } = drawing\n const look = {\n color: cell.look.color,\n background: cell.look.background,\n align: cell.look.align,\n valign: cell.look.valign,\n bold: cell.look.bold,\n italic: cell.look.italic,\n fontFamily: theme.fontFamily,\n fontSize: theme.fontSize,\n }\n const text = (\n value: string,\n box: SheetDrawRect = { x: 0, y: 0, width: cell.width, height: cell.height },\n options: SheetDrawTextOptions = {},\n ) => {\n const line = firstLine(value)\n if (!line) return ''\n const align = options.align ?? look.align\n const valign = options.valign ?? look.valign\n const size = options.size ?? look.fontSize\n const bold = options.bold ?? look.bold\n const italic = options.italic ?? look.italic\n const width = measure(\n line,\n `${italic ? 'italic ' : ''}${bold ? theme.boldWeight : '400'} ${size}px ${theme.fontFamily}`,\n )\n const x = alignX(align, box.x, box.width, width)\n const y = alignY(valign, box.y, box.height, size * LINE_HEIGHT) + (size * LINE_HEIGHT) / 2\n let attrs = ` fill=\"${options.color ?? look.color}\"`\n if (size !== theme.fontSize) attrs += ` font-size=\"${n(size)}\"`\n if (bold) attrs += ` font-weight=\"bold\"`\n if (italic) attrs += ` font-style=\"italic\"`\n return `<text x=\"${n(x)}\" y=\"${n(y)}\" dominant-baseline=\"central\"${attrs}>${escapeXML(line)}</text>`\n }\n return {\n width: cell.width,\n height: cell.height,\n formatted: cell.text,\n look,\n text,\n icon: drawing.icon ?? (() => ''),\n color: drawing.color ?? ((value) => value),\n escape: escapeXML,\n }\n}\n\nfunction textAttrs(look: DrawLook) {\n let attrs = ''\n if (look.bold) attrs += ` font-weight=\"bold\"`\n if (look.italic) attrs += ` font-style=\"italic\"`\n const deco = [look.underline && 'underline', look.strike && 'line-through'].filter(Boolean)\n if (deco.length) attrs += ` text-decoration=\"${deco.join(' ')}\"`\n return attrs\n}\n\nconst alignX = (align: DrawLook['align'], x: number, width: number, size: number) =>\n align === 'center' ? x + (width - size) / 2 : align === 'right' ? x + width - PAD - size : x + PAD\n\nconst alignY = (valign: DrawLook['valign'], y: number, height: number, size: number) =>\n valign === 'top' ? y + 4 : valign === 'bottom' ? y + height - 4 - size : y + (height - size) / 2\n\n/** Where each line's far edge is, from the first line's near edge: offset → line after it. */\nfunction edgesOf(sizes: number[]) {\n const at = new Map<number, number>([[0, 0]])\n let sum = 0\n sizes.forEach((size, i) => at.set((sum += size), i + 1))\n return at\n}\n\n/**\n * The grid lines a merge hides: for each column edge (after column `i`)\n * the runs of y it covers, and for each row edge the runs of x.\n */\nfunction coveredEdges(drawing: SheetDrawing) {\n const cols = new Map<number, [number, number][]>()\n const rows = new Map<number, [number, number][]>()\n const merged = drawing.cells.filter((cell) => cell.merged)\n if (!merged.length) return { cols, rows }\n const xs = edgesOf(drawing.colWidths)\n const ys = edgesOf(drawing.rowHeights)\n for (const cell of merged) {\n const left = xs.get(cell.x)\n const top = ys.get(cell.y)\n const right = xs.get(cell.x + cell.width)\n const bottom = ys.get(cell.y + cell.height)\n if (left === undefined || top === undefined || right === undefined || bottom === undefined)\n continue\n for (let i = left + 1; i < right; i++)\n push(cols, i - 1, [\n drawing.headerHeight + cell.y,\n drawing.headerHeight + cell.y + cell.height,\n ])\n for (let i = top + 1; i < bottom; i++)\n push(rows, i - 1, [drawing.headerWidth + cell.x, drawing.headerWidth + cell.x + cell.width])\n }\n return { cols, rows }\n}\n\nfunction push(map: Map<number, [number, number][]>, key: number, run: [number, number]) {\n const list = map.get(key)\n if (list) list.push(run)\n else map.set(key, [run])\n}\n\n/** The parts of a line from the first to the last of `edges` not under any of `covered`. */\nfunction openRuns(edges: number[], covered: [number, number][] | undefined): [number, number][] {\n const start = edges[0]!\n const end = edges[edges.length - 1]!\n if (!covered) return [[start, end]]\n const runs: [number, number][] = []\n let at = start\n // oxlint-disable-next-line unicorn/no-array-sort -- sorts a copy\n for (const [a, b] of [...covered].sort((p, q) => p[0] - q[0])) {\n if (a > at) runs.push([at, a])\n at = Math.max(at, b)\n }\n if (at < end) runs.push([at, end])\n return runs\n}\n"],"mappings":"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"}