ooxml-core 0.19.0 → 0.20.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 (291) hide show
  1. package/dist/automation/index.cjs +195 -193
  2. package/dist/automation/index.mjs +195 -193
  3. package/dist/diagram/index.cjs +2 -1
  4. package/dist/diagram/index.mjs +2 -1
  5. package/dist/docx/attr-units.d.ts +11 -0
  6. package/dist/docx/attr-units.d.ts.map +1 -0
  7. package/dist/docx/block-parser.d.ts.map +1 -1
  8. package/dist/docx/case-transform.d.ts +9 -0
  9. package/dist/docx/case-transform.d.ts.map +1 -0
  10. package/dist/docx/embedded.cjs +2 -1
  11. package/dist/docx/embedded.mjs +2 -1
  12. package/dist/docx/index.cjs +289 -3
  13. package/dist/docx/index.d.ts +5 -0
  14. package/dist/docx/index.d.ts.map +1 -1
  15. package/dist/docx/index.mjs +269 -4
  16. package/dist/docx/layout/adapter.d.ts.map +1 -1
  17. package/dist/docx/layout/table-layout.d.ts.map +1 -1
  18. package/dist/docx/load/index.cjs +2 -1
  19. package/dist/docx/load/index.mjs +2 -1
  20. package/dist/docx/page-setup-model.d.ts +29 -0
  21. package/dist/docx/page-setup-model.d.ts.map +1 -0
  22. package/dist/docx/page-size.d.ts +11 -0
  23. package/dist/docx/page-size.d.ts.map +1 -0
  24. package/dist/docx/parse.d.ts.map +1 -1
  25. package/dist/docx/section-edit.d.ts +19 -0
  26. package/dist/docx/section-edit.d.ts.map +1 -0
  27. package/dist/docx/tab-stops.d.ts.map +1 -1
  28. package/dist/docx/ui/backstage-focus.d.ts +6 -0
  29. package/dist/docx/ui/backstage-focus.d.ts.map +1 -0
  30. package/dist/docx/ui/break-note-schema.d.ts +11 -0
  31. package/dist/docx/ui/break-note-schema.d.ts.map +1 -0
  32. package/dist/docx/ui/collaboration-authority.d.ts +31 -0
  33. package/dist/docx/ui/collaboration-authority.d.ts.map +1 -0
  34. package/dist/docx/ui/collaboration-identity.d.ts +8 -0
  35. package/dist/docx/ui/collaboration-identity.d.ts.map +1 -0
  36. package/dist/docx/ui/collaboration-protocol.d.ts +25 -0
  37. package/dist/docx/ui/collaboration-protocol.d.ts.map +1 -0
  38. package/dist/docx/ui/collaboration.d.ts +30 -0
  39. package/dist/docx/ui/collaboration.d.ts.map +1 -0
  40. package/dist/docx/ui/defined.d.ts +3 -0
  41. package/dist/docx/ui/defined.d.ts.map +1 -0
  42. package/dist/docx/ui/dirty-state.d.ts +9 -0
  43. package/dist/docx/ui/dirty-state.d.ts.map +1 -0
  44. package/dist/docx/ui/field-guard.d.ts +21 -0
  45. package/dist/docx/ui/field-guard.d.ts.map +1 -0
  46. package/dist/docx/ui/header-footer-history.d.ts +15 -0
  47. package/dist/docx/ui/header-footer-history.d.ts.map +1 -0
  48. package/dist/docx/ui/index.cjs +2380 -0
  49. package/dist/docx/ui/index.d.ts +30 -0
  50. package/dist/docx/ui/index.d.ts.map +1 -0
  51. package/dist/docx/ui/index.mjs +2317 -0
  52. package/dist/docx/ui/inline-content-schema.d.ts +15 -0
  53. package/dist/docx/ui/inline-content-schema.d.ts.map +1 -0
  54. package/dist/docx/ui/ligature-style.d.ts +4 -0
  55. package/dist/docx/ui/ligature-style.d.ts.map +1 -0
  56. package/dist/docx/ui/node-numbering.d.ts +8 -0
  57. package/dist/docx/ui/node-numbering.d.ts.map +1 -0
  58. package/dist/docx/ui/review-schema.d.ts +90 -0
  59. package/dist/docx/ui/review-schema.d.ts.map +1 -0
  60. package/dist/docx/ui/ribbon-action-ids.d.ts +26 -0
  61. package/dist/docx/ui/ribbon-action-ids.d.ts.map +1 -0
  62. package/dist/docx/ui/ribbon-colors.d.ts +3 -0
  63. package/dist/docx/ui/ribbon-colors.d.ts.map +1 -0
  64. package/dist/docx/ui/ribbon-legacy-labels.d.ts +6 -0
  65. package/dist/docx/ui/ribbon-legacy-labels.d.ts.map +1 -0
  66. package/dist/docx/ui/run-compare.d.ts +5 -0
  67. package/dist/docx/ui/run-compare.d.ts.map +1 -0
  68. package/dist/docx/ui/run-extra-mark.d.ts +17 -0
  69. package/dist/docx/ui/run-extra-mark.d.ts.map +1 -0
  70. package/dist/docx/ui/schema-marks.d.ts +273 -0
  71. package/dist/docx/ui/schema-marks.d.ts.map +1 -0
  72. package/dist/docx/ui/smartart-theme.d.ts +21 -0
  73. package/dist/docx/ui/smartart-theme.d.ts.map +1 -0
  74. package/dist/docx/ui/table-render.d.ts +24 -0
  75. package/dist/docx/ui/table-render.d.ts.map +1 -0
  76. package/dist/docx/ui/table-visuals.d.ts +3 -0
  77. package/dist/docx/ui/table-visuals.d.ts.map +1 -0
  78. package/dist/docx/ui/theme/css-vars.d.ts +6 -0
  79. package/dist/docx/ui/theme/css-vars.d.ts.map +1 -0
  80. package/dist/docx/ui/theme/defaults.d.ts +12 -0
  81. package/dist/docx/ui/theme/defaults.d.ts.map +1 -0
  82. package/dist/docx/ui/theme/element.d.ts +9 -0
  83. package/dist/docx/ui/theme/element.d.ts.map +1 -0
  84. package/dist/docx/ui/theme/index.d.ts +5 -0
  85. package/dist/docx/ui/theme/index.d.ts.map +1 -0
  86. package/dist/docx/ui/theme/types.d.ts +42 -0
  87. package/dist/docx/ui/theme/types.d.ts.map +1 -0
  88. package/dist/docx/ui/word-count.d.ts +3 -0
  89. package/dist/docx/ui/word-count.d.ts.map +1 -0
  90. package/dist/docx/ui/zoom-fit.d.ts +16 -0
  91. package/dist/docx/ui/zoom-fit.d.ts.map +1 -0
  92. package/dist/docx/validate-paragraph.d.ts.map +1 -1
  93. package/dist/index.cjs +2 -1
  94. package/dist/index.mjs +2 -1
  95. package/dist/math/index.cjs +2 -1
  96. package/dist/math/index.mjs +2 -1
  97. package/dist/opc/index.cjs +2 -1
  98. package/dist/opc/index.mjs +2 -1
  99. package/dist/visio/index.cjs +2 -1
  100. package/dist/visio/index.mjs +2 -1
  101. package/dist/visio/ui/contract.d.ts +33 -0
  102. package/dist/visio/ui/contract.d.ts.map +1 -0
  103. package/dist/visio/ui/demo-document.d.ts +4 -0
  104. package/dist/visio/ui/demo-document.d.ts.map +1 -0
  105. package/dist/visio/ui/diagnostics.d.ts +10 -0
  106. package/dist/visio/ui/diagnostics.d.ts.map +1 -0
  107. package/dist/visio/ui/document-history.d.ts +43 -0
  108. package/dist/visio/ui/document-history.d.ts.map +1 -0
  109. package/dist/visio/ui/document-text-search.d.ts +45 -0
  110. package/dist/visio/ui/document-text-search.d.ts.map +1 -0
  111. package/dist/visio/ui/edit-commands.d.ts +4 -0
  112. package/dist/visio/ui/edit-commands.d.ts.map +1 -0
  113. package/dist/visio/ui/edit-error.d.ts +5 -0
  114. package/dist/visio/ui/edit-error.d.ts.map +1 -0
  115. package/dist/visio/ui/foreign-vector-budget.d.ts +25 -0
  116. package/dist/visio/ui/foreign-vector-budget.d.ts.map +1 -0
  117. package/dist/visio/ui/index.cjs +1523 -0
  118. package/dist/visio/ui/index.d.ts +12 -0
  119. package/dist/visio/ui/index.d.ts.map +1 -0
  120. package/dist/visio/ui/index.mjs +1498 -0
  121. package/dist/visio/ui/scene-details.d.ts +8 -0
  122. package/dist/visio/ui/scene-details.d.ts.map +1 -0
  123. package/dist/visio/ui/scene-validation.d.ts +5 -0
  124. package/dist/visio/ui/scene-validation.d.ts.map +1 -0
  125. package/dist/visio/ui/snapshot-scene.d.ts +9 -0
  126. package/dist/visio/ui/snapshot-scene.d.ts.map +1 -0
  127. package/dist/xlsx/index.cjs +100 -98
  128. package/dist/xlsx/index.mjs +100 -98
  129. package/dist/xlsx/load/index.cjs +68 -66
  130. package/dist/xlsx/load/index.mjs +68 -66
  131. package/dist/xlsx/ui/backstage/templates.d.ts +16 -0
  132. package/dist/xlsx/ui/backstage/templates.d.ts.map +1 -0
  133. package/dist/xlsx/ui/commands/alignment.d.ts +4 -0
  134. package/dist/xlsx/ui/commands/alignment.d.ts.map +1 -0
  135. package/dist/xlsx/ui/commands/cells.d.ts +3 -0
  136. package/dist/xlsx/ui/commands/cells.d.ts.map +1 -0
  137. package/dist/xlsx/ui/commands/cf-presets.d.ts +15 -0
  138. package/dist/xlsx/ui/commands/cf-presets.d.ts.map +1 -0
  139. package/dist/xlsx/ui/commands/clipboard.d.ts +22 -0
  140. package/dist/xlsx/ui/commands/clipboard.d.ts.map +1 -0
  141. package/dist/xlsx/ui/commands/contextual.d.ts +13 -0
  142. package/dist/xlsx/ui/commands/contextual.d.ts.map +1 -0
  143. package/dist/xlsx/ui/commands/data.d.ts +3 -0
  144. package/dist/xlsx/ui/commands/data.d.ts.map +1 -0
  145. package/dist/xlsx/ui/commands/editing.d.ts +13 -0
  146. package/dist/xlsx/ui/commands/editing.d.ts.map +1 -0
  147. package/dist/xlsx/ui/commands/font.d.ts +21 -0
  148. package/dist/xlsx/ui/commands/font.d.ts.map +1 -0
  149. package/dist/xlsx/ui/commands/formulas.d.ts +15 -0
  150. package/dist/xlsx/ui/commands/formulas.d.ts.map +1 -0
  151. package/dist/xlsx/ui/commands/i18n/core-features.d.ts +3 -0
  152. package/dist/xlsx/ui/commands/i18n/core-features.d.ts.map +1 -0
  153. package/dist/xlsx/ui/commands/i18n/format-cells.d.ts +3 -0
  154. package/dist/xlsx/ui/commands/i18n/format-cells.d.ts.map +1 -0
  155. package/dist/xlsx/ui/commands/i18n/index.d.ts +4 -0
  156. package/dist/xlsx/ui/commands/i18n/index.d.ts.map +1 -0
  157. package/dist/xlsx/ui/commands/i18n/messages.d.ts +3 -0
  158. package/dist/xlsx/ui/commands/i18n/messages.d.ts.map +1 -0
  159. package/dist/xlsx/ui/commands/i18n/navigation.d.ts +3 -0
  160. package/dist/xlsx/ui/commands/i18n/navigation.d.ts.map +1 -0
  161. package/dist/xlsx/ui/commands/i18n/ribbon-home.d.ts +3 -0
  162. package/dist/xlsx/ui/commands/i18n/ribbon-home.d.ts.map +1 -0
  163. package/dist/xlsx/ui/commands/i18n/ribbon-tabs.d.ts +3 -0
  164. package/dist/xlsx/ui/commands/i18n/ribbon-tabs.d.ts.map +1 -0
  165. package/dist/xlsx/ui/commands/i18n/rules.d.ts +3 -0
  166. package/dist/xlsx/ui/commands/i18n/rules.d.ts.map +1 -0
  167. package/dist/xlsx/ui/commands/i18n/tools.d.ts +3 -0
  168. package/dist/xlsx/ui/commands/i18n/tools.d.ts.map +1 -0
  169. package/dist/xlsx/ui/commands/i18n/types.d.ts +5 -0
  170. package/dist/xlsx/ui/commands/i18n/types.d.ts.map +1 -0
  171. package/dist/xlsx/ui/commands/icons.d.ts +4 -0
  172. package/dist/xlsx/ui/commands/icons.d.ts.map +1 -0
  173. package/dist/xlsx/ui/commands/number.d.ts +11 -0
  174. package/dist/xlsx/ui/commands/number.d.ts.map +1 -0
  175. package/dist/xlsx/ui/commands/page-layout.d.ts +10 -0
  176. package/dist/xlsx/ui/commands/page-layout.d.ts.map +1 -0
  177. package/dist/xlsx/ui/commands/select-special.d.ts +12 -0
  178. package/dist/xlsx/ui/commands/select-special.d.ts.map +1 -0
  179. package/dist/xlsx/ui/commands/sort-filter.d.ts +3 -0
  180. package/dist/xlsx/ui/commands/sort-filter.d.ts.map +1 -0
  181. package/dist/xlsx/ui/commands/style-presets.d.ts +21 -0
  182. package/dist/xlsx/ui/commands/style-presets.d.ts.map +1 -0
  183. package/dist/xlsx/ui/commands/util.d.ts +59 -0
  184. package/dist/xlsx/ui/commands/util.d.ts.map +1 -0
  185. package/dist/xlsx/ui/commands.d.ts +36 -0
  186. package/dist/xlsx/ui/commands.d.ts.map +1 -0
  187. package/dist/xlsx/ui/context-menu/items.d.ts +36 -0
  188. package/dist/xlsx/ui/context-menu/items.d.ts.map +1 -0
  189. package/dist/xlsx/ui/context.d.ts +65 -0
  190. package/dist/xlsx/ui/context.d.ts.map +1 -0
  191. package/dist/xlsx/ui/dialogs/format-cells/number-categories.d.ts +28 -0
  192. package/dist/xlsx/ui/dialogs/format-cells/number-categories.d.ts.map +1 -0
  193. package/dist/xlsx/ui/dialogs/format-cells/types.d.ts +40 -0
  194. package/dist/xlsx/ui/dialogs/format-cells/types.d.ts.map +1 -0
  195. package/dist/xlsx/ui/dialogs/insert-chart-model.d.ts +9 -0
  196. package/dist/xlsx/ui/dialogs/insert-chart-model.d.ts.map +1 -0
  197. package/dist/xlsx/ui/dialogs.d.ts +9 -0
  198. package/dist/xlsx/ui/dialogs.d.ts.map +1 -0
  199. package/dist/xlsx/ui/dirty-state.d.ts +9 -0
  200. package/dist/xlsx/ui/dirty-state.d.ts.map +1 -0
  201. package/dist/xlsx/ui/formula-bar/name-resolve.d.ts +23 -0
  202. package/dist/xlsx/ui/formula-bar/name-resolve.d.ts.map +1 -0
  203. package/dist/xlsx/ui/grid/cell-items.d.ts +42 -0
  204. package/dist/xlsx/ui/grid/cell-items.d.ts.map +1 -0
  205. package/dist/xlsx/ui/grid/cell-paint.d.ts +26 -0
  206. package/dist/xlsx/ui/grid/cell-paint.d.ts.map +1 -0
  207. package/dist/xlsx/ui/grid/edit-bridge.d.ts +47 -0
  208. package/dist/xlsx/ui/grid/edit-bridge.d.ts.map +1 -0
  209. package/dist/xlsx/ui/grid/geometry.d.ts +76 -0
  210. package/dist/xlsx/ui/grid/geometry.d.ts.map +1 -0
  211. package/dist/xlsx/ui/grid/icon-sets.d.ts +3 -0
  212. package/dist/xlsx/ui/grid/icon-sets.d.ts.map +1 -0
  213. package/dist/xlsx/ui/grid/number-fit.d.ts +3 -0
  214. package/dist/xlsx/ui/grid/number-fit.d.ts.map +1 -0
  215. package/dist/xlsx/ui/grid/selection-ops.d.ts +32 -0
  216. package/dist/xlsx/ui/grid/selection-ops.d.ts.map +1 -0
  217. package/dist/xlsx/ui/grid/view-cache.d.ts +15 -0
  218. package/dist/xlsx/ui/grid/view-cache.d.ts.map +1 -0
  219. package/dist/xlsx/ui/index.cjs +28484 -0
  220. package/dist/xlsx/ui/index.d.ts +56 -0
  221. package/dist/xlsx/ui/index.d.ts.map +1 -0
  222. package/dist/xlsx/ui/index.mjs +28290 -0
  223. package/dist/xlsx/ui/locales/de/commands.d.ts +2 -0
  224. package/dist/xlsx/ui/locales/de/commands.d.ts.map +1 -0
  225. package/dist/xlsx/ui/locales/de/grid.d.ts +2 -0
  226. package/dist/xlsx/ui/locales/de/grid.d.ts.map +1 -0
  227. package/dist/xlsx/ui/locales/de/index.d.ts +2 -0
  228. package/dist/xlsx/ui/locales/de/index.d.ts.map +1 -0
  229. package/dist/xlsx/ui/locales/de/shell.d.ts +2 -0
  230. package/dist/xlsx/ui/locales/de/shell.d.ts.map +1 -0
  231. package/dist/xlsx/ui/locales/en/commands.d.ts +2 -0
  232. package/dist/xlsx/ui/locales/en/commands.d.ts.map +1 -0
  233. package/dist/xlsx/ui/locales/en/grid.d.ts +2 -0
  234. package/dist/xlsx/ui/locales/en/grid.d.ts.map +1 -0
  235. package/dist/xlsx/ui/locales/en/index.d.ts +2 -0
  236. package/dist/xlsx/ui/locales/en/index.d.ts.map +1 -0
  237. package/dist/xlsx/ui/locales/en/shell.d.ts +2 -0
  238. package/dist/xlsx/ui/locales/en/shell.d.ts.map +1 -0
  239. package/dist/xlsx/ui/locales/es/commands.d.ts +2 -0
  240. package/dist/xlsx/ui/locales/es/commands.d.ts.map +1 -0
  241. package/dist/xlsx/ui/locales/es/grid.d.ts +2 -0
  242. package/dist/xlsx/ui/locales/es/grid.d.ts.map +1 -0
  243. package/dist/xlsx/ui/locales/es/index.d.ts +2 -0
  244. package/dist/xlsx/ui/locales/es/index.d.ts.map +1 -0
  245. package/dist/xlsx/ui/locales/es/shell.d.ts +2 -0
  246. package/dist/xlsx/ui/locales/es/shell.d.ts.map +1 -0
  247. package/dist/xlsx/ui/locales/fr/commands.d.ts +2 -0
  248. package/dist/xlsx/ui/locales/fr/commands.d.ts.map +1 -0
  249. package/dist/xlsx/ui/locales/fr/grid.d.ts +2 -0
  250. package/dist/xlsx/ui/locales/fr/grid.d.ts.map +1 -0
  251. package/dist/xlsx/ui/locales/fr/index.d.ts +2 -0
  252. package/dist/xlsx/ui/locales/fr/index.d.ts.map +1 -0
  253. package/dist/xlsx/ui/locales/fr/shell.d.ts +2 -0
  254. package/dist/xlsx/ui/locales/fr/shell.d.ts.map +1 -0
  255. package/dist/xlsx/ui/locales/merge.d.ts +7 -0
  256. package/dist/xlsx/ui/locales/merge.d.ts.map +1 -0
  257. package/dist/xlsx/ui/locales/zh-CN/commands.d.ts +2 -0
  258. package/dist/xlsx/ui/locales/zh-CN/commands.d.ts.map +1 -0
  259. package/dist/xlsx/ui/locales/zh-CN/grid.d.ts +2 -0
  260. package/dist/xlsx/ui/locales/zh-CN/grid.d.ts.map +1 -0
  261. package/dist/xlsx/ui/locales/zh-CN/index.d.ts +2 -0
  262. package/dist/xlsx/ui/locales/zh-CN/index.d.ts.map +1 -0
  263. package/dist/xlsx/ui/locales/zh-CN/shell.d.ts +2 -0
  264. package/dist/xlsx/ui/locales/zh-CN/shell.d.ts.map +1 -0
  265. package/dist/xlsx/ui/localization.d.ts +23 -0
  266. package/dist/xlsx/ui/localization.d.ts.map +1 -0
  267. package/dist/xlsx/ui/ribbon/icon-paths.d.ts +9 -0
  268. package/dist/xlsx/ui/ribbon/icon-paths.d.ts.map +1 -0
  269. package/dist/xlsx/ui/ribbon/parts.d.ts +88 -0
  270. package/dist/xlsx/ui/ribbon/parts.d.ts.map +1 -0
  271. package/dist/xlsx/ui/ribbon/tab-api.d.ts +21 -0
  272. package/dist/xlsx/ui/ribbon/tab-api.d.ts.map +1 -0
  273. package/dist/xlsx/ui/ribbon/tabs/review-view.d.ts +5 -0
  274. package/dist/xlsx/ui/ribbon/tabs/review-view.d.ts.map +1 -0
  275. package/dist/xlsx/ui/ribbon/tabs/theme-palette.d.ts +8 -0
  276. package/dist/xlsx/ui/ribbon/tabs/theme-palette.d.ts.map +1 -0
  277. package/dist/xlsx/ui/ribbon/tell-me.d.ts +16 -0
  278. package/dist/xlsx/ui/ribbon/tell-me.d.ts.map +1 -0
  279. package/dist/xlsx/ui/selection.d.ts +34 -0
  280. package/dist/xlsx/ui/selection.d.ts.map +1 -0
  281. package/dist/xlsx/ui/theme/css-vars.d.ts +6 -0
  282. package/dist/xlsx/ui/theme/css-vars.d.ts.map +1 -0
  283. package/dist/xlsx/ui/theme/defaults.d.ts +6 -0
  284. package/dist/xlsx/ui/theme/defaults.d.ts.map +1 -0
  285. package/dist/xlsx/ui/theme/element.d.ts +9 -0
  286. package/dist/xlsx/ui/theme/element.d.ts.map +1 -0
  287. package/dist/xlsx/ui/theme/types.d.ts +54 -0
  288. package/dist/xlsx/ui/theme/types.d.ts.map +1 -0
  289. package/dist/xml/index.cjs +2 -1
  290. package/dist/xml/index.mjs +2 -1
  291. package/package.json +30 -3
@@ -0,0 +1,2380 @@
1
+ 'use strict';
2
+
3
+ var prosemirrorTransform = require('prosemirror-transform');
4
+ var prosemirrorCollab = require('prosemirror-collab');
5
+ var prosemirrorState = require('prosemirror-state');
6
+
7
+ // src/docx/ui/backstage-focus.ts
8
+ function backstageFocus(element) {
9
+ let opener = null;
10
+ const siblings = /* @__PURE__ */ new Map();
11
+ const active = () => element.getRootNode().activeElement;
12
+ return {
13
+ open() {
14
+ const current = active();
15
+ if (current instanceof HTMLElement && !element.contains(current)) opener = current;
16
+ for (const sibling of element.parentElement?.children ?? []) {
17
+ if (!(sibling instanceof HTMLElement) || sibling === element || siblings.has(sibling))
18
+ continue;
19
+ siblings.set(sibling, Boolean(sibling.inert));
20
+ sibling.inert = true;
21
+ }
22
+ },
23
+ close() {
24
+ for (const [sibling, wasInert] of siblings) sibling.inert = wasInert;
25
+ siblings.clear();
26
+ if (opener?.isConnected) opener.focus();
27
+ opener = null;
28
+ }
29
+ };
30
+ }
31
+
32
+ // src/docx/ui/break-note-schema.ts
33
+ var pageBreakNodeSpec = {
34
+ group: "inline",
35
+ inline: true,
36
+ atom: true,
37
+ selectable: true,
38
+ attrs: { kind: { default: "page" } },
39
+ leafText: () => "",
40
+ parseDOM: [
41
+ {
42
+ tag: "span[data-docx-break]",
43
+ getAttrs: (el) => ({
44
+ kind: el.dataset.docxBreak === "column" ? "column" : "page"
45
+ })
46
+ }
47
+ ],
48
+ toDOM: (node) => [
49
+ "span",
50
+ { class: "dve-break-marker", "data-docx-break": node.attrs.kind, contenteditable: "false" },
51
+ node.attrs.kind === "column" ? "Column Break" : "Page Break"
52
+ ]
53
+ };
54
+ var noteReferenceNodeSpec = {
55
+ group: "inline",
56
+ inline: true,
57
+ atom: true,
58
+ selectable: false,
59
+ attrs: {
60
+ kind: { default: "footnote" },
61
+ id: { default: "" },
62
+ number: { default: 1 },
63
+ /** The number as shown, in the document's footnote/endnote number format. */
64
+ label: { default: null },
65
+ /** The reference run's own formatting (e.g. superscript, FootnoteReference style) as JSON.
66
+ * Kept as an attribute, not marks, so text typed beside a reference doesn't inherit it. */
67
+ format: { default: null }
68
+ },
69
+ leafText: (node) => String(node.attrs.label ?? node.attrs.number),
70
+ parseDOM: [
71
+ {
72
+ tag: "sup[data-docx-note-kind]",
73
+ getAttrs: (el) => ({
74
+ kind: el.dataset.docxNoteKind === "endnote" ? "endnote" : "footnote",
75
+ id: el.dataset.docxNoteId || "",
76
+ number: Number(el.textContent) || 1
77
+ })
78
+ }
79
+ ],
80
+ toDOM: (node) => [
81
+ "sup",
82
+ {
83
+ class: "dve-note-reference",
84
+ "data-docx-note-kind": node.attrs.kind,
85
+ "data-docx-note-id": node.attrs.id,
86
+ contenteditable: "false"
87
+ },
88
+ String(node.attrs.label ?? node.attrs.number)
89
+ ]
90
+ };
91
+ var fieldMarkerNodeSpec = {
92
+ group: "inline",
93
+ inline: true,
94
+ atom: true,
95
+ selectable: false,
96
+ attrs: { kind: { default: "begin" }, code: { default: null }, format: { default: null } },
97
+ leafText: () => "",
98
+ parseDOM: [
99
+ {
100
+ tag: "span[data-field-marker]",
101
+ getAttrs: (el) => ({
102
+ kind: el.dataset.fieldMarker || "begin",
103
+ code: el.dataset.fieldCode ?? null
104
+ })
105
+ }
106
+ ],
107
+ toDOM: (node) => [
108
+ "span",
109
+ {
110
+ class: "dve-field-marker",
111
+ "data-field-marker": node.attrs.kind,
112
+ ...node.attrs.code != null ? { "data-field-code": node.attrs.code } : {},
113
+ contenteditable: "false"
114
+ }
115
+ ]
116
+ };
117
+
118
+ // src/docx/ui/defined.ts
119
+ function expectDefined(value, context) {
120
+ if (value === void 0 || value === null) throw new Error(`Expected ${context} to be present.`);
121
+ return value;
122
+ }
123
+
124
+ // src/collab/validation.ts
125
+ function isValidId(value, max = 160) {
126
+ return typeof value === "string" && value.length > 0 && value.length <= max;
127
+ }
128
+ function isNonNegativeSafeInteger(value) {
129
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
130
+ }
131
+
132
+ // src/collab/identity.ts
133
+ function clientKey(clientId) {
134
+ if (!isValidId(clientId)) throw new Error("Invalid collaboration client ID");
135
+ return Array.from(clientId, (character) => character.codePointAt(0).toString(16)).join("_");
136
+ }
137
+ function createIdGenerator(clientId, prefix = "cid") {
138
+ const key = clientKey(clientId);
139
+ let counter = 0;
140
+ return (kind) => {
141
+ const safeKind = kind.replace(/[^a-zA-Z0-9_-]/g, "").slice(0, 24) || "item";
142
+ return `${prefix}-${safeKind}-${key}-${++counter}`;
143
+ };
144
+ }
145
+
146
+ // src/collab/ordering.ts
147
+ function classifyVersion(messageVersion, currentVersion) {
148
+ if (!isNonNegativeSafeInteger(messageVersion) || !isNonNegativeSafeInteger(currentVersion))
149
+ return "invalid";
150
+ if (messageVersion < currentVersion) return "stale";
151
+ return messageVersion > currentVersion ? "out-of-order" : "apply";
152
+ }
153
+ var BoundedMap = class {
154
+ constructor(limit) {
155
+ this.limit = limit;
156
+ if (!Number.isSafeInteger(limit) || limit < 1) throw new Error("limit must be positive");
157
+ }
158
+ limit;
159
+ entries = /* @__PURE__ */ new Map();
160
+ get size() {
161
+ return this.entries.size;
162
+ }
163
+ get(key) {
164
+ return this.entries.get(key);
165
+ }
166
+ has(key) {
167
+ return this.entries.has(key);
168
+ }
169
+ set(key, value) {
170
+ this.entries.delete(key);
171
+ this.entries.set(key, value);
172
+ if (this.entries.size > this.limit) {
173
+ const oldest = this.entries.keys().next();
174
+ if (!oldest.done) this.entries.delete(oldest.value);
175
+ }
176
+ }
177
+ delete(key) {
178
+ return this.entries.delete(key);
179
+ }
180
+ clear() {
181
+ this.entries.clear();
182
+ }
183
+ };
184
+ var IdempotencyCache = class {
185
+ seen;
186
+ constructor(limit = 5e3) {
187
+ this.seen = new BoundedMap(limit);
188
+ }
189
+ check(clientId, messageId, fingerprint) {
190
+ const prior = this.seen.get(`${clientId}\0${messageId}`);
191
+ if (!prior) return { status: "fresh" };
192
+ return prior.fingerprint === fingerprint ? { status: "duplicate", value: prior.value } : { status: "reused" };
193
+ }
194
+ remember(clientId, messageId, fingerprint, value) {
195
+ this.seen.set(`${clientId}\0${messageId}`, { fingerprint, value });
196
+ }
197
+ };
198
+ function freezeDeep(value) {
199
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
200
+ for (const child of Object.values(value)) freezeDeep(child);
201
+ Object.freeze(value);
202
+ }
203
+ return value;
204
+ }
205
+ var freezeBatch = (batch) => freezeDeep(batch);
206
+ function parseBatch(value, schema) {
207
+ if (!value || typeof value !== "object" || Array.isArray(value)) return "Batch must be an object";
208
+ const input = value;
209
+ if (input.protocol !== 1) return "Unsupported collaboration protocol";
210
+ if (!isValidId(input.sessionId) || !isValidId(input.batchId) || !isValidId(input.clientId))
211
+ return "Session, batch, and client IDs must be non-empty strings";
212
+ if (!Number.isSafeInteger(input.version) || Number(input.version) < 0)
213
+ return "Version must be a non-negative safe integer";
214
+ if (!Array.isArray(input.steps) || input.steps.length < 1 || input.steps.length > 500)
215
+ return "Batch must contain between 1 and 500 steps";
216
+ let serialized;
217
+ try {
218
+ serialized = JSON.stringify(input.steps);
219
+ } catch {
220
+ return "Steps are not serializable";
221
+ }
222
+ if (serialized.length > 1e6) return "Step batch exceeds the 1 MB limit";
223
+ try {
224
+ const steps = input.steps.map((step) => prosemirrorTransform.Step.fromJSON(schema, step));
225
+ const batch = {
226
+ protocol: 1,
227
+ sessionId: input.sessionId,
228
+ batchId: input.batchId,
229
+ version: Number(input.version),
230
+ clientId: input.clientId,
231
+ steps: input.steps
232
+ };
233
+ return { batch, steps, fingerprint: JSON.stringify(batch) };
234
+ } catch (cause) {
235
+ return cause instanceof Error ? `Invalid step JSON: ${cause.message}` : "Invalid step JSON";
236
+ }
237
+ }
238
+
239
+ // src/docx/ui/collaboration-authority.ts
240
+ var MAX_CACHED_REQUESTS = 5e3;
241
+ function hasMirror(mapping) {
242
+ return typeof mapping.setMirror === "function";
243
+ }
244
+ function setMirror(transform, from, to) {
245
+ if (!hasMirror(transform.mapping))
246
+ throw new Error("prosemirror-transform Mapping.setMirror is unavailable.");
247
+ transform.mapping.setMirror(from, to);
248
+ }
249
+ var CollaborationAuthority = class {
250
+ sessionId;
251
+ schema;
252
+ stepHistoryLimit;
253
+ version;
254
+ documents = /* @__PURE__ */ new Map();
255
+ records = [];
256
+ requests = new IdempotencyCache(MAX_CACHED_REQUESTS);
257
+ constructor(config) {
258
+ if (!isValidId(config.sessionId)) throw new Error("Collaboration sessionId must be non-empty");
259
+ const version = config.version ?? 0;
260
+ if (!Number.isSafeInteger(version) || version < 0) throw new Error("Invalid starting version");
261
+ this.sessionId = config.sessionId;
262
+ this.schema = config.doc.type.schema;
263
+ this.version = version;
264
+ this.stepHistoryLimit = config.stepHistoryLimit ?? 2e3;
265
+ if (!Number.isSafeInteger(this.stepHistoryLimit) || this.stepHistoryLimit < 1)
266
+ throw new Error("stepHistoryLimit must be positive");
267
+ this.documents.set(version, config.doc);
268
+ }
269
+ get currentVersion() {
270
+ return this.version;
271
+ }
272
+ get doc() {
273
+ return this.documents.get(this.version);
274
+ }
275
+ submit(input) {
276
+ const parsed = parseBatch(input, this.schema);
277
+ if (typeof parsed === "string") return { status: "rejected", reason: parsed };
278
+ const { batch, steps, fingerprint } = parsed;
279
+ if (batch.sessionId !== this.sessionId) return { status: "rejected", reason: "wrong-session" };
280
+ const prior = this.requests.check(batch.clientId, batch.batchId, fingerprint);
281
+ if (prior.status === "duplicate") return { status: "duplicate", batch: prior.value };
282
+ if (prior.status === "reused") return { status: "rejected", reason: "batch-id-reused" };
283
+ if (classifyVersion(batch.version, this.version) === "out-of-order")
284
+ return { status: "rejected", reason: "out-of-order" };
285
+ const oldestVersion = this.records[0]?.version ?? this.version;
286
+ if (batch.version < oldestVersion || !this.documents.has(batch.version))
287
+ return { status: "rejected", reason: "stale" };
288
+ const baseDoc = this.documents.get(batch.version);
289
+ const committed = [];
290
+ let transform;
291
+ try {
292
+ const local = new prosemirrorTransform.Transform(baseDoc);
293
+ for (const step of steps) {
294
+ const result = local.maybeStep(step);
295
+ if (result.failed) return { status: "rejected", reason: `step-failed: ${result.failed}` };
296
+ }
297
+ transform = new prosemirrorTransform.Transform(local.doc);
298
+ for (let index = steps.length - 1; index >= 0; index--) {
299
+ const step = expectDefined(steps[index], "local step");
300
+ const result = transform.maybeStep(
301
+ step.invert(expectDefined(local.docs[index], "document before local step"))
302
+ );
303
+ if (result.failed) return { status: "rejected", reason: "could-not-rebase-local-steps" };
304
+ }
305
+ for (const record of this.records.filter((item) => item.version >= batch.version)) {
306
+ const result = transform.maybeStep(record.step);
307
+ if (result.failed) return { status: "rejected", reason: "authority-history-invalid" };
308
+ }
309
+ let mapFrom = steps.length;
310
+ for (const step of steps) {
311
+ const mapped = step.map(transform.mapping.slice(mapFrom));
312
+ mapFrom--;
313
+ if (!mapped) return { status: "rejected", reason: "rebase-conflict" };
314
+ const result = transform.maybeStep(mapped);
315
+ if (result.failed) return { status: "rejected", reason: "rebase-conflict" };
316
+ setMirror(transform, mapFrom, transform.steps.length - 1);
317
+ committed.push(mapped);
318
+ }
319
+ } catch (cause) {
320
+ return {
321
+ status: "rejected",
322
+ reason: cause instanceof Error ? `invalid-step: ${cause.message}` : "invalid-step"
323
+ };
324
+ }
325
+ const committedBatch = freezeBatch({
326
+ protocol: 1,
327
+ sessionId: this.sessionId,
328
+ batchId: batch.batchId,
329
+ version: this.version,
330
+ clientId: batch.clientId,
331
+ steps: committed.map((step) => step.toJSON())
332
+ });
333
+ const committedStart = transform.steps.length - committed.length;
334
+ for (const [index, step] of committed.entries()) {
335
+ this.records.push({ version: this.version, clientId: batch.clientId, step });
336
+ this.version++;
337
+ const doc = index === committed.length - 1 ? transform.doc : expectDefined(transform.docs[committedStart + index + 1], "committed document");
338
+ this.documents.set(this.version, doc);
339
+ }
340
+ this.requests.remember(batch.clientId, batch.batchId, fingerprint, committedBatch);
341
+ this.pruneHistory();
342
+ return { status: "accepted", batch: committedBatch };
343
+ }
344
+ pruneHistory() {
345
+ while (this.records.length > this.stepHistoryLimit) {
346
+ const removed = this.records.shift();
347
+ for (const version of this.documents.keys())
348
+ if (version <= removed.version) this.documents.delete(version);
349
+ }
350
+ }
351
+ };
352
+
353
+ // src/docx/ui/collaboration-identity.ts
354
+ function createCollaborationIdGenerator(clientId) {
355
+ return createIdGenerator(clientId, "dve");
356
+ }
357
+ function repairCollaborativeDocumentIds(state, clientId, idGenerator = createCollaborationIdGenerator(clientId)) {
358
+ const reserved = /* @__PURE__ */ new Set();
359
+ const seen = /* @__PURE__ */ new Set();
360
+ state.doc.descendants((node) => {
361
+ if ((node.type.name === "paragraph" || node.type.name === "table") && node.attrs.id)
362
+ reserved.add(String(node.attrs.id));
363
+ });
364
+ let transaction = state.tr;
365
+ state.doc.descendants((node, pos) => {
366
+ if (node.type.name !== "paragraph" && node.type.name !== "table") return;
367
+ const id = String(node.attrs.id || "");
368
+ if (id && !seen.has(id)) {
369
+ seen.add(id);
370
+ return;
371
+ }
372
+ let generated = "";
373
+ const kind = node.type.name === "table" ? "table" : "paragraph";
374
+ do
375
+ generated = idGenerator(kind);
376
+ while (reserved.has(generated));
377
+ reserved.add(generated);
378
+ seen.add(generated);
379
+ transaction = transaction.setNodeMarkup(pos, void 0, { ...node.attrs, id: generated });
380
+ });
381
+ return transaction.docChanged ? transaction : null;
382
+ }
383
+ var repairCollaborativeParagraphIds = repairCollaborativeDocumentIds;
384
+ var MAX_RECENT_BATCHES = 1e3;
385
+ function fromSendable(data, config, batchId) {
386
+ return freezeBatch({
387
+ protocol: 1,
388
+ sessionId: config.sessionId,
389
+ batchId,
390
+ version: data.version,
391
+ clientId: config.clientId,
392
+ steps: data.steps.map((step) => step.toJSON())
393
+ });
394
+ }
395
+ var CollaborationClient = class {
396
+ plugin;
397
+ sessionId;
398
+ clientId;
399
+ config;
400
+ sequence = 0;
401
+ pending;
402
+ received = new IdempotencyCache(MAX_RECENT_BATCHES);
403
+ constructor(config) {
404
+ if (!isValidId(config.sessionId) || !isValidId(config.clientId))
405
+ throw new Error("Collaboration sessionId and clientId must be non-empty strings");
406
+ const version = config.version ?? 0;
407
+ if (!Number.isSafeInteger(version) || version < 0) throw new Error("Invalid starting version");
408
+ this.config = { ...config, version };
409
+ this.sessionId = config.sessionId;
410
+ this.clientId = config.clientId;
411
+ this.plugin = prosemirrorCollab.collab({ clientID: config.clientId, version });
412
+ }
413
+ get hasPendingAck() {
414
+ return Boolean(this.pending);
415
+ }
416
+ pendingStepCount(state) {
417
+ return prosemirrorCollab.sendableSteps(state)?.steps.length ?? 0;
418
+ }
419
+ /** Returns the same envelope until acknowledged, so transport retries are idempotent. */
420
+ createPendingBatch(state) {
421
+ if (this.pending) return this.pending;
422
+ const sendable = prosemirrorCollab.sendableSteps(state);
423
+ if (!sendable) return null;
424
+ if (String(sendable.clientID) !== this.clientId)
425
+ throw new Error("EditorState uses a different collaboration client ID");
426
+ this.pending = fromSendable(sendable, this.config, String(++this.sequence));
427
+ return this.pending;
428
+ }
429
+ /** Converts one ordered authority batch into the transaction hosts should dispatch. */
430
+ receive(state, input) {
431
+ const parsed = parseBatch(input, state.schema);
432
+ if (typeof parsed === "string") return { status: "invalid", reason: parsed };
433
+ const { batch, steps, fingerprint } = parsed;
434
+ if (batch.sessionId !== this.sessionId) return { status: "wrong-session" };
435
+ const seen = this.received.check(batch.clientId, batch.batchId, fingerprint);
436
+ if (seen.status === "duplicate") return { status: "duplicate" };
437
+ if (seen.status === "reused") return { status: "invalid" };
438
+ const order = classifyVersion(batch.version, collaborationVersion(state));
439
+ if (order === "stale" || order === "out-of-order") return { status: order };
440
+ if (batch.clientId === this.clientId) {
441
+ const sendable = prosemirrorCollab.sendableSteps(state);
442
+ const acknowledged = JSON.stringify(steps.map((step) => step.toJSON()));
443
+ if (!this.pending || this.pending.batchId !== batch.batchId || !sendable || sendable.steps.length < steps.length || JSON.stringify(sendable.steps.slice(0, steps.length).map((step) => step.toJSON())) !== acknowledged)
444
+ return { status: "invalid", reason: "Unexpected or mismatched acknowledgement" };
445
+ }
446
+ let transaction;
447
+ try {
448
+ transaction = prosemirrorCollab.receiveTransaction(
449
+ state,
450
+ steps,
451
+ steps.map(() => batch.clientId),
452
+ { mapSelectionBackward: true }
453
+ );
454
+ } catch (cause) {
455
+ return {
456
+ status: "invalid",
457
+ reason: cause instanceof Error ? cause.message : "Could not apply collaboration steps"
458
+ };
459
+ }
460
+ this.received.remember(batch.clientId, batch.batchId, fingerprint, void 0);
461
+ if (batch.clientId === this.clientId && this.pending?.batchId === batch.batchId)
462
+ this.pending = void 0;
463
+ return { status: "applied", transaction };
464
+ }
465
+ };
466
+ function collaborationVersion(state) {
467
+ try {
468
+ return prosemirrorCollab.getVersion(state);
469
+ } catch {
470
+ throw new Error("EditorState is missing the collaboration plugin");
471
+ }
472
+ }
473
+
474
+ // src/docx/ui/dirty-state.ts
475
+ var DirtyState = class {
476
+ constructor(changed) {
477
+ this.changed = changed;
478
+ }
479
+ changed;
480
+ value = false;
481
+ get dirty() {
482
+ return this.value;
483
+ }
484
+ set(dirty) {
485
+ if (this.value === dirty) return;
486
+ this.value = dirty;
487
+ this.changed(dirty);
488
+ }
489
+ };
490
+ function markerKinds(doc) {
491
+ const kinds = [];
492
+ doc.descendants((node) => {
493
+ if (node.type.name === "fieldMarker") kinds.push(String(node.attrs.kind));
494
+ });
495
+ return kinds;
496
+ }
497
+ function fieldsBalanced(doc) {
498
+ const stack = [];
499
+ for (const kind of markerKinds(doc)) {
500
+ if (kind === "begin") stack.push("code");
501
+ else if (kind === "code") {
502
+ if (stack.at(-1) !== "code") return false;
503
+ } else if (kind === "separate") {
504
+ if (stack.at(-1) !== "code") return false;
505
+ stack[stack.length - 1] = "result";
506
+ } else if (kind === "end") {
507
+ if (!stack.length) return false;
508
+ stack.pop();
509
+ }
510
+ }
511
+ return stack.length === 0;
512
+ }
513
+ function fieldGuardPlugin() {
514
+ return new prosemirrorState.Plugin({
515
+ props: {
516
+ handleTextInput: (view, from, to, text) => {
517
+ const transaction = replaceAroundMarkers(view.state, from, to, text);
518
+ if (transaction) view.dispatch(transaction);
519
+ return Boolean(transaction);
520
+ },
521
+ handleKeyDown: (view, event) => {
522
+ if (event.key !== "Backspace" && event.key !== "Delete") return false;
523
+ const transaction = deleteAroundMarkers(view.state, event.key === "Backspace");
524
+ if (transaction) view.dispatch(transaction);
525
+ return Boolean(transaction);
526
+ }
527
+ },
528
+ appendTransaction: (transactions, _old, state) => transactions.some((transaction) => transaction.docChanged) ? markFieldResults(state) : transactions.some((transaction) => transaction.selectionSet) ? trimSelection(state) : null,
529
+ filterTransaction(transaction, state) {
530
+ if (!transaction.docChanged) return true;
531
+ let hadMarkers = false;
532
+ state.doc.descendants((node) => {
533
+ if (node.type.name === "fieldMarker") hadMarkers = true;
534
+ return !hadMarkers;
535
+ });
536
+ if (!hadMarkers || !fieldsBalanced(state.doc)) return true;
537
+ return fieldsBalanced(transaction.doc);
538
+ }
539
+ });
540
+ }
541
+ function markFieldResults(state) {
542
+ const fieldMark = state.schema.marks.field;
543
+ if (!fieldMark) return null;
544
+ const stack = [];
545
+ const missing = [];
546
+ state.doc.descendants((node, pos) => {
547
+ if (node.type.name === "fieldMarker") {
548
+ const kind = node.attrs.kind;
549
+ if (kind === "begin") stack.push({ code: "", inResult: false });
550
+ else if (kind === "code" && stack.length) {
551
+ const open = stack[stack.length - 1];
552
+ if (open) open.code += node.attrs.code ?? "";
553
+ } else if (kind === "separate" && stack.length) {
554
+ const open = stack[stack.length - 1];
555
+ if (open) open.inResult = true;
556
+ } else if (kind === "end") stack.pop();
557
+ return false;
558
+ }
559
+ const top = stack.at(-1);
560
+ if (node.isText && top?.inResult && !fieldMark.isInSet(node.marks))
561
+ missing.push({ from: pos, to: pos + node.nodeSize, instr: top.code.trim() });
562
+ return true;
563
+ });
564
+ if (!missing.length) return null;
565
+ const transaction = state.tr;
566
+ for (const { from, to, instr } of missing)
567
+ transaction.addMark(from, to, fieldMark.create({ instr, simple: false }));
568
+ return transaction;
569
+ }
570
+ var isMarker = (node) => node?.type.name === "fieldMarker";
571
+ function trimSelection(state) {
572
+ const { selection, doc } = state;
573
+ if (!(selection instanceof prosemirrorState.TextSelection) || selection.empty) return null;
574
+ let { from, to } = selection;
575
+ while (from < to && isMarker(doc.resolve(from).nodeAfter)) from++;
576
+ while (to > from && isMarker(doc.resolve(to).nodeBefore)) to--;
577
+ if (from === selection.from && to === selection.to) return null;
578
+ const reversed = selection.anchor > selection.head;
579
+ return state.tr.setSelection(
580
+ prosemirrorState.TextSelection.create(doc, reversed ? to : from, reversed ? from : to)
581
+ );
582
+ }
583
+ function markersIn(doc, from, to) {
584
+ const markers = [];
585
+ doc.nodesBetween(from, to, (node, pos) => {
586
+ if (isMarker(node) && pos >= from && pos + node.nodeSize <= to)
587
+ markers.push({ pos, size: node.nodeSize });
588
+ });
589
+ return markers;
590
+ }
591
+ function replaceAroundMarkers(state, from, to, text) {
592
+ if (from === to) return null;
593
+ const markers = markersIn(state.doc, from, to);
594
+ if (!markers.length) return null;
595
+ const whole = state.tr.delete(from, to);
596
+ if (fieldsBalanced(whole.doc) || !fieldsBalanced(state.doc)) return null;
597
+ const marks = state.doc.resolve(from).marksAcross(state.doc.resolve(to)) ?? [];
598
+ const transaction = state.tr;
599
+ let end = to;
600
+ for (const marker of [...markers].reverse()) {
601
+ const after = marker.pos + marker.size;
602
+ if (after < end) transaction.delete(after, end);
603
+ end = marker.pos;
604
+ }
605
+ if (from < end) transaction.delete(from, end);
606
+ if (text) transaction.insert(from, state.schema.text(text, marks));
607
+ return transaction.setSelection(prosemirrorState.TextSelection.create(transaction.doc, from + text.length));
608
+ }
609
+ function deleteAroundMarkers(state, backward) {
610
+ const { selection, doc } = state;
611
+ if (!(selection instanceof prosemirrorState.TextSelection)) return null;
612
+ if (!selection.empty) return replaceAroundMarkers(state, selection.from, selection.to, "");
613
+ let pos = selection.from;
614
+ const step = () => backward ? doc.resolve(pos).nodeBefore : doc.resolve(pos).nodeAfter;
615
+ if (!isMarker(step())) return null;
616
+ while (isMarker(step())) pos += backward ? -doc.resolve(pos).nodeBefore.nodeSize : 1;
617
+ const neighbor = step();
618
+ if (!neighbor?.isText) return state.tr.setSelection(prosemirrorState.TextSelection.create(doc, pos));
619
+ const transaction = backward ? state.tr.delete(pos - 1, pos) : state.tr.delete(pos, pos + 1);
620
+ const caret = backward ? pos - 1 : pos;
621
+ return transaction.setSelection(prosemirrorState.TextSelection.create(transaction.doc, caret));
622
+ }
623
+
624
+ // src/docx/ligatures.ts
625
+ var LIGATURE_VALUES = [
626
+ "none",
627
+ "standard",
628
+ "contextual",
629
+ "historical",
630
+ "discretional",
631
+ "standardContextual",
632
+ "standardHistorical",
633
+ "contextualHistorical",
634
+ "standardDiscretional",
635
+ "contextualDiscretional",
636
+ "historicalDiscretional",
637
+ "standardContextualHistorical",
638
+ "standardContextualDiscretional",
639
+ "standardHistoricalDiscretional",
640
+ "contextualHistoricalDiscretional",
641
+ "all"
642
+ ];
643
+ var isLigatures = (value) => typeof value === "string" && LIGATURE_VALUES.includes(value);
644
+
645
+ // src/docx/paragraph-styles.ts
646
+ function resolveStyleNumbering(styleId, catalog) {
647
+ const chain = [];
648
+ const visited = /* @__PURE__ */ new Set();
649
+ let current = styleId;
650
+ while (current && !visited.has(current)) {
651
+ visited.add(current);
652
+ const style = catalog.styles[current];
653
+ if (!style) break;
654
+ chain.push(style);
655
+ current = style.basedOn;
656
+ }
657
+ return chain.find((style) => style.numbering)?.numbering;
658
+ }
659
+
660
+ // src/docx/highlight.ts
661
+ var WORD_HIGHLIGHT_TOKENS = [
662
+ "black",
663
+ "blue",
664
+ "cyan",
665
+ "green",
666
+ "magenta",
667
+ "red",
668
+ "yellow",
669
+ "white",
670
+ "darkBlue",
671
+ "darkCyan",
672
+ "darkGreen",
673
+ "darkMagenta",
674
+ "darkRed",
675
+ "darkYellow",
676
+ "darkGray",
677
+ "lightGray",
678
+ "none"
679
+ ];
680
+ function isWordHighlightToken(value) {
681
+ return WORD_HIGHLIGHT_TOKENS.includes(value);
682
+ }
683
+
684
+ // src/docx/resolve-table.ts
685
+ function styleChain(styleId, catalog) {
686
+ if (!styleId || !catalog) return [];
687
+ const chain = [];
688
+ const visited = /* @__PURE__ */ new Set();
689
+ let current = styleId;
690
+ while (current && !visited.has(current)) {
691
+ const style = catalog.styles[current];
692
+ if (!style) break;
693
+ visited.add(current);
694
+ chain.push(style);
695
+ current = style.basedOn;
696
+ }
697
+ return chain.reverse();
698
+ }
699
+ function applicableRegions(look, rowIndex, rowCount, colIndex, colCount) {
700
+ const regions = ["wholeTable"];
701
+ if (!look?.noVBand) regions.push(colIndex % 2 === 0 ? "band1Vert" : "band2Vert");
702
+ if (!look?.noHBand) regions.push(rowIndex % 2 === 0 ? "band1Horz" : "band2Horz");
703
+ if (look?.lastColumn && colIndex === colCount - 1) regions.push("lastCol");
704
+ if (look?.firstColumn && colIndex === 0) regions.push("firstCol");
705
+ if (look?.lastRow && rowIndex === rowCount - 1) regions.push("lastRow");
706
+ if (look?.firstRow && rowIndex === 0) regions.push("firstRow");
707
+ return regions;
708
+ }
709
+ function resolveTableStyleFormatting(tableStyleId, catalog, look, rowIndex, rowCount, colIndex, colCount) {
710
+ const chain = styleChain(tableStyleId, catalog);
711
+ const regions = applicableRegions(look, rowIndex, rowCount, colIndex, colCount);
712
+ const result = {};
713
+ for (const style of chain) {
714
+ if (style.borders) result.borders = { ...result.borders, ...style.borders };
715
+ if (style.shadingFill) result.shadingFill = style.shadingFill;
716
+ for (const region of regions) {
717
+ const formatting = style.conditional[region];
718
+ if (!formatting) continue;
719
+ if (formatting.borders) result.borders = { ...result.borders, ...formatting.borders };
720
+ if (formatting.shadingFill) result.shadingFill = formatting.shadingFill;
721
+ if (formatting.shadingThemeFill) result.shadingThemeFill = formatting.shadingThemeFill;
722
+ if (formatting.run) result.run = { ...result.run, ...formatting.run };
723
+ }
724
+ }
725
+ return result;
726
+ }
727
+
728
+ // src/color/color-primitives.ts
729
+ function clampUnitInterval(value) {
730
+ return Math.min(1, Math.max(0, value));
731
+ }
732
+ function hexToRgbChannels(color) {
733
+ const normalized = color.replace("#", "");
734
+ if (!/^[0-9a-fA-F]{6}$/.test(normalized)) {
735
+ return null;
736
+ }
737
+ return {
738
+ r: Number.parseInt(normalized.slice(0, 2), 16),
739
+ g: Number.parseInt(normalized.slice(2, 4), 16),
740
+ b: Number.parseInt(normalized.slice(4, 6), 16)
741
+ };
742
+ }
743
+ function percentDivisorFor(text) {
744
+ return text.endsWith("%") ? 100 : 1e5;
745
+ }
746
+ function parseOoxmlPercent(value) {
747
+ const text = String(value ?? "").trim();
748
+ const divisor = percentDivisorFor(text);
749
+ const magnitude = Number.parseFloat(divisor === 100 ? text.slice(0, -1) : text);
750
+ if (!Number.isFinite(magnitude)) {
751
+ return void 0;
752
+ }
753
+ return magnitude / divisor;
754
+ }
755
+ function parseDrawingPercent(value) {
756
+ const parsed = parseOoxmlPercent(value);
757
+ return parsed === void 0 ? void 0 : clampUnitInterval(parsed);
758
+ }
759
+ function scrgbLinearToSrgb8(linear) {
760
+ const l = Math.min(1, Math.max(0, linear));
761
+ const companded = l <= 31308e-7 ? 12.92 * l : 1.055 * l ** (1 / 2.4) - 0.055;
762
+ return Math.min(255, Math.max(0, Math.round(companded * 255)));
763
+ }
764
+ function toHex(value) {
765
+ return Math.min(255, Math.max(0, Math.round(value))).toString(16).padStart(2, "0").toUpperCase();
766
+ }
767
+ function rgbToHsl(r, g, b) {
768
+ const rN = r / 255;
769
+ const gN = g / 255;
770
+ const bN = b / 255;
771
+ const cMax = Math.max(rN, gN, bN);
772
+ const cMin = Math.min(rN, gN, bN);
773
+ const delta = cMax - cMin;
774
+ const l = (cMax + cMin) / 2;
775
+ let s = 0;
776
+ if (delta !== 0) {
777
+ s = delta / (1 - Math.abs(2 * l - 1));
778
+ }
779
+ let h = 0;
780
+ if (delta !== 0) {
781
+ if (cMax === rN) {
782
+ h = 60 * ((gN - bN) / delta % 6);
783
+ } else if (cMax === gN) {
784
+ h = 60 * ((bN - rN) / delta + 2);
785
+ } else {
786
+ h = 60 * ((rN - gN) / delta + 4);
787
+ }
788
+ }
789
+ if (h < 0) {
790
+ h += 360;
791
+ }
792
+ return { h, s: clampUnitInterval(s), l: clampUnitInterval(l) };
793
+ }
794
+ function hslToRgb(h, s, l) {
795
+ const sC = clampUnitInterval(s);
796
+ const lC = clampUnitInterval(l);
797
+ const hN = (h % 360 + 360) % 360;
798
+ const c = (1 - Math.abs(2 * lC - 1)) * sC;
799
+ const x = c * (1 - Math.abs(hN / 60 % 2 - 1));
800
+ const m = lC - c / 2;
801
+ let rP = 0;
802
+ let gP = 0;
803
+ let bP = 0;
804
+ if (hN < 60) {
805
+ rP = c;
806
+ gP = x;
807
+ bP = 0;
808
+ } else if (hN < 120) {
809
+ rP = x;
810
+ gP = c;
811
+ bP = 0;
812
+ } else if (hN < 180) {
813
+ rP = 0;
814
+ gP = c;
815
+ bP = x;
816
+ } else if (hN < 240) {
817
+ rP = 0;
818
+ gP = x;
819
+ bP = c;
820
+ } else if (hN < 300) {
821
+ rP = x;
822
+ gP = 0;
823
+ bP = c;
824
+ } else {
825
+ rP = c;
826
+ gP = 0;
827
+ bP = x;
828
+ }
829
+ return {
830
+ r: Math.round((rP + m) * 255),
831
+ g: Math.round((gP + m) * 255),
832
+ b: Math.round((bP + m) * 255)
833
+ };
834
+ }
835
+ function parseDrawingFraction(value) {
836
+ return parseOoxmlPercent(value);
837
+ }
838
+ function parseDrawingHueDegrees(value) {
839
+ const parsed = Number.parseFloat(String(value ?? "").trim());
840
+ if (!Number.isFinite(parsed)) {
841
+ return void 0;
842
+ }
843
+ return parsed / 6e4;
844
+ }
845
+
846
+ // src/color/color-linear.ts
847
+ function srgb255ToLinear(channel) {
848
+ const c = clampUnitInterval(channel / 255);
849
+ return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
850
+ }
851
+ function linearToSrgb255(linear) {
852
+ const c = clampUnitInterval(linear);
853
+ return 255 * (c <= 31308e-7 ? c * 12.92 : 1.055 * c ** (1 / 2.4) - 0.055);
854
+ }
855
+
856
+ // src/diagram/drawing-color.ts
857
+ var PRESET_COLORS = {
858
+ black: "#000000",
859
+ white: "#FFFFFF",
860
+ red: "#FF0000",
861
+ green: "#008000",
862
+ blue: "#0000FF",
863
+ yellow: "#FFFF00",
864
+ gray: "#808080",
865
+ grey: "#808080"
866
+ };
867
+ function baseHex(color, theme) {
868
+ switch (color.kind) {
869
+ case "srgb":
870
+ return /^[0-9a-f]{6}$/i.test(color.value) ? `#${color.value.toUpperCase()}` : void 0;
871
+ case "scheme":
872
+ return theme?.scheme(color.value);
873
+ case "system":
874
+ return color.fallback && /^[0-9a-f]{6}$/i.test(color.fallback) ? `#${color.fallback.toUpperCase()}` : void 0;
875
+ case "preset":
876
+ return PRESET_COLORS[color.value];
877
+ case "scrgb": {
878
+ const [r, g, b] = color.value.split(",").map((part) => parseDrawingFraction(part));
879
+ if (r === void 0 || g === void 0 || b === void 0) return void 0;
880
+ return `#${toHex(scrgbLinearToSrgb8(r))}${toHex(scrgbLinearToSrgb8(g))}${toHex(scrgbLinearToSrgb8(b))}`;
881
+ }
882
+ case "hsl": {
883
+ const [h, s, l] = color.value.split(",");
884
+ const hue = parseDrawingHueDegrees(h);
885
+ const sat = parseDrawingFraction(s);
886
+ const lum = parseDrawingFraction(l);
887
+ if (hue === void 0 || sat === void 0 || lum === void 0) return void 0;
888
+ const { r, g, b } = hslToRgb(hue, sat, lum);
889
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
890
+ }
891
+ }
892
+ }
893
+ var APPLIED = /* @__PURE__ */ new Set([
894
+ "alpha",
895
+ "alphaMod",
896
+ "alphaOff",
897
+ "comp",
898
+ "inv",
899
+ "gray",
900
+ "shade",
901
+ "tint",
902
+ "hue",
903
+ "hueMod",
904
+ "hueOff",
905
+ "sat",
906
+ "satMod",
907
+ "satOff",
908
+ "lum",
909
+ "lumMod",
910
+ "lumOff"
911
+ ]);
912
+ function resolveDrawingColor(color, theme) {
913
+ const base = baseHex(color, theme);
914
+ const rgb = base ? hexToRgbChannels(base) : null;
915
+ if (!rgb) return void 0;
916
+ let { r, g, b } = rgb;
917
+ const find = (name) => color.transforms.find((entry) => entry.name === name)?.value;
918
+ const has = (name) => color.transforms.some((entry) => entry.name === name);
919
+ if (has("comp")) {
920
+ const hsl = rgbToHsl(r, g, b);
921
+ ({ r, g, b } = hslToRgb((hsl.h + 180) % 360, hsl.s, hsl.l));
922
+ }
923
+ if (has("inv")) [r, g, b] = [255 - r, 255 - g, 255 - b];
924
+ if (has("gray")) r = g = b = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
925
+ const shade = parseDrawingPercent(find("shade"));
926
+ if (shade !== void 0) {
927
+ r = linearToSrgb255(srgb255ToLinear(r) * shade);
928
+ g = linearToSrgb255(srgb255ToLinear(g) * shade);
929
+ b = linearToSrgb255(srgb255ToLinear(b) * shade);
930
+ }
931
+ const tint = parseDrawingPercent(find("tint"));
932
+ if (tint !== void 0) {
933
+ r = linearToSrgb255(1 - (1 - srgb255ToLinear(r)) * tint);
934
+ g = linearToSrgb255(1 - (1 - srgb255ToLinear(g)) * tint);
935
+ b = linearToSrgb255(1 - (1 - srgb255ToLinear(b)) * tint);
936
+ }
937
+ if (["hue", "hueMod", "hueOff", "sat", "satMod", "satOff", "lum", "lumMod", "lumOff"].some(has)) {
938
+ const hsl = rgbToHsl(r, g, b);
939
+ const wrap = (degrees) => (degrees % 360 + 360) % 360;
940
+ const hueAbs = parseDrawingHueDegrees(find("hue"));
941
+ if (hueAbs !== void 0) hsl.h = wrap(hueAbs);
942
+ const hueMod = parseDrawingFraction(find("hueMod"));
943
+ if (hueMod !== void 0) hsl.h = wrap(hsl.h * hueMod);
944
+ const hueOff = parseDrawingHueDegrees(find("hueOff"));
945
+ if (hueOff !== void 0) hsl.h = wrap(hsl.h + hueOff);
946
+ const satAbs = parseDrawingFraction(find("sat"));
947
+ if (satAbs !== void 0) hsl.s = clampUnitInterval(satAbs);
948
+ const satMod = parseDrawingFraction(find("satMod"));
949
+ if (satMod !== void 0) hsl.s = clampUnitInterval(hsl.s * satMod);
950
+ const satOff = parseDrawingFraction(find("satOff"));
951
+ if (satOff !== void 0) hsl.s = clampUnitInterval(hsl.s + satOff);
952
+ const lumAbs = parseDrawingFraction(find("lum"));
953
+ if (lumAbs !== void 0) hsl.l = clampUnitInterval(lumAbs);
954
+ const lumMod = parseDrawingFraction(find("lumMod"));
955
+ if (lumMod !== void 0) hsl.l = clampUnitInterval(hsl.l * lumMod);
956
+ const lumOff = parseDrawingFraction(find("lumOff"));
957
+ if (lumOff !== void 0) hsl.l = clampUnitInterval(hsl.l + lumOff);
958
+ ({ r, g, b } = hslToRgb(hsl.h, hsl.s, hsl.l));
959
+ }
960
+ let alpha = parseDrawingPercent(find("alpha")) ?? 1;
961
+ const alphaMod = parseDrawingFraction(find("alphaMod"));
962
+ if (alphaMod !== void 0) alpha = clampUnitInterval(alpha * alphaMod);
963
+ const alphaOff = parseDrawingFraction(find("alphaOff"));
964
+ if (alphaOff !== void 0) alpha = clampUnitInterval(alpha + alphaOff);
965
+ return {
966
+ hex: `#${toHex(r)}${toHex(g)}${toHex(b)}`,
967
+ alpha,
968
+ unapplied: [...new Set(color.transforms.map((entry) => entry.name))].filter(
969
+ (name) => !APPLIED.has(name)
970
+ )
971
+ };
972
+ }
973
+
974
+ // src/docx/numbering-parse.ts
975
+ function resolveNumberingLevel(catalog, numId, level) {
976
+ const num = catalog.nums[numId];
977
+ if (!num) return void 0;
978
+ const override = num.levelOverrides?.[level];
979
+ const base = override?.lvl ?? catalog.abstractNums[num.abstractNumId]?.levels[level];
980
+ if (!base) return void 0;
981
+ return override?.startOverride !== void 0 ? { ...base, start: override.startOverride } : base;
982
+ }
983
+
984
+ // src/docx/diagram-theme.ts
985
+ var DEFAULT_MAPPING = {
986
+ bg1: "lt1",
987
+ tx1: "dk1",
988
+ bg2: "lt2",
989
+ tx2: "dk2"
990
+ };
991
+ var SLOTS = /* @__PURE__ */ new Set([
992
+ "dk1",
993
+ "lt1",
994
+ "dk2",
995
+ "lt2",
996
+ "accent1",
997
+ "accent2",
998
+ "accent3",
999
+ "accent4",
1000
+ "accent5",
1001
+ "accent6",
1002
+ "hlink",
1003
+ "folHlink"
1004
+ ]);
1005
+ function diagramColorTheme(theme) {
1006
+ return {
1007
+ scheme(name) {
1008
+ if (!theme) return void 0;
1009
+ const mapped = name in DEFAULT_MAPPING ? theme.colorMapping[name] ?? DEFAULT_MAPPING[name] : SLOTS.has(name) ? name : void 0;
1010
+ const hex = mapped ? theme.colors[mapped] : void 0;
1011
+ return hex ? `#${hex.replace(/^#/, "").toUpperCase()}` : void 0;
1012
+ }
1013
+ };
1014
+ }
1015
+ function resolveDiagramColor(color, theme) {
1016
+ return resolveDrawingColor(color, diagramColorTheme(theme));
1017
+ }
1018
+
1019
+ // src/docx/numbering-format.ts
1020
+ function resolveParagraphNumbering(paragraph, styleCatalog, numberingCatalog) {
1021
+ if (paragraph.numbering)
1022
+ return paragraph.numbering.numId > 0 ? paragraph.numbering : void 0;
1023
+ if (!styleCatalog) return void 0;
1024
+ const inherited = resolveStyleNumbering(paragraph.style, styleCatalog);
1025
+ if (!inherited || inherited.numId <= 0) return void 0;
1026
+ if (numberingCatalog && paragraph.style && styleCatalog.styles[paragraph.style]) {
1027
+ for (let level = 0; level < 9; level++) {
1028
+ const definition = resolveNumberingLevel(numberingCatalog, String(inherited.numId), level);
1029
+ if (definition?.paragraphStyleId === paragraph.style)
1030
+ return { numId: inherited.numId, level };
1031
+ }
1032
+ }
1033
+ return inherited;
1034
+ }
1035
+
1036
+ // src/docx/table-visuals.ts
1037
+ var NONE = { style: "none" };
1038
+ function edgeFrom(borders, side, onBoundary) {
1039
+ if (!borders) return void 0;
1040
+ if (onBoundary) return borders[side];
1041
+ return side === "top" || side === "bottom" ? borders.insideH : borders.insideV;
1042
+ }
1043
+ function resolveCellVisuals(table, cell, placement, styles) {
1044
+ const styled = table.style ? resolveTableStyleFormatting(
1045
+ table.style,
1046
+ styles,
1047
+ table.look,
1048
+ placement.row,
1049
+ placement.rowCount,
1050
+ placement.column,
1051
+ placement.columnCount
1052
+ ) : {};
1053
+ const hasBorderInfo = Boolean(styled.borders || table.borders || cell.borders);
1054
+ const shadingFill = cell.shadingFill ?? styled.shadingFill;
1055
+ if (!hasBorderInfo) return shadingFill ? { shadingFill } : {};
1056
+ const boundary = {
1057
+ top: placement.row === 0,
1058
+ bottom: placement.lastRow === placement.rowCount - 1,
1059
+ left: placement.column === 0,
1060
+ right: placement.lastColumn === placement.columnCount - 1
1061
+ };
1062
+ const borders = {};
1063
+ for (const side of ["top", "bottom", "left", "right"])
1064
+ borders[side] = cell.borders?.[side] ?? edgeFrom(table.borders, side, boundary[side]) ?? edgeFrom(styled.borders, side, boundary[side]) ?? NONE;
1065
+ return { borders, ...shadingFill ? { shadingFill } : {} };
1066
+ }
1067
+
1068
+ // src/docx/section-layout.ts
1069
+ function sectionLayoutJson(sections) {
1070
+ return JSON.stringify(
1071
+ sections.map(({ headers: _headers, footers: _footers, ...layout }) => layout)
1072
+ );
1073
+ }
1074
+ function sectionsFromLayout(json, prior, blocks) {
1075
+ const layout = JSON.parse(json);
1076
+ const order = new Map(blocks.map((block, index) => [block.id, index]));
1077
+ const priorSections = prior ?? [];
1078
+ const endOf = (section, index, list) => index === list.length - 1 ? Number.POSITIVE_INFINITY : order.get(section.endsAtBlockId) ?? -1;
1079
+ const kept = layout.filter(
1080
+ (section, index) => index === layout.length - 1 || order.has(section.endsAtBlockId)
1081
+ );
1082
+ return kept.map((section, index) => {
1083
+ const end = endOf(section, index, kept);
1084
+ const source = priorSections.find((candidate) => candidate.endsAtBlockId === section.endsAtBlockId) ?? priorSections.find(
1085
+ (candidate, position) => endOf(candidate, position, priorSections) >= end
1086
+ ) ?? priorSections.at(-1);
1087
+ return {
1088
+ ...section,
1089
+ ...source?.headers ? { headers: source.headers } : {},
1090
+ ...source?.footers ? { footers: source.footers } : {}
1091
+ };
1092
+ });
1093
+ }
1094
+ var SectionPartsStep = class _SectionPartsStep extends prosemirrorTransform.DocAttrStep {
1095
+ constructor(value) {
1096
+ super("sectionParts", value);
1097
+ }
1098
+ getMap() {
1099
+ return new prosemirrorTransform.StepMap([0, 0, 0]);
1100
+ }
1101
+ invert(doc) {
1102
+ return new _SectionPartsStep(doc.attrs.sectionParts);
1103
+ }
1104
+ };
1105
+ function sectionPartsJson(sections) {
1106
+ return JSON.stringify(
1107
+ (sections ?? []).map(({ endsAtBlockId, headers, footers }) => ({
1108
+ endsAtBlockId,
1109
+ ...headers ? { headers } : {},
1110
+ ...footers ? { footers } : {}
1111
+ }))
1112
+ );
1113
+ }
1114
+ function restoreSectionParts(layout, json, blocks) {
1115
+ const parts = JSON.parse(json);
1116
+ const base = layout.at(-1);
1117
+ if (!base) return layout;
1118
+ const sources = parts.map((part, i) => {
1119
+ const { headers: _headers, footers: _footers, ...geometry } = layout[i] ?? base;
1120
+ return { ...geometry, ...part };
1121
+ });
1122
+ return sectionsFromLayout(sectionLayoutJson(layout), sources, blocks);
1123
+ }
1124
+ var HEADER_FOOTER_INPUT = "header-footer-input";
1125
+
1126
+ // src/docx/ui/inline-content-schema.ts
1127
+ var safeAttrValue = (value) => String(value ?? "").replace(/[;{}"]/g, "");
1128
+ function placementClass(value) {
1129
+ if (typeof value !== "string") return "";
1130
+ let placement;
1131
+ try {
1132
+ placement = JSON.parse(value);
1133
+ } catch {
1134
+ return "";
1135
+ }
1136
+ const side = placement.align === "right" || placement.align === "outside" ? "right" : placement.align === "center" ? "center" : placement.align ? "left" : (placement.offsetXPx ?? 0) > 312 ? "right" : "left";
1137
+ if (placement.wrap === "topAndBottom") return `dve-float-block dve-float-block-${side}`;
1138
+ if (placement.wrap === "square" || placement.wrap === "tight" || placement.wrap === "through")
1139
+ return side === "center" ? "dve-float-block dve-float-block-center" : `dve-float-${side}`;
1140
+ return "";
1141
+ }
1142
+ function textBoxLines(value) {
1143
+ if (typeof value !== "string") return [];
1144
+ try {
1145
+ const lines = JSON.parse(value);
1146
+ return Array.isArray(lines) ? lines.map((line) => ["span", { class: "dve-textbox-line" }, String(line)]) : [];
1147
+ } catch {
1148
+ return [];
1149
+ }
1150
+ }
1151
+ var imageNodeSpec = {
1152
+ group: "inline",
1153
+ inline: true,
1154
+ atom: true,
1155
+ selectable: true,
1156
+ attrs: {
1157
+ relId: { default: "" },
1158
+ partName: { default: "" },
1159
+ contentType: { default: "" },
1160
+ widthPx: { default: 96 },
1161
+ heightPx: { default: 96 },
1162
+ altText: { default: null },
1163
+ title: { default: null },
1164
+ anchored: { default: false },
1165
+ /** Floating picture wrapping/position (`PicturePlacement`) as JSON; display only. */
1166
+ placement: { default: null },
1167
+ /** SVG original shown instead of the PNG fallback in `partName`. */
1168
+ svgPartName: { default: null },
1169
+ unsupported: { default: null },
1170
+ /** A text box's paragraphs as a JSON string array; shown read-only inside its placeholder. */
1171
+ textBoxText: { default: null },
1172
+ /** The text box is the simple editable form; `textBoxBorder` is its outline. */
1173
+ textBoxEditable: { default: null },
1174
+ textBoxBorder: { default: null },
1175
+ /** A SmartArt graphic (`DocxDiagram`) as JSON; shown read-only by the SmartArt node view. */
1176
+ diagram: { default: null }
1177
+ },
1178
+ parseDOM: [
1179
+ {
1180
+ tag: "img[data-docx-image], span[data-docx-image-placeholder]",
1181
+ getAttrs: (el) => ({
1182
+ relId: el.dataset.relId || "",
1183
+ partName: el.dataset.partName || "",
1184
+ contentType: el.dataset.contentType || "",
1185
+ widthPx: Number(el.dataset.widthPx) || 96,
1186
+ heightPx: Number(el.dataset.heightPx) || 96,
1187
+ altText: el.getAttribute("alt") || null,
1188
+ title: el.getAttribute("title") || null,
1189
+ anchored: el.dataset.anchored === "1",
1190
+ unsupported: el.dataset.unsupported || null
1191
+ })
1192
+ }
1193
+ ],
1194
+ toDOM: (node) => node.attrs.unsupported ? [
1195
+ "span",
1196
+ {
1197
+ "data-docx-image-placeholder": "1",
1198
+ ...node.attrs.diagram ? { "data-docx-smartart": "1" } : {},
1199
+ class: "dve-image-placeholder",
1200
+ style: `width:${node.attrs.widthPx}px;height:${node.attrs.heightPx}px`
1201
+ },
1202
+ node.attrs.unsupported,
1203
+ ...textBoxLines(node.attrs.textBoxText)
1204
+ ] : [
1205
+ "img",
1206
+ {
1207
+ "data-docx-image": "1",
1208
+ "data-rel-id": node.attrs.relId,
1209
+ "data-part-name": node.attrs.partName,
1210
+ "data-content-type": node.attrs.contentType,
1211
+ "data-width-px": String(node.attrs.widthPx),
1212
+ "data-height-px": String(node.attrs.heightPx),
1213
+ "data-anchored": node.attrs.anchored ? "1" : "0",
1214
+ class: [
1215
+ "dve-image",
1216
+ node.attrs.anchored ? "dve-image-anchored" : "",
1217
+ placementClass(node.attrs.placement)
1218
+ ].filter(Boolean).join(" "),
1219
+ alt: node.attrs.altText || "",
1220
+ title: node.attrs.title || "",
1221
+ width: String(node.attrs.widthPx),
1222
+ height: String(node.attrs.heightPx)
1223
+ }
1224
+ ]
1225
+ };
1226
+ function isNavigableHref(href) {
1227
+ return typeof href === "string" && /^(https?:|mailto:)/i.test(href.trim());
1228
+ }
1229
+ var linkMarkSpec = {
1230
+ attrs: {
1231
+ href: { default: null },
1232
+ anchor: { default: null },
1233
+ tooltip: { default: null }
1234
+ },
1235
+ inclusive: false,
1236
+ parseDOM: [
1237
+ {
1238
+ tag: "a[data-docx-link]",
1239
+ getAttrs: (el) => ({
1240
+ href: el.dataset.href || (el.dataset.anchor ? null : el.getAttribute("href")) || null,
1241
+ anchor: el.dataset.anchor || null,
1242
+ tooltip: el.getAttribute("title") || null
1243
+ })
1244
+ }
1245
+ ],
1246
+ toDOM: (mark) => [
1247
+ "a",
1248
+ {
1249
+ "data-docx-link": "1",
1250
+ href: isNavigableHref(mark.attrs.href) ? mark.attrs.href : mark.attrs.anchor ? `#${safeAttrValue(mark.attrs.anchor)}` : "",
1251
+ ...mark.attrs.href ? { "data-href": mark.attrs.href } : {},
1252
+ ...mark.attrs.anchor ? { "data-anchor": mark.attrs.anchor } : {},
1253
+ ...mark.attrs.tooltip ? { title: mark.attrs.tooltip } : {},
1254
+ class: "dve-link"
1255
+ },
1256
+ 0
1257
+ ]
1258
+ };
1259
+
1260
+ // src/docx/layout/ligatures.ts
1261
+ function ligatureCss(value) {
1262
+ const enabled = (token) => value === "all" || value.toLowerCase().includes(token);
1263
+ return `${enabled("standard") ? "common-ligatures" : "no-common-ligatures"} ${enabled("contextual") ? "contextual" : "no-contextual"} ${enabled("historical") ? "historical-ligatures" : "no-historical-ligatures"} ${enabled("discretional") ? "discretionary-ligatures" : "no-discretionary-ligatures"}`;
1264
+ }
1265
+
1266
+ // src/docx/ui/ligature-style.ts
1267
+ var ligatureStyle = (value) => isLigatures(value) ? `font-variant-ligatures:${ligatureCss(value)}` : "";
1268
+
1269
+ // src/docx/ui/node-numbering.ts
1270
+ function nodeNumbering(node, model) {
1271
+ return resolveParagraphNumbering(
1272
+ {
1273
+ id: node.attrs.id,
1274
+ style: node.attrs.style,
1275
+ ...node.attrs.numId != null ? { numbering: { numId: Number(node.attrs.numId), level: Number(node.attrs.ilvl ?? 0) } } : {}
1276
+ },
1277
+ model.paragraphStyles,
1278
+ model.numberingCatalog
1279
+ );
1280
+ }
1281
+
1282
+ // src/docx/ui/review-schema.ts
1283
+ var REVIEW_AUTHOR_PALETTE = [
1284
+ "#c2431f",
1285
+ "#1a73e8",
1286
+ "#188038",
1287
+ "#8430ce",
1288
+ "#b2103c",
1289
+ "#00838f",
1290
+ "#e37400",
1291
+ "#5b6bc0"
1292
+ ];
1293
+ function authorColor(author) {
1294
+ let hash = 0;
1295
+ for (let i = 0; i < author.length; i++) hash = hash * 31 + author.charCodeAt(i) >>> 0;
1296
+ return REVIEW_AUTHOR_PALETTE[hash % REVIEW_AUTHOR_PALETTE.length] ?? "#c2431f";
1297
+ }
1298
+ function moveName(value) {
1299
+ if (typeof value !== "string") return void 0;
1300
+ try {
1301
+ const name = JSON.parse(value).name;
1302
+ return typeof name === "string" ? name : void 0;
1303
+ } catch {
1304
+ return void 0;
1305
+ }
1306
+ }
1307
+ var reviewMarks = {
1308
+ insertion: {
1309
+ // `move`: JSON `{ name, rangeId? }` when this is one side of a tracked move (moveTo/moveFrom).
1310
+ attrs: {
1311
+ author: { default: "" },
1312
+ date: { default: null },
1313
+ id: { default: "" },
1314
+ move: { default: null }
1315
+ },
1316
+ parseDOM: [
1317
+ {
1318
+ tag: "ins[data-revision-id]",
1319
+ getAttrs: (el) => ({
1320
+ author: el.dataset.author || "",
1321
+ date: el.dataset.date || null,
1322
+ id: el.dataset.revisionId || "",
1323
+ move: null
1324
+ })
1325
+ }
1326
+ ],
1327
+ toDOM: (mark) => [
1328
+ "ins",
1329
+ {
1330
+ "data-revision-id": mark.attrs.id,
1331
+ "data-author": mark.attrs.author,
1332
+ ...mark.attrs.date ? { "data-date": mark.attrs.date } : {},
1333
+ class: mark.attrs.move ? "dve-revision-insert dve-revision-move" : "dve-revision-insert",
1334
+ ...mark.attrs.move ? { "data-move": moveName(mark.attrs.move) } : {},
1335
+ style: `--dve-revision-color:${authorColor(mark.attrs.author)}`
1336
+ },
1337
+ 0
1338
+ ]
1339
+ },
1340
+ deletion: {
1341
+ // `move`: JSON `{ name, rangeId? }` when this is one side of a tracked move (moveTo/moveFrom).
1342
+ attrs: {
1343
+ author: { default: "" },
1344
+ date: { default: null },
1345
+ id: { default: "" },
1346
+ move: { default: null }
1347
+ },
1348
+ parseDOM: [
1349
+ {
1350
+ tag: "del[data-revision-id]",
1351
+ getAttrs: (el) => ({
1352
+ author: el.dataset.author || "",
1353
+ date: el.dataset.date || null,
1354
+ id: el.dataset.revisionId || "",
1355
+ move: null
1356
+ })
1357
+ }
1358
+ ],
1359
+ toDOM: (mark) => [
1360
+ "del",
1361
+ {
1362
+ "data-revision-id": mark.attrs.id,
1363
+ "data-author": mark.attrs.author,
1364
+ ...mark.attrs.date ? { "data-date": mark.attrs.date } : {},
1365
+ class: mark.attrs.move ? "dve-revision-delete dve-revision-move" : "dve-revision-delete",
1366
+ ...mark.attrs.move ? { "data-move": moveName(mark.attrs.move) } : {},
1367
+ style: `--dve-revision-color:${authorColor(mark.attrs.author)}`
1368
+ },
1369
+ 0
1370
+ ]
1371
+ },
1372
+ comment: {
1373
+ attrs: { ids: { default: [] } },
1374
+ parseDOM: [
1375
+ {
1376
+ tag: "span[data-comment-ids]",
1377
+ getAttrs: (el) => ({
1378
+ ids: (el.dataset.commentIds || "").split(",").filter(Boolean)
1379
+ })
1380
+ }
1381
+ ],
1382
+ toDOM: (mark) => [
1383
+ "span",
1384
+ { class: "dve-comment-range", "data-comment-ids": mark.attrs.ids.join(",") },
1385
+ 0
1386
+ ]
1387
+ }
1388
+ };
1389
+
1390
+ // src/docx/ui/ribbon-action-ids.ts
1391
+ var RIBBON_ACTION_IDS = [
1392
+ "paste",
1393
+ "delete-comment",
1394
+ "previous-comment",
1395
+ "next-comment",
1396
+ "insert-caption",
1397
+ "cross-reference",
1398
+ "ruler",
1399
+ "page-setup-dialog",
1400
+ "cover-page",
1401
+ "bookmark",
1402
+ "sort",
1403
+ "find-options",
1404
+ "select-options",
1405
+ "add-text",
1406
+ "blank-page",
1407
+ "read-aloud",
1408
+ "gridlines",
1409
+ "navigation-pane",
1410
+ "shading",
1411
+ "borders",
1412
+ "header",
1413
+ "footer",
1414
+ "page-number",
1415
+ "header-footer-link",
1416
+ "header-footer-close",
1417
+ "header-footer-go-header",
1418
+ "header-footer-go-footer",
1419
+ "header-footer-previous",
1420
+ "header-footer-next",
1421
+ "header-from-top",
1422
+ "footer-from-bottom",
1423
+ "page-size",
1424
+ "font-dialog",
1425
+ "paragraph-dialog",
1426
+ "indent-left",
1427
+ "indent-right",
1428
+ "zoom-actual-size",
1429
+ "multiple-pages",
1430
+ "page-width",
1431
+ "one-page",
1432
+ "word-count",
1433
+ "spelling",
1434
+ "symbol",
1435
+ "date-and-time",
1436
+ "line-numbers",
1437
+ "multilevel-list",
1438
+ "drop-cap",
1439
+ "change-case",
1440
+ "format-painter",
1441
+ "show-paragraph-marks",
1442
+ "select-all",
1443
+ "replace",
1444
+ "cut",
1445
+ "copy",
1446
+ "grow-font",
1447
+ "shrink-font",
1448
+ "font-family",
1449
+ "font-size",
1450
+ "bold",
1451
+ "italic",
1452
+ "underline",
1453
+ "strikethrough",
1454
+ "superscript",
1455
+ "subscript",
1456
+ "font-color",
1457
+ "text-highlight",
1458
+ "clear-formatting",
1459
+ "decrease-indent",
1460
+ "increase-indent",
1461
+ "spacing-after",
1462
+ "spacing-before",
1463
+ "line-spacing",
1464
+ "bulleted-list",
1465
+ "numbered-list",
1466
+ "decrease-list-level",
1467
+ "increase-list-level",
1468
+ "remove-list",
1469
+ "align-left",
1470
+ "align-center",
1471
+ "align-right",
1472
+ "justify",
1473
+ "find-and-replace",
1474
+ "insert-table",
1475
+ "insert-picture",
1476
+ "format-picture",
1477
+ "insert-link",
1478
+ "insert-page-break",
1479
+ "insert-column-break",
1480
+ "margins",
1481
+ "orientation",
1482
+ "vertical-alignment",
1483
+ "columns",
1484
+ "page-color",
1485
+ "text-box",
1486
+ "page-borders",
1487
+ "watermark",
1488
+ "hyphenation",
1489
+ "page-number-format",
1490
+ "page-numbering",
1491
+ "different-first-page",
1492
+ "different-odd-and-even-pages",
1493
+ "next-page-section-break",
1494
+ "continuous-section-break",
1495
+ "even-page-section-break",
1496
+ "odd-page-section-break",
1497
+ "insert-table-of-contents",
1498
+ "update-table-of-contents",
1499
+ "update-fields",
1500
+ "insert-table-of-figures",
1501
+ "insert-footnote",
1502
+ "insert-endnote",
1503
+ "paragraph-direction",
1504
+ "text-language",
1505
+ "custom-text-language-tag",
1506
+ "east-asian-language",
1507
+ "custom-east-asian-language-tag",
1508
+ "complex-script-language",
1509
+ "custom-complex-script-language-tag",
1510
+ "run-direction",
1511
+ "track-changes",
1512
+ "display-for-review",
1513
+ "previous-change",
1514
+ "next-change",
1515
+ "accept",
1516
+ "reject",
1517
+ "accept-all",
1518
+ "reject-all",
1519
+ "add-comment",
1520
+ "comments",
1521
+ "show-hidden-text",
1522
+ "page-thumbnails",
1523
+ "zoom",
1524
+ "zoom-dialog",
1525
+ "layout-view",
1526
+ "print",
1527
+ "insert-row-above",
1528
+ "insert-row-below",
1529
+ "delete-row",
1530
+ "insert-column-left",
1531
+ "insert-column-right",
1532
+ "delete-column",
1533
+ "delete-table",
1534
+ "table-properties"
1535
+ ];
1536
+ var RIBBON_ACTION_LABELS = {
1537
+ paste: "Paste",
1538
+ "delete-comment": "Delete comment",
1539
+ "previous-comment": "Previous comment",
1540
+ "next-comment": "Next comment",
1541
+ "insert-caption": "Insert caption",
1542
+ "cross-reference": "Cross-reference",
1543
+ ruler: "Ruler",
1544
+ "page-setup-dialog": "Page setup settings",
1545
+ "cover-page": "Cover page",
1546
+ bookmark: "Bookmark",
1547
+ sort: "Sort",
1548
+ "find-options": "Find options",
1549
+ "select-options": "Select options",
1550
+ "add-text": "Add text",
1551
+ "blank-page": "Blank page",
1552
+ "read-aloud": "Read aloud",
1553
+ gridlines: "Gridlines",
1554
+ shading: "Shading",
1555
+ borders: "Borders",
1556
+ header: "Header",
1557
+ footer: "Footer",
1558
+ "page-number": "Page number",
1559
+ "header-footer-link": "Link to Previous",
1560
+ "header-footer-close": "Close Header and Footer",
1561
+ "header-footer-go-header": "Go to Header",
1562
+ "header-footer-go-footer": "Go to Footer",
1563
+ "header-footer-previous": "Previous Section",
1564
+ "header-footer-next": "Next Section",
1565
+ "header-from-top": "Header from Top (inches)",
1566
+ "footer-from-bottom": "Footer from Bottom (inches)",
1567
+ "page-size": "Page size",
1568
+ "font-dialog": "Font settings",
1569
+ "paragraph-dialog": "Paragraph settings",
1570
+ "indent-left": "Indent left",
1571
+ "indent-right": "Indent right",
1572
+ "zoom-actual-size": "Zoom to 100%",
1573
+ "multiple-pages": "Multiple pages",
1574
+ "page-width": "Page width",
1575
+ "one-page": "One page",
1576
+ "word-count": "Word count",
1577
+ spelling: "Spelling",
1578
+ symbol: "Symbol",
1579
+ "date-and-time": "Date and time",
1580
+ "line-numbers": "Line numbers",
1581
+ "multilevel-list": "Multilevel list",
1582
+ "drop-cap": "Drop cap",
1583
+ "change-case": "Change case",
1584
+ "format-painter": "Format painter",
1585
+ "show-paragraph-marks": "Show paragraph marks",
1586
+ "select-all": "Select all",
1587
+ replace: "Replace",
1588
+ cut: "Cut",
1589
+ copy: "Copy",
1590
+ "grow-font": "Grow font",
1591
+ "shrink-font": "Shrink font",
1592
+ "font-family": "Font family",
1593
+ "font-size": "Font size",
1594
+ bold: "Bold",
1595
+ italic: "Italic",
1596
+ underline: "Underline",
1597
+ strikethrough: "Strikethrough",
1598
+ superscript: "Superscript",
1599
+ subscript: "Subscript",
1600
+ "font-color": "Font color",
1601
+ "text-highlight": "Text highlight",
1602
+ "clear-formatting": "Clear formatting",
1603
+ "decrease-indent": "Decrease indent",
1604
+ "increase-indent": "Increase indent",
1605
+ "spacing-after": "Spacing after",
1606
+ "spacing-before": "Spacing before",
1607
+ "line-spacing": "Line spacing",
1608
+ "bulleted-list": "Bulleted list",
1609
+ "numbered-list": "Numbered list",
1610
+ "decrease-list-level": "Decrease list level",
1611
+ "increase-list-level": "Increase list level",
1612
+ "remove-list": "Remove list",
1613
+ "align-left": "Align left",
1614
+ "align-center": "Align center",
1615
+ "align-right": "Align right",
1616
+ justify: "Justify",
1617
+ "find-and-replace": "Find and replace",
1618
+ "insert-table": "Insert table",
1619
+ "insert-picture": "Insert picture",
1620
+ "format-picture": "Format picture",
1621
+ "insert-link": "Insert link",
1622
+ "insert-page-break": "Insert page break",
1623
+ "insert-column-break": "Insert column break",
1624
+ margins: "Margins",
1625
+ orientation: "Orientation",
1626
+ "vertical-alignment": "Vertical alignment",
1627
+ columns: "Columns",
1628
+ "page-color": "Page color",
1629
+ "text-box": "Text box",
1630
+ "page-borders": "Page borders",
1631
+ watermark: "Watermark",
1632
+ hyphenation: "Hyphenation",
1633
+ "page-number-format": "Page number format",
1634
+ "page-numbering": "Page numbering",
1635
+ "different-first-page": "Different first page",
1636
+ "different-odd-and-even-pages": "Different odd and even pages",
1637
+ "next-page-section-break": "Next page section break",
1638
+ "continuous-section-break": "Continuous section break",
1639
+ "even-page-section-break": "Even page section break",
1640
+ "odd-page-section-break": "Odd page section break",
1641
+ "insert-table-of-contents": "Insert table of contents",
1642
+ "update-table-of-contents": "Update table of contents",
1643
+ "update-fields": "Update fields",
1644
+ "insert-table-of-figures": "Insert table of figures",
1645
+ "insert-footnote": "Insert footnote",
1646
+ "insert-endnote": "Insert endnote",
1647
+ "paragraph-direction": "Paragraph direction",
1648
+ "text-language": "Text language",
1649
+ "custom-text-language-tag": "Custom text language tag",
1650
+ "east-asian-language": "East Asian language",
1651
+ "custom-east-asian-language-tag": "Custom east asian language tag",
1652
+ "complex-script-language": "Complex script language",
1653
+ "custom-complex-script-language-tag": "Custom complex script language tag",
1654
+ "run-direction": "Run direction",
1655
+ "track-changes": "Track changes",
1656
+ "display-for-review": "Display for review",
1657
+ "previous-change": "Previous change",
1658
+ "next-change": "Next change",
1659
+ accept: "Accept",
1660
+ reject: "Reject",
1661
+ "accept-all": "Accept all",
1662
+ "reject-all": "Reject all",
1663
+ "add-comment": "Add comment",
1664
+ comments: "Comments",
1665
+ "show-hidden-text": "Show hidden text",
1666
+ "page-thumbnails": "Page thumbnails",
1667
+ "navigation-pane": "Navigation pane",
1668
+ zoom: "Zoom",
1669
+ "zoom-dialog": "Zoom dialog",
1670
+ "layout-view": "Layout view",
1671
+ print: "Print",
1672
+ "insert-row-above": "Insert row above",
1673
+ "insert-row-below": "Insert row below",
1674
+ "delete-row": "Delete row",
1675
+ "insert-column-left": "Insert column left",
1676
+ "insert-column-right": "Insert column right",
1677
+ "delete-column": "Delete column",
1678
+ "delete-table": "Delete table",
1679
+ "table-properties": "Table properties"
1680
+ };
1681
+ var labelToId = new Map(
1682
+ RIBBON_ACTION_IDS.map((id) => [RIBBON_ACTION_LABELS[id], id])
1683
+ );
1684
+ function isRibbonActionId(value) {
1685
+ return RIBBON_ACTION_IDS.includes(value);
1686
+ }
1687
+ function ribbonActionIdForLabel(label) {
1688
+ return labelToId.get(label ?? "") ?? null;
1689
+ }
1690
+ function normalizeRibbonActions(input) {
1691
+ const ids = [];
1692
+ const legacy = [];
1693
+ for (const value of input) {
1694
+ if (isRibbonActionId(value)) ids.push(value);
1695
+ else {
1696
+ const id = labelToId.get(value);
1697
+ if (id) {
1698
+ ids.push(id);
1699
+ legacy.push(value);
1700
+ }
1701
+ }
1702
+ }
1703
+ return { ids, legacy };
1704
+ }
1705
+
1706
+ // src/docx/ui/ribbon-colors.ts
1707
+ var NAMED_COLORS = {
1708
+ yellow: "#ffff00",
1709
+ green: "#00ff00",
1710
+ cyan: "#00ffff",
1711
+ magenta: "#ff00ff",
1712
+ blue: "#0000ff",
1713
+ red: "#ff0000",
1714
+ darkBlue: "#000080",
1715
+ darkCyan: "#008080",
1716
+ darkGreen: "#008000",
1717
+ darkMagenta: "#800080",
1718
+ darkRed: "#800000",
1719
+ darkYellow: "#808000",
1720
+ darkGray: "#808080",
1721
+ lightGray: "#c0c0c0",
1722
+ black: "#000000",
1723
+ white: "#ffffff"
1724
+ };
1725
+ function swatchColor(value) {
1726
+ return value === "none" ? "transparent" : NAMED_COLORS[value] ?? value;
1727
+ }
1728
+
1729
+ // src/docx/ui/run-extra-mark.ts
1730
+ var extraRunFields = [
1731
+ "caps",
1732
+ "smallCaps",
1733
+ "doubleStrike",
1734
+ "vanish",
1735
+ "underlineStyle",
1736
+ "underlineColor",
1737
+ "characterSpacingTwips",
1738
+ "textScalePercent",
1739
+ "ligatures",
1740
+ "kerningHalfPoints",
1741
+ "positionHalfPoints",
1742
+ "shadingFill",
1743
+ "shadingThemeFill",
1744
+ "colorTheme",
1745
+ "fontTheme"
1746
+ ];
1747
+ var explicitOffFields = ["bold", "italic", "strike", "underline"];
1748
+ function extraRunProperties(run) {
1749
+ const extra = {};
1750
+ for (const field of extraRunFields) if (run[field] !== void 0) extra[field] = run[field];
1751
+ for (const field of explicitOffFields) if (run[field] === false) extra[field] = false;
1752
+ return Object.keys(extra).length ? extra : void 0;
1753
+ }
1754
+ var cssColor = (value) => typeof value === "string" && /^#[0-9a-f]{6}$/i.test(value) ? value : void 0;
1755
+ function extraRunStyle(props) {
1756
+ const css = [];
1757
+ if (props.ligatures) css.push(ligatureStyle(props.ligatures));
1758
+ if (props.caps) css.push("text-transform:uppercase");
1759
+ if (props.smallCaps) css.push("font-variant:small-caps");
1760
+ const decorations = [];
1761
+ if (props.underlineStyle) decorations.push("underline");
1762
+ if (props.doubleStrike) decorations.push("line-through");
1763
+ if (decorations.length) css.push(`text-decoration-line:${decorations.join(" ")}`);
1764
+ if (props.doubleStrike) css.push("text-decoration-style:double");
1765
+ else if (props.underlineStyle === "double") css.push("text-decoration-style:double");
1766
+ else if (props.underlineStyle && /dot/i.test(props.underlineStyle))
1767
+ css.push("text-decoration-style:dotted");
1768
+ else if (props.underlineStyle && /dash/i.test(props.underlineStyle))
1769
+ css.push("text-decoration-style:dashed");
1770
+ else if (props.underlineStyle && /wav/i.test(props.underlineStyle))
1771
+ css.push("text-decoration-style:wavy");
1772
+ const underlineColor = cssColor(props.underlineColor);
1773
+ if (underlineColor) css.push(`text-decoration-color:${underlineColor}`);
1774
+ if (typeof props.characterSpacingTwips === "number")
1775
+ css.push(`letter-spacing:${(props.characterSpacingTwips / 20).toFixed(2)}pt`);
1776
+ if (typeof props.positionHalfPoints === "number")
1777
+ css.push(`vertical-align:${props.positionHalfPoints / 2}pt`);
1778
+ if (props.kerningHalfPoints === 0) css.push("font-kerning:none");
1779
+ const shading = cssColor(props.shadingFill);
1780
+ if (shading) css.push(`background-color:${shading}`);
1781
+ if (props.vanish) css.push("opacity:0.45;text-decoration:underline dotted");
1782
+ return css.join(";");
1783
+ }
1784
+ var runPropertiesMark = {
1785
+ attrs: { props: { default: null } },
1786
+ parseDOM: [
1787
+ {
1788
+ tag: "span[data-run-props]",
1789
+ getAttrs: (el) => {
1790
+ try {
1791
+ return { props: JSON.parse(el.dataset.runProps || "null") };
1792
+ } catch {
1793
+ return { props: null };
1794
+ }
1795
+ }
1796
+ }
1797
+ ],
1798
+ toDOM: (mark) => {
1799
+ const props = mark.attrs.props ?? {};
1800
+ const style = extraRunStyle(props);
1801
+ return [
1802
+ "span",
1803
+ {
1804
+ "data-run-props": JSON.stringify(props),
1805
+ ...props.vanish ? { class: "dve-hidden-text" } : {},
1806
+ ...style ? { style } : {}
1807
+ },
1808
+ 0
1809
+ ];
1810
+ }
1811
+ };
1812
+
1813
+ // src/docx/ui/run-compare.ts
1814
+ var sameJson = (left, right) => JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
1815
+ function sameRevisionMeta(left, right) {
1816
+ return JSON.stringify(left.revision) === JSON.stringify(right.revision) && JSON.stringify(left.commentIds) === JSON.stringify(right.commentIds) && JSON.stringify(extraRunProperties(left)) === JSON.stringify(extraRunProperties(right)) && JSON.stringify(left.field) === JSON.stringify(right.field) && left.fieldChar === right.fieldChar && left.fieldCode === right.fieldCode;
1817
+ }
1818
+ function sameRuns(left, right) {
1819
+ const compact = (runs) => runs.reduce((result, run) => {
1820
+ const normalized = { ...run };
1821
+ const previous = result.at(-1);
1822
+ const fields2 = [
1823
+ "bold",
1824
+ "italic",
1825
+ "underline",
1826
+ "strike",
1827
+ "highlight",
1828
+ "verticalAlign",
1829
+ "language",
1830
+ "eastAsiaLanguage",
1831
+ "bidiLanguage",
1832
+ "rtl",
1833
+ "fontFamily",
1834
+ "fontSize",
1835
+ "color",
1836
+ "style",
1837
+ "break"
1838
+ ];
1839
+ if (previous && !previous.noteReference && !normalized.noteReference && !previous.fieldChar && !normalized.fieldChar && previous.fieldCode === void 0 && normalized.fieldCode === void 0 && !previous.image && !normalized.image && !previous.equation && !normalized.equation && sameJson(previous.link, normalized.link) && fields2.every((field) => previous[field] === normalized[field]) && sameRevisionMeta(previous, normalized))
1840
+ previous.text += normalized.text;
1841
+ else result.push(normalized);
1842
+ return result;
1843
+ }, []);
1844
+ const a = compact(left);
1845
+ const b = compact(right);
1846
+ const fields = [
1847
+ "bold",
1848
+ "italic",
1849
+ "underline",
1850
+ "strike",
1851
+ "highlight",
1852
+ "verticalAlign",
1853
+ "language",
1854
+ "eastAsiaLanguage",
1855
+ "bidiLanguage",
1856
+ "rtl",
1857
+ "fontFamily",
1858
+ "fontSize",
1859
+ "color",
1860
+ "style",
1861
+ "break"
1862
+ ];
1863
+ const sameNoteReference = (x, y) => x?.kind === y?.kind && x?.id === y?.id;
1864
+ return a.length === b.length && a.every((run, index) => {
1865
+ const other = b[index];
1866
+ return other !== void 0 && run.text === other.text && fields.every((field) => run[field] === other[field]) && sameNoteReference(run.noteReference, other.noteReference) && sameJson(run.link, other.link) && sameJson(run.image, other.image) && sameJson(run.equation, other.equation) && sameRevisionMeta(run, other);
1867
+ });
1868
+ }
1869
+
1870
+ // src/docx/ui/schema-marks.ts
1871
+ var safeCssValue = (value) => String(value ?? "").replace(/[;{}]/g, "");
1872
+ var GENERIC_FAMILIES = /* @__PURE__ */ new Set([
1873
+ "serif",
1874
+ "sans-serif",
1875
+ "monospace",
1876
+ "cursive",
1877
+ "fantasy",
1878
+ "system-ui"
1879
+ ]);
1880
+ function pastedFontFamily(value) {
1881
+ const first = value.split(",")[0]?.trim().replace(/^['"]|['"]$/g, "") ?? "";
1882
+ return first && !GENERIC_FAMILIES.has(first.toLowerCase()) ? first : null;
1883
+ }
1884
+ function pastedColor(value) {
1885
+ const hex = /^#([0-9a-f]{6})$/i.exec(value.trim());
1886
+ if (hex?.[1]) return `#${hex[1].toLowerCase()}`;
1887
+ const short = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(value.trim());
1888
+ if (short)
1889
+ return `#${short[1]}${short[1]}${short[2]}${short[2]}${short[3]}${short[3]}`.toLowerCase();
1890
+ const rgb = /^rgba?\(\s*(\d+),\s*(\d+),\s*(\d+)\s*(?:,\s*([\d.]+)\s*)?\)$/i.exec(value.trim());
1891
+ if (!rgb || rgb[4] !== void 0 && Number(rgb[4]) === 0) return null;
1892
+ return `#${rgb.slice(1, 4).map((part) => Math.min(255, Number(part)).toString(16).padStart(2, "0")).join("")}`;
1893
+ }
1894
+ function parseFontSize(value) {
1895
+ const match = /^\s*(\d+(?:\.\d+)?)\s*(pt|px)?\s*$/i.exec(value);
1896
+ if (!match) return null;
1897
+ const size = Number(match[1]) * (match[2]?.toLowerCase() === "px" ? 0.75 : 1);
1898
+ return Number.isFinite(size) && size > 0 ? size : null;
1899
+ }
1900
+ var wordHighlightColors = {
1901
+ black: "#000000",
1902
+ blue: "#0000ff",
1903
+ cyan: "#00ffff",
1904
+ green: "#00ff00",
1905
+ magenta: "#ff00ff",
1906
+ red: "#ff0000",
1907
+ yellow: "#ffff00",
1908
+ white: "#ffffff",
1909
+ darkBlue: "#000080",
1910
+ darkCyan: "#008080",
1911
+ darkGreen: "#008000",
1912
+ darkMagenta: "#800080",
1913
+ darkRed: "#800000",
1914
+ darkYellow: "#808000",
1915
+ darkGray: "#808080",
1916
+ lightGray: "#c0c0c0"
1917
+ };
1918
+ var markSpecs = {
1919
+ bold: { parseDOM: [{ tag: "strong" }, { tag: "b" }], toDOM: () => ["strong", 0] },
1920
+ italic: { parseDOM: [{ tag: "em" }, { tag: "i" }], toDOM: () => ["em", 0] },
1921
+ underline: { parseDOM: [{ tag: "u" }], toDOM: () => ["u", 0] },
1922
+ strike: {
1923
+ parseDOM: [{ tag: "s" }, { tag: "del" }, { style: "text-decoration=line-through" }],
1924
+ toDOM: () => ["s", 0]
1925
+ },
1926
+ highlight: {
1927
+ attrs: { color: { default: null } },
1928
+ parseDOM: [
1929
+ {
1930
+ tag: 'span[style*="background-color"]',
1931
+ getAttrs: (el) => {
1932
+ const color = el.style.backgroundColor.toLowerCase();
1933
+ if (color === "white" || color === "rgb(255, 255, 255)" || color === "#ffffff")
1934
+ return false;
1935
+ const entry = Object.entries(wordHighlightColors).find(([, css]) => {
1936
+ const hex = css.slice(1);
1937
+ const rgb = `rgb(${parseInt(hex.slice(0, 2), 16)}, ${parseInt(hex.slice(2, 4), 16)}, ${parseInt(hex.slice(4, 6), 16)})`;
1938
+ return css.toLowerCase() === color || rgb === color;
1939
+ });
1940
+ return entry ? { color: entry[0] } : false;
1941
+ }
1942
+ }
1943
+ ],
1944
+ toDOM: (mark) => {
1945
+ const value = String(mark.attrs.color || "");
1946
+ const token = isWordHighlightToken(value) && value !== "none" ? value : null;
1947
+ return token ? ["span", { style: `background-color:${wordHighlightColors[token]}` }, 0] : ["span", 0];
1948
+ }
1949
+ },
1950
+ verticalAlign: {
1951
+ attrs: { value: { default: "superscript" } },
1952
+ excludes: "verticalAlign",
1953
+ parseDOM: [
1954
+ { tag: "sup", attrs: { value: "superscript" } },
1955
+ { tag: "sub", attrs: { value: "subscript" } },
1956
+ { tag: 'span[data-docx-vertical-align="baseline"]', attrs: { value: "baseline" } }
1957
+ ],
1958
+ toDOM: (mark) => mark.attrs.value === "baseline" ? ["span", { "data-docx-vertical-align": "baseline" }, 0] : [mark.attrs.value === "subscript" ? "sub" : "sup", 0]
1959
+ },
1960
+ language: {
1961
+ attrs: {
1962
+ language: { default: null },
1963
+ eastAsiaLanguage: { default: null },
1964
+ bidiLanguage: { default: null }
1965
+ },
1966
+ parseDOM: [
1967
+ {
1968
+ tag: "span[lang], span[data-docx-east-asia-language], span[data-docx-bidi-language]",
1969
+ getAttrs: (el) => ({
1970
+ language: el.getAttribute("lang"),
1971
+ eastAsiaLanguage: el.dataset.docxEastAsiaLanguage || null,
1972
+ bidiLanguage: el.dataset.docxBidiLanguage || null
1973
+ })
1974
+ }
1975
+ ],
1976
+ toDOM: (mark) => {
1977
+ const attrs = {};
1978
+ if (mark.attrs.language) attrs.lang = mark.attrs.language;
1979
+ if (mark.attrs.eastAsiaLanguage)
1980
+ attrs["data-docx-east-asia-language"] = mark.attrs.eastAsiaLanguage;
1981
+ if (mark.attrs.bidiLanguage) attrs["data-docx-bidi-language"] = mark.attrs.bidiLanguage;
1982
+ return ["span", attrs, 0];
1983
+ }
1984
+ },
1985
+ runRtl: {
1986
+ attrs: { value: { default: true } },
1987
+ excludes: "runRtl",
1988
+ parseDOM: [
1989
+ { tag: 'span[dir="rtl"]', attrs: { value: true } },
1990
+ { tag: 'span[dir="ltr"]', attrs: { value: false } }
1991
+ ],
1992
+ toDOM: (mark) => ["span", { dir: mark.attrs.value ? "rtl" : "ltr" }, 0]
1993
+ },
1994
+ ...reviewMarks,
1995
+ runProperties: runPropertiesMark,
1996
+ link: linkMarkSpec,
1997
+ font: {
1998
+ attrs: { family: { default: null }, size: { default: null }, color: { default: null } },
1999
+ parseDOM: [
2000
+ {
2001
+ tag: "span",
2002
+ getAttrs: (el) => {
2003
+ const style = el.style;
2004
+ const attrs = {
2005
+ family: pastedFontFamily(style.fontFamily),
2006
+ size: style.fontSize ? parseFontSize(style.fontSize) : null,
2007
+ color: pastedColor(style.color)
2008
+ };
2009
+ return attrs.family || attrs.size || attrs.color ? attrs : false;
2010
+ }
2011
+ }
2012
+ ],
2013
+ toDOM: (mark) => [
2014
+ "span",
2015
+ {
2016
+ style: [
2017
+ mark.attrs.family && `font-family:${safeCssValue(mark.attrs.family)}`,
2018
+ Number.isFinite(mark.attrs.size) && mark.attrs.size > 0 && `font-size:${mark.attrs.size}pt`,
2019
+ mark.attrs.color && `color:${safeCssValue(mark.attrs.color)}`
2020
+ ].filter(Boolean).join(";")
2021
+ },
2022
+ 0
2023
+ ]
2024
+ },
2025
+ /** Direct `w:rStyle` character style reference; the toolbar picker edits it, decorations render it. */
2026
+ characterStyle: {
2027
+ attrs: { id: { default: null } },
2028
+ parseDOM: [
2029
+ {
2030
+ tag: "span[data-docx-style]",
2031
+ getAttrs: (el) => ({ id: el.dataset.docxStyle || null })
2032
+ }
2033
+ ],
2034
+ toDOM: (mark) => ["span", { "data-docx-style": mark.attrs.id }, 0]
2035
+ },
2036
+ /** Field result text: carries the field code so results can be recalculated and re-wrapped. */
2037
+ field: {
2038
+ attrs: { instr: { default: "" }, simple: { default: false } },
2039
+ inclusive: false,
2040
+ parseDOM: [
2041
+ {
2042
+ tag: "span[data-field]",
2043
+ getAttrs: (el) => ({
2044
+ instr: el.dataset.field || "",
2045
+ simple: el.dataset.fieldSimple === "1"
2046
+ })
2047
+ }
2048
+ ],
2049
+ toDOM: (mark) => [
2050
+ "span",
2051
+ {
2052
+ "data-field": mark.attrs.instr,
2053
+ ...mark.attrs.simple ? { "data-field-simple": "1" } : {}
2054
+ },
2055
+ 0
2056
+ ]
2057
+ }
2058
+ };
2059
+
2060
+ // src/docx/ui/smartart-theme.ts
2061
+ var SCHEME_NAMES = [
2062
+ "dk1",
2063
+ "lt1",
2064
+ "dk2",
2065
+ "lt2",
2066
+ "accent1",
2067
+ "accent2",
2068
+ "accent3",
2069
+ "accent4",
2070
+ "accent5",
2071
+ "accent6",
2072
+ "hlink",
2073
+ "folHlink",
2074
+ "tx1",
2075
+ "bg1",
2076
+ "tx2",
2077
+ "bg2"
2078
+ ];
2079
+ var isColor = (value) => typeof value === "object" && value !== null && typeof value.kind === "string" && typeof value.value === "string" && Array.isArray(value.transforms);
2080
+ function themeDrawing(drawing, theme) {
2081
+ const unapplied = /* @__PURE__ */ new Set();
2082
+ let alphaDropped = false;
2083
+ const walk = (value) => {
2084
+ if (Array.isArray(value)) return value.map(walk);
2085
+ if (typeof value !== "object" || value === null) return value;
2086
+ if (isColor(value) && value.kind !== "srgb") {
2087
+ const resolved = resolveDiagramColor(value, theme);
2088
+ if (resolved) {
2089
+ for (const name of resolved.unapplied) unapplied.add(name);
2090
+ if (resolved.alpha < 1) alphaDropped = true;
2091
+ return { kind: "srgb", value: resolved.hex.replace(/^#/u, ""), transforms: [] };
2092
+ }
2093
+ }
2094
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, walk(entry)]));
2095
+ };
2096
+ const colors = diagramColorTheme(theme);
2097
+ const schemeColors = {};
2098
+ for (const name of SCHEME_NAMES) {
2099
+ const hex = colors.scheme(name);
2100
+ if (hex) schemeColors[name] = hex;
2101
+ }
2102
+ return {
2103
+ drawing: walk(drawing),
2104
+ schemeColors,
2105
+ unappliedTransforms: [...unapplied],
2106
+ alphaDropped
2107
+ };
2108
+ }
2109
+
2110
+ // src/docx/ui/table-render.ts
2111
+ var NONE_STYLES = /* @__PURE__ */ new Set(["none", "nil"]);
2112
+ function cssBorderStyle(style) {
2113
+ if (!style || NONE_STYLES.has(style)) return "none";
2114
+ if (style === "double") return "double";
2115
+ if (style.toLowerCase().includes("dot")) return "dotted";
2116
+ if (style.toLowerCase().includes("dash")) return "dashed";
2117
+ return "solid";
2118
+ }
2119
+ function cssBorderSide(side) {
2120
+ if (!side || NONE_STYLES.has(side.style ?? "")) return null;
2121
+ const widthPx = side.sizeEighthPoints ? Math.max(1, Math.round(side.sizeEighthPoints / 8 * (4 / 3))) : 1;
2122
+ const color = side.color ?? "#000000";
2123
+ return `${widthPx}px ${cssBorderStyle(side.style)} ${color}`;
2124
+ }
2125
+ function parseBordersJson(value) {
2126
+ if (typeof value !== "string" || !value) return void 0;
2127
+ try {
2128
+ return JSON.parse(value);
2129
+ } catch {
2130
+ return void 0;
2131
+ }
2132
+ }
2133
+ var twipsPx = (value) => Number.isSafeInteger(value) ? `${Number(value) / 15}px` : null;
2134
+ function tableStyle(attrs) {
2135
+ const borders = parseBordersJson(attrs.borders);
2136
+ const margins = marginValues(attrs.cellMargins);
2137
+ const declarations = [
2138
+ "border-collapse:collapse",
2139
+ twipsPx(attrs.widthTwips) && `width:${twipsPx(attrs.widthTwips)}`,
2140
+ attrs.alignment === "center" && "margin-left:auto;margin-right:auto",
2141
+ attrs.alignment === "right" && "margin-left:auto",
2142
+ twipsPx(attrs.indentTwips) && attrs.alignment !== "center" && `margin-left:${twipsPx(attrs.indentTwips)}`,
2143
+ // Cells without their own resolved borders (e.g. a table inserted in the editor) draw the
2144
+ // table's inside line; tables with no border information fall back to dashed gridlines.
2145
+ borders && `--dve-cell-border:${cssBorderSide(borders.insideH ?? borders.top) ?? "none"}`,
2146
+ // Cells without their own margins use the table's (`w:tblCellMar`).
2147
+ ...["top", "right", "bottom", "left"].map(
2148
+ (side) => `--dve-cell-padding-${side}:${margins[side] ?? DEFAULT_CELL_MARGINS[side] / 15}px`
2149
+ )
2150
+ ].filter(Boolean);
2151
+ return declarations.join(";");
2152
+ }
2153
+ var DEFAULT_CELL_MARGINS = { top: 0, bottom: 0, left: 108, right: 108 };
2154
+ function marginValues(value) {
2155
+ let margins = {};
2156
+ if (typeof value === "string")
2157
+ try {
2158
+ margins = JSON.parse(value);
2159
+ } catch {
2160
+ margins = {};
2161
+ }
2162
+ return Object.fromEntries(
2163
+ Object.entries(margins).map(([key, twips]) => [key, Number(twips) / 15])
2164
+ );
2165
+ }
2166
+ function cellPadding(value) {
2167
+ const margins = marginValues(value);
2168
+ return `padding:${["top", "right", "bottom", "left"].map(
2169
+ (side) => margins[side] === void 0 ? `var(--dve-cell-padding-${side}, ${DEFAULT_CELL_MARGINS[side] / 15}px)` : `${margins[side]}px`
2170
+ ).join(" ")}`;
2171
+ }
2172
+ function tableCellStyle(attrs) {
2173
+ const borders = parseBordersJson(attrs.borders);
2174
+ const verticalAlign = attrs.verticalAlign === "center" ? "middle" : attrs.verticalAlign === "bottom" ? "bottom" : "top";
2175
+ const declarations = [
2176
+ cellPadding(attrs.margins),
2177
+ `vertical-align:${verticalAlign}`,
2178
+ twipsPx(attrs.widthTwips) && `width:${twipsPx(attrs.widthTwips)}`,
2179
+ typeof attrs.shadingFill === "string" && `background-color:${attrs.shadingFill}`,
2180
+ ...["top", "bottom", "left", "right"].map(
2181
+ (side) => borders && (cssBorderSide(borders[side]) ? `border-${side}:${cssBorderSide(borders[side])}` : `border-${side}-style:none`)
2182
+ )
2183
+ ].filter(Boolean);
2184
+ return declarations.join(";");
2185
+ }
2186
+ function paragraphBoxCss(borders, shadingFill) {
2187
+ const parsed = typeof borders === "string" ? parseBordersJson(borders) : borders;
2188
+ const css = [];
2189
+ for (const side of ["top", "bottom", "left", "right"]) {
2190
+ const line = cssBorderSide(parsed?.[side]);
2191
+ if (!line) continue;
2192
+ css.push(
2193
+ `border-${side}:${line}`,
2194
+ `padding-${side}:${(parsed[side].spacePoints ?? 0) * 4 / 3}px`
2195
+ );
2196
+ }
2197
+ if (typeof shadingFill === "string" && /^#?[0-9a-f]{6}$/i.test(shadingFill))
2198
+ css.push(`background-color:#${shadingFill.replace(/^#/, "")}`);
2199
+ return css;
2200
+ }
2201
+
2202
+ // src/docx/ui/theme/css-vars.ts
2203
+ var THEME_KEYS = [
2204
+ "background",
2205
+ "foreground",
2206
+ "card",
2207
+ "cardForeground",
2208
+ "popover",
2209
+ "popoverForeground",
2210
+ "primary",
2211
+ "primaryForeground",
2212
+ "secondary",
2213
+ "secondaryForeground",
2214
+ "muted",
2215
+ "mutedForeground",
2216
+ "accent",
2217
+ "accentForeground",
2218
+ "destructive",
2219
+ "destructiveForeground",
2220
+ "border",
2221
+ "input",
2222
+ "ring",
2223
+ "radius"
2224
+ ];
2225
+ var kebab = (key) => key.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
2226
+ function themeToCssVars(theme) {
2227
+ const vars = {};
2228
+ if (!theme) return vars;
2229
+ for (const key of THEME_KEYS) {
2230
+ const value = theme[key];
2231
+ if (typeof value === "string" && value.trim()) vars[`--dve-${kebab(key)}`] = value.trim();
2232
+ }
2233
+ return vars;
2234
+ }
2235
+
2236
+ // src/docx/ui/theme/defaults.ts
2237
+ var lightTheme = {
2238
+ background: "#f3f2f1",
2239
+ foreground: "#1f1f1f",
2240
+ card: "#ffffff",
2241
+ cardForeground: "#1f1f1f",
2242
+ popover: "#ffffff",
2243
+ popoverForeground: "#1f1f1f",
2244
+ primary: "#185abd",
2245
+ primaryForeground: "#ffffff",
2246
+ secondary: "#eceae8",
2247
+ secondaryForeground: "#1f1f1f",
2248
+ muted: "#eceae8",
2249
+ mutedForeground: "#605e5c",
2250
+ accent: "#e6edf8",
2251
+ accentForeground: "#103f91",
2252
+ destructive: "#dc2626",
2253
+ destructiveForeground: "#ffffff",
2254
+ border: "#e1dfdd",
2255
+ input: "#c8c6c4",
2256
+ ring: "#185abd",
2257
+ radius: "4px"
2258
+ };
2259
+ var darkTheme = {
2260
+ background: "#030712",
2261
+ foreground: "#f3f4f6",
2262
+ card: "#111827",
2263
+ cardForeground: "#f3f4f6",
2264
+ popover: "#111827",
2265
+ popoverForeground: "#f3f4f6",
2266
+ primary: "#4f8ef7",
2267
+ primaryForeground: "#ffffff",
2268
+ secondary: "#1f2937",
2269
+ secondaryForeground: "#f3f4f6",
2270
+ muted: "#1f2937",
2271
+ mutedForeground: "#9ca3af",
2272
+ accent: "#1e2f4f",
2273
+ accentForeground: "#f3f4f6",
2274
+ destructive: "#ef4444",
2275
+ destructiveForeground: "#ffffff",
2276
+ border: "#374151",
2277
+ input: "#374151",
2278
+ ring: "#4f8ef7",
2279
+ radius: "4px"
2280
+ };
2281
+
2282
+ // src/docx/ui/theme/types.ts
2283
+ var EDITOR_THEME_MODES = ["light", "dark", "auto"];
2284
+
2285
+ // src/docx/ui/theme/element.ts
2286
+ function normalizeThemeMode(value) {
2287
+ return EDITOR_THEME_MODES.includes(value) ? value : "auto";
2288
+ }
2289
+ function applyThemeColors(host, previous, colors) {
2290
+ for (const name of previous) host.style.removeProperty(name);
2291
+ const vars = themeToCssVars(colors);
2292
+ for (const [name, value] of Object.entries(vars)) host.style.setProperty(name, value);
2293
+ return Object.keys(vars);
2294
+ }
2295
+
2296
+ // src/docx/ui/word-count.ts
2297
+ function countWords(text, locale) {
2298
+ if (typeof Intl.Segmenter === "function") {
2299
+ let segmenter;
2300
+ try {
2301
+ segmenter = new Intl.Segmenter(locale || void 0, { granularity: "word" });
2302
+ } catch {
2303
+ segmenter = new Intl.Segmenter(void 0, { granularity: "word" });
2304
+ }
2305
+ return [...segmenter.segment(text)].filter((part) => part.isWordLike).length;
2306
+ }
2307
+ return text.match(/[\p{L}\p{N}][\p{L}\p{M}\p{N}'’]*/gu)?.length ?? 0;
2308
+ }
2309
+
2310
+ // src/docx/ui/zoom-fit.ts
2311
+ var PAGE_GAP = 24;
2312
+ function fitZoomPercent(mode, viewport, page) {
2313
+ if (mode === "actual" || page.width <= 0 || page.height <= 0) return 100;
2314
+ const byWidth = viewport.width / page.width;
2315
+ const ratio = mode === "width" ? byWidth : mode === "pages" ? Math.min(viewport.width / (page.width * 2 + PAGE_GAP), viewport.height / page.height) : Math.min(byWidth, viewport.height / page.height);
2316
+ return Math.max(10, Math.min(500, Math.floor(ratio * 100)));
2317
+ }
2318
+
2319
+ exports.CollaborationAuthority = CollaborationAuthority;
2320
+ exports.CollaborationClient = CollaborationClient;
2321
+ exports.DirtyState = DirtyState;
2322
+ exports.EDITOR_THEME_MODES = EDITOR_THEME_MODES;
2323
+ exports.HEADER_FOOTER_INPUT = HEADER_FOOTER_INPUT;
2324
+ exports.PAGE_GAP = PAGE_GAP;
2325
+ exports.RIBBON_ACTION_IDS = RIBBON_ACTION_IDS;
2326
+ exports.RIBBON_ACTION_LABELS = RIBBON_ACTION_LABELS;
2327
+ exports.SectionPartsStep = SectionPartsStep;
2328
+ exports.THEME_KEYS = THEME_KEYS;
2329
+ exports.applyThemeColors = applyThemeColors;
2330
+ exports.authorColor = authorColor;
2331
+ exports.backstageFocus = backstageFocus;
2332
+ exports.countWords = countWords;
2333
+ exports.createCollaborationIdGenerator = createCollaborationIdGenerator;
2334
+ exports.cssBorderSide = cssBorderSide;
2335
+ exports.darkTheme = darkTheme;
2336
+ exports.deleteAroundMarkers = deleteAroundMarkers;
2337
+ exports.expectDefined = expectDefined;
2338
+ exports.explicitOffFields = explicitOffFields;
2339
+ exports.extraRunFields = extraRunFields;
2340
+ exports.extraRunProperties = extraRunProperties;
2341
+ exports.fieldGuardPlugin = fieldGuardPlugin;
2342
+ exports.fieldMarkerNodeSpec = fieldMarkerNodeSpec;
2343
+ exports.fieldsBalanced = fieldsBalanced;
2344
+ exports.fitZoomPercent = fitZoomPercent;
2345
+ exports.freezeBatch = freezeBatch;
2346
+ exports.imageNodeSpec = imageNodeSpec;
2347
+ exports.isNavigableHref = isNavigableHref;
2348
+ exports.isRibbonActionId = isRibbonActionId;
2349
+ exports.ligatureCss = ligatureCss;
2350
+ exports.ligatureStyle = ligatureStyle;
2351
+ exports.lightTheme = lightTheme;
2352
+ exports.linkMarkSpec = linkMarkSpec;
2353
+ exports.markSpecs = markSpecs;
2354
+ exports.moveName = moveName;
2355
+ exports.nodeNumbering = nodeNumbering;
2356
+ exports.normalizeRibbonActions = normalizeRibbonActions;
2357
+ exports.normalizeThemeMode = normalizeThemeMode;
2358
+ exports.noteReferenceNodeSpec = noteReferenceNodeSpec;
2359
+ exports.pageBreakNodeSpec = pageBreakNodeSpec;
2360
+ exports.paragraphBoxCss = paragraphBoxCss;
2361
+ exports.parseBatch = parseBatch;
2362
+ exports.parseBordersJson = parseBordersJson;
2363
+ exports.placementClass = placementClass;
2364
+ exports.repairCollaborativeDocumentIds = repairCollaborativeDocumentIds;
2365
+ exports.repairCollaborativeParagraphIds = repairCollaborativeParagraphIds;
2366
+ exports.replaceAroundMarkers = replaceAroundMarkers;
2367
+ exports.resolveCellVisuals = resolveCellVisuals;
2368
+ exports.restoreSectionParts = restoreSectionParts;
2369
+ exports.reviewMarks = reviewMarks;
2370
+ exports.ribbonActionIdForLabel = ribbonActionIdForLabel;
2371
+ exports.runPropertiesMark = runPropertiesMark;
2372
+ exports.sameJson = sameJson;
2373
+ exports.sameRuns = sameRuns;
2374
+ exports.sectionPartsJson = sectionPartsJson;
2375
+ exports.swatchColor = swatchColor;
2376
+ exports.tableCellStyle = tableCellStyle;
2377
+ exports.tableStyle = tableStyle;
2378
+ exports.themeDrawing = themeDrawing;
2379
+ exports.themeToCssVars = themeToCssVars;
2380
+ exports.wordHighlightColors = wordHighlightColors;