@betteroffice/docx 0.0.1

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 (190) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +41 -0
  3. package/dist/Subscribable-DOz6Ohoo.d.mts +33 -0
  4. package/dist/agent/index.d.mts +531 -0
  5. package/dist/agent/index.mjs +1 -0
  6. package/dist/chunk-34K66SY4.mjs +1 -0
  7. package/dist/chunk-3UBMCDME.mjs +1 -0
  8. package/dist/chunk-4RCISPPE.mjs +1 -0
  9. package/dist/chunk-4UD54UM5.mjs +1 -0
  10. package/dist/chunk-52GB3Y42.mjs +1 -0
  11. package/dist/chunk-6NEKRDXF.mjs +1 -0
  12. package/dist/chunk-6PW4CWUG.mjs +1 -0
  13. package/dist/chunk-7DEIW7FL.mjs +1 -0
  14. package/dist/chunk-7PCO5I2O.mjs +1 -0
  15. package/dist/chunk-BI3B33LI.mjs +1 -0
  16. package/dist/chunk-BIQWVK5P.mjs +2 -0
  17. package/dist/chunk-CIRN3LZA.mjs +1 -0
  18. package/dist/chunk-DXKG3HQ5.mjs +16 -0
  19. package/dist/chunk-EUUIJVM6.mjs +0 -0
  20. package/dist/chunk-FPZBTOD6.mjs +1 -0
  21. package/dist/chunk-FZIA7OFY.mjs +1 -0
  22. package/dist/chunk-GWKJ2Y4Y.mjs +1 -0
  23. package/dist/chunk-H3JCIGWK.mjs +1 -0
  24. package/dist/chunk-HJGAQIU7.mjs +2 -0
  25. package/dist/chunk-I6KKMUUC.mjs +1 -0
  26. package/dist/chunk-IL5JZJT7.mjs +1 -0
  27. package/dist/chunk-JY6ILTNS.mjs +1 -0
  28. package/dist/chunk-KEE52TT5.mjs +1 -0
  29. package/dist/chunk-KVKLLTDP.mjs +58 -0
  30. package/dist/chunk-KXNZFTTK.mjs +1 -0
  31. package/dist/chunk-L5ISVQ3W.mjs +1 -0
  32. package/dist/chunk-LDUWIM7M.mjs +1 -0
  33. package/dist/chunk-N5Q3YN64.mjs +1 -0
  34. package/dist/chunk-NEWOMDTX.mjs +1 -0
  35. package/dist/chunk-O2QSE2I7.mjs +1 -0
  36. package/dist/chunk-OBQGPMPQ.mjs +1 -0
  37. package/dist/chunk-OJOHXQNQ.mjs +1 -0
  38. package/dist/chunk-OMR3TWCD.mjs +2 -0
  39. package/dist/chunk-P3KDV4M2.mjs +1 -0
  40. package/dist/chunk-Q7PO7V73.mjs +1 -0
  41. package/dist/chunk-QOUFE3VX.mjs +1 -0
  42. package/dist/chunk-SINEY6ZF.mjs +1 -0
  43. package/dist/chunk-T4EZMUXM.mjs +1 -0
  44. package/dist/chunk-TTRUPDAB.mjs +1 -0
  45. package/dist/chunk-TYHI7RAD.mjs +1 -0
  46. package/dist/chunk-UIEJWORW.mjs +1 -0
  47. package/dist/chunk-VAOUFAUH.mjs +1 -0
  48. package/dist/chunk-VBOTMRXV.mjs +1 -0
  49. package/dist/chunk-VCER63GQ.mjs +1 -0
  50. package/dist/chunk-WAUF2UC7.mjs +2 -0
  51. package/dist/chunk-WRWRCBLK.mjs +1 -0
  52. package/dist/chunk-X4XDO3LZ.mjs +1 -0
  53. package/dist/chunk-XQBCCJBO.mjs +9 -0
  54. package/dist/chunk-XWUOLYRQ.mjs +2 -0
  55. package/dist/chunk-XYH6XWP3.mjs +10 -0
  56. package/dist/chunk-YBIM6UJV.mjs +8 -0
  57. package/dist/chunk-YCIH2Q3E.mjs +1 -0
  58. package/dist/chunk-YUOKI2HB.mjs +1 -0
  59. package/dist/chunk-ZOV5KL7C.mjs +1 -0
  60. package/dist/colorResolver-n0o7H7ep.d.mts +290 -0
  61. package/dist/content-sSHuWw49.d.mts +2202 -0
  62. package/dist/core-plugins.d.mts +37 -0
  63. package/dist/core-plugins.mjs +1 -0
  64. package/dist/core.d.mts +451 -0
  65. package/dist/core.mjs +1 -0
  66. package/dist/displayListQueries-p-ijSzdh.d.mts +222 -0
  67. package/dist/docx/index.d.mts +618 -0
  68. package/dist/docx/index.mjs +2 -0
  69. package/dist/docx/parser.d.mts +41 -0
  70. package/dist/docx/parser.mjs +1 -0
  71. package/dist/docx/rezip.d.mts +148 -0
  72. package/dist/docx/rezip.mjs +1 -0
  73. package/dist/docx/serializer/index.d.mts +42 -0
  74. package/dist/docx/serializer/index.mjs +1 -0
  75. package/dist/docx/wrapTypes.d.mts +19 -0
  76. package/dist/docx/wrapTypes.mjs +1 -0
  77. package/dist/docxInput-DTbCa48g.d.mts +21 -0
  78. package/dist/editor/index.d.mts +170 -0
  79. package/dist/editor/index.mjs +1 -0
  80. package/dist/editorTree-DO5PyDK8.d.mts +37 -0
  81. package/dist/executor-7O2RBJ2B.mjs +1 -0
  82. package/dist/fontLoader-Bx6DK6-2.d.mts +327 -0
  83. package/dist/formatting-DoL7KBSL.d.mts +823 -0
  84. package/dist/generated/edit/docx_edit_bg.wasm +0 -0
  85. package/dist/generated/layout/docx_layout_bg.wasm +0 -0
  86. package/dist/generated/opc/ooxml_opc_bg.wasm +0 -0
  87. package/dist/generated/parse/docx_parse_bg.wasm +0 -0
  88. package/dist/headerFooterLayout-0zPT64Qc.d.mts +316 -0
  89. package/dist/headless.d.mts +69 -0
  90. package/dist/headless.mjs +1 -0
  91. package/dist/layout/flow/index.d.mts +149 -0
  92. package/dist/layout/flow/index.mjs +1 -0
  93. package/dist/layout/index.d.mts +307 -0
  94. package/dist/layout/index.mjs +1 -0
  95. package/dist/layout/measure/index.d.mts +324 -0
  96. package/dist/layout/measure/index.mjs +1 -0
  97. package/dist/layout/pagination/index.d.mts +60 -0
  98. package/dist/layout/pagination/index.mjs +1 -0
  99. package/dist/layout/pagination/types.d.mts +4 -0
  100. package/dist/layout/pagination/types.mjs +1 -0
  101. package/dist/layout/render/index.d.mts +733 -0
  102. package/dist/layout/render/index.mjs +1 -0
  103. package/dist/loadWasmAsset-CMvnVkfA.d.mts +3 -0
  104. package/dist/managers/AutoSaveManager.d.mts +81 -0
  105. package/dist/managers/AutoSaveManager.mjs +1 -0
  106. package/dist/managers/TableSelectionManager.d.mts +74 -0
  107. package/dist/managers/TableSelectionManager.mjs +1 -0
  108. package/dist/managers/types.d.mts +113 -0
  109. package/dist/managers/types.mjs +0 -0
  110. package/dist/mcp-cli.mjs +142 -0
  111. package/dist/mcp.d.mts +162 -0
  112. package/dist/mcp.mjs +16 -0
  113. package/dist/measureBlocksPipeline-Df0Bbrwy.d.mts +109 -0
  114. package/dist/measuredBlock-DZwz8zhD.d.mts +26 -0
  115. package/dist/plugin-api/RenderedDomContext.d.mts +114 -0
  116. package/dist/plugin-api/RenderedDomContext.mjs +1 -0
  117. package/dist/plugin-api/index.d.mts +7 -0
  118. package/dist/plugin-api/index.mjs +0 -0
  119. package/dist/plugin-api/resolveItemPositions.d.mts +39 -0
  120. package/dist/plugin-api/resolveItemPositions.mjs +1 -0
  121. package/dist/plugin-api/types.d.mts +193 -0
  122. package/dist/plugin-api/types.mjs +0 -0
  123. package/dist/processTemplate-HDUIZFJ5.mjs +1 -0
  124. package/dist/registry-DMM5VTdT.d.mts +165 -0
  125. package/dist/rustDisplayList-dqunvwxH.d.mts +1036 -0
  126. package/dist/rustPagination-Bj2hq013.d.mts +106 -0
  127. package/dist/sectionConfigs-DW3J8q0X.d.mts +55 -0
  128. package/dist/selectionContext-Buc9BCU1.d.mts +570 -0
  129. package/dist/selectiveSave-oFBJ1n71.d.mts +16 -0
  130. package/dist/selectiveXmlPatch-ypkxlTD_.d.mts +23 -0
  131. package/dist/settingsParser-CcGvtmCK.d.mts +33 -0
  132. package/dist/styles/index.d.mts +162 -0
  133. package/dist/styles/index.mjs +1 -0
  134. package/dist/styles-VxNcXLdi.d.mts +189 -0
  135. package/dist/types/agentApi.d.mts +456 -0
  136. package/dist/types/agentApi.mjs +1 -0
  137. package/dist/types/content.d.mts +3 -0
  138. package/dist/types/content.mjs +1 -0
  139. package/dist/types/document.d.mts +117 -0
  140. package/dist/types/document.mjs +1 -0
  141. package/dist/types-DNrYr6yQ.d.mts +1754 -0
  142. package/dist/types-dYdjUZMo.d.mts +311 -0
  143. package/dist/units-O5Y02RKQ.d.mts +34 -0
  144. package/dist/utils/autoScroll.d.mts +24 -0
  145. package/dist/utils/autoScroll.mjs +1 -0
  146. package/dist/utils/cardStyles.d.mts +22 -0
  147. package/dist/utils/cardStyles.mjs +1 -0
  148. package/dist/utils/comments.d.mts +120 -0
  149. package/dist/utils/comments.mjs +4 -0
  150. package/dist/utils/findReplace.d.mts +114 -0
  151. package/dist/utils/findReplace.mjs +2 -0
  152. package/dist/utils/findVerticalScrollParent.d.mts +25 -0
  153. package/dist/utils/findVerticalScrollParent.mjs +1 -0
  154. package/dist/utils/fontOptions.d.mts +21 -0
  155. package/dist/utils/fontOptions.mjs +1 -0
  156. package/dist/utils/headingCollector.d.mts +28 -0
  157. package/dist/utils/headingCollector.mjs +1 -0
  158. package/dist/utils/highlightColors.d.mts +14 -0
  159. package/dist/utils/highlightColors.mjs +1 -0
  160. package/dist/utils/index.d.mts +956 -0
  161. package/dist/utils/index.mjs +84 -0
  162. package/dist/utils/listState.d.mts +27 -0
  163. package/dist/utils/listState.mjs +1 -0
  164. package/dist/utils/reportIssue.d.mts +23 -0
  165. package/dist/utils/reportIssue.mjs +2 -0
  166. package/dist/utils/sidebarConstants.d.mts +10 -0
  167. package/dist/utils/sidebarConstants.mjs +1 -0
  168. package/dist/utils/stylePreview.d.mts +70 -0
  169. package/dist/utils/stylePreview.mjs +1 -0
  170. package/dist/utils/textSelection.d.mts +92 -0
  171. package/dist/utils/textSelection.mjs +1 -0
  172. package/dist/utils/units.d.mts +78 -0
  173. package/dist/utils/units.mjs +1 -0
  174. package/dist/variableDetector-Borj29SF.d.mts +115 -0
  175. package/dist/wasm-FZQ5XB2Y.mjs +1 -0
  176. package/dist/wasm-SA237OSP.mjs +1 -0
  177. package/dist/wasm-edit.d.mts +473 -0
  178. package/dist/wasm-edit.mjs +1 -0
  179. package/dist/wasm-layout.d.mts +112 -0
  180. package/dist/wasm-layout.mjs +1 -0
  181. package/dist/wasm-opc.d.mts +16 -0
  182. package/dist/wasm-opc.mjs +1 -0
  183. package/dist/wasm-parse.d.mts +18 -0
  184. package/dist/wasm-parse.mjs +1 -0
  185. package/dist/watermarkApi-DCxjutkg.d.mts +38 -0
  186. package/dist/yrs/index.d.mts +882 -0
  187. package/dist/yrs/index.mjs +1 -0
  188. package/dist/yrs/residentEngineWorker.d.mts +2 -0
  189. package/dist/yrs/residentEngineWorker.mjs +1 -0
  190. package/package.json +365 -0
@@ -0,0 +1,1754 @@
1
+ import { aL as SdtControlState, aP as SdtProperties, bg as RevisionInfo, bh as CellMarker, bi as PresetGeometryPathCommand, Z as DrawingScene, aW as ShapeEffect, b0 as ShapeTextBodyProperties, n as Chart, W as Watermark, a8 as FootnoteProperties, a0 as EndnoteProperties } from './content-sSHuWw49.mjs';
2
+ import { x as TextModernEffects, B as BorderSpec } from './formatting-DoL7KBSL.mjs';
3
+
4
+ /**
5
+ * Layout checkpoints — page-start bookmarks carried on `Layout.checkpoints`.
6
+ *
7
+ * A checkpoint captures everything a paginator holds when a block starts on a
8
+ * pristine page: the block about to be placed, the section cursor, and the
9
+ * live page-flow geometry (including any continuous-section geometry still
10
+ * queued per ECMA-376 §17.6.22). The field is derived data — fully determined
11
+ * by the same inputs as the layout itself — and remains an optional part of
12
+ * the `Layout` contract (omitted from the golden serialization; see
13
+ * `__golden__/serializeLayout.ts`). The Rust engine performs full passes and
14
+ * does not resume from checkpoints.
15
+ */
16
+
17
+ /** Stable section/page state copied onto every page created in a section. */
18
+ type PageSectionState = {
19
+ emitPageMetadata?: boolean;
20
+ sectionIndex?: number;
21
+ sectionId?: string;
22
+ orientation?: 'portrait' | 'landscape';
23
+ headerFooterRefs?: PageHeaderFooterRefs;
24
+ pageNumbering?: PageNumberingContract;
25
+ pageBorders?: PageBorderContract;
26
+ watermark?: SectionBreakBlock['watermark'];
27
+ verticalAlign?: SectionBreakBlock['verticalAlign'];
28
+ noteSettings?: NoteSettingsContract;
29
+ };
30
+ /**
31
+ * The page-flow geometry a layout checkpoint captures: everything a
32
+ * paginator's closure holds that survives across pages, including geometry
33
+ * queued by a continuous section break (ECMA-376 §17.6.22) that has not been
34
+ * applied yet. Plain data — checkpoints ride on `Layout`.
35
+ */
36
+ type PageFlowGeometry = {
37
+ pageSize: {
38
+ w: number;
39
+ h: number;
40
+ };
41
+ margins: PageMargins;
42
+ columns: ColumnLayout;
43
+ pendingPageSize?: {
44
+ w: number;
45
+ h: number;
46
+ };
47
+ pendingMargins?: PageMargins;
48
+ section?: PageSectionState;
49
+ pendingSection?: PageSectionState;
50
+ sectionPageIndex?: number;
51
+ lastLogicalPageNumber?: number;
52
+ lastCreatedSectionKey?: string;
53
+ };
54
+ interface LayoutCheckpoint {
55
+ /** Index of the measured block about to be placed on the pristine page. */
56
+ blockIndex: number;
57
+ /** The place walk's section cursor at that point. */
58
+ sectionIdx: number;
59
+ /** Index into `Layout.pages` of the page being started. */
60
+ pageIndex: number;
61
+ /** 1-based page number of that page. */
62
+ pageNumber: number;
63
+ /** Live paginator geometry at the moment the page was created. */
64
+ flow: PageFlowGeometry;
65
+ }
66
+
67
+ /**
68
+ * Inline SDT widget metadata carried by a painted text run.
69
+ */
70
+ interface InlineSdtWidget {
71
+ kind: 'checkbox';
72
+ /** Stable per-document id derived from the ProseMirror node position. */
73
+ groupId: string;
74
+ /** ProseMirror position of the inline SDT node. */
75
+ pos: number;
76
+ /** Word tag value (`w:tag`). */
77
+ tag?: string;
78
+ /** Word alias value (`w:alias`). */
79
+ alias?: string;
80
+ /** Live checkbox glyph state. */
81
+ checked?: boolean;
82
+ }
83
+ /**
84
+ * One run's visible slice on a laid-out line: the run to render/measure plus
85
+ * its on-line text. For a boundary text run this is a shallow copy sliced to
86
+ * the line's head/tail char (PM positions shifted to match); tabs, images,
87
+ * line breaks, and fields pass through whole with an empty `text`. `text` is
88
+ * the run's textual contribution to the line (empty for non-text runs), so
89
+ * joining a line's segment texts reconstructs the line's visible characters.
90
+ * Materialized during layout by the Rust engine.
91
+ * @public
92
+ */
93
+ type ResolvedSegment = {
94
+ run: Run;
95
+ text: string;
96
+ };
97
+ /**
98
+ * A laid-out line's resolved run segments (see {@link ResolvedSegment}). One
99
+ * is carried per line on `ParagraphFragment.resolvedLines`.
100
+ * @public
101
+ */
102
+ type ResolvedLine = {
103
+ segments: ResolvedSegment[];
104
+ };
105
+ /**
106
+ * Key that identifies a flow block across measure/paginate/paint passes —
107
+ * usually the block's index, sometimes an `${index}-${type}` compound.
108
+ */
109
+ type BlockId = string | number;
110
+ /** Script-specific font slots carried until shaping chooses a face. */
111
+ type RunFontSlots = {
112
+ ascii?: string;
113
+ hAnsi?: string;
114
+ eastAsia?: string;
115
+ cs?: string;
116
+ asciiTheme?: string;
117
+ hAnsiTheme?: string;
118
+ eastAsiaTheme?: string;
119
+ csTheme?: string;
120
+ hint?: 'default' | 'eastAsia' | 'cs';
121
+ };
122
+ /** Three-slot `w:lang` projection; missing slots inherit/no-op. */
123
+ type RunLanguageSlots = {
124
+ latin?: string;
125
+ eastAsia?: string;
126
+ bidi?: string;
127
+ };
128
+ /**
129
+ * Character-level formatting shared by every run flavor (mirrors w:rPr).
130
+ */
131
+ type RunFormatting = {
132
+ bold?: boolean;
133
+ italic?: boolean;
134
+ underline?: boolean | {
135
+ style?: string;
136
+ color?: string;
137
+ };
138
+ strike?: boolean;
139
+ color?: string;
140
+ highlight?: string;
141
+ fontFamily?: string;
142
+ /** All authored font slots. Undefined = use legacy `fontFamily`. */
143
+ fontSlots?: RunFontSlots;
144
+ fontSize?: number;
145
+ /** Complex-script font size in px. Undefined = use `fontSize`. */
146
+ fontSizeCs?: number;
147
+ /** Complex-script bold override. Undefined = use `bold`. */
148
+ boldCs?: boolean;
149
+ /** Complex-script italic override. Undefined = use `italic`. */
150
+ italicCs?: boolean;
151
+ /** Force complex-script formatting (`w:cs`). Undefined = false. */
152
+ complexScript?: boolean;
153
+ /** Run languages. Undefined = no language override. */
154
+ language?: RunLanguageSlots;
155
+ letterSpacing?: number;
156
+ superscript?: boolean;
157
+ subscript?: boolean;
158
+ /** Render glyphs as uppercase regardless of source case (OOXML w:caps). */
159
+ allCaps?: boolean;
160
+ /** Render lowercase glyphs as small uppercase (OOXML w:smallCaps). */
161
+ smallCaps?: boolean;
162
+ /**
163
+ * Vertical baseline shift in CSS pixels (positive = up). OOXML w:position is
164
+ * authored in half-points; converted to px during the bridge so the painter
165
+ * can apply it directly via vertical-align without re-doing the math.
166
+ */
167
+ positionPx?: number;
168
+ /**
169
+ * Horizontal text scale as a percentage (100 = normal, 50 = half-width,
170
+ * 200 = double-width). OOXML w:w specifies pct in raw % (e.g. 90 means 90%).
171
+ */
172
+ horizontalScale?: number;
173
+ /**
174
+ * Minimum font size in points at which kerning kicks in (OOXML w:kern, half-
175
+ * points in source). When this run's effective font size is at or above this
176
+ * threshold, the painter enables font-kerning: normal.
177
+ */
178
+ kerningMinPt?: number;
179
+ /** Engraved/imprint effect (OOXML w:imprint, §17.3.2.18). */
180
+ imprint?: boolean;
181
+ /** Embossed/raised effect (OOXML w:emboss, §17.3.2.13). */
182
+ emboss?: boolean;
183
+ /** Drop-shadow effect (OOXML w:shadow, §17.3.2.31). */
184
+ textShadow?: boolean;
185
+ /** Outlined / hollow text (OOXML w:outline, §17.3.2.23). */
186
+ textOutline?: boolean;
187
+ /**
188
+ * CJK emphasis mark (OOXML w:em, §17.3.2.12). Maps to CSS `text-emphasis`
189
+ * with a position and style; the painter handles the variant lookup.
190
+ */
191
+ emphasisMark?: 'dot' | 'comma' | 'circle' | 'underDot';
192
+ /** Hidden run (OOXML w:vanish, §17.3.2.41). Painter skips the run. */
193
+ hidden?: boolean;
194
+ /**
195
+ * Per-run right-to-left direction (OOXML w:rtl, §17.3.2.30). Independent
196
+ * from the paragraph's bidi flag — a single run may flip direction within
197
+ * an LTR paragraph.
198
+ */
199
+ rtl?: boolean;
200
+ /**
201
+ * Legacy text-effect animation (OOXML w:effect, §17.3.2.11). The painter
202
+ * surfaces it as a class hook so host CSS can opt in to animations.
203
+ */
204
+ textEffect?: 'blinkBackground' | 'lights' | 'antsBlack' | 'antsRed' | 'shimmer' | 'sparkle';
205
+ /**
206
+ * Modern w14 text effects (glow/shadow/reflection/textFill/textOutline),
207
+ * threaded losslessly to the display-list contract. Undefined = none.
208
+ */
209
+ modernEffects?: TextModernEffects;
210
+ /** Hyperlink info if this run is a link */
211
+ hyperlink?: HyperlinkInfo;
212
+ /** Footnote reference ID (if this run contains a footnote reference) */
213
+ footnoteRefId?: number;
214
+ /** Endnote reference ID (if this run contains an endnote reference) */
215
+ endnoteRefId?: number;
216
+ /** Comment IDs if this run is within a comment range */
217
+ commentIds?: number[];
218
+ /** Whether this run is a tracked insertion */
219
+ isInsertion?: boolean;
220
+ /** Whether this run is a tracked deletion */
221
+ isDeletion?: boolean;
222
+ /** Author of the tracked change */
223
+ changeAuthor?: string;
224
+ /** Date of the tracked change */
225
+ changeDate?: string;
226
+ /** Revision ID of the tracked change (for sidebar matching) */
227
+ changeRevisionId?: number;
228
+ /** Logical source-order index, independent of bidi visual paint order. */
229
+ logicalOrder?: number;
230
+ /** Resolved Unicode bidi embedding level. Undefined = resolve downstream. */
231
+ bidiLevel?: number;
232
+ };
233
+ /**
234
+ * Link target attached to a run.
235
+ */
236
+ type HyperlinkInfo = {
237
+ href: string;
238
+ tooltip?: string;
239
+ /** Safe target frame. Undefined = host default. */
240
+ target?: string;
241
+ /** Authored visited-history bit. Undefined = false/unmanaged. */
242
+ history?: boolean;
243
+ /** Location in the target document. */
244
+ docLocation?: string;
245
+ /**
246
+ * Skip the painter's "Word default" blue + underline fallback when the run
247
+ * has no resolved color/underline. Set by the layout for hyperlinks
248
+ * inside TOC paragraphs, where Word renders entries in the TOCx paragraph
249
+ * color rather than the Hyperlink character style's color.
250
+ */
251
+ noDefaultStyle?: boolean;
252
+ };
253
+ /**
254
+ * Run carrying literal text.
255
+ */
256
+ type TextRun = RunFormatting & {
257
+ kind: 'text';
258
+ text: string;
259
+ /** Hyperlink information if this run is a link. */
260
+ hyperlink?: HyperlinkInfo;
261
+ /** PM doc offset where the run's text begins. */
262
+ pmStart?: number;
263
+ /** PM doc offset one past the run's final character. */
264
+ pmEnd?: number;
265
+ /** Inline content-control widget metadata when this run is the visible glyph. */
266
+ inlineSdtWidget?: InlineSdtWidget;
267
+ };
268
+ /** Run for one tab character; measurement resolves its width from the tab grid. */
269
+ type TabRun = RunFormatting & {
270
+ kind: 'tab';
271
+ pmStart?: number;
272
+ pmEnd?: number;
273
+ /** resolved advance in pixels, filled in by measurement */
274
+ width?: number;
275
+ /** Shaped leader glyph metadata. Undefined = no/synthetic legacy leader. */
276
+ leaderGlyphs?: {
277
+ glyph?: string;
278
+ count?: number;
279
+ advance?: number;
280
+ font?: string;
281
+ fontSize?: number;
282
+ color?: string;
283
+ };
284
+ };
285
+ /**
286
+ * Anchor placement for a floating image: each axis pairs a reference frame
287
+ * with either a fixed offset or a named alignment.
288
+ */
289
+ type ImageRunPosition = {
290
+ useSimplePos?: boolean;
291
+ simplePos?: {
292
+ x?: number;
293
+ y?: number;
294
+ };
295
+ relativeHeight?: number;
296
+ behindDoc?: boolean;
297
+ horizontal?: {
298
+ align?: string;
299
+ posOffset?: number;
300
+ relativeTo?: string;
301
+ };
302
+ vertical?: {
303
+ align?: string;
304
+ posOffset?: number;
305
+ relativeTo?: string;
306
+ };
307
+ };
308
+ type WrapTextDirection = 'bothSides' | 'left' | 'right' | 'largest';
309
+ /**
310
+ * Run holding a picture, inline or anchored.
311
+ */
312
+ type ImageRun = {
313
+ kind: 'image';
314
+ src: string;
315
+ width: number;
316
+ height: number;
317
+ alt?: string;
318
+ /** CSS transform string (rotation, flip) */
319
+ transform?: string;
320
+ /** Position for floating/anchored images */
321
+ position?: ImageRunPosition;
322
+ /** Wrap type from DOCX (inline, square, tight, through, topAndBottom, etc.) */
323
+ wrapType?: string;
324
+ /** Display mode for CSS rendering */
325
+ displayMode?: 'inline' | 'block' | 'float';
326
+ /** CSS float direction */
327
+ cssFloat?: 'left' | 'right' | 'none';
328
+ /** Wrap distances in pixels */
329
+ distTop?: number;
330
+ distBottom?: number;
331
+ distLeft?: number;
332
+ distRight?: number;
333
+ /** wp:srcRect crop fractions in [0, 1]; emit as CSS clip-path inset. */
334
+ cropTop?: number;
335
+ cropRight?: number;
336
+ cropBottom?: number;
337
+ cropLeft?: number;
338
+ /** a:alphaModFix → CSS opacity in [0, 1]. */
339
+ opacity?: number;
340
+ /** Decomposed rotation; undefined = parse legacy `transform`. */
341
+ rotationDeg?: number;
342
+ /** Decomposed horizontal flip; undefined = false. */
343
+ flipH?: boolean;
344
+ /** Decomposed vertical flip; undefined = false. */
345
+ flipV?: boolean;
346
+ /** Post-transform footprint used for flow. Undefined = width/height. */
347
+ rotationBounds?: {
348
+ width?: number;
349
+ height?: number;
350
+ offsetX?: number;
351
+ offsetY?: number;
352
+ };
353
+ /** Square/tight/through side choice. Undefined = bothSides. */
354
+ wrapText?: WrapTextDirection;
355
+ /** Tight/through contour in authored coordinates. */
356
+ wrapPolygon?: Array<{
357
+ x?: number;
358
+ y?: number;
359
+ }>;
360
+ /** `wp:anchor/@allowOverlap`; undefined = true. */
361
+ allowOverlap?: boolean;
362
+ /** `wp:anchor/@layoutInCell`; undefined = true. */
363
+ layoutInCell?: boolean;
364
+ /** Effect extent in px. Undefined = zero. */
365
+ effectExtent?: {
366
+ top?: number;
367
+ right?: number;
368
+ bottom?: number;
369
+ left?: number;
370
+ };
371
+ /** Ordered image effects. Undefined = none. */
372
+ effects?: Array<{
373
+ kind?: string;
374
+ amount?: number;
375
+ colors?: string[];
376
+ }>;
377
+ /** Picture border metadata. Undefined = none. */
378
+ outline?: CellBorderSpec;
379
+ /** Accessibility decorative flag. Undefined = false. */
380
+ decorative?: boolean;
381
+ /** Full hyperlink metadata for picture links. */
382
+ hyperlink?: HyperlinkInfo;
383
+ /** Whether this picture is itself a tracked insertion (`<w:ins>`). */
384
+ isInsertion?: boolean;
385
+ /** Whether this picture is itself a tracked deletion (`<w:del>`). */
386
+ isDeletion?: boolean;
387
+ /** Author of the tracked change wrapping the picture. */
388
+ changeAuthor?: string;
389
+ /** Date of the tracked change wrapping the picture. */
390
+ changeDate?: string;
391
+ /** Revision id of the tracked change (for sidebar matching). */
392
+ changeRevisionId?: number;
393
+ pmStart?: number;
394
+ pmEnd?: number;
395
+ };
396
+ /** Run for an explicit w:br — ends the line, not the paragraph. */
397
+ type LineBreakRun = {
398
+ kind: 'lineBreak';
399
+ pmStart?: number;
400
+ pmEnd?: number;
401
+ };
402
+ /**
403
+ * Run whose text is a field instruction (PAGE, NUMPAGES, ...) resolved by the
404
+ * painter once the page context is known.
405
+ */
406
+ type FieldRun = RunFormatting & {
407
+ kind: 'field';
408
+ fieldType: 'PAGE' | 'NUMPAGES' | 'DATE' | 'TIME' | 'OTHER';
409
+ /**
410
+ * Raw Word field type token (e.g. `TOC`, `PAGEREF`) when `fieldType`
411
+ * collapsed it to a painter category. Carried for a11y announcement only.
412
+ */
413
+ rawType?: string;
414
+ /**
415
+ * Raw field instruction text (`w:instrText`), carried INERT so the display
416
+ * list can announce field identity. Never parsed into behavior or executed.
417
+ */
418
+ instruction?: string;
419
+ /** Fallback text if field can't be resolved */
420
+ fallback?: string;
421
+ pmStart?: number;
422
+ pmEnd?: number;
423
+ };
424
+ /**
425
+ * Any run a paragraph can contain.
426
+ */
427
+ type Run = TextRun | TabRun | ImageRun | LineBreakRun | FieldRun;
428
+ /** Paragraph spacing (w:spacing): above/below plus the w:lineRule line rule. */
429
+ type ParagraphSpacing = {
430
+ before?: number;
431
+ after?: number;
432
+ line?: number;
433
+ lineUnit?: 'px' | 'multiplier';
434
+ lineRule?: 'auto' | 'exact' | 'atLeast';
435
+ };
436
+ /**
437
+ * Paragraph indents in pixels (w:ind), including first-line and hanging.
438
+ */
439
+ type ParagraphIndent = {
440
+ left?: number;
441
+ right?: number;
442
+ firstLine?: number;
443
+ hanging?: number;
444
+ };
445
+ /** How text anchors on a tab stop; mirrors w:tab/@w:val (§17.3.1.37). */
446
+ type TabAlignment = 'start' | 'end' | 'center' | 'decimal' | 'bar' | 'clear';
447
+ /**
448
+ * One entry of a paragraph's tab-stop grid.
449
+ */
450
+ type TabStop = {
451
+ /** Tab alignment mode */
452
+ val: TabAlignment;
453
+ /** Position in twips from left margin */
454
+ pos: number;
455
+ /** Optional leader character */
456
+ leader?: 'none' | 'dot' | 'hyphen' | 'underscore' | 'heavy' | 'middleDot';
457
+ };
458
+ /**
459
+ * One edge of a paragraph border (w:pBdr child), pre-converted to pixels.
460
+ */
461
+ type BorderStyle = {
462
+ color?: string;
463
+ style?: string;
464
+ width?: number;
465
+ space?: number;
466
+ };
467
+ /** Paragraph border edges, incl. the between-paragraphs rule and bar edge. */
468
+ type ParagraphBorders = {
469
+ top?: BorderStyle;
470
+ bottom?: BorderStyle;
471
+ left?: BorderStyle;
472
+ right?: BorderStyle;
473
+ between?: BorderStyle;
474
+ bar?: BorderStyle;
475
+ };
476
+ /**
477
+ * Numbering reference of a list paragraph (w:numPr): instance id + level.
478
+ */
479
+ type ListNumPr = {
480
+ numId?: number;
481
+ ilvl?: number;
482
+ };
483
+ /**
484
+ * Everything paragraph-level the measurer and painter need (derived from
485
+ * w:pPr plus resolved list/numbering state).
486
+ */
487
+ type ParagraphAttrs = {
488
+ alignment?: 'left' | 'center' | 'right' | 'justify';
489
+ spacing?: ParagraphSpacing;
490
+ /** See ParagraphFormatting.spacingExplicit. */
491
+ spacingExplicit?: {
492
+ before?: boolean;
493
+ after?: boolean;
494
+ };
495
+ indent?: ParagraphIndent;
496
+ keepNext?: boolean;
497
+ keepLines?: boolean;
498
+ pageBreakBefore?: boolean;
499
+ styleId?: string;
500
+ contextualSpacing?: boolean;
501
+ /** Right-to-left paragraph direction */
502
+ bidi?: boolean;
503
+ borders?: ParagraphBorders;
504
+ shading?: string;
505
+ tabs?: TabStop[];
506
+ numPr?: ListNumPr;
507
+ listMarker?: string;
508
+ listIsBullet?: boolean;
509
+ listMarkerHidden?: boolean;
510
+ listMarkerFontFamily?: string;
511
+ listMarkerFontSize?: number;
512
+ listMarkerSuffix?: 'tab' | 'space' | 'nothing';
513
+ /**
514
+ * Tracked-change state of the list numbering itself. When a list is applied
515
+ * (or removed) under suggesting mode, the marker paints in the insertion /
516
+ * deletion color so an inserted list item's number reads as part of the
517
+ * suggestion, matching Word. `undefined` = numbering is not a pending change.
518
+ */
519
+ listMarkerRevision?: 'ins' | 'del';
520
+ /** Document-wide `w:defaultTabStop` in twips (§17.6.13). Default 720. */
521
+ defaultTabStopTwips?: number;
522
+ defaultFontSize?: number;
523
+ defaultFontFamily?: string;
524
+ /**
525
+ * Skip the empty-paragraph line-height fallback. Used by HF measurement
526
+ * for the canonical OOXML "trailing empty paragraph after a table" pattern
527
+ * — Word renders that paragraph as a zero-height anchor, not as a full
528
+ * line-height of phantom space. See `normalizeHeaderFooterMeasureBlocks`
529
+ * (#381).
530
+ */
531
+ suppressEmptyParagraphHeight?: boolean;
532
+ /**
533
+ * Tracked-change marker on the paragraph mark itself
534
+ * (`<w:pPr><w:rPr><w:ins/>`). The painter renders a pilcrow and margin
535
+ * change bar; the cache key includes presence so two paragraphs with
536
+ * different revisions don't share a measurement.
537
+ */
538
+ pPrIns?: RevisionInfo | null;
539
+ /** Tracked-change marker on the paragraph mark (`<w:pPr><w:rPr><w:del/>`). */
540
+ pPrDel?: RevisionInfo | null;
541
+ };
542
+ /**
543
+ * Flow block for one paragraph: its runs plus resolved attributes.
544
+ */
545
+ type ParagraphBlock = {
546
+ /** Enclosing block-SDT group memberships (outermost first), if any. */
547
+ sdtGroups?: SdtGroup[];
548
+ kind: 'paragraph';
549
+ id: BlockId;
550
+ /** Stable Word `w14:paraId` / PM `paraId`, when available. */
551
+ paraId?: string;
552
+ runs: Run[];
553
+ attrs?: ParagraphAttrs;
554
+ /** ProseMirror start position for this block. */
555
+ pmStart?: number;
556
+ /** ProseMirror end position for this block. */
557
+ pmEnd?: number;
558
+ };
559
+ /**
560
+ * One edge of a table-cell border, in painter-ready CSS units.
561
+ */
562
+ type CellBorderSpec = {
563
+ width?: number;
564
+ color?: string;
565
+ style?: string;
566
+ };
567
+ /**
568
+ * Border edges of a single cell.
569
+ */
570
+ type CellBorders = {
571
+ top?: CellBorderSpec;
572
+ right?: CellBorderSpec;
573
+ bottom?: CellBorderSpec;
574
+ left?: CellBorderSpec;
575
+ };
576
+ /**
577
+ * One cell of a table row; its content is a nested block list.
578
+ */
579
+ type TableCell = {
580
+ id: BlockId;
581
+ blocks: LayoutBlock[];
582
+ colSpan?: number;
583
+ rowSpan?: number;
584
+ width?: number;
585
+ /** Original DOCX cell width value, before unit conversion. */
586
+ widthValue?: number;
587
+ /** Original DOCX cell width type ('auto', 'pct', 'dxa', 'nil'). */
588
+ widthType?: string;
589
+ /** Preferred `tcW` retained as one typed value. Undefined = legacy fields. */
590
+ preferredWidth?: {
591
+ value?: number;
592
+ type?: 'auto' | 'pct' | 'dxa' | 'nil';
593
+ };
594
+ /** Grid column where this cell starts. Undefined = derive sequentially. */
595
+ gridStart?: number;
596
+ /** Min-content width in px. Undefined = not measured. */
597
+ minContentWidth?: number;
598
+ /** Max-content width in px. Undefined = not measured. */
599
+ maxContentWidth?: number;
600
+ verticalAlign?: 'top' | 'center' | 'bottom';
601
+ background?: string;
602
+ borders?: CellBorders;
603
+ /** Per-cell padding in pixels (from w:tcMar or table-level w:tblCellMar) */
604
+ padding?: {
605
+ top: number;
606
+ right: number;
607
+ bottom: number;
608
+ left: number;
609
+ };
610
+ /**
611
+ * `w:noWrap`: when true, the cell forbids text wrapping inside it. The
612
+ * painter renders this as `white-space: nowrap` on the content container
613
+ * — content stays on one line and the cell expands horizontally.
614
+ */
615
+ noWrap?: boolean;
616
+ /** Tracked cell marker (`<w:cellIns>` / `<w:cellDel>` / `<w:cellMerge>`) — painter colors the top border. */
617
+ trackedMarker?: CellMarker;
618
+ };
619
+ /**
620
+ * One row of a table block.
621
+ */
622
+ type TableRow = {
623
+ id: BlockId;
624
+ cells: TableCell[];
625
+ height?: number;
626
+ heightRule?: 'auto' | 'atLeast' | 'exact';
627
+ isHeader?: boolean;
628
+ /**
629
+ * `w:cantSplit` (§17.4.6): the row may not break across a page boundary.
630
+ * The layout engine keeps such a row whole, moving it wholesale to the next
631
+ * page rather than splitting its content.
632
+ */
633
+ cantSplit?: boolean;
634
+ /** Leading omitted grid columns (`w:gridBefore`). Undefined = 0. */
635
+ gridBefore?: number;
636
+ /** Trailing omitted grid columns (`w:gridAfter`). Undefined = 0. */
637
+ gridAfter?: number;
638
+ /** Preferred width before cells. Undefined = 0/auto. */
639
+ widthBefore?: {
640
+ value?: number;
641
+ type?: 'auto' | 'pct' | 'dxa' | 'nil';
642
+ };
643
+ /** Preferred width after cells. Undefined = 0/auto. */
644
+ widthAfter?: {
645
+ value?: number;
646
+ type?: 'auto' | 'pct' | 'dxa' | 'nil';
647
+ };
648
+ /** Tracked row ins / del (`<w:trPr><w:ins/>` / `<w:del/>`). */
649
+ trackedIns?: RevisionInfo;
650
+ /** see trackedIns */ trackedDel?: RevisionInfo;
651
+ };
652
+ /**
653
+ * Placement of a floating table (w:tblpPr), converted to pixels: anchors,
654
+ * fixed or named x/y, and the wrap distances around it.
655
+ */
656
+ type FloatingTablePosition = {
657
+ horzAnchor?: 'margin' | 'page' | 'text';
658
+ tblpX?: number;
659
+ tblpXSpec?: 'left' | 'center' | 'right' | 'inside' | 'outside';
660
+ vertAnchor?: 'margin' | 'page' | 'text';
661
+ tblpY?: number;
662
+ tblpYSpec?: 'top' | 'center' | 'bottom' | 'inside' | 'outside' | 'inline';
663
+ topFromText?: number;
664
+ rightFromText?: number;
665
+ bottomFromText?: number;
666
+ leftFromText?: number;
667
+ };
668
+ /**
669
+ * Flow block for a table: rows plus grid/justification/float properties.
670
+ */
671
+ type TableBlock = {
672
+ /** Enclosing block-SDT group memberships (outermost first), if any. */
673
+ sdtGroups?: SdtGroup[];
674
+ kind: 'table';
675
+ id: BlockId;
676
+ rows: TableRow[];
677
+ columnWidths?: number[];
678
+ /** Authored `w:tblGrid` values, before algorithmic adjustment. */
679
+ gridWidths?: number[];
680
+ /** Table width value (twips for dxa, 50ths of percent for pct). */
681
+ width?: number;
682
+ /** Table width type ('auto', 'pct', 'dxa', 'nil'). */
683
+ widthType?: string;
684
+ /** Preferred `tblW` retained as one typed value. Undefined = legacy fields. */
685
+ preferredWidth?: {
686
+ value?: number;
687
+ type?: 'auto' | 'pct' | 'dxa' | 'nil';
688
+ };
689
+ /** `w:tblLayout`; undefined preserves the legacy resolver. */
690
+ layoutMode?: 'fixed' | 'autofit';
691
+ /** Intrinsic sizing policy. Undefined = legacy fill-available-width. */
692
+ widthAlgorithm?: 'legacy' | 'fixed' | 'autofit';
693
+ /** Resolved table-style provenance/conditionals. */
694
+ styleCascade?: {
695
+ selectedStyleId?: string;
696
+ defaultStyleId?: string;
697
+ basedOnStyleIds?: string[];
698
+ appliedRegions?: string[];
699
+ rowBandSize?: number;
700
+ columnBandSize?: number;
701
+ };
702
+ /** Resolved table background. Undefined = transparent. */
703
+ background?: string;
704
+ /** Table horizontal alignment */
705
+ justification?: 'left' | 'center' | 'right';
706
+ /** Visual RTL column order (`w:bidiVisual`): painter renders logical column 0 rightmost. */
707
+ bidi?: boolean;
708
+ /** Table indent from left margin (in pixels, from w:tblInd) */
709
+ indent?: number;
710
+ /** Floating table properties (pixel values). */
711
+ floating?: FloatingTablePosition;
712
+ pmStart?: number;
713
+ pmEnd?: number;
714
+ };
715
+ /**
716
+ * Flow block for an image promoted out of the text flow (anchored/floating).
717
+ */
718
+ type ImageBlock = {
719
+ /** Enclosing block-SDT group memberships (outermost first), if any. */
720
+ sdtGroups?: SdtGroup[];
721
+ kind: 'image';
722
+ id: BlockId;
723
+ src: string;
724
+ width: number;
725
+ height: number;
726
+ alt?: string;
727
+ /** CSS transform string (rotation, flip) */
728
+ transform?: string;
729
+ opacity?: number;
730
+ rotationDeg?: number;
731
+ flipH?: boolean;
732
+ flipV?: boolean;
733
+ rotationBounds?: {
734
+ width?: number;
735
+ height?: number;
736
+ offsetX?: number;
737
+ offsetY?: number;
738
+ };
739
+ anchor?: {
740
+ isAnchored?: boolean;
741
+ offsetH?: number;
742
+ offsetV?: number;
743
+ behindDoc?: boolean;
744
+ position?: ImageRunPosition;
745
+ relativeHeight?: number;
746
+ allowOverlap?: boolean;
747
+ layoutInCell?: boolean;
748
+ wrapType?: string;
749
+ wrapText?: WrapTextDirection;
750
+ wrapPolygon?: Array<{
751
+ x?: number;
752
+ y?: number;
753
+ }>;
754
+ };
755
+ /** Hyperlink URL for clickable image */
756
+ hlinkHref?: string;
757
+ hlinkTitle?: string;
758
+ decorative?: boolean;
759
+ crop?: {
760
+ top?: number;
761
+ right?: number;
762
+ bottom?: number;
763
+ left?: number;
764
+ };
765
+ effects?: Array<{
766
+ kind?: string;
767
+ amount?: number;
768
+ colors?: string[];
769
+ }>;
770
+ outline?: CellBorderSpec;
771
+ pmStart?: number;
772
+ pmEnd?: number;
773
+ };
774
+ /** Fill data carried by a DrawingML shape block. */
775
+ type ShapeBlockFill = {
776
+ type: 'none' | 'solid' | 'gradient' | 'pattern' | 'picture';
777
+ color?: string;
778
+ gradientType?: string;
779
+ gradientAngle?: number;
780
+ gradientStops?: Array<{
781
+ position: number;
782
+ color: string;
783
+ }>;
784
+ patternPreset?: string;
785
+ foregroundColor?: string;
786
+ backgroundColor?: string;
787
+ pictureRelId?: string;
788
+ /** Resolved SAFE embedded picture source (`blob:`/`data:` only; never external). */
789
+ pictureSrc?: string;
790
+ /** Picture source crop fractions (`a:srcRect`, 0..1; negative = outset). */
791
+ pictureSrcRect?: {
792
+ left?: number;
793
+ top?: number;
794
+ right?: number;
795
+ bottom?: number;
796
+ };
797
+ /** Picture fill mode. Undefined = 'stretch'. */
798
+ pictureFillMode?: 'stretch' | 'tile';
799
+ /** Tile parameters when `pictureFillMode` = 'tile'. Offsets px, scales fractions. */
800
+ pictureTile?: {
801
+ offsetX?: number;
802
+ offsetY?: number;
803
+ scaleX?: number;
804
+ scaleY?: number;
805
+ alignment?: string;
806
+ flip?: 'none' | 'x' | 'y' | 'xy';
807
+ };
808
+ /** Stretch target rect fractions of the shape box (`a:fillRect`, 0..1). */
809
+ pictureStretchRect?: {
810
+ left?: number;
811
+ top?: number;
812
+ right?: number;
813
+ bottom?: number;
814
+ };
815
+ /** Picture alpha 0..1 (`a:alphaModFix`). Undefined = opaque. */
816
+ pictureOpacity?: number;
817
+ themeRefIndex?: number;
818
+ };
819
+ /** Stroke data carried by a DrawingML shape block. */
820
+ type ShapeBlockStroke = {
821
+ color?: string;
822
+ /** Width in CSS pixels. */
823
+ width?: number;
824
+ /** DrawingML/CSS dash style token. */
825
+ dash?: string;
826
+ compound?: string;
827
+ alignment?: string;
828
+ cap?: string;
829
+ join?: string;
830
+ miterLimit?: number;
831
+ customDash?: number[];
832
+ headEnd?: {
833
+ type?: string;
834
+ width?: string;
835
+ length?: string;
836
+ };
837
+ tailEnd?: {
838
+ type?: string;
839
+ width?: string;
840
+ length?: string;
841
+ };
842
+ };
843
+ /** Rotation/flip transform carried by a DrawingML shape block. */
844
+ type ShapeBlockTransform = {
845
+ /** Rotation in degrees. */
846
+ rotation?: number;
847
+ flipH?: boolean;
848
+ flipV?: boolean;
849
+ };
850
+ /**
851
+ * Flow block for a basic DrawingML autoshape/connector.
852
+ *
853
+ * `geometryPath` is normalized to the shape-local `[0, 1]` box; consumers scale
854
+ * it by `width`/`height` and place the corresponding `ShapeFragment` at `x/y`.
855
+ */
856
+ type ShapeBlock = {
857
+ /** Enclosing block-SDT group memberships (outermost first), if any. */
858
+ sdtGroups?: SdtGroup[];
859
+ kind: 'shape';
860
+ id: BlockId;
861
+ /** Preset geometry name or source shape label; `geometryPath` is authoritative. */
862
+ shapeType: string;
863
+ geometryPath: PresetGeometryPathCommand[];
864
+ fill?: ShapeBlockFill;
865
+ stroke?: ShapeBlockStroke;
866
+ transform?: ShapeBlockTransform;
867
+ width: number;
868
+ height: number;
869
+ /** Optional placed coordinates; page fragments are the authoritative placement. */
870
+ x?: number;
871
+ y?: number;
872
+ /** Optional inner paragraphs for future text-bearing shape rendering. */
873
+ innerText?: ParagraphBlock[];
874
+ /** Pre-measured inner paragraph measures for display-list shape text. */
875
+ innerMeasures?: ParagraphExtent[];
876
+ /** Child shapes positioned relative to this shape's top-left corner. */
877
+ children?: ShapeBlock[];
878
+ /** General heterogeneous scene. Undefined = legacy shape-only children. */
879
+ scene?: DrawingScene;
880
+ /** Ordered 2-D effects. Undefined = none. */
881
+ effects?: ShapeEffect[];
882
+ /** Full text-body/autofit settings. */
883
+ textBodyProperties?: ShapeTextBodyProperties;
884
+ /** Anchor/wrap metadata. Undefined = in-flow. */
885
+ position?: ImageRunPosition;
886
+ wrapType?: string;
887
+ wrapText?: WrapTextDirection;
888
+ relativeHeight?: number;
889
+ behindDoc?: boolean;
890
+ decorative?: boolean;
891
+ title?: string;
892
+ description?: string;
893
+ /** PM/doc positions for selection mapping. */
894
+ docStart?: number;
895
+ docEnd?: number;
896
+ pmStart?: number;
897
+ pmEnd?: number;
898
+ };
899
+ /**
900
+ * Flow block for a basic DrawingML chart.
901
+ *
902
+ * v1 measurement is the drawing extent bbox; display-list emission renders the
903
+ * common chart families from the normalized chart model.
904
+ */
905
+ type ChartBlock = {
906
+ /** Enclosing block-SDT group memberships (outermost first), if any. */
907
+ sdtGroups?: SdtGroup[];
908
+ kind: 'chart';
909
+ id: BlockId;
910
+ chart: Chart;
911
+ width: number;
912
+ height: number;
913
+ position?: ImageRunPosition;
914
+ wrapType?: string;
915
+ wrapText?: WrapTextDirection;
916
+ relativeHeight?: number;
917
+ behindDoc?: boolean;
918
+ docStart?: number;
919
+ docEnd?: number;
920
+ pmStart?: number;
921
+ pmEnd?: number;
922
+ };
923
+ /**
924
+ * Flow block marking a section boundary and the page geometry the next
925
+ * section requests (applied by the Rust engine's section handling;
926
+ * ECMA-376 §17.6.22).
927
+ */
928
+ type SectionBreakBlock = {
929
+ /** Enclosing block-SDT group memberships (outermost first), if any. */
930
+ sdtGroups?: SdtGroup[];
931
+ kind: 'sectionBreak';
932
+ id: BlockId;
933
+ type?: 'continuous' | 'nextPage' | 'evenPage' | 'oddPage' | 'nextColumn';
934
+ /** Stable section identity. Undefined = derive from break order. */
935
+ sectionId?: string;
936
+ /** Zero-based section index. Undefined = derive during pagination. */
937
+ sectionIndex?: number;
938
+ pageSize?: {
939
+ w: number;
940
+ h: number;
941
+ };
942
+ orientation?: 'portrait' | 'landscape';
943
+ margins?: PageMargins;
944
+ columns?: ColumnLayout;
945
+ /** Effective header/footer references for the section. */
946
+ headerFooterRefs?: PageHeaderFooterRefs;
947
+ /** Section-relative page-number settings. */
948
+ pageNumbering?: PageNumberingContract;
949
+ /** Page-border contract retained for per-page selection. */
950
+ pageBorders?: PageBorderContract;
951
+ /** Effective watermark metadata. Undefined = none. */
952
+ watermark?: Watermark;
953
+ /** Vertical page alignment. Undefined = top. */
954
+ verticalAlign?: 'top' | 'center' | 'both' | 'bottom';
955
+ /** Per-section note settings. Undefined = document defaults. */
956
+ noteSettings?: NoteSettingsContract;
957
+ };
958
+ /**
959
+ * Flow block for a hard page break (w:br type="page").
960
+ */
961
+ type PageBreakBlock = {
962
+ /** Enclosing block-SDT group memberships (outermost first), if any. */
963
+ sdtGroups?: SdtGroup[];
964
+ kind: 'pageBreak';
965
+ id: BlockId;
966
+ pmStart?: number;
967
+ pmEnd?: number;
968
+ };
969
+ /**
970
+ * Flow block for a hard column break (w:br type="column").
971
+ */
972
+ type ColumnBreakBlock = {
973
+ /** Enclosing block-SDT group memberships (outermost first), if any. */
974
+ sdtGroups?: SdtGroup[];
975
+ kind: 'columnBreak';
976
+ id: BlockId;
977
+ pmStart?: number;
978
+ pmEnd?: number;
979
+ };
980
+ /** Default internal margins for text boxes (OOXML defaults in pixels) */
981
+ declare const DEFAULT_TEXTBOX_MARGINS: {
982
+ top: number;
983
+ bottom: number;
984
+ left: number;
985
+ right: number;
986
+ };
987
+ /** Default text box width in pixels when no width is specified */
988
+ declare const DEFAULT_TEXTBOX_WIDTH = 200;
989
+ /**
990
+ * Text box block — positioned container with paragraph content.
991
+ */
992
+ type TextBoxBlock = {
993
+ /** Enclosing block-SDT group memberships (outermost first), if any. */
994
+ sdtGroups?: SdtGroup[];
995
+ kind: 'textBox';
996
+ id: BlockId;
997
+ /** Width in pixels */
998
+ width: number;
999
+ /** Height in pixels (may be auto-calculated) */
1000
+ height?: number;
1001
+ /** Fill/background color */
1002
+ fillColor?: string;
1003
+ /** Border width in pixels */
1004
+ outlineWidth?: number;
1005
+ /** Border color */
1006
+ outlineColor?: string;
1007
+ /** Border style */
1008
+ outlineStyle?: string;
1009
+ /** Internal padding */
1010
+ margins?: {
1011
+ top: number;
1012
+ bottom: number;
1013
+ left: number;
1014
+ right: number;
1015
+ };
1016
+ /** Paragraph blocks inside the text box */
1017
+ content: ParagraphBlock[];
1018
+ /** Display mode copied from the ProseMirror text box node */
1019
+ displayMode?: 'inline' | 'float' | 'block';
1020
+ /** CSS float direction copied from the ProseMirror text box node */
1021
+ cssFloat?: 'left' | 'right' | 'none';
1022
+ /** OOXML wrap type for anchored text boxes */
1023
+ wrapType?: string;
1024
+ /** OOXML wrapText direction */
1025
+ wrapText?: WrapTextDirection;
1026
+ /** Anchor target used during DOCX import/export */
1027
+ anchorTarget?: 'followingBlock';
1028
+ /** Position for floating/anchored text boxes */
1029
+ position?: ImageRunPosition;
1030
+ /** Wrap distances in pixels */
1031
+ distTop?: number;
1032
+ distBottom?: number;
1033
+ distLeft?: number;
1034
+ distRight?: number;
1035
+ pmStart?: number;
1036
+ pmEnd?: number;
1037
+ };
1038
+ /**
1039
+ * Identity of a block-level Structured Document Tag (content control) enclosing
1040
+ * a run of flow blocks. Block SDTs flatten into their child flow blocks for
1041
+ * pagination; each child carries its group(s) so the painter draws the boundary.
1042
+ */
1043
+ interface SdtGroup {
1044
+ id: string;
1045
+ sdtType: string;
1046
+ tag?: string;
1047
+ alias?: string;
1048
+ lock?: string;
1049
+ checked?: boolean;
1050
+ bound?: boolean;
1051
+ repeatingItem?: boolean;
1052
+ /** Authored numeric `w:id`; undefined = address by `id`/PM position. */
1053
+ controlId?: number;
1054
+ /** Stable PM position for untagged controls. */
1055
+ pos?: number;
1056
+ /** Typed overlay state. Undefined = derive from content. */
1057
+ controlState?: SdtControlState;
1058
+ /** Typed list/date metadata used by overlays. */
1059
+ properties?: SdtProperties;
1060
+ }
1061
+ /**
1062
+ * Union of every block kind the layout engine knows about.
1063
+ *
1064
+ * Two sites must stay in sync with this type:
1065
+ * - `createMeasureBlock` in `layout/measure/rustMeasureSource.ts` (the sole
1066
+ * measurer — it ends in `assertExhaustiveLayoutBlock(block, '<site>')`,
1067
+ * so adding a variant here without updating it is a typecheck error)
1068
+ * - the Rust engine's block enum (`crates/docx-layout/src/types.rs`), which
1069
+ * deserializes the same contract
1070
+ */
1071
+ type LayoutBlock = ParagraphBlock | TableBlock | ImageBlock | ShapeBlock | ChartBlock | TextBoxBlock | SectionBreakBlock | PageBreakBlock | ColumnBreakBlock;
1072
+ /**
1073
+ * Exhaustiveness guard for `LayoutBlock`-shaped switches. Call from the
1074
+ * `default` arm with the still-typed value; TypeScript will refuse to
1075
+ * compile if any variant of `LayoutBlock` was missed. The thrown error
1076
+ * names the calling site so runtime failures (e.g. an old adapter
1077
+ * compiled against a newer core) point future debuggers at the contract.
1078
+ */
1079
+ declare function assertExhaustiveLayoutBlock(block: never, site: string): never;
1080
+ /**
1081
+ * One typeset line of a measured paragraph: which run/char span it covers
1082
+ * and its vertical metrics.
1083
+ */
1084
+ type TypesetRow = {
1085
+ /** Starting run index (inclusive). */
1086
+ headRun: number;
1087
+ /** Starting character index within headRun. */
1088
+ headChar: number;
1089
+ /** Ending run index (inclusive). */
1090
+ tailRun: number;
1091
+ /** Ending character index within tailRun (exclusive). */
1092
+ tailChar: number;
1093
+ /** Total width of the line in pixels. */
1094
+ width: number;
1095
+ /** Ascent (height above baseline) in pixels. */
1096
+ ascent: number;
1097
+ /** Descent (height below baseline) in pixels. */
1098
+ descent: number;
1099
+ /** Total line height in pixels. */
1100
+ lineHeight: number;
1101
+ /** Left offset from floating images (pixels from content left edge). */
1102
+ leftOffset?: number;
1103
+ /** Right offset from floating images (pixels from content right edge). */
1104
+ rightOffset?: number;
1105
+ /** Optional split segments for centered floating exclusions. */
1106
+ segments?: TypesetRowSegment[];
1107
+ /**
1108
+ * Vertical space inserted before this line to skip past floats that leave
1109
+ * no usable horizontal width at the natural line Y. Painters render this
1110
+ * as marginTop on the line element; measurement adds it to totalHeight.
1111
+ */
1112
+ floatSkipBefore?: number;
1113
+ /** Exact per-run advances in visual paint order. Undefined = legacy estimation. */
1114
+ runAdvances?: TypesetRunAdvance[];
1115
+ /** Exact shaped cluster advances. Undefined = legacy estimation. */
1116
+ clusterAdvances?: TypesetClusterAdvance[];
1117
+ /** Bidi slices with separate visual/logical order. */
1118
+ bidiSlices?: TypesetBidiSlice[];
1119
+ };
1120
+ type TypesetRunAdvance = {
1121
+ runIndex?: number;
1122
+ startChar?: number;
1123
+ endChar?: number;
1124
+ advance?: number;
1125
+ logicalOrder?: number;
1126
+ };
1127
+ type TypesetClusterAdvance = {
1128
+ runIndex?: number;
1129
+ startChar?: number;
1130
+ endChar?: number;
1131
+ advance?: number;
1132
+ xOffset?: number;
1133
+ bidiLevel?: number;
1134
+ logicalOrder?: number;
1135
+ };
1136
+ type TypesetBidiSlice = {
1137
+ runIndex?: number;
1138
+ startChar?: number;
1139
+ endChar?: number;
1140
+ advance?: number;
1141
+ bidiLevel?: number;
1142
+ visualOrder?: number;
1143
+ logicalOrder?: number;
1144
+ };
1145
+ type TypesetRowSegment = {
1146
+ headRun: number;
1147
+ headChar: number;
1148
+ tailRun: number;
1149
+ tailChar: number;
1150
+ leftOffset: number;
1151
+ availableWidth: number;
1152
+ width: number;
1153
+ };
1154
+ /**
1155
+ * Extent of a paragraph: its typeset lines and their combined height.
1156
+ */
1157
+ type ParagraphExtent = {
1158
+ kind: 'paragraph';
1159
+ lines: TypesetRow[];
1160
+ totalHeight: number;
1161
+ };
1162
+ /**
1163
+ * Extent of an image block (its display box).
1164
+ */
1165
+ type ImageExtent = {
1166
+ kind: 'image';
1167
+ width: number;
1168
+ height: number;
1169
+ };
1170
+ /**
1171
+ * Extent of a DrawingML shape block (v1 measurement is its bounding box).
1172
+ */
1173
+ type ShapeExtent = {
1174
+ kind: 'shape';
1175
+ width: number;
1176
+ height: number;
1177
+ /** Pre-measured inner paragraph measures for text-bearing shapes. */
1178
+ innerMeasures?: ParagraphExtent[];
1179
+ };
1180
+ /**
1181
+ * Extent of a chart block (its drawing bbox).
1182
+ */
1183
+ type ChartExtent = {
1184
+ kind: 'chart';
1185
+ width: number;
1186
+ height: number;
1187
+ };
1188
+ /**
1189
+ * Extent of one table cell, with the extents of its nested blocks.
1190
+ */
1191
+ type TableCellExtent = {
1192
+ blocks: BlockExtent[];
1193
+ width: number;
1194
+ height: number;
1195
+ colSpan?: number;
1196
+ rowSpan?: number;
1197
+ };
1198
+ /**
1199
+ * Extent of one table row.
1200
+ */
1201
+ type TableRowExtent = {
1202
+ cells: TableCellExtent[];
1203
+ height: number;
1204
+ };
1205
+ /**
1206
+ * Extent of a whole table: per-row extents plus the resolved column grid.
1207
+ */
1208
+ type TableExtent = {
1209
+ kind: 'table';
1210
+ rows: TableRowExtent[];
1211
+ columnWidths: number[];
1212
+ totalWidth: number;
1213
+ totalHeight: number;
1214
+ };
1215
+ /** Extent placeholder for a section break — occupies no space itself. */
1216
+ type SectionBreakExtent = {
1217
+ kind: 'sectionBreak';
1218
+ };
1219
+ /** Extent placeholder for a page break — zero-size by definition. */
1220
+ type PageBreakExtent = {
1221
+ kind: 'pageBreak';
1222
+ };
1223
+ /** Extent placeholder for a column break — zero-size by definition. */
1224
+ type ColumnBreakExtent = {
1225
+ kind: 'columnBreak';
1226
+ };
1227
+ /**
1228
+ * Extent of a text box, with its inner paragraphs pre-measured.
1229
+ */
1230
+ type TextBoxExtent = {
1231
+ kind: 'textBox';
1232
+ width: number;
1233
+ height: number;
1234
+ /** Pre-measured inner paragraph measures (avoids re-measuring during render) */
1235
+ innerMeasures: ParagraphExtent[];
1236
+ };
1237
+ /**
1238
+ * Extent of any flow block.
1239
+ */
1240
+ type BlockExtent = ParagraphExtent | ImageExtent | ShapeExtent | ChartExtent | TableExtent | TextBoxExtent | SectionBreakExtent | PageBreakExtent | ColumnBreakExtent;
1241
+ /**
1242
+ * Fields every fragment carries: which block it came from, where it sits on
1243
+ * its page, and the PM span it maps to.
1244
+ */
1245
+ type FragmentBase = {
1246
+ /** Block ID this fragment belongs to. */
1247
+ blockId: BlockId;
1248
+ /** X position on page (relative to page left). */
1249
+ x: number;
1250
+ /** Y position on page (relative to page top). */
1251
+ y: number;
1252
+ /** Width of the fragment. */
1253
+ width: number;
1254
+ /** ProseMirror start position (for click mapping). */
1255
+ pmStart?: number;
1256
+ /** ProseMirror end position (for click mapping). */
1257
+ pmEnd?: number;
1258
+ };
1259
+ /**
1260
+ * The slice of a paragraph shown on one page — a half-open line range
1261
+ * `[fromLine, toLine)` of the measure, so a page-split paragraph yields one
1262
+ * fragment per page.
1263
+ */
1264
+ type ParagraphFragment = FragmentBase & {
1265
+ kind: 'paragraph';
1266
+ /** First line index (inclusive) from the measure. */
1267
+ fromLine: number;
1268
+ /** Last line index (exclusive) from the measure. */
1269
+ toLine: number;
1270
+ /** Height of this fragment. */
1271
+ height: number;
1272
+ /** True if this continues from a previous page. */
1273
+ carriedFromPrev?: boolean;
1274
+ /** True if this continues onto the next page. */
1275
+ carriedToNext?: boolean;
1276
+ /** Per-line resolved run segments for `[fromLine, toLine)`, aligned so `resolvedLines[k]` is line `fromLine + k` (see {@link ResolvedLine}); materialized during layout, omitted from golden serialization. */
1277
+ resolvedLines?: ResolvedLine[];
1278
+ };
1279
+ /**
1280
+ * The slice of a table shown on one page — a half-open row range plus
1281
+ * optional top/bottom clips when a single row breaks mid-content.
1282
+ */
1283
+ type TableFragment = FragmentBase & {
1284
+ kind: 'table';
1285
+ /** First row index (inclusive). */
1286
+ rowStart: number;
1287
+ /** Last row index (exclusive). */
1288
+ rowEnd: number;
1289
+ /** Height of this fragment. */
1290
+ height: number;
1291
+ /** True if this is a floating table. */
1292
+ isFloating?: boolean;
1293
+ /** True if this continues from a previous page. */
1294
+ carriedFromPrev?: boolean;
1295
+ /** True if this continues onto the next page. */
1296
+ carriedToNext?: boolean;
1297
+ /** Number of header rows prepended to this continuation fragment (0 or undefined for first fragment). */
1298
+ headerRowCount?: number;
1299
+ /**
1300
+ * Pixels to skip from the top of `rowStart`. Non-zero when this fragment's
1301
+ * first row is the continuation of a row that broke across a page boundary
1302
+ * (Word's "allow row to break across pages"). The painter renders the row
1303
+ * shifted up by this amount so the already-shown top slice is clipped.
1304
+ */
1305
+ clipTop?: number;
1306
+ /**
1307
+ * Visible height (px) measured from the top of the LAST row (`rowEnd - 1`).
1308
+ * Set when that row breaks mid-content onto the next page; `undefined`
1309
+ * means the last row is fully visible. When `rowStart === rowEnd - 1`, the
1310
+ * visible band of that single row is `[clipTop, clipBottom)`.
1311
+ */
1312
+ clipBottom?: number;
1313
+ };
1314
+ /**
1315
+ * An image placed on a page.
1316
+ */
1317
+ type ImageFragment = FragmentBase & {
1318
+ kind: 'image';
1319
+ /** Height of the image. */
1320
+ height: number;
1321
+ /** True if this is an anchored/floating image. */
1322
+ isAnchored?: boolean;
1323
+ /** Z-index for layering. */
1324
+ zIndex?: number;
1325
+ /** Original content frame when `width`/`height` are transformed bbox dimensions. */
1326
+ contentFrame?: {
1327
+ x?: number;
1328
+ y?: number;
1329
+ width?: number;
1330
+ height?: number;
1331
+ };
1332
+ };
1333
+ /**
1334
+ * A DrawingML shape placed on a page.
1335
+ */
1336
+ type ShapeFragment = FragmentBase & {
1337
+ kind: 'shape';
1338
+ /** Height of the shape bbox. */
1339
+ height: number;
1340
+ /** PM/doc positions for display-list consumers that use docStart/docEnd names. */
1341
+ docStart?: number;
1342
+ docEnd?: number;
1343
+ /** True when positioned outside normal flow. */
1344
+ isAnchored?: boolean;
1345
+ /** Z-index for layering. */
1346
+ zIndex?: number;
1347
+ };
1348
+ /**
1349
+ * A DrawingML chart placed on a page.
1350
+ */
1351
+ type ChartFragment = FragmentBase & {
1352
+ kind: 'chart';
1353
+ /** Height of the chart bbox. */
1354
+ height: number;
1355
+ docStart?: number;
1356
+ docEnd?: number;
1357
+ /** True when positioned outside normal flow. Undefined = false. */
1358
+ isAnchored?: boolean;
1359
+ /** Stable z-order. Undefined = source order. */
1360
+ zIndex?: number;
1361
+ };
1362
+ /**
1363
+ * A text box placed on a page.
1364
+ */
1365
+ type TextBoxFragment = FragmentBase & {
1366
+ kind: 'textBox';
1367
+ /** Height of the text box. */
1368
+ height: number;
1369
+ /** True when positioned outside normal document flow. */
1370
+ isFloating?: boolean;
1371
+ /** Stack order hint for anchored text boxes. */
1372
+ zIndex?: number;
1373
+ };
1374
+ /**
1375
+ * Any placed fragment.
1376
+ */
1377
+ type Fragment = ParagraphFragment | TableFragment | ImageFragment | ShapeFragment | ChartFragment | TextBoxFragment;
1378
+ /**
1379
+ * Page margins in pixels (w:pgMar), including header/footer distances.
1380
+ */
1381
+ type PageMargins = {
1382
+ top: number;
1383
+ right: number;
1384
+ bottom: number;
1385
+ left: number;
1386
+ /** w:header — offset of the header band from the sheet's top edge. */
1387
+ header?: number;
1388
+ /** w:footer — offset of the footer band from the sheet's bottom edge. */
1389
+ footer?: number;
1390
+ /** Binding gutter in px. Undefined = 0. */
1391
+ gutter?: number;
1392
+ };
1393
+ /** Effective header/footer relationship ids for one section/page. */
1394
+ type PageHeaderFooterRefs = {
1395
+ headerDefault?: string;
1396
+ headerFirst?: string;
1397
+ headerEven?: string;
1398
+ footerDefault?: string;
1399
+ footerFirst?: string;
1400
+ footerEven?: string;
1401
+ };
1402
+ /** Section-relative logical page label contract. */
1403
+ type PageNumberingContract = {
1404
+ start?: number;
1405
+ format?: string;
1406
+ chapterStyle?: number;
1407
+ chapterSeparator?: 'colon' | 'emDash' | 'enDash' | 'hyphen' | 'period';
1408
+ };
1409
+ /** Page-border data retained until per-page section selection. */
1410
+ type PageBorderContract = {
1411
+ top?: BorderSpec;
1412
+ right?: BorderSpec;
1413
+ bottom?: BorderSpec;
1414
+ left?: BorderSpec;
1415
+ display?: 'allPages' | 'firstPage' | 'notFirstPage';
1416
+ offsetFrom?: 'page' | 'text';
1417
+ zOrder?: 'front' | 'back';
1418
+ };
1419
+ /** Cascaded note settings used by section-aware pagination. */
1420
+ type NoteSettingsContract = {
1421
+ footnote?: FootnoteProperties;
1422
+ endnote?: EndnoteProperties;
1423
+ footnoteColumns?: number;
1424
+ };
1425
+ /** One measured, non-fragmented note in a page note region. */
1426
+ type NoteLayoutItem = {
1427
+ kind?: 'footnote' | 'endnote';
1428
+ id?: number;
1429
+ displayLabel?: string;
1430
+ blocks?: LayoutBlock[];
1431
+ measures?: BlockExtent[];
1432
+ height?: number;
1433
+ anchorDocStart?: number;
1434
+ anchorDocEnd?: number;
1435
+ customMarkFollows?: boolean;
1436
+ };
1437
+ /** Footnote/endnote area attached to a page/section boundary. */
1438
+ type NoteAreaContract = {
1439
+ kind?: 'footnote' | 'endnote';
1440
+ placement?: 'pageBottom' | 'beneathText' | 'sectEnd' | 'docEnd';
1441
+ y?: number;
1442
+ height?: number;
1443
+ columns?: number;
1444
+ separator?: NoteLayoutItem;
1445
+ notes?: NoteLayoutItem[];
1446
+ sectionId?: string;
1447
+ };
1448
+ /**
1449
+ * One laid-out page: its fragments, geometry, and header/footer/footnote
1450
+ * bookkeeping.
1451
+ */
1452
+ type Page = {
1453
+ /** Page number (1-indexed). */
1454
+ number: number;
1455
+ /** Fragments positioned on this page. */
1456
+ fragments: Fragment[];
1457
+ /** Page margins. */
1458
+ margins: PageMargins;
1459
+ /** Page size (width, height). */
1460
+ size: {
1461
+ w: number;
1462
+ h: number;
1463
+ };
1464
+ /** Page orientation. */
1465
+ orientation?: 'portrait' | 'landscape';
1466
+ /** Section index this page belongs to. */
1467
+ sectionIndex?: number;
1468
+ /** Stable section identity. Undefined = derive from `sectionIndex`. */
1469
+ sectionId?: string;
1470
+ /** Zero-based physical page ordinal within its section. */
1471
+ sectionPageIndex?: number;
1472
+ /** One-based logical page number after section restart. */
1473
+ sectionPageNumber?: number;
1474
+ /** Fully formatted PAGE-field label. Undefined = decimal `number`. */
1475
+ pageLabel?: string;
1476
+ /** Effective page numbering contract. */
1477
+ pageNumbering?: PageNumberingContract;
1478
+ /** Header/footer references for this page. */
1479
+ headerFooterRefs?: PageHeaderFooterRefs;
1480
+ /** Effective per-page header distance in px. Undefined = margins.header/default. */
1481
+ headerDistance?: number;
1482
+ /** Effective per-page footer distance in px. Undefined = margins.footer/default. */
1483
+ footerDistance?: number;
1484
+ /** Effective section page borders. Undefined = none. */
1485
+ pageBorders?: PageBorderContract;
1486
+ /** Effective header-owned watermark. Undefined = none. */
1487
+ watermark?: Watermark;
1488
+ /** Vertical section alignment. Undefined = top. */
1489
+ verticalAlign?: 'top' | 'center' | 'both' | 'bottom';
1490
+ /** Footnote IDs that appear on this page (for rendering). */
1491
+ footnoteIds?: number[];
1492
+ /** Height reserved for the footnote area at page bottom (pixels). */
1493
+ footnoteReservedHeight?: number;
1494
+ /** Footnote-area columns (`w15:footnoteColumns`); absent/1 = single column. */
1495
+ footnoteColumns?: number;
1496
+ /** Typed note regions. Undefined = use legacy footnote id/reservation fields. */
1497
+ noteAreas?: NoteAreaContract[];
1498
+ /** Column layout for this page (if multi-column). */
1499
+ columns?: ColumnLayout;
1500
+ };
1501
+ /**
1502
+ * Multi-column setup for a section (w:cols).
1503
+ */
1504
+ type ColumnLayout = {
1505
+ count: number;
1506
+ gap: number;
1507
+ equalWidth?: boolean;
1508
+ /** Draw vertical separator line between columns (w:sep). */
1509
+ separator?: boolean;
1510
+ /** Authored unequal column geometry. Undefined = derive equal widths. */
1511
+ columns?: Array<{
1512
+ width?: number;
1513
+ space?: number;
1514
+ }>;
1515
+ };
1516
+ /**
1517
+ * Laid-out content of one header or footer variant.
1518
+ */
1519
+ type HeaderFooterLayout = {
1520
+ height: number;
1521
+ fragments: Fragment[];
1522
+ };
1523
+ /**
1524
+ * The paginator's complete result — everything the painter needs.
1525
+ */
1526
+ type Layout = {
1527
+ /** Serialization contract version. Undefined reads as legacy version 0. */
1528
+ contractVersion?: number;
1529
+ /** Default page size for the document. */
1530
+ pageSize: {
1531
+ w: number;
1532
+ h: number;
1533
+ };
1534
+ /** All rendered pages with positioned fragments. */
1535
+ pages: Page[];
1536
+ /** Column configuration (if multi-column). */
1537
+ columns?: ColumnLayout;
1538
+ /** Header layouts by type (default, first, even). */
1539
+ headers?: Record<string, HeaderFooterLayout>;
1540
+ /** Footer layouts by type (default, first, even). */
1541
+ footers?: Record<string, HeaderFooterLayout>;
1542
+ /** Gap between pages in pixels (for rendering). */
1543
+ pageGap?: number;
1544
+ /**
1545
+ * Resume bookmarks for incremental pagination (derived data — omitted from
1546
+ * golden serialization). See `checkpoints.ts`.
1547
+ */
1548
+ checkpoints?: LayoutCheckpoint[];
1549
+ };
1550
+ /**
1551
+ * Measured header/footer heights keyed by variant.
1552
+ */
1553
+ type HeaderFooterContentHeights = Partial<Record<'default' | 'first' | 'even' | 'odd', number>>;
1554
+ /**
1555
+ * A footnote's blocks and measures, resolved ahead of pagination so page
1556
+ * bottoms can reserve the right space.
1557
+ */
1558
+ type FootnoteContent = {
1559
+ /** Footnote ID. */
1560
+ id: number;
1561
+ /** Display number (e.g. 1, 2, 3). */
1562
+ displayNumber: number;
1563
+ /** FlowBlocks for rendering the footnote content. */
1564
+ blocks: LayoutBlock[];
1565
+ /** Measurements for the blocks. */
1566
+ measures: BlockExtent[];
1567
+ /** Total height in pixels. */
1568
+ height: number;
1569
+ /** Stable note kind. Undefined = footnote. */
1570
+ noteKind?: 'footnote' | 'endnote';
1571
+ /** Fully formatted number/custom mark. Undefined = decimal displayNumber. */
1572
+ displayLabel?: string;
1573
+ /** Body-reference document range. */
1574
+ anchor?: {
1575
+ docStart?: number;
1576
+ docEnd?: number;
1577
+ };
1578
+ /** `customMarkFollows`; undefined = false. */
1579
+ customMarkFollows?: boolean;
1580
+ };
1581
+ /**
1582
+ * Inputs that configure a pagination run.
1583
+ */
1584
+ type LayoutOptions = {
1585
+ /** Serialization contract version. Undefined reads as legacy version 0. */
1586
+ contractVersion?: number;
1587
+ /** Initial page size. */
1588
+ pageSize: {
1589
+ w: number;
1590
+ h: number;
1591
+ };
1592
+ /** Initial page margins. */
1593
+ margins: PageMargins;
1594
+ /** Body-level (final section) page size, used after the last explicit section break. */
1595
+ finalPageSize?: {
1596
+ w: number;
1597
+ h: number;
1598
+ };
1599
+ /** Body-level (final section) margins, used after the last explicit section break. */
1600
+ finalMargins?: PageMargins;
1601
+ /** Column configuration. */
1602
+ columns?: ColumnLayout;
1603
+ /** Gap between rendered pages (for UI). */
1604
+ pageGap?: number;
1605
+ /** Default line height multiplier. */
1606
+ defaultLineHeight?: number;
1607
+ /** Header content heights by variant. */
1608
+ headerContentHeights?: HeaderFooterContentHeights;
1609
+ /** Footer content heights by variant. */
1610
+ footerContentHeights?: HeaderFooterContentHeights;
1611
+ /** Whether section has different first page header/footer. */
1612
+ titlePage?: boolean;
1613
+ /** Whether section has different even/odd headers/footers. */
1614
+ evenAndOddHeaders?: boolean;
1615
+ /** Per-page footnote reserved heights (pageNumber → height in pixels). */
1616
+ footnoteReservedHeights?: Map<number, number>;
1617
+ /** Section break type for the body-level (final) section (for section transition logic). */
1618
+ bodyBreakType?: 'continuous' | 'nextPage' | 'evenPage' | 'oddPage';
1619
+ /** Effective section states, indexed by section. Undefined = legacy globals. */
1620
+ sections?: Array<{
1621
+ sectionId?: string;
1622
+ pageSize?: {
1623
+ w?: number;
1624
+ h?: number;
1625
+ };
1626
+ margins?: Partial<PageMargins>;
1627
+ columns?: ColumnLayout;
1628
+ headerFooterRefs?: PageHeaderFooterRefs;
1629
+ pageNumbering?: PageNumberingContract;
1630
+ pageBorders?: PageBorderContract;
1631
+ watermark?: Watermark;
1632
+ noteSettings?: NoteSettingsContract;
1633
+ }>;
1634
+ };
1635
+ /**
1636
+ * What a pointer position resolved to: the page, the fragment under it (if
1637
+ * any), and the position local to that fragment.
1638
+ */
1639
+ type HitTestResult = {
1640
+ /** Page index (0-based). */
1641
+ pageIndex: number;
1642
+ /** Fragment that was hit, if any. */
1643
+ fragment?: Fragment;
1644
+ /** Local X coordinate within the fragment. */
1645
+ localX?: number;
1646
+ /** Local Y coordinate within the fragment. */
1647
+ localY?: number;
1648
+ };
1649
+ /**
1650
+ * A location expressed in block/run/character terms, with the matching PM
1651
+ * position when known.
1652
+ */
1653
+ type DocumentPosition = {
1654
+ /** Block index. */
1655
+ blockIndex: number;
1656
+ /** Run index within the block (for paragraphs). */
1657
+ runIndex?: number;
1658
+ /** Character offset within the run. */
1659
+ charOffset?: number;
1660
+ /** ProseMirror position. */
1661
+ pmPos?: number;
1662
+ };
1663
+ /**
1664
+ * Page geometry needed to translate OOXML `relativeFrom` anchors into painter
1665
+ * coordinates. All values are in CSS pixels.
1666
+ */
1667
+ interface PageGeometry {
1668
+ pageWidth: number;
1669
+ pageHeight: number;
1670
+ marginLeft: number;
1671
+ marginTop: number;
1672
+ contentWidth: number;
1673
+ contentHeight: number;
1674
+ }
1675
+ /**
1676
+ * Derive {@link PageGeometry} (px) from a laid-out page's size + margins. Pure
1677
+ * arithmetic — shared by the measure pipeline (float-band reservation), the
1678
+ * painter, and the layout compute pass so a reserved zone lines up with where
1679
+ * an anchored object is placed.
1680
+ */
1681
+ declare function pageGeometryFromPage(page: Pick<Page, 'size' | 'margins'>): PageGeometry;
1682
+ /**
1683
+ * Minimal anchored object shape needed to resolve OOXML positioning against
1684
+ * page geometry. Shared by the retained measure pipeline and the DOM painter's
1685
+ * compatibility re-export until paint/ is deleted.
1686
+ */
1687
+ interface AnchoredObjectPositionInput {
1688
+ width: number;
1689
+ height: number;
1690
+ position?: {
1691
+ horizontal?: {
1692
+ relativeTo?: string;
1693
+ posOffset?: number;
1694
+ align?: string;
1695
+ };
1696
+ vertical?: {
1697
+ relativeTo?: string;
1698
+ posOffset?: number;
1699
+ align?: string;
1700
+ };
1701
+ };
1702
+ cssFloat?: 'left' | 'right' | 'none';
1703
+ }
1704
+ /**
1705
+ * Content-area top Y (px) of an anchored object, resolving its OOXML vertical
1706
+ * anchor (`page` / `margin` / `topMargin` / `bottomMargin` / `paragraph`, with
1707
+ * `align` or `posOffset`). Exposed so the measure pipeline can reserve a
1708
+ * `topAndBottom` band at the exact Y the painter will place the object.
1709
+ */
1710
+ declare function resolveAnchoredObjectVerticalTop(object: AnchoredObjectPositionInput, fragmentY: number, geometry?: PageGeometry): number;
1711
+ /**
1712
+ * Check if a floating image should create text wrapping exclusion zones.
1713
+ * wrapNone images (`behind` / `inFront`) are positioned floats but do not
1714
+ * shrink line widths; text paints over or under them.
1715
+ */
1716
+ declare function isTextWrappingFloatingImageRun(run: ImageRun): boolean;
1717
+ /**
1718
+ * Header/footer content for rendering.
1719
+ */
1720
+ interface HeaderFooterContent {
1721
+ /** Flow blocks for the header/footer content. */
1722
+ blocks: LayoutBlock[];
1723
+ /** Measurements for the blocks. */
1724
+ measures: BlockExtent[];
1725
+ /** Total height of the content (in-flow stack incl. floating blocks). */
1726
+ height: number;
1727
+ /**
1728
+ * In-flow band height: the height of strictly in-flow content
1729
+ * (paragraphs, tables, inline images/text boxes), EXCLUDING anchored /
1730
+ * floating objects. This is what grows the header/footer band and pushes
1731
+ * the body margin, mirroring Word: a page/margin-anchored shape (e.g. a
1732
+ * full-page letterhead in a header) is positioned independently and does
1733
+ * NOT push body text down. Use this — not `height`/`visualBottom` — for
1734
+ * margin extension. Falls back to `height` when undefined.
1735
+ */
1736
+ flowHeight?: number;
1737
+ /** Top-most visual extent relative to the nominal flow origin. */
1738
+ visualTop?: number;
1739
+ /** Bottom-most visual extent relative to the nominal flow origin. */
1740
+ visualBottom?: number;
1741
+ }
1742
+ /**
1743
+ * A single footnote item ready for rendering at page bottom.
1744
+ */
1745
+ interface FootnoteRenderItem {
1746
+ /** Display number (e.g. "1", "2") */
1747
+ displayNumber: string;
1748
+ /** Plain text content */
1749
+ text: string;
1750
+ /** Measured body-pipeline content used for WYSIWYG painting. */
1751
+ content?: FootnoteContent;
1752
+ }
1753
+
1754
+ export { type PageSectionState as $, type AnchoredObjectPositionInput as A, type BlockExtent as B, type ColumnLayout as C, DEFAULT_TEXTBOX_MARGINS as D, type HyperlinkInfo as E, type FootnoteContent as F, type ImageBlock as G, type HeaderFooterContent as H, type ImageRun as I, type ImageExtent as J, type ImageFragment as K, type LayoutOptions as L, type ImageRunPosition as M, type NoteSettingsContract as N, type InlineSdtWidget as O, type PageMargins as P, type LayoutCheckpoint as Q, type LineBreakRun as R, type SectionBreakBlock as S, type TextBoxBlock as T, type ListNumPr as U, type NoteAreaContract as V, type WrapTextDirection as W, type NoteLayoutItem as X, type PageBreakBlock as Y, type PageBreakExtent as Z, type PageFlowGeometry as _, type Layout as a, type ParagraphAttrs as a0, type ParagraphBlock as a1, type ParagraphBorders as a2, type ParagraphExtent as a3, type ParagraphFragment as a4, type ParagraphIndent as a5, type ParagraphSpacing as a6, type ResolvedLine as a7, type ResolvedSegment as a8, type Run as a9, type TypesetRow as aA, type TypesetRowSegment as aB, type TypesetRunAdvance as aC, assertExhaustiveLayoutBlock as aD, isTextWrappingFloatingImageRun as aE, pageGeometryFromPage as aF, resolveAnchoredObjectVerticalTop as aG, type RunFontSlots as aa, type RunFormatting as ab, type RunLanguageSlots as ac, type SdtGroup as ad, type SectionBreakExtent as ae, type ShapeBlock as af, type ShapeBlockFill as ag, type ShapeBlockStroke as ah, type ShapeBlockTransform as ai, type ShapeExtent as aj, type ShapeFragment as ak, type TabAlignment as al, type TabRun as am, type TabStop as an, type TableBlock as ao, type TableCell as ap, type TableCellExtent as aq, type TableExtent as ar, type TableFragment as as, type TableRow as at, type TableRowExtent as au, type TextBoxExtent as av, type TextBoxFragment as aw, type TextRun as ax, type TypesetBidiSlice as ay, type TypesetClusterAdvance as az, type PageHeaderFooterRefs as b, type PageNumberingContract as c, type PageBorderContract as d, type LayoutBlock as e, type BlockId as f, type Page as g, type FootnoteRenderItem as h, type PageGeometry as i, type BorderStyle as j, type CellBorderSpec as k, type CellBorders as l, type ChartBlock as m, type ChartExtent as n, type ChartFragment as o, type ColumnBreakBlock as p, type ColumnBreakExtent as q, DEFAULT_TEXTBOX_WIDTH as r, type DocumentPosition as s, type FieldRun as t, type FloatingTablePosition as u, type Fragment as v, type FragmentBase as w, type HeaderFooterContentHeights as x, type HeaderFooterLayout as y, type HitTestResult as z };