@stll/folio-core 0.54.1 → 0.55.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 (251) hide show
  1. package/dist/ai-edits/apply.d.ts +1 -1
  2. package/dist/ai-edits/apply.js +40 -32
  3. package/dist/ai-edits/headless.d.ts +1 -2
  4. package/dist/ai-edits/headless.js +13 -27
  5. package/dist/ai-edits/read.d.ts +1 -0
  6. package/dist/ai-edits/read.js +7 -2
  7. package/dist/ai-edits/table-mutation-plan.d.ts +2 -1
  8. package/dist/ai-edits/table-mutation-plan.js +39 -1
  9. package/dist/ai-suggestions/apply.d.ts +1 -1
  10. package/dist/ai-suggestions/apply.js +3 -2
  11. package/dist/compare/compare.js +2 -1
  12. package/dist/compare/content-types.d.ts +3 -15
  13. package/dist/controller/canonicalComposition.d.ts +36 -0
  14. package/dist/controller/canonicalComposition.js +168 -0
  15. package/dist/controller/canonicalInput.d.ts +45 -0
  16. package/dist/controller/canonicalInput.js +338 -0
  17. package/dist/controller/canonicalOperations.d.ts +22 -0
  18. package/dist/controller/canonicalOperations.js +85 -0
  19. package/dist/controller/canonicalReview.d.ts +12 -0
  20. package/dist/controller/canonicalReview.js +19 -0
  21. package/dist/controller/canonicalSession.d.ts +149 -0
  22. package/dist/controller/canonicalSession.js +1038 -0
  23. package/dist/controller/canonicalStoryEditor.d.ts +34 -0
  24. package/dist/controller/canonicalStoryEditor.js +82 -0
  25. package/dist/controller/canonicalStructure.d.ts +16 -0
  26. package/dist/controller/canonicalStructure.js +269 -0
  27. package/dist/controller/folioEditor.d.ts +1 -1
  28. package/dist/controller/folioEditor.js +9 -0
  29. package/dist/controller/headerFooterEditorManager.d.ts +4 -0
  30. package/dist/controller/headerFooterEditorManager.js +71 -3
  31. package/dist/controller/hiddenEditorApi.d.ts +35 -0
  32. package/dist/controller/hiddenEditorApi.js +25 -8
  33. package/dist/controller/hiddenEditorManager.d.ts +11 -2
  34. package/dist/controller/hiddenEditorManager.js +456 -30
  35. package/dist/controller/layoutPipeline.d.ts +1 -1
  36. package/dist/controller/layoutPipeline.js +2 -0
  37. package/dist/controller/noteEditorManager.d.ts +4 -0
  38. package/dist/controller/noteEditorManager.js +113 -15
  39. package/dist/docx/attributeRemainder.js +1 -0
  40. package/dist/docx/bookmarkIds.d.ts +11 -0
  41. package/dist/docx/bookmarkIds.js +33 -0
  42. package/dist/docx/canonicalSessionInput.d.ts +11 -0
  43. package/dist/docx/canonicalSessionInput.js +27 -0
  44. package/dist/docx/canonicalStoryRepack.d.ts +10 -0
  45. package/dist/docx/canonicalStoryRepack.js +41 -0
  46. package/dist/docx/contentTypeRegistry.d.ts +8 -0
  47. package/dist/docx/contentTypeRegistry.js +64 -0
  48. package/dist/docx/documentParser.d.ts +14 -1
  49. package/dist/docx/documentParser.js +17 -4
  50. package/dist/docx/drawingIdNormalization.js +23 -8
  51. package/dist/docx/ensureParaIds.d.ts +12 -1
  52. package/dist/docx/ensureParaIds.js +173 -213
  53. package/dist/docx/foldedListNumberFields.d.ts +85 -0
  54. package/dist/docx/foldedListNumberFields.js +267 -0
  55. package/dist/docx/headerFooterVerbatim.d.ts +14 -1
  56. package/dist/docx/headerFooterVerbatim.js +95 -2
  57. package/dist/docx/listNumberingInstances.js +11 -9
  58. package/dist/docx/noteIds.d.ts +9 -0
  59. package/dist/docx/noteIds.js +17 -0
  60. package/dist/docx/noteReferenceMark.d.ts +3 -1
  61. package/dist/docx/noteReferenceMark.js +15 -14
  62. package/dist/docx/numberingIds.d.ts +14 -0
  63. package/dist/docx/numberingIds.js +16 -0
  64. package/dist/docx/numberingParser.d.ts +3 -1
  65. package/dist/docx/numberingParser.js +17 -3
  66. package/dist/docx/numericIdAllocator.d.ts +12 -0
  67. package/dist/docx/numericIdAllocator.js +33 -0
  68. package/dist/docx/numericIdNormalization.d.ts +16 -0
  69. package/dist/docx/numericIdNormalization.js +174 -0
  70. package/dist/docx/packageParts.d.ts +3 -1
  71. package/dist/docx/packageParts.js +65 -16
  72. package/dist/docx/paragraphMarkPropertyPresence.d.ts +9 -0
  73. package/dist/docx/paragraphMarkPropertyPresence.js +21 -0
  74. package/dist/docx/paragraphParser.js +101 -53
  75. package/dist/docx/paragraphPropertySource.d.ts +15 -1
  76. package/dist/docx/paragraphPropertySource.js +76 -22
  77. package/dist/docx/paragraphTextBoxEnrichment.js +2 -1
  78. package/dist/docx/parser.js +19 -6
  79. package/dist/docx/rasterMime.d.ts +64 -0
  80. package/dist/docx/rasterMime.js +116 -0
  81. package/dist/docx/replyToComment.js +13 -6
  82. package/dist/docx/reviewHistoryNamespace.d.ts +4 -0
  83. package/dist/docx/reviewHistoryNamespace.js +4 -0
  84. package/dist/docx/reviewResolutionProvenance.d.ts +25 -0
  85. package/dist/docx/reviewResolutionProvenance.js +153 -0
  86. package/dist/docx/rezip.d.ts +7 -3
  87. package/dist/docx/rezip.js +121 -52
  88. package/dist/docx/runConsolidator.d.ts +2 -58
  89. package/dist/docx/runConsolidator.js +3 -175
  90. package/dist/docx/runParser.d.ts +2 -1
  91. package/dist/docx/runParser.js +156 -116
  92. package/dist/docx/saveDiagnostics.d.ts +11 -0
  93. package/dist/docx/saveDiagnostics.js +0 -0
  94. package/dist/docx/selectiveSave.d.ts +2 -1
  95. package/dist/docx/selectiveSave.js +14 -1
  96. package/dist/docx/selectiveXmlPatch.d.ts +16 -8
  97. package/dist/docx/selectiveXmlPatch.js +74 -2
  98. package/dist/docx/serializer/headerFooterSerializer.d.ts +5 -1
  99. package/dist/docx/serializer/headerFooterSerializer.js +19 -11
  100. package/dist/docx/serializer/noteSerializer.d.ts +2 -2
  101. package/dist/docx/serializer/noteSerializer.js +24 -8
  102. package/dist/docx/serializer/paragraphSerializer.js +41 -4
  103. package/dist/docx/serializer/partNamespaces.js +6 -3
  104. package/dist/docx/serializer/runSerializer.js +8 -5
  105. package/dist/docx/serializer/trackedChangeAttributes.js +7 -1
  106. package/dist/docx/server/build.js +14 -3
  107. package/dist/docx/server/createBilingualDocument.js +10 -9
  108. package/dist/docx/settingsHeaderFooterUpdate.d.ts +5 -0
  109. package/dist/docx/settingsHeaderFooterUpdate.js +90 -0
  110. package/dist/docx/settingsParser.d.ts +1 -2
  111. package/dist/docx/settingsParser.js +5 -6
  112. package/dist/docx/storyBlockReplay.d.ts +11 -0
  113. package/dist/docx/storyBlockReplay.js +367 -0
  114. package/dist/docx/streamingXmlParser.d.ts +31 -1
  115. package/dist/docx/streamingXmlParser.js +136 -21
  116. package/dist/docx/structuralXmlPatch.js +8 -1
  117. package/dist/docx/unzip.d.ts +3 -1
  118. package/dist/docx/unzip.js +36 -16
  119. package/dist/docx/verbatimCapture.d.ts +3 -1
  120. package/dist/docx/verbatimCapture.js +49 -6
  121. package/dist/i18n/messages/ar.gen.d.ts +5 -0
  122. package/dist/i18n/messages/ar.gen.js +656 -0
  123. package/dist/i18n/messages/cs.gen.d.ts +5 -0
  124. package/dist/i18n/messages/cs.gen.js +656 -0
  125. package/dist/i18n/messages/de.gen.d.ts +5 -0
  126. package/dist/i18n/messages/de.gen.js +656 -0
  127. package/dist/i18n/messages/en.gen.d.ts +5 -0
  128. package/dist/i18n/messages/en.gen.js +656 -0
  129. package/dist/i18n/messages/es.gen.d.ts +5 -0
  130. package/dist/i18n/messages/es.gen.js +656 -0
  131. package/dist/i18n/messages/et.gen.d.ts +5 -0
  132. package/dist/i18n/messages/et.gen.js +656 -0
  133. package/dist/i18n/messages/fr.gen.d.ts +5 -0
  134. package/dist/i18n/messages/fr.gen.js +656 -0
  135. package/dist/i18n/messages/he.gen.d.ts +5 -0
  136. package/dist/i18n/messages/he.gen.js +656 -0
  137. package/dist/i18n/messages/hi.gen.d.ts +5 -0
  138. package/dist/i18n/messages/hi.gen.js +656 -0
  139. package/dist/i18n/messages/hu.gen.d.ts +5 -0
  140. package/dist/i18n/messages/hu.gen.js +656 -0
  141. package/dist/i18n/messages/locales.d.ts +5 -0
  142. package/dist/i18n/messages/locales.js +22 -0
  143. package/dist/i18n/messages/lt.gen.d.ts +5 -0
  144. package/dist/i18n/messages/lt.gen.js +656 -0
  145. package/dist/i18n/messages/lv.gen.d.ts +5 -0
  146. package/dist/i18n/messages/lv.gen.js +656 -0
  147. package/dist/i18n/messages/pl.gen.d.ts +5 -0
  148. package/dist/i18n/messages/pl.gen.js +656 -0
  149. package/dist/i18n/messages/pt-BR.gen.d.ts +5 -0
  150. package/dist/i18n/messages/pt-BR.gen.js +656 -0
  151. package/dist/i18n/messages/sk.gen.d.ts +5 -0
  152. package/dist/i18n/messages/sk.gen.js +656 -0
  153. package/dist/i18n/messages/tr.gen.d.ts +5 -0
  154. package/dist/i18n/messages/tr.gen.js +656 -0
  155. package/dist/i18n/messages/zh-CN.gen.d.ts +5 -0
  156. package/dist/i18n/messages/zh-CN.gen.js +656 -0
  157. package/dist/i18n/messages.d.ts +2 -3
  158. package/dist/i18n/messages.js +1 -19
  159. package/dist/internal/noteMarkerAttrs.d.ts +8 -0
  160. package/dist/internal/noteMarkerAttrs.js +16 -0
  161. package/dist/internal/pageBreakRunSourceDescendantIndex.js +1 -0
  162. package/dist/internal/prosemirrorAttrBoundary.d.ts +21 -0
  163. package/dist/internal/prosemirrorAttrBoundary.js +50 -0
  164. package/dist/layout-bridge/convert/fixedTableColumnWidths.d.ts +6 -0
  165. package/dist/layout-bridge/convert/fixedTableColumnWidths.js +23 -0
  166. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  167. package/dist/layout-bridge/convert/footnoteLayout.js +3 -3
  168. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  169. package/dist/layout-bridge/convert/headerFooterLayout.js +1 -0
  170. package/dist/layout-bridge/convert/noteReferences.d.ts +1 -3
  171. package/dist/layout-bridge/convert/noteReferences.js +1 -6
  172. package/dist/layout-bridge/convert/paragraphRuns.js +2 -4
  173. package/dist/layout-bridge/convert/tableConversion.js +4 -1
  174. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +2 -2
  175. package/dist/layout-bridge/convert/toFlowBlocks.js +2 -2
  176. package/dist/layout-painter/index.js +2 -5
  177. package/dist/managers/DocumentLoaderManager.d.ts +1 -0
  178. package/dist/managers/DocumentLoaderManager.js +8 -1
  179. package/dist/markdown/renderBlock.js +15 -1
  180. package/dist/markdown/renderParagraph.js +9 -13
  181. package/dist/markdown/renderRuns.js +3 -2
  182. package/dist/markdown/renderTable.js +2 -0
  183. package/dist/markdown/types.d.ts +3 -9
  184. package/dist/paged-layout/editorScrollRoot.d.ts +15 -0
  185. package/dist/paged-layout/editorScrollRoot.js +72 -0
  186. package/dist/paged-layout/scrollToPmPosition.js +8 -22
  187. package/dist/prosemirror/attrs/index.d.ts +2 -12
  188. package/dist/prosemirror/attrs/index.js +22 -48
  189. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +2 -1
  190. package/dist/prosemirror/canonicalCommands.d.ts +97 -0
  191. package/dist/prosemirror/canonicalCommands.js +28 -0
  192. package/dist/prosemirror/commands/clearParagraphIndent.d.ts +6 -0
  193. package/dist/prosemirror/commands/clearParagraphIndent.js +25 -0
  194. package/dist/prosemirror/commands/pageBreak.js +15 -1
  195. package/dist/prosemirror/commentIdAllocator.d.ts +15 -22
  196. package/dist/prosemirror/commentIdAllocator.js +50 -25
  197. package/dist/prosemirror/commentReferenceAttrs.d.ts +2 -1
  198. package/dist/prosemirror/conversion/fromProseDoc.js +91 -19
  199. package/dist/prosemirror/conversion/listRenderingDefinition.d.ts +6 -0
  200. package/dist/prosemirror/conversion/listRenderingDefinition.js +97 -0
  201. package/dist/prosemirror/conversion/toProseDoc.d.ts +4 -3
  202. package/dist/prosemirror/conversion/toProseDoc.js +51 -11
  203. package/dist/prosemirror/executeEditorCommand.d.ts +11 -0
  204. package/dist/prosemirror/executeEditorCommand.js +26 -0
  205. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  206. package/dist/prosemirror/extensions/core/HistoryExtension.js +97 -5
  207. package/dist/prosemirror/extensions/core/ParagraphExtension.js +53 -20
  208. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +22 -28
  209. package/dist/prosemirror/extensions/features/ListExtension.js +18 -5
  210. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +5 -2
  211. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +13 -1
  212. package/dist/prosemirror/extensions/marks/TextColorExtension.js +3 -2
  213. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  214. package/dist/prosemirror/extensions/marks/markUtils.js +70 -8
  215. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.d.ts +6 -0
  216. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.js +36 -0
  217. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +4 -2
  218. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +8 -6
  219. package/dist/prosemirror/listMarker.d.ts +1 -0
  220. package/dist/prosemirror/listMarker.js +16 -7
  221. package/dist/prosemirror/listNumbering.js +26 -5
  222. package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
  223. package/dist/prosemirror/listRenderingAttrs.js +3 -0
  224. package/dist/prosemirror/markupViewNotes.js +3 -2
  225. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +2 -1
  226. package/dist/prosemirror/noteReferenceReview.js +5 -3
  227. package/dist/prosemirror/plugins/revisionIds.d.ts +23 -19
  228. package/dist/prosemirror/plugins/revisionIds.js +110 -29
  229. package/dist/prosemirror/plugins/suggestionMode.d.ts +2 -2
  230. package/dist/prosemirror/plugins/suggestionMode.js +246 -42
  231. package/dist/prosemirror/rangeAnchorAttrs.d.ts +2 -1
  232. package/dist/prosemirror/runFormattingFromMarks.d.ts +4 -1
  233. package/dist/prosemirror/runFormattingFromMarks.js +15 -1
  234. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -1
  235. package/dist/prosemirror/runFormattingInlineCarriers.js +4 -1
  236. package/dist/prosemirror/schema/marks.d.ts +2 -0
  237. package/dist/prosemirror/schema/nodes.d.ts +10 -2
  238. package/dist/prosemirror/storyListNumbering.js +11 -9
  239. package/dist/prosemirror/textBoxAnchorAttrs.d.ts +2 -1
  240. package/dist/prosemirror/textInput.d.ts +6 -1
  241. package/dist/prosemirror/textInput.js +14 -3
  242. package/dist/prosemirror/trackedRevisionPath.js +2 -1
  243. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -0
  244. package/dist/prosemirror/trackedRunInlineAtoms.js +1 -0
  245. package/dist/prosemirror/utils/visualLineNavigation.js +6 -8
  246. package/dist/prosemirror/validation.js +4 -0
  247. package/dist/types/content.d.ts +2 -2
  248. package/dist/utils/createDocument.js +2 -2
  249. package/dist/utils/mergeDocumentContent.d.ts +2 -2
  250. package/dist/utils/mergeDocumentContent.js +11 -8
  251. package/package.json +14 -2
@@ -1,9 +1,11 @@
1
+ import { hasNoteReferenceMark } from "../noteReferenceMark.js";
1
2
  import { serializeBlockCustomXml } from "./blockCustomXmlSerializer.js";
2
3
  import { serializeBlockSdt } from "./blockSdtSerializer.js";
3
4
  import { serializeBookmarkMarker } from "./markupRangeAttributes.js";
4
5
  import { serializeParagraph } from "./paragraphSerializer.js";
5
6
  import { serializePartElement } from "./partNamespaces.js";
6
7
  import { serializeTable } from "./tableSerializer.js";
8
+ import { noteUsesCustomMark } from "@stll/docx-core/ops";
7
9
  //#region src/docx/serializer/noteSerializer.ts
8
10
  const NOTE_BASELINE_PREFIXES = [
9
11
  "wpc",
@@ -66,8 +68,9 @@ const NOTE_SEPARATOR_BODY = "<w:p><w:pPr><w:spacing w:after=\"0\" w:line=\"240\"
66
68
  function serializeRequiredNoteSeparators(elementName) {
67
69
  return `<w:${elementName} w:type="separator" w:id="-1">${NOTE_SEPARATOR_BODY}<w:r><w:separator/></w:r></w:p></w:${elementName}><w:${elementName} w:type="continuationSeparator" w:id="0">${NOTE_SEPARATOR_BODY}<w:r><w:continuationSeparator/></w:r></w:p></w:${elementName}>`;
68
70
  }
69
- function insertNoteReferenceMark(xml, elementName) {
70
- if (new RegExp(`<(?:[\\w.-]+:)?${elementName}Ref[\\s/>]`, "u").test(xml)) return xml;
71
+ function insertNoteReferenceMark({ xml, elementName, note, customMark }) {
72
+ if (customMark) return xml;
73
+ if (hasNoteReferenceMark(elementName, note.content)) return xml;
71
74
  const paragraphOpen = /<w:p(?=[\s>])[^>]*>/u.exec(xml);
72
75
  if (!paragraphOpen) return `${`<w:p><w:r><w:rPr><w:rStyle w:val="${elementName === "footnote" ? "FootnoteReference" : "EndnoteReference"}"/></w:rPr><w:${elementName}Ref/></w:r></w:p>`}${xml}`;
73
76
  const paragraphStart = paragraphOpen.index + paragraphOpen[0].length;
@@ -77,8 +80,13 @@ function insertNoteReferenceMark(xml, elementName) {
77
80
  const referenceRun = `<w:r><w:rPr><w:rStyle w:val="${elementName === "footnote" ? "FootnoteReference" : "EndnoteReference"}"/></w:rPr><w:${elementName}Ref/></w:r>`;
78
81
  return `${xml.slice(0, insertAt)}${referenceRun}${xml.slice(insertAt)}`;
79
82
  }
80
- function serializeNewNotePart(elementName, notes) {
81
- const serializedNotes = notes.map((note) => insertNoteReferenceMark(serializeNote(elementName, note), elementName)).join("");
83
+ function serializeNewNotePart({ elementName, notes, document }) {
84
+ const serializedNotes = notes.map((note) => insertNoteReferenceMark({
85
+ xml: serializeNote(elementName, note),
86
+ elementName,
87
+ note,
88
+ customMark: document ? noteUsesCustomMark(document, note) : false
89
+ })).join("");
82
90
  return serializeNotePart(elementName, serializeRequiredNoteSeparators(elementName) + serializedNotes);
83
91
  }
84
92
  /**
@@ -101,13 +109,21 @@ function serializeEndnotes(endnotes) {
101
109
  }
102
110
  /** Serialize a brand-new footnote part, including Word's required separators
103
111
  * and the automatic reference mark at the start of every normal note. */
104
- function serializeNewFootnotesPart(footnotes) {
105
- return serializeNewNotePart("footnote", footnotes);
112
+ function serializeNewFootnotesPart(footnotes, document) {
113
+ return serializeNewNotePart({
114
+ elementName: "footnote",
115
+ notes: footnotes,
116
+ ...document ? { document } : {}
117
+ });
106
118
  }
107
119
  /** Serialize a brand-new endnote part, including Word's required separators
108
120
  * and the automatic reference mark at the start of every normal note. */
109
- function serializeNewEndnotesPart(endnotes) {
110
- return serializeNewNotePart("endnote", endnotes);
121
+ function serializeNewEndnotesPart(endnotes, document) {
122
+ return serializeNewNotePart({
123
+ elementName: "endnote",
124
+ notes: endnotes,
125
+ ...document ? { document } : {}
126
+ });
111
127
  }
112
128
  //#endregion
113
129
  export { serializeEndnotes, serializeFootnotes, serializeNewEndnotesPart, serializeNewFootnotesPart };
@@ -2,7 +2,9 @@ import { modelParagraphFormattingEmission, serializeParagraphPropertySet } from
2
2
  import { serializePreservedAttributes } from "../attributeRemainder.js";
3
3
  import { CONTAINER_CHILDREN } from "../containerChildren.gen.js";
4
4
  import { fieldStateAttributes } from "../fieldState.js";
5
+ import { serializeEmptyMarkProperties } from "../paragraphMarkPropertyPresence.js";
5
6
  import { getParagraphPropertySource, paragraphPropertySourceMatchesEmission } from "../paragraphPropertySource.js";
7
+ import { ReviewResolutionProvenanceError, paragraphMarkResolutionJoinAttributes, serializeParagraphMarkResolutionJoin, serializeResolutionJoins } from "../reviewResolutionProvenance.js";
6
8
  import { DATE_UTC_ATTRIBUTE } from "../trackedChangeInfo.js";
7
9
  import { toTransitionalNamespaceUri } from "../transitionalSpelling.js";
8
10
  import { captureVerbatimXml, createCapturedXmlSanitizer } from "../verbatimCapture.js";
@@ -20,11 +22,22 @@ import { PARAGRAPH_MARK_CHANGE_KINDS } from "@stll/docx-core/model";
20
22
  import { SEQUENCE_CHILDREN } from "@stll/docx-core/schema";
21
23
  //#region src/docx/serializer/paragraphSerializer.ts
22
24
  /**
25
+ * Paragraph Serializer - Serialize paragraphs to OOXML XML
26
+ *
27
+ * Converts Paragraph objects back to <w:p> XML format for DOCX files.
28
+ * Handles all paragraph properties and child content (runs, hyperlinks, fields, bookmarks).
29
+ *
30
+ * OOXML Reference:
31
+ * - Paragraph: w:p
32
+ * - Paragraph properties: w:pPr
33
+ * - Runs, hyperlinks, bookmarks, fields as child elements
34
+ */
35
+ /**
23
36
  * Serialize paragraph formatting properties to w:pPr XML
24
37
  */
25
38
  function serializeParagraphMarkChange(mark) {
26
39
  const attrs = serializeTrackedChangeAttributes(mark.info);
27
- return `<w:${mark.kind} ${attrs}/>`;
40
+ return `<w:${mark.kind} ${attrs}${serializeParagraphMarkResolutionJoin(mark)}/>`;
28
41
  }
29
42
  const RESERVED_PARAGRAPH_PROPERTY_CHILDREN = /* @__PURE__ */ new Set(["pPrChange", "sectPr"]);
30
43
  /**
@@ -212,7 +225,10 @@ const withTrailingParagraphPropertyChildren = (sourceXml, children) => {
212
225
  const withParagraphMarkChange = (sourceXml, mark) => {
213
226
  const root = parseXml(sourceXml, OOXML_NAMESPACE_SCOPE).elements?.at(0);
214
227
  if (!root || root.type !== "element") panic("A validated paragraph-property capture could not be parsed for composition");
215
- const attributes = trackedChangeAttributeRecord(mark.info);
228
+ const attributes = {
229
+ ...trackedChangeAttributeRecord(mark.info),
230
+ ...paragraphMarkResolutionJoinAttributes(mark)
231
+ };
216
232
  const markElement = cloneElement(root, {
217
233
  name: `w:${mark.kind}`,
218
234
  attributes,
@@ -339,6 +355,20 @@ function serializeComplexField(field) {
339
355
  parts.push(`<w:r>${rPrXml}<w:fldChar w:fldCharType="end"/></w:r>`);
340
356
  return parts.join("");
341
357
  }
358
+ var UnrepresentableTrackedCaptureError = class extends TaggedError("UnrepresentableTrackedCaptureError") {};
359
+ /**
360
+ * Preserved markup inside a removal. Markup captured from a removal already
361
+ * spells its text as deleted text. Markup captured outside one and put under
362
+ * a removal afterwards does not: plain runs are respelled here, as a deleted
363
+ * run is. A folded list-number capture that cannot be respelled is refused,
364
+ * rather than written as live text inside the removal.
365
+ */
366
+ function serializeRemovedPreservedInline(item) {
367
+ if (!/<w:(?:t|instrText)[\s>]/u.test(item.xml)) return item.xml;
368
+ if (/^<w:r[\s>]/u.test(item.xml) && !/<w:(?:drawing|pict|object)\b|<mc:AlternateContent\b/u.test(item.xml)) return rewriteRunTextAsDeleted(item.xml);
369
+ if (item.foldedListNumber) throw new UnrepresentableTrackedCaptureError({ message: "A folded list-number field holds markup that cannot be written as deleted content." });
370
+ return item.xml;
371
+ }
342
372
  var UnrepresentableTrackedSimpleFieldError = class extends TaggedError("UnrepresentableTrackedSimpleFieldError") {};
343
373
  /** A revision can contain run-level field characters, but not `w:fldSimple`. */
344
374
  function serializeTrackedSimpleField(field) {
@@ -429,7 +459,12 @@ function trackedChangeTag(change) {
429
459
  }
430
460
  }
431
461
  function serializeTrackedChange(tag, change) {
432
- const attrs = serializeTrackedChangeAttributes(change.info);
462
+ if (change.resolutionJoins !== void 0 && change.content.some((item) => item.type === "hyperlink")) throw new ReviewResolutionProvenanceError({
463
+ attribute: "resolutionJoins",
464
+ reason: "unrepresentable",
465
+ message: "Tracked-resolution provenance cannot be repartitioned across serialized hyperlinks."
466
+ });
467
+ const attrs = serializeTrackedChangeAttributes(change.info) + serializeResolutionJoins(change.resolutionJoins);
433
468
  const disposition = tag === "del" || tag === "moveFrom" ? "removed" : "kept";
434
469
  const serializeContentRun = (run) => serializeInlineRun(run, disposition);
435
470
  const serializeWrappedItem = (item) => {
@@ -451,7 +486,7 @@ function serializeTrackedChange(tag, change) {
451
486
  case "moveFromRangeEnd": return `<w:moveFromRangeEnd ${markupRangeAttributes(item).join(" ")}/>`;
452
487
  case "moveToRangeStart": return serializeMoveRangeStart("moveToRangeStart", item);
453
488
  case "moveToRangeEnd": return `<w:moveToRangeEnd ${markupRangeAttributes(item).join(" ")}/>`;
454
- case "preservedInline": return item.xml;
489
+ case "preservedInline": return disposition === "removed" ? serializeRemovedPreservedInline(item) : item.xml;
455
490
  case "inlineWrapper":
456
491
  case "inlineSdt": return serializeParagraphContent(item, disposition);
457
492
  default: return item;
@@ -574,6 +609,8 @@ function serializeParagraph(paragraph) {
574
609
  if (paragraph.paraId) attrs.push(`w14:paraId="${escapeXmlAttribute(paragraph.paraId)}"`);
575
610
  if (paragraph.textId) attrs.push(`w14:textId="${escapeXmlAttribute(paragraph.textId)}"`);
576
611
  if (paragraph.reviewCarrier) attrs.push(`folio:reviewCarrier="${paragraph.reviewCarrier}"`);
612
+ const emptyMarkProperties = serializeEmptyMarkProperties(paragraph);
613
+ if (emptyMarkProperties !== void 0) attrs.push(emptyMarkProperties);
577
614
  const written = serializePreservedAttributes(attrs, paragraph.preservedAttributes);
578
615
  const attrsStr = written.length > 0 ? ` ${written.join(" ")}` : "";
579
616
  parts.push(serializeParagraphFormattingWithOptions(paragraph.formatting, {
@@ -1,6 +1,7 @@
1
+ import { FOLIO_REVIEW_HISTORY_NAMESPACE } from "../reviewHistoryNamespace.js";
1
2
  import { toTransitionalNamespaceUri } from "../transitionalSpelling.js";
2
3
  import { TaggedError } from "better-result";
3
- import { escapeXmlAttribute } from "@stll/docx-core";
4
+ import { assertValidOoxmlNumericIds, escapeXmlAttribute } from "@stll/docx-core";
4
5
  import { OOXML_NS } from "@stll/docx-utils";
5
6
  //#region src/docx/serializer/partNamespaces.ts
6
7
  /**
@@ -144,7 +145,7 @@ const OOXML_NAMESPACES = {
144
145
  ignorable: true
145
146
  },
146
147
  folio: {
147
- uri: "urn:stella:folio:review-history:1",
148
+ uri: FOLIO_REVIEW_HISTORY_NAMESPACE,
148
149
  ignorable: true
149
150
  },
150
151
  wpg: {
@@ -322,7 +323,9 @@ const serializePartElement = ({ partPath, rootName, rootAttributes, baselinePref
322
323
  const attributes = orderedPrefixes.map((prefix) => `xmlns:${prefix}="${escapeXmlAttribute(bindings.get(prefix))}"`);
323
324
  const ignorable = orderedPrefixes.filter((prefix) => NAMESPACE_TABLE.get(prefix)?.ignorable === true);
324
325
  if (ignorable.length > 0) attributes.push(`mc:Ignorable="${ignorable.join(" ")}"`);
325
- return `${openingTag} ${attributes.join(" ")}>${body}</${rootName}>`;
326
+ const xml = `${openingTag} ${attributes.join(" ")}>${body}</${rootName}>`;
327
+ assertValidOoxmlNumericIds(xml, partPath);
328
+ return xml;
326
329
  };
327
330
  //#endregion
328
331
  export { OOXML_NAMESPACES, UnboundNamespacePrefixError, readRootNamespaceBindings, serializePartElement };
@@ -7,6 +7,7 @@ import { serializeGraphicFrameLocks } from "../graphicFrameLocks.js";
7
7
  import { DECORATIVE_EXTENSION_URI, DECORATIVE_NAMESPACE } from "../imageParser.js";
8
8
  import { canReplayEditableImageRawXml } from "../imageRawXml.js";
9
9
  import { serializeNonVisualDrawingNames } from "../nonVisualDrawingProps.js";
10
+ import { serializeBoundaryJoins } from "../reviewResolutionProvenance.js";
10
11
  import { runHoldsPayload } from "../runPayload.js";
11
12
  import { replayableShapeAlternateContent } from "../shapeAlternateContent.js";
12
13
  import { requiredWrapPolygon, serializeWrapPolygon } from "../wrapPolygon.js";
@@ -16,7 +17,7 @@ import { serializeTextFormatting } from "./textFormattingSerializer.js";
16
17
  import { getSingularRunPropertyChange, serializeTrackedChangeAttributes } from "./trackedChangeAttributes.js";
17
18
  import { intAttr } from "./xmlUtils.js";
18
19
  import { panic } from "better-result";
19
- import { escapeXmlAttribute, escapeXmlText, requiresXmlSpacePreserve } from "@stll/docx-core";
20
+ import { escapeXmlAttribute, escapeXmlText, isValidOoxmlNumericId, requiresXmlSpacePreserve } from "@stll/docx-core";
20
21
  import { SCHEME_COLOR_VALUE_BY_THEME_COLOR, knownThemeColor, presetLineDashToken } from "@stll/docx-core/model";
21
22
  //#region src/docx/serializer/runSerializer.ts
22
23
  /**
@@ -32,7 +33,7 @@ import { SCHEME_COLOR_VALUE_BY_THEME_COLOR, knownThemeColor, presetLineDashToken
32
33
  */
33
34
  /**
34
35
  * Auto-incrementing counter for generating unique image/shape IDs.
35
- * Used as a fallback when `image.id` or `shape.id` is undefined (e.g., pasted images).
36
+ * Used when a model id cannot identify a DrawingML object (e.g., a VML lexical id).
36
37
  * Starts high (100000) to avoid collisions with IDs parsed from existing DOCX content.
37
38
  */
38
39
  let nextAutoId = 1e5;
@@ -43,14 +44,15 @@ let nextAutoId = 1e5;
43
44
  function resetAutoIdCounter() {
44
45
  nextAutoId = 1e5;
45
46
  }
46
- /** Get a unique positive integer ID, using the provided value or generating one */
47
+ /** Get an unsigned integer ID, using the provided value or generating one */
47
48
  function getUniqueId(id) {
48
- if (id !== void 0 && id !== "" && id !== 0) return String(id);
49
+ if (id !== void 0 && isValidOoxmlNumericId(id, "unsigned32")) return String(id);
50
+ if (!isValidOoxmlNumericId(nextAutoId, "unsigned32")) panic("DrawingML generated id space is exhausted.");
49
51
  return String(nextAutoId++);
50
52
  }
51
53
  function serializeRunPropertyChange(change) {
52
54
  const previousRPrXml = serializeTextFormatting(change.previousFormatting) || "<w:rPr/>";
53
- return `<w:rPrChange ${serializeTrackedChangeAttributes(change.info)}>${previousRPrXml}</w:rPrChange>`;
55
+ return `<w:rPrChange ${serializeTrackedChangeAttributes(change.info)}${serializeBoundaryJoins(change.boundaryJoins)}>${previousRPrXml}</w:rPrChange>`;
54
56
  }
55
57
  function serializeRunProperties(formatting, propertyChanges) {
56
58
  const propertyChange = getSingularRunPropertyChange(propertyChanges);
@@ -536,6 +538,7 @@ function serializeRunContent(content) {
536
538
  case "symbol": return serializeSymbolContent(content);
537
539
  case "footnoteRef":
538
540
  case "endnoteRef": return serializeNoteReference(content);
541
+ case "noteMarker": return content.kind === "footnote" ? "<w:footnoteRef/>" : "<w:endnoteRef/>";
539
542
  case "fieldChar": return serializeFieldChar(content);
540
543
  case "instrText": return serializeInstrText(content);
541
544
  case "softHyphen": return serializeSoftHyphen(content);
@@ -1,6 +1,6 @@
1
1
  import { DATE_UTC_ATTRIBUTE } from "../trackedChangeInfo.js";
2
2
  import { panic } from "better-result";
3
- import { escapeXmlAttribute } from "@stll/docx-core";
3
+ import { assertValidOoxmlNumericId, escapeXmlAttribute } from "@stll/docx-core";
4
4
  import { normalizeRevisionId } from "@stll/docx-core/model";
5
5
  //#region src/docx/serializer/trackedChangeAttributes.ts
6
6
  /** Enforces the singular `w:rPrChange` child in a run-property container. */
@@ -14,6 +14,12 @@ const getSingularRunPropertyChange = (propertyChanges) => {
14
14
  };
15
15
  /** Normalized, unescaped attributes in schema order for an XML element or string serializer. */
16
16
  const trackedChangeAttributeEntries = (info) => {
17
+ assertValidOoxmlNumericId({
18
+ value: info.id,
19
+ partPath: "word/*.xml",
20
+ elementName: "tracked change",
21
+ attributeName: "w:id"
22
+ });
17
23
  const author = typeof info.author === "string" ? info.author.trim() : "";
18
24
  const date = typeof info.date === "string" ? info.date.trim() : "";
19
25
  const rawUtcDate = info.utcDate;
@@ -1,4 +1,7 @@
1
+ import { mintBookmarkId, reserveBookmarkIds } from "../bookmarkIds.js";
2
+ import { mintEndnoteId } from "../noteIds.js";
1
3
  import { TaggedError } from "better-result";
4
+ import { assertValidOoxmlNumericId } from "@stll/docx-core";
2
5
  //#region src/docx/server/build.ts
3
6
  /**
4
7
  * Headless document builders.
@@ -103,10 +106,18 @@ const hyperlink = ({ text, formatting, tooltip, href, anchor }) => ({
103
106
  ...formatting
104
107
  })]
105
108
  });
106
- let nextBookmarkId = 0;
107
109
  /** `content` wrapped in a named bookmark, the target of `hyperlink({ anchor })`. */
108
110
  const bookmark = ({ name, content, id }) => {
109
- const bookmarkId = id ?? nextBookmarkId++;
111
+ if (id !== void 0) {
112
+ assertValidOoxmlNumericId({
113
+ value: id,
114
+ partPath: "word/document.xml",
115
+ elementName: "w:bookmarkStart",
116
+ attributeName: "w:id"
117
+ });
118
+ reserveBookmarkIds([id]);
119
+ }
120
+ const bookmarkId = id ?? mintBookmarkId();
110
121
  const start = {
111
122
  type: "bookmarkStart",
112
123
  id: bookmarkId,
@@ -225,7 +236,7 @@ const table = ({ header, rows, columnWidths, headerShading, repeatHeader = true
225
236
  const endnote = (doc, content) => {
226
237
  const endnotes = doc.package.endnotes ?? [];
227
238
  doc.package.endnotes = endnotes;
228
- const id = Math.max(0, ...endnotes.map((note) => note.id)) + 1;
239
+ const id = mintEndnoteId(endnotes.map((note) => note.id));
229
240
  const note = {
230
241
  type: "endnote",
231
242
  id,
@@ -1,5 +1,7 @@
1
1
  import { deterministicHexId } from "../../utils/hexId.js";
2
+ import { createBookmarkIdAllocator } from "../bookmarkIds.js";
2
3
  import { createBuiltInStyleIndex, resolveHeadingLevel } from "../builtInStyles.js";
4
+ import { createNumberingIdAllocator } from "../numberingIds.js";
3
5
  import { mergeParagraphNumbering, paragraphNumberingReference, paragraphNumberingReferenceId } from "../numberingReference.js";
4
6
  import { getParagraphText } from "../paragraphParser.js";
5
7
  import { cloneParagraphWithoutPropertySource } from "../paragraphPropertySource.js";
@@ -271,8 +273,8 @@ const createNumberingCloner = ({ numbering, styleById, warnings }) => {
271
273
  const nums = numbering?.nums ?? [];
272
274
  const abstractById = new Map(abstractNums.map((item) => [item.abstractNumId, item]));
273
275
  const numById = new Map(nums.map((item) => [item.numId, item]));
274
- let nextAbstractNumId = Math.max(0, ...abstractNums.map((item) => item.abstractNumId)) + 1;
275
- let nextNumId = Math.max(0, ...nums.map((item) => item.numId)) + 1;
276
+ const abstractIds = createNumberingIdAllocator("abstract", abstractById.keys());
277
+ const instanceIds = createNumberingIdAllocator("num", numById.keys());
276
278
  const clonedAbstract = /* @__PURE__ */ new Map();
277
279
  const clonedNum = /* @__PURE__ */ new Map();
278
280
  /**
@@ -291,10 +293,9 @@ const createNumberingCloner = ({ numbering, styleById, warnings }) => {
291
293
  const { numStyleLink: _numStyleLink, styleLink: _styleLink, ...rest } = resolved;
292
294
  const clone = {
293
295
  ...rest,
294
- abstractNumId: nextAbstractNumId,
296
+ abstractNumId: abstractIds.next(),
295
297
  levels: structuredClone(resolved.levels)
296
298
  };
297
- nextAbstractNumId += 1;
298
299
  clonedAbstract.set(sourceId, clone);
299
300
  return clone;
300
301
  };
@@ -326,10 +327,9 @@ const createNumberingCloner = ({ numbering, styleById, warnings }) => {
326
327
  if (!abstract) warnings.push(`Numbering instance ${numId} references abstractNum ${source.abstractNumId}, which is not defined; its copy shares the source counters.`);
327
328
  const clone = {
328
329
  ...source,
329
- numId: nextNumId,
330
+ numId: instanceIds.next(),
330
331
  abstractNumId: abstract ? abstract.abstractNumId : source.abstractNumId
331
332
  };
332
- nextNumId += 1;
333
333
  clonedNum.set(numId, clone);
334
334
  return clone.numId;
335
335
  };
@@ -411,7 +411,7 @@ const cloneParagraphForTarget = (paragraph, targetParaId, styleCloner, cloner, b
411
411
  return cloned;
412
412
  };
413
413
  const createBookmarkIdMinter = (source) => {
414
- let nextId = 0;
414
+ const reservedIds = [];
415
415
  const remapped = /* @__PURE__ */ new Map();
416
416
  const visit = (value, seen) => {
417
417
  if (typeof value !== "object" || value === null || seen.has(value)) return;
@@ -423,15 +423,16 @@ const createBookmarkIdMinter = (source) => {
423
423
  const record = value;
424
424
  if (record["type"] === "bookmarkStart" || record["type"] === "bookmarkEnd") {
425
425
  const id = record["id"];
426
- if (typeof id === "number") nextId = Math.max(nextId, id + 1);
426
+ if (typeof id === "number") reservedIds.push(id);
427
427
  }
428
428
  Object.values(record).forEach((item) => visit(item, seen));
429
429
  };
430
430
  visit(source, /* @__PURE__ */ new Set());
431
+ const allocator = createBookmarkIdAllocator(reservedIds);
431
432
  return { mint: (sourceId) => {
432
433
  const existing = remapped.get(sourceId);
433
434
  if (existing !== void 0) return existing;
434
- const id = nextId++;
435
+ const id = allocator.next();
435
436
  remapped.set(sourceId, id);
436
437
  return id;
437
438
  } };
@@ -0,0 +1,5 @@
1
+ //#region src/docx/settingsHeaderFooterUpdate.d.ts
2
+ /** Null means the source is malformed or outside the supported namespace profiles. */
3
+ declare const updateEvenAndOddHeaders: (xml: string, enabled: boolean | undefined) => string | null;
4
+ //#endregion
5
+ export { updateEvenAndOddHeaders };
@@ -0,0 +1,90 @@
1
+ import { spliceXml } from "./selectiveXmlPatch.js";
2
+ import { WORDPROCESSINGML_NAMESPACE_URIS, getChildElements, getLocalName, getNamespaceUri, parseXmlDocument } from "./xmlParser.js";
3
+ import { panic } from "better-result";
4
+ import { SETTINGS_CHILDREN } from "@stll/docx-core/schema";
5
+ //#region src/docx/settingsHeaderFooterUpdate.ts
6
+ /** Preserve producer settings while updating the document-wide header/footer switch. */
7
+ const XML_TOKEN = /<!--[\s\S]*?-->|<!\[CDATA\[[\s\S]*?\]\]>|<\?[\s\S]*?\?>|<(?:"[^"]*"|'[^']*'|[^'">])*>/gu;
8
+ const SETTINGS_CHILD_ORDINALS = new Map(SETTINGS_CHILDREN.map((name, index) => [name, index]));
9
+ const EVEN_AND_ODD_HEADERS_ORDER = SETTINGS_CHILD_ORDINALS.get("evenAndOddHeaders");
10
+ /** Null means the source is malformed or outside the supported namespace profiles. */
11
+ const updateEvenAndOddHeaders = (xml, enabled) => {
12
+ const root = parseXmlDocument(xml);
13
+ if (!root || getLocalName(root.name) !== "settings" || !WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(root) ?? "")) return null;
14
+ const children = getChildElements(root);
15
+ const spans = [];
16
+ const stack = [];
17
+ let childIndex = 0;
18
+ let childStart = -1;
19
+ let rootEnd = -1;
20
+ let rootOpenEnd = -1;
21
+ let selfClosingRootStart = -1;
22
+ let firstFollowingChildStart = -1;
23
+ if (EVEN_AND_ODD_HEADERS_ORDER === void 0) panic("Generated CT_Settings schema does not define evenAndOddHeaders");
24
+ for (const token of xml.matchAll(XML_TOKEN)) {
25
+ const tag = token[0];
26
+ if (tag.startsWith("<!") || tag.startsWith("<?")) continue;
27
+ const closing = tag.startsWith("</");
28
+ const name = tag.slice(closing ? 2 : 1).split(/[\s/>]/u).at(0);
29
+ if (!name) return null;
30
+ if (closing) {
31
+ if (stack.pop() !== name) return null;
32
+ if (stack.length === 1) {
33
+ const child = children[childIndex++];
34
+ if (!child || childStart < 0) return null;
35
+ if (getLocalName(child.name) === "evenAndOddHeaders" && WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(child) ?? "")) spans.push({
36
+ start: childStart,
37
+ end: token.index + tag.length,
38
+ newXml: ""
39
+ });
40
+ childStart = -1;
41
+ }
42
+ if (stack.length === 0) rootEnd = token.index;
43
+ continue;
44
+ }
45
+ if (stack.length === 0) {
46
+ rootOpenEnd = token.index + tag.length;
47
+ if (tag.endsWith("/>")) selfClosingRootStart = token.index;
48
+ }
49
+ if (stack.length === 1) {
50
+ const child = children[childIndex];
51
+ if (child?.name !== name) return null;
52
+ if (firstFollowingChildStart < 0 && WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(child) ?? "") && (SETTINGS_CHILD_ORDINALS.get(getLocalName(child.name)) ?? -1) > EVEN_AND_ODD_HEADERS_ORDER) firstFollowingChildStart = token.index;
53
+ childStart = token.index;
54
+ if (tag.endsWith("/>")) {
55
+ childIndex += 1;
56
+ if (getLocalName(child.name) === "evenAndOddHeaders" && WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(child) ?? "")) spans.push({
57
+ start: token.index,
58
+ end: token.index + tag.length,
59
+ newXml: ""
60
+ });
61
+ childStart = -1;
62
+ }
63
+ }
64
+ if (!tag.endsWith("/>")) stack.push(name);
65
+ }
66
+ if (stack.length !== 0 || childIndex !== children.length) return null;
67
+ const flag = enabled === void 0 ? "" : `<folioW:evenAndOddHeaders xmlns:folioW="${getNamespaceUri(root)}"${enabled ? "" : " folioW:val=\"0\""}/>`;
68
+ if (selfClosingRootStart >= 0) {
69
+ if (!flag) return xml;
70
+ return spliceXml(xml, [{
71
+ start: rootOpenEnd - 2,
72
+ end: rootOpenEnd,
73
+ newXml: `>${flag}</${root.name}>`
74
+ }]);
75
+ }
76
+ if (rootEnd < 0) return null;
77
+ const existingFlag = spans.at(0);
78
+ if (flag && existingFlag) existingFlag.newXml = flag;
79
+ else if (flag) {
80
+ const insertAt = firstFollowingChildStart >= 0 ? firstFollowingChildStart : rootEnd;
81
+ spans.push({
82
+ start: insertAt,
83
+ end: insertAt,
84
+ newXml: flag
85
+ });
86
+ }
87
+ return spliceXml(xml, spans);
88
+ };
89
+ //#endregion
90
+ export { updateEvenAndOddHeaders };
@@ -1,7 +1,6 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
+ import { DEFAULT_TAB_STOP_TWIPS } from "@stll/docx-core/model";
2
3
  //#region src/docx/settingsParser.d.ts
3
- /** OOXML default per §17.6.13 when `w:defaultTabStop` is absent. */
4
- declare const DEFAULT_TAB_STOP_TWIPS = 720;
5
4
  declare function parseSettings(xml: string | null): document_d_exports.DocumentSettings;
6
5
  //#endregion
7
6
  export { DEFAULT_TAB_STOP_TWIPS, parseSettings };
@@ -1,8 +1,7 @@
1
1
  import { parseEndnoteProperties } from "./notePropertiesParser.js";
2
2
  import { WORDPROCESSINGML_NAMESPACE_URIS, findChild, findChildByNamespaceUri, findChildren, getAttribute, parseBooleanElement, parseXmlDocument } from "./xmlParser.js";
3
+ import { DEFAULT_TAB_STOP_TWIPS, DEFAULT_TAB_STOP_TWIPS as DEFAULT_TAB_STOP_TWIPS$1 } from "@stll/docx-core/model";
3
4
  //#region src/docx/settingsParser.ts
4
- /** OOXML default per §17.6.13 when `w:defaultTabStop` is absent. */
5
- const DEFAULT_TAB_STOP_TWIPS = 720;
6
5
  /**
7
6
  * Sanity cap on `w:defaultTabStop`. Word's maximum margin is ~22 inches
8
7
  * (31 680 twips); anything past that is corruption or a hostile input and
@@ -111,13 +110,13 @@ function parseKinsokuOverride(root, name) {
111
110
  };
112
111
  }
113
112
  function parseDefaultTabStop(root) {
114
- if (!root) return 720;
113
+ if (!root) return DEFAULT_TAB_STOP_TWIPS$1;
115
114
  const el = findChild(root, "w", "defaultTabStop");
116
- if (!el) return 720;
115
+ if (!el) return DEFAULT_TAB_STOP_TWIPS$1;
117
116
  const raw = getAttribute(el, "w", "val");
118
- if (raw === null) return 720;
117
+ if (raw === null) return DEFAULT_TAB_STOP_TWIPS$1;
119
118
  const parsed = Number.parseInt(raw, 10);
120
- if (!Number.isFinite(parsed) || parsed < MIN_TAB_STOP_TWIPS || parsed > MAX_TAB_STOP_TWIPS) return 720;
119
+ if (!Number.isFinite(parsed) || parsed < MIN_TAB_STOP_TWIPS || parsed > MAX_TAB_STOP_TWIPS) return DEFAULT_TAB_STOP_TWIPS$1;
121
120
  return parsed;
122
121
  }
123
122
  //#endregion
@@ -0,0 +1,11 @@
1
+ import { document_d_exports } from "../types/document.js";
2
+ //#region src/docx/storyBlockReplay.d.ts
3
+ type StoryBlockReplayOptions = {
4
+ sourceXml: string;
5
+ baselineContent: readonly document_d_exports.BlockContent[];
6
+ currentContent: readonly document_d_exports.BlockContent[];
7
+ serializedXml: string;
8
+ };
9
+ declare const buildStoryBlockReplay: (options: StoryBlockReplayOptions) => string | null;
10
+ //#endregion
11
+ export { buildStoryBlockReplay };