@docx-editor.dev/core 2.30.0 → 2.32.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 (133) hide show
  1. package/README.md +24 -0
  2. package/dist/automation.cjs +1 -1
  3. package/dist/automation.d.ts +18 -27
  4. package/dist/automation.js +1 -1
  5. package/dist/binding.cjs +1 -1
  6. package/dist/binding.d.ts +17 -16
  7. package/dist/binding.js +1 -1
  8. package/dist/bookmark-names-DDuAra_V.d.ts +37 -0
  9. package/dist/{chrome-print-BM3Js-6X.d.ts → chrome-print-CznJ0ucN.d.ts} +361 -41
  10. package/dist/chunk-25EXMBV2.cjs +5 -0
  11. package/dist/chunk-2CWQY27B.cjs +1 -0
  12. package/dist/chunk-3IEXDEFH.cjs +7 -0
  13. package/dist/chunk-65XBN67F.cjs +2 -0
  14. package/dist/chunk-6NVZNB7O.cjs +3 -0
  15. package/dist/chunk-6UDJUI3W.cjs +2 -0
  16. package/dist/chunk-ACLR4DMK.js +1 -0
  17. package/dist/{chunk-RJCQGJR7.js → chunk-B2BEELUE.js} +1 -1
  18. package/dist/chunk-DDFHKQFU.js +30 -0
  19. package/dist/chunk-E4IAO4CY.cjs +2 -0
  20. package/dist/chunk-ETDZFNMI.js +2 -0
  21. package/dist/chunk-FDSL5OJU.cjs +30 -0
  22. package/dist/chunk-FS7CMYLT.js +4 -0
  23. package/dist/chunk-GDS24SZN.js +30 -0
  24. package/dist/chunk-GIY6NT2X.js +5 -0
  25. package/dist/chunk-GWM3AKUD.js +18 -0
  26. package/dist/chunk-HDOXACHP.js +2 -0
  27. package/dist/chunk-IILEENID.js +1 -0
  28. package/dist/chunk-L5TYBFDB.js +1 -0
  29. package/dist/chunk-MNF2K7NN.cjs +30 -0
  30. package/dist/chunk-O324RB6R.cjs +1 -0
  31. package/dist/chunk-OKMEMSKB.cjs +1 -0
  32. package/dist/chunk-QXJKYNYZ.js +1 -0
  33. package/dist/chunk-RALTVLB6.js +2 -0
  34. package/dist/chunk-SRVKFUFI.js +3 -0
  35. package/dist/chunk-TELQ52LG.cjs +1 -0
  36. package/dist/chunk-TJHE5EET.cjs +1 -0
  37. package/dist/chunk-UMMRURPE.js +7 -0
  38. package/dist/chunk-WN7ICTA5.js +1 -0
  39. package/dist/{chunk-FLBEJC6X.cjs → chunk-XJYZVGQR.cjs} +1 -1
  40. package/dist/chunk-ZGTIE3QJ.cjs +4 -0
  41. package/dist/chunk-ZOZI27AW.cjs +18 -0
  42. package/dist/collaboration/replication.cjs +1 -1
  43. package/dist/collaboration/replication.d.ts +20 -5
  44. package/dist/collaboration/replication.js +1 -1
  45. package/dist/collaboration.cjs +1 -1
  46. package/dist/collaboration.d.ts +5 -6
  47. package/dist/collaboration.js +1 -1
  48. package/dist/contracts/document.d.ts +3 -3
  49. package/dist/contracts/editor.d.ts +13 -10
  50. package/dist/contracts/interaction.d.ts +2 -2
  51. package/dist/contracts/modules.d.ts +15 -13
  52. package/dist/contracts/types.d.ts +135 -2
  53. package/dist/{custom-node-writes-0v0Kgw1T.d.ts → custom-node-writes-CLJKGD9t.d.ts} +7 -2
  54. package/dist/{diagnostic-context-CcAO4q1s.d.ts → diagnostic-context-BtDUY3v2.d.ts} +3 -2
  55. package/dist/{diagnostic-hints-2Bke6H_w.d.ts → diagnostic-hints-DK8-V0fk.d.ts} +2 -2
  56. package/dist/{document-protection-8eyMWIJ0.d.ts → document-protection-NaniLHWF.d.ts} +1 -1
  57. package/dist/{editor-DaEJd2so.d.ts → editor-DZwOTmlR.d.ts} +386 -279
  58. package/dist/editor-fonts-D_-vjuJi.d.ts +53 -0
  59. package/dist/{editor-scope-7o9xweiJ.d.ts → editor-scope-B3L-1ALc.d.ts} +57 -4
  60. package/dist/editor.cjs +1 -1
  61. package/dist/editor.css +6 -4
  62. package/dist/editor.d.ts +646 -31
  63. package/dist/editor.js +1 -1
  64. package/dist/export.cjs +2 -2
  65. package/dist/export.d.ts +9 -16
  66. package/dist/export.js +2 -2
  67. package/dist/{failure-NS2lsya4.d.ts → failure-6KGFrDO9.d.ts} +1 -1
  68. package/dist/{font-resolver-CL9BVKZo.d.ts → font-resolver-BlQNGdvR.d.ts} +1 -1
  69. package/dist/{headless-document-view-DZQN8Bnx.d.ts → headless-document-view-Bcz9_Qva.d.ts} +115 -4
  70. package/dist/index.cjs +1 -1
  71. package/dist/index.d.ts +27 -26
  72. package/dist/index.js +1 -1
  73. package/dist/{layout-shaping-cEnVrhWg.d.ts → layout-shaping-E5J4Z1Gf.d.ts} +1 -1
  74. package/dist/layout.cjs +1 -1
  75. package/dist/layout.d.ts +95 -23
  76. package/dist/layout.js +1 -1
  77. package/dist/{note-properties-9FH8zAeG.d.ts → note-properties-Ds5R2_3F.d.ts} +1 -1
  78. package/dist/output.cjs +1 -1
  79. package/dist/output.d.ts +24 -10
  80. package/dist/output.js +1 -1
  81. package/dist/{protocol-CZ1uUlPO.d.ts → protocol-DKa4qt7F.d.ts} +167 -5
  82. package/dist/{review-paragraph-order-CqVelc5A.d.ts → review-paragraph-order-Dc17w_6v.d.ts} +1 -1
  83. package/dist/revision-projection-Cn6rZJ7H.d.ts +258 -0
  84. package/dist/{semantic-cell-selection-Dr9yxFZt.d.ts → semantic-cell-selection-BaUR0iJ4.d.ts} +2 -2
  85. package/dist/{semantic-interaction-Dc3pf3hr.d.ts → semantic-interaction-CJoHLoOl.d.ts} +1 -1
  86. package/dist/{semantic-paint-Bz3FBAoH.d.ts → semantic-paint-BPw_n0li.d.ts} +7 -4
  87. package/dist/{semantic-record-queries-Bx0pl6kL.d.ts → semantic-record-queries-C0rJ3sB4.d.ts} +1 -1
  88. package/dist/{semantic-records-CjcF26ZL.d.ts → semantic-records-BvN-WWst.d.ts} +365 -512
  89. package/dist/store.cjs +1 -1
  90. package/dist/store.d.ts +47 -22
  91. package/dist/store.js +1 -1
  92. package/dist/{types-barrel-CA0xB8kH.d.ts → tree-op-types-C_S2niXW.d.ts} +1239 -747
  93. package/dist/{tree-package-store-DKhdEVym.d.ts → tree-package-store-CRHvMyNj.d.ts} +676 -646
  94. package/dist/{tree-session-contract-CwnTEVLF.d.ts → tree-session-contract-D1awo_dA.d.ts} +26 -13
  95. package/dist/unsupported-elements-CVos5cqe.d.ts +23 -0
  96. package/docs/accept-reject-without-scrolling.md +95 -0
  97. package/docs/comment-on-found-text.md +72 -0
  98. package/docs/custom-review-cards.md +178 -0
  99. package/docs/highlight-ranges.md +48 -0
  100. package/docs/index.md +36 -0
  101. package/docs/propose-rewrite.md +247 -0
  102. package/docs/tracked-replacement.md +68 -0
  103. package/package.json +3 -2
  104. package/dist/chunk-2PV5L5NJ.js +0 -5
  105. package/dist/chunk-5OTS2EJ7.js +0 -7
  106. package/dist/chunk-5P4223J4.cjs +0 -27
  107. package/dist/chunk-5RRAZMBU.cjs +0 -1
  108. package/dist/chunk-5SPITS5F.js +0 -18
  109. package/dist/chunk-6JIJOZDW.js +0 -1
  110. package/dist/chunk-7ATNKARV.js +0 -2
  111. package/dist/chunk-BGCUTKWE.cjs +0 -5
  112. package/dist/chunk-BTQKU64Q.cjs +0 -1
  113. package/dist/chunk-EBCXSH2W.js +0 -3
  114. package/dist/chunk-ERECKTIR.cjs +0 -2
  115. package/dist/chunk-HYASLE2G.cjs +0 -1
  116. package/dist/chunk-JC47NRJC.cjs +0 -3
  117. package/dist/chunk-KJRTNY2Q.cjs +0 -2
  118. package/dist/chunk-NKPUH3QJ.js +0 -1
  119. package/dist/chunk-PF5NJWS3.js +0 -2
  120. package/dist/chunk-PWTRJSES.cjs +0 -18
  121. package/dist/chunk-QFKGI242.cjs +0 -30
  122. package/dist/chunk-RPPV4S6T.cjs +0 -4
  123. package/dist/chunk-T32MGBJS.js +0 -1
  124. package/dist/chunk-UM26GH5B.js +0 -30
  125. package/dist/chunk-VRCZBFLH.js +0 -27
  126. package/dist/chunk-WF7JZ755.cjs +0 -1
  127. package/dist/chunk-WK5X2MMA.cjs +0 -7
  128. package/dist/chunk-WPDD2Y32.js +0 -2
  129. package/dist/chunk-YBMWBXST.cjs +0 -2
  130. package/dist/chunk-YZGUBCHP.js +0 -1
  131. package/dist/chunk-ZOS2PM4A.js +0 -4
  132. package/dist/image-resources-Bipz8toD.d.ts +0 -211
  133. package/dist/omml-equation-DP2WpUbK.d.ts +0 -97
@@ -1,27 +1,54 @@
1
- import { c as HistoryGroupOutcome } from './editor-scope-7o9xweiJ.js';
1
+ import { H as HistoryGroupOutcome } from './editor-scope-B3L-1ALc.js';
2
2
 
3
3
  /**
4
- * How a tracked change is addressed: `@w:id`, `@w:author` and `@w:date` together, within a
5
- * part.
4
+ * Why a zip was refused at the trust boundary.
6
5
  *
7
- * All of them, always. `@w:id` is unique only within a part, so an id alone names two
8
- * revisions in any package with a header or a comments part — and it is not author-scoped
9
- * either, so `(part, id)` would merge two authors' distinct revisions. One logical revision is
10
- * also deliberately many elements sharing an id, as a tracked row insertion is, which no
11
- * uniqueness rule could express.
6
+ * `too-large` and `too-many-entries` are the zip-bomb guards; `bad-name` catches path traversal —
7
+ * an entry with `..` or a leading `/` is rejected rather than normalized.
12
8
  */
13
- interface RevisionAddress {
14
- readonly id: string;
15
- readonly author: string;
16
- /** Absent when the file wrote no `@w:date`; part of the identity either way. */
17
- readonly date?: string;
18
- }
19
- /** The author and timestamp a tracked edit is recorded under. */
20
- interface RevisionAttributionInput {
21
- readonly author: string;
22
- /** ISO-8601. Omitted writes no `@w:date`. */
23
- readonly date?: string;
9
+ type ZipRejection = 'too-many-entries' | 'too-large' | 'bad-name' | 'inflate-error';
10
+ /** Archive caps: entry count, total decompressed bytes, and the decompression ratio. */
11
+ interface ZipLimits {
12
+ readonly maxEntries: number;
13
+ /** Max total UNCOMPRESSED bytes across the archive. */
14
+ readonly maxTotalBytes: number;
15
+ /**
16
+ * Max ratio of the archive's total declared uncompressed bytes to the archive's own byte
17
+ * length (zip-bomb guard). Applies once that total exceeds 8 MiB, so a small archive is
18
+ * never refused for compressing well.
19
+ */
20
+ readonly maxRatio?: number;
24
21
  }
22
+ /** The archive caps in force when a host configures none. Conservative and finite. */
23
+ declare const DEFAULT_ZIP_LIMITS: ZipLimits;
24
+ /** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
25
+ type ZipReadResult = {
26
+ readonly ok: true;
27
+ readonly entries: ReadonlyMap<string, Uint8Array>;
28
+ } | {
29
+ readonly ok: false;
30
+ readonly reason: ZipRejection;
31
+ readonly detail?: string;
32
+ readonly limit?: 'zip.maxTotalBytes' | 'zip.maxRatio';
33
+ };
34
+ /**
35
+ * Inflate a ZIP archive with bounds + OPC name normalization. Entry name, count, archive
36
+ * ratio, and total-uncompressed-size limits are enforced BEFORE each entry is decompressed
37
+ * (via fflate's pre-inflation filter), so a zip bomb or a traversal name is rejected without
38
+ * ever being inflated. Keys are canonical part names.
39
+ *
40
+ * The budgets count each entry's DECLARED sizes, and the declared size is also a hard cap on
41
+ * what the entry may produce: fflate inflates into a buffer of exactly `originalSize` bytes
42
+ * and never grows it, so an entry whose stream holds more than it declares is truncated (or
43
+ * refused as `inflate-error`), never expanded past its budget. A stored entry is copied at
44
+ * its compressed size, so the larger of its two declared sizes is what counts.
45
+ */
46
+ declare function readZip(bytes: Uint8Array, limits?: ZipLimits): ZipReadResult;
47
+ /** Deflate a set of canonical-part-name -> bytes into a ZIP archive. Every part name
48
+ * is re-validated through the OPC normalization profile before writing, so a
49
+ * traversal/encoded/normalized-alias name from an untrusted serialized model can
50
+ * never be smuggled into a ZIP entry (write-side path-traversal guard). */
51
+ declare function writeZip(entries: ReadonlyMap<string, Uint8Array>): Uint8Array;
25
52
 
26
53
  /**
27
54
  * One parsed XML node, preserving significant order, whitespace and raw lexical values.
@@ -83,108 +110,331 @@ declare function textContent(node: Extract<XmlNode, {
83
110
  type: 'element';
84
111
  }>): string;
85
112
 
86
- /** The WordprocessingML main namespace — the `w:` prefix in every `word/document.xml`. */
87
- declare const WML_NAMESPACE_URI = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
88
- /** The reserved `xml:` namespace, which carries `xml:space`. */
89
- declare const XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
90
- /** The reserved `xmlns:` namespace that namespace declarations themselves live in. */
91
- declare const XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
92
- /** The `w14` wordml-2010 extension namespace — `w14:paraId`/`w14:textId` live here. */
93
- declare const W14_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2010/wordml";
94
- declare const DRAWINGML_MAIN_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/main";
95
- declare const WP_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
96
- declare const PIC_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/picture";
97
- /** The four content-position revision wrappers, which nest and carry runs. */
98
- declare function isContentRevisionKind(kind: OoxmlNode['kind']): kind is 'revisionInsert' | 'revisionDelete' | 'revisionMoveFrom' | 'revisionMoveTo';
99
- /** Move-range and comment-range boundary markers, which are empty and sit between runs. */
100
- declare function isRangeMarkerKind(kind: OoxmlNode['kind']): kind is 'moveFromRangeStart' | 'moveFromRangeEnd' | 'moveToRangeStart' | 'moveToRangeEnd' | 'commentRangeStart' | 'commentRangeEnd';
101
113
  /**
102
- * OOXML on/off toggle: on only when a same-namespace child is present and its `w:val`
103
- * (same namespace as the child) does not explicitly disable. Foreign-namespace siblings
104
- * with the same local name cannot turn the flag on.
114
+ * Why a part or relationship name was refused.
115
+ *
116
+ * Path traversal is the reason this exists: a name with `..` or a leading `/` is refused rather
117
+ * than normalized, because normalizing is how a crafted package reaches outside itself.
105
118
  */
106
- declare function readOnOffChild(parent: OoxmlNode, localName: string, namespaceUri?: string): boolean;
119
+ type NameRejection = 'empty' | 'control-char' | 'backslash' | 'drive-or-unc' | 'encoded-separator' | 'encoded-dot' | 'bad-encoding' | 'empty-segment' | 'dot-segment' | 'unsafe-key' | 'segment-trailing-dot' | 'traversal-escape' | 'not-absolute-uri' | 'unsafe-scheme';
120
+ /** A validated OPC name, or the typed reason it was refused. */
121
+ type NameResult = {
122
+ readonly ok: true;
123
+ readonly partName: string;
124
+ } | {
125
+ readonly ok: false;
126
+ readonly reason: NameRejection;
127
+ };
128
+ /**
129
+ * Normalize a ZIP entry name or OPC part name into a canonical part name
130
+ * (`/word/document.xml`). Accepts leading-slash and no-leading-slash inputs;
131
+ * rejects traversal, dot segments, and the attack surface. Duplicate detection
132
+ * folds ASCII case (OPC part-name equivalence).
133
+ */
134
+ declare function normalizePartName(raw: string): NameResult;
135
+ /**
136
+ * ASCII-only lowercase fold. OPC part-name/extension equivalence is US-ASCII
137
+ * case-insensitive; a locale `toLowerCase()` mis-folds e.g. Turkish `I`/`İ` and
138
+ * could let two "equivalent" part names evade duplicate detection.
139
+ */
140
+ declare function asciiFold(s: string): string;
141
+ /** Case-folded key for OPC part-name equivalence / duplicate detection. */
142
+ declare function partNameKey(partName: string): string;
143
+ /**
144
+ * Detect archive entries that collide after normalization (before inflation).
145
+ * Returns the case-folded keys that more than one raw name maps to.
146
+ */
147
+ declare function detectDuplicateNames(rawNames: readonly string[]): {
148
+ readonly duplicates: readonly string[];
149
+ readonly rejected: readonly {
150
+ raw: string;
151
+ reason: NameRejection;
152
+ }[];
153
+ };
154
+ /**
155
+ * Resolve an internal relationship target against its owner part, without
156
+ * escaping the package root. `ownerPartName` is a canonical part name; the base
157
+ * is its containing folder. A leading "/" target is package-absolute. `.`/`..`
158
+ * segments resolve on a stack; popping above root is `traversal-escape`.
159
+ */
160
+ declare function resolveInternalTarget(ownerPartName: string, rawTarget: string): NameResult;
161
+ /**
162
+ * Validate an external-mode relationship target. It MUST be an absolute URI, is
163
+ * retained verbatim by the caller, and is NEVER owner-resolved or fetched here.
164
+ * Unsafe schemes (javascript/vbscript/data/file) are rejected for runtime sinks;
165
+ * the raw lexical form is still preserved separately by the authored record.
166
+ */
167
+ declare function validateExternalTarget(raw: string): NameResult;
107
168
 
169
+ /** OOXML image relationship type for embedded or linked media parts. */
170
+ declare const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
108
171
  /**
109
- * A node's stable identity within its part.
172
+ * Whether a relationship points inside the package or out of it.
110
173
  *
111
- * Minted deterministically from the structural path at parse, then RETAINED through structural
112
- * sharing — the same bytes always produce the same ids, and an edit elsewhere in the document
113
- * does not renumber untouched nodes. Every tree op addresses nodes by these.
174
+ * The security-relevant distinction: an `External` target is retained VERBATIM and never
175
+ * owner-resolved or fetched, because auto-loading a file-supplied remote target is a zero-click
176
+ * external fetch.
114
177
  */
115
- type OoxmlNodeId = string;
178
+ type TargetMode = 'Internal' | 'External';
116
179
  /**
117
- * One `xmlns:` declaration carried on a node.
118
- *
119
- * Preserved rather than normalized away: a document that binds `w14` at the root and a document
120
- * that binds it on a paragraph are different bytes, and re-emitting the wrong one is a fidelity
121
- * loss even though the semantics match.
180
+ * One authored relationship, with nothing materialized away: owner part, id, type, raw target
181
+ * lexical form, mode, and position.
122
182
  */
123
- interface OoxmlNamespaceBinding {
124
- readonly prefix: string;
125
- readonly namespaceUri: string;
126
- }
127
- interface OoxmlAttributeBase {
128
- readonly namespaceUri: string;
129
- readonly localName: string;
130
- readonly prefix?: string;
131
- readonly value: string;
132
- }
133
- /** `xml:space`, which decides whether a run's leading and trailing whitespace survives. */
134
- interface OoxmlXmlSpaceAttribute extends OoxmlAttributeBase {
135
- readonly kind: 'xmlSpace';
136
- readonly namespaceUri: typeof XML_NAMESPACE_URI;
137
- readonly localName: 'space';
138
- readonly prefix: 'xml';
139
- readonly value: 'default' | 'preserve';
140
- }
141
- /** `w:val` — the attribute nearly every WordprocessingML property carries its value in. */
142
- interface OoxmlWmlValAttribute extends OoxmlAttributeBase {
143
- readonly kind: 'wmlVal';
144
- readonly namespaceUri: typeof WML_NAMESPACE_URI;
145
- readonly localName: 'val';
183
+ interface RelationshipRecord {
184
+ readonly ownerPart: string;
185
+ readonly id: string;
186
+ readonly type: string;
187
+ readonly rawTarget: string;
188
+ readonly targetMode: TargetMode;
189
+ readonly order: number;
146
190
  }
191
+ /** Why a relationship set is invalid. Duplicate ids within one owner fail closed. */
192
+ type RelationshipError = {
193
+ readonly code: 'duplicate-id';
194
+ readonly ownerPart: string;
195
+ readonly id: string;
196
+ };
197
+ /** The validated relationship set, or the conflict that rejected it. */
198
+ type RelationshipSetResult = {
199
+ readonly ok: true;
200
+ readonly byOwner: ReadonlyMap<string, readonly RelationshipRecord[]>;
201
+ } | {
202
+ readonly ok: false;
203
+ readonly error: RelationshipError;
204
+ };
205
+ /** Group relationships by owner in authored order; reject duplicate ids per owner. */
206
+ declare function buildRelationshipSet(records: readonly RelationshipRecord[]): RelationshipSetResult;
147
207
  /**
148
- * Any attribute outside the typed vocabulary, carried verbatim.
208
+ * A relationship resolved to a part, or the reason it could not be.
149
209
  *
150
- * Where losslessness actually happens: an attribute this engine has no model for is preserved
151
- * exactly rather than dropped, so a save re-emits what the file said.
210
+ * External targets resolve to a refusal by design: they are never followed from a file.
152
211
  */
153
- interface OoxmlGenericExtensionAttribute extends OoxmlAttributeBase {
154
- readonly kind: 'genericExtension';
155
- }
156
- /** Any attribute on any node: the two typed ones, plus the verbatim catch-all. */
157
- type OoxmlAttribute = OoxmlXmlSpaceAttribute | OoxmlWmlValAttribute | OoxmlGenericExtensionAttribute;
212
+ type ResolvedRelationship = {
213
+ readonly mode: 'Internal';
214
+ readonly target: NameResult;
215
+ readonly raw: string;
216
+ } | {
217
+ readonly mode: 'External';
218
+ readonly sinkSafe: NameResult;
219
+ readonly raw: string;
220
+ };
158
221
  /**
159
- * Attributes a TYPED node may carry.
222
+ * Resolve a relationship to a runtime projection while the raw target stays
223
+ * authored. Internal -> owner-relative part name; External -> sink-safe
224
+ * validation only (never owner-resolved, never fetched). `raw` is always the
225
+ * verbatim authored target.
226
+ */
227
+ declare function resolveRelationship(rec: RelationshipRecord): ResolvedRelationship;
228
+ /**
229
+ * An image relationship resolved to package bytes, or why it was refused.
160
230
  *
161
- * Excludes `w:val` on purpose: a node the engine models keeps its value in typed fields, and
162
- * allowing a stray `w:val` alongside them would create two sources of truth for one property.
231
+ * External-mode image rels are refused rather than fetched — the no-zero-click-external-fetch
232
+ * rule applies to images exactly as it does to links.
163
233
  */
164
- type OoxmlKnownNodeAttribute = OoxmlXmlSpaceAttribute | OoxmlGenericExtensionAttribute;
165
- interface OoxmlElementBase<Children extends readonly OoxmlNode[] = readonly OoxmlNode[], Attributes extends readonly OoxmlAttribute[] = readonly OoxmlAttribute[]> {
166
- readonly id: OoxmlNodeId;
167
- readonly namespaceUri: string;
168
- readonly localName: string;
169
- /** Authored prefix retained as non-authoritative fidelity evidence. */
170
- readonly prefix?: string;
171
- /** Namespace declarations authored directly on this element, in source order. */
172
- readonly namespaceBindings: readonly OoxmlNamespaceBinding[];
173
- readonly attributes: Attributes;
174
- readonly children: Children;
175
- }
176
- /** `w:document` — the root of a main document part. */
177
- interface OoxmlDocumentNode extends OoxmlElementBase<readonly (OoxmlBodyNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
178
- readonly kind: 'document';
179
- readonly namespaceUri: typeof WML_NAMESPACE_URI;
180
- readonly localName: 'document';
181
- }
182
- /** `w:body` — the main story's block content. */
183
- interface OoxmlBodyNode extends OoxmlElementBase<readonly (OoxmlParagraphNode | OoxmlTableNode | OoxmlContentControlNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
184
- readonly kind: 'body';
185
- readonly namespaceUri: typeof WML_NAMESPACE_URI;
186
- readonly localName: 'body';
187
- }
234
+ type ImageRelationshipResolution = {
235
+ readonly mode: 'internal';
236
+ readonly partName: string;
237
+ readonly raw: string;
238
+ } | {
239
+ readonly mode: 'external';
240
+ readonly sinkSafe: boolean;
241
+ readonly raw: string;
242
+ } | {
243
+ readonly mode: 'missing';
244
+ };
245
+ /**
246
+ * Resolve an image relationship id from an owner part. Internal targets resolve
247
+ * owner-relative; external targets are never fetched; a missing id is `missing`.
248
+ */
249
+ declare function resolveImageRelationship(records: readonly RelationshipRecord[] | undefined, ownerPart: string, relationshipId: string): ImageRelationshipResolution;
250
+
251
+ /** One `<Default>`: a file extension mapped to a content type. */
252
+ interface DefaultRecord {
253
+ readonly extension: string;
254
+ readonly contentType: string;
255
+ readonly order: number;
256
+ }
257
+ /** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
258
+ interface OverrideRecord {
259
+ readonly partName: string;
260
+ readonly contentType: string;
261
+ readonly order: number;
262
+ }
263
+ /**
264
+ * The authored `[Content_Types].xml` records, in significant order.
265
+ *
266
+ * Retained rather than collapsed into a lookup, because the file's lexical form and ordering are
267
+ * part of what a lossless save re-emits.
268
+ */
269
+ interface ContentTypeRecords {
270
+ readonly defaults: readonly DefaultRecord[];
271
+ readonly overrides: readonly OverrideRecord[];
272
+ }
273
+ /**
274
+ * Why content-type records could not be indexed.
275
+ *
276
+ * All fail CLOSED: conflicting Defaults on one extension, duplicate normalized Override names, or
277
+ * invalid MIME syntax are refused rather than resolved by picking one.
278
+ */
279
+ type ContentTypeError = {
280
+ readonly code: 'invalid-mime';
281
+ readonly value: string;
282
+ } | {
283
+ readonly code: 'conflicting-default';
284
+ readonly extension: string;
285
+ } | {
286
+ readonly code: 'duplicate-override';
287
+ readonly partName: string;
288
+ } | {
289
+ readonly code: 'invalid-override-name';
290
+ readonly partName: string;
291
+ } | {
292
+ readonly code: 'too-many-records';
293
+ readonly limit: number;
294
+ };
295
+ /** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
296
+ declare function isValidMime(value: string): boolean;
297
+ /** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
298
+ declare function extensionKey(extension: string): string;
299
+ /** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
300
+ interface ContentTypeIndex {
301
+ /** ext key -> single MIME (identical duplicates collapsed). */
302
+ readonly defaults: ReadonlyMap<string, string>;
303
+ /** case-folded part name -> MIME. */
304
+ readonly overrides: ReadonlyMap<string, string>;
305
+ }
306
+ /** The built index, or the conflict that made it impossible. */
307
+ type IndexResult = {
308
+ readonly ok: true;
309
+ readonly index: ContentTypeIndex;
310
+ } | {
311
+ readonly ok: false;
312
+ readonly error: ContentTypeError;
313
+ };
314
+ /**
315
+ * Build a resolved content-type index, failing closed on conflict/duplicate/MIME
316
+ * errors. `maxRecords` bounds the combined record count (N/N+1 gate).
317
+ */
318
+ declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
319
+ /**
320
+ * A part's content type, or why it has none.
321
+ *
322
+ * An orphan record never determines a part's type — a Default with no matching part is preserved
323
+ * inertly rather than applied.
324
+ */
325
+ type ResolveResult = {
326
+ readonly ok: true;
327
+ readonly contentType: string;
328
+ readonly source: 'override' | 'default';
329
+ } | {
330
+ readonly ok: false;
331
+ readonly reason: 'unknown';
332
+ };
333
+ /** Resolve a part's content type: Override wins over Default; else unknown. */
334
+ declare function resolveContentType(index: ContentTypeIndex, partName: string): ResolveResult;
335
+
336
+ /** The WordprocessingML main namespace — the `w:` prefix in every `word/document.xml`. */
337
+ declare const WML_NAMESPACE_URI = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
338
+ /** The reserved `xml:` namespace, which carries `xml:space`. */
339
+ declare const XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
340
+ /** The reserved `xmlns:` namespace that namespace declarations themselves live in. */
341
+ declare const XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
342
+ /** The `w14` wordml-2010 extension namespace — `w14:paraId`/`w14:textId` live here. */
343
+ declare const W14_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2010/wordml";
344
+ declare const DRAWINGML_MAIN_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/main";
345
+ declare const WP_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
346
+ declare const PIC_NAMESPACE_URI = "http://schemas.openxmlformats.org/drawingml/2006/picture";
347
+ /** The four content-position revision wrappers, which nest and carry runs. */
348
+ declare function isContentRevisionKind(kind: OoxmlNode['kind']): kind is 'revisionInsert' | 'revisionDelete' | 'revisionMoveFrom' | 'revisionMoveTo';
349
+ /** Move-range and comment-range boundary markers, which are empty and sit between runs. */
350
+ declare function isRangeMarkerKind(kind: OoxmlNode['kind']): kind is 'moveFromRangeStart' | 'moveFromRangeEnd' | 'moveToRangeStart' | 'moveToRangeEnd' | 'commentRangeStart' | 'commentRangeEnd';
351
+ /**
352
+ * OOXML on/off toggle: on only when a same-namespace child is present and its `w:val`
353
+ * (same namespace as the child) does not explicitly disable. Foreign-namespace siblings
354
+ * with the same local name cannot turn the flag on.
355
+ */
356
+ declare function readOnOffChild(parent: OoxmlNode, localName: string, namespaceUri?: string): boolean;
357
+
358
+ /**
359
+ * A node's stable identity within its part.
360
+ *
361
+ * Minted deterministically from the structural path at parse, then RETAINED through structural
362
+ * sharing — the same bytes always produce the same ids, and an edit elsewhere in the document
363
+ * does not renumber untouched nodes. Every tree op addresses nodes by these.
364
+ */
365
+ type OoxmlNodeId = string;
366
+ /**
367
+ * One `xmlns:` declaration carried on a node.
368
+ *
369
+ * Preserved rather than normalized away: a document that binds `w14` at the root and a document
370
+ * that binds it on a paragraph are different bytes, and re-emitting the wrong one is a fidelity
371
+ * loss even though the semantics match.
372
+ */
373
+ interface OoxmlNamespaceBinding {
374
+ readonly prefix: string;
375
+ readonly namespaceUri: string;
376
+ }
377
+ interface OoxmlAttributeBase {
378
+ readonly namespaceUri: string;
379
+ readonly localName: string;
380
+ readonly prefix?: string;
381
+ readonly value: string;
382
+ }
383
+ /** `xml:space`, which decides whether a run's leading and trailing whitespace survives. */
384
+ interface OoxmlXmlSpaceAttribute extends OoxmlAttributeBase {
385
+ readonly kind: 'xmlSpace';
386
+ readonly namespaceUri: typeof XML_NAMESPACE_URI;
387
+ readonly localName: 'space';
388
+ readonly prefix: 'xml';
389
+ readonly value: 'default' | 'preserve';
390
+ }
391
+ /** `w:val` — the attribute nearly every WordprocessingML property carries its value in. */
392
+ interface OoxmlWmlValAttribute extends OoxmlAttributeBase {
393
+ readonly kind: 'wmlVal';
394
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
395
+ readonly localName: 'val';
396
+ }
397
+ /**
398
+ * Any attribute outside the typed vocabulary, carried verbatim.
399
+ *
400
+ * Where losslessness actually happens: an attribute this engine has no model for is preserved
401
+ * exactly rather than dropped, so a save re-emits what the file said.
402
+ */
403
+ interface OoxmlGenericExtensionAttribute extends OoxmlAttributeBase {
404
+ readonly kind: 'genericExtension';
405
+ }
406
+ /** Any attribute on any node: the two typed ones, plus the verbatim catch-all. */
407
+ type OoxmlAttribute = OoxmlXmlSpaceAttribute | OoxmlWmlValAttribute | OoxmlGenericExtensionAttribute;
408
+ /**
409
+ * Attributes a TYPED node may carry.
410
+ *
411
+ * Excludes `w:val` on purpose: a node the engine models keeps its value in typed fields, and
412
+ * allowing a stray `w:val` alongside them would create two sources of truth for one property.
413
+ */
414
+ type OoxmlKnownNodeAttribute = OoxmlXmlSpaceAttribute | OoxmlGenericExtensionAttribute;
415
+ interface OoxmlElementBase<Children extends readonly OoxmlNode[] = readonly OoxmlNode[], Attributes extends readonly OoxmlAttribute[] = readonly OoxmlAttribute[]> {
416
+ readonly id: OoxmlNodeId;
417
+ readonly namespaceUri: string;
418
+ readonly localName: string;
419
+ /** Authored prefix retained as non-authoritative fidelity evidence. */
420
+ readonly prefix?: string;
421
+ /** Namespace declarations authored directly on this element, in source order. */
422
+ readonly namespaceBindings: readonly OoxmlNamespaceBinding[];
423
+ readonly attributes: Attributes;
424
+ readonly children: Children;
425
+ }
426
+ /** `w:document` — the root of a main document part. */
427
+ interface OoxmlDocumentNode extends OoxmlElementBase<readonly (OoxmlBodyNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
428
+ readonly kind: 'document';
429
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
430
+ readonly localName: 'document';
431
+ }
432
+ /** `w:body` — the main story's block content. */
433
+ interface OoxmlBodyNode extends OoxmlElementBase<readonly (OoxmlParagraphNode | OoxmlTableNode | OoxmlContentControlNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
434
+ readonly kind: 'body';
435
+ readonly namespaceUri: typeof WML_NAMESPACE_URI;
436
+ readonly localName: 'body';
437
+ }
188
438
  interface OoxmlTableNode extends OoxmlElementBase<readonly (OoxmlTablePropertiesNode | OoxmlTableGridNode | OoxmlTableRowNode | OoxmlContentControlNode | OoxmlGenericElementNode)[], readonly OoxmlKnownNodeAttribute[]> {
189
439
  readonly kind: 'table';
190
440
  readonly namespaceUri: typeof WML_NAMESPACE_URI;
@@ -894,322 +1144,23 @@ type OoxmlInvariantResult = {
894
1144
  */
895
1145
  declare function readOoxmlPart(xml: string, metadata: OoxmlPartMetadata, limits?: XmlLimits): OoxmlReadResult;
896
1146
 
897
- type AutomationTableMutation = {
898
- readonly kind: 'insertRows';
899
- readonly rowId: string;
900
- readonly location: 'before' | 'after';
901
- readonly count: number;
902
- readonly values?: readonly (readonly string[])[];
903
- } | {
904
- readonly kind: 'values';
905
- readonly values: readonly (readonly string[])[];
906
- } | {
907
- readonly kind: 'addRows' | 'addColumns';
908
- readonly location: 'start' | 'end';
909
- readonly count: number;
910
- readonly values?: readonly (readonly string[])[];
911
- } | {
912
- readonly kind: 'deleteRows' | 'deleteColumns';
913
- readonly index: number;
914
- readonly count: number;
915
- } | {
916
- readonly kind: 'delete';
917
- } | {
918
- readonly kind: 'properties';
919
- readonly styleId?: string;
920
- readonly headerRowCount?: number;
921
- } | {
922
- readonly kind: 'cell';
923
- readonly cellId: string;
924
- readonly value?: string;
925
- readonly columnWidth?: number;
926
- readonly shadingColor?: string;
927
- readonly verticalAlignment?: 'Top' | 'Center' | 'Bottom';
928
- };
929
-
930
- /** Select one declared entry of a legacy Word dropdown form field. */
931
- interface SetLegacyDropdownOp {
932
- readonly op: 'setLegacyDropdown';
933
- readonly paragraphId: string;
934
- readonly fieldNodeId: string;
935
- readonly selectedIndex: number;
936
- }
937
-
938
- interface SetFieldCodeOp {
939
- readonly op: 'setFieldCode';
940
- readonly paragraphId: string;
941
- readonly fieldNodeId: string;
942
- readonly code: string;
1147
+ /** Plain text fitted to a floating shape box, painted with one fill and an optional outline. */
1148
+ interface LegacyTextArtProjection {
1149
+ readonly text: string;
1150
+ readonly fontFamily: string;
1151
+ readonly bold: boolean;
1152
+ readonly italic: boolean;
1153
+ /** `RRGGBB`, or null when the shape is not filled. */
1154
+ readonly fillHex: string | null;
1155
+ readonly fillAlpha: number;
1156
+ /** `RRGGBB`, or null when the shape is not stroked. */
1157
+ readonly strokeHex: string | null;
1158
+ readonly strokeAlpha: number;
1159
+ readonly strokeWidthPt: number;
1160
+ /** Clockwise rotation about the box centre, in [0, 360). */
1161
+ readonly rotationDegrees: number;
943
1162
  }
944
1163
 
945
- type InsertTextOp = {
946
- readonly op: 'insertText';
947
- readonly paragraphId: string;
948
- /** Legacy text form identity for protected filling; never an inline wrapper owner. */
949
- readonly textFormFieldId?: string;
950
- readonly offset: number;
951
- readonly text: string;
952
- /**
953
- * Write this as a TRACKED insertion, attributed here.
954
- *
955
- * On the op rather than on the store, so suggesting stays a decision the surface makes
956
- * per edit and the write vocabulary stays explicit — a global "everything is tracked
957
- * now" flag is exactly what `DocEdits` refuses, because it makes the meaning of an op
958
- * depend on state the op does not carry.
959
- */
960
- readonly revision?: RevisionAttributionInput;
961
- /**
962
- * When set, the text belongs INSIDE this content control, whatever sits at the offset.
963
- *
964
- * A boundary offset is owned by the run that starts there, which at a control's trailing
965
- * edge is the run after the control — so an offset alone cannot say "append to this field",
966
- * the way it cannot say which run of a field result to format (see `targetRunIds`). A
967
- * caller that names the control gets the text in the control; one that does not gets the
968
- * plain offset rule, which is what a keystroke beside a field means.
969
- */
970
- readonly inside?: string;
971
- /**
972
- * Which side of a run BOUNDARY the text joins. Default `'left'` — Word's typing rule:
973
- * the next character takes the formatting of the character before the caret.
974
- *
975
- * `'right'` is for a caller that is not typing but placing text inside the run that
976
- * STARTS at the offset — the hyperlink editor rewriting a link's display text, where
977
- * landing left of the boundary would put the new text outside the link. Ignored when
978
- * the offset falls strictly inside a run, which has no boundary to choose.
979
- */
980
- readonly bias?: 'left' | 'right';
981
- };
982
- type DeleteTextOp = {
983
- readonly op: 'deleteText';
984
- readonly paragraphId: string;
985
- /** Legacy text form identity for protected filling; never an inline wrapper owner. */
986
- readonly textFormFieldId?: string;
987
- readonly start: number;
988
- readonly end: number;
989
- /** Write this as a TRACKED deletion — the characters stay, wrapped in `w:del`. */
990
- readonly revision?: RevisionAttributionInput;
991
- };
992
-
993
- /** Editable legacy text input types. Other authored types remain inert. */
994
- type TextFormFieldType = 'regular' | 'number' | 'date';
995
- /** Options stored in the legacy field definition. Zero means unlimited length. */
996
- interface TextFormFieldOptions {
997
- readonly type: TextFormFieldType;
998
- readonly maxLength: number;
999
- readonly format: string;
1000
- readonly enabled: boolean;
1001
- }
1002
- /** Supported format choices for legacy text input fields. @public */
1003
- declare const TEXT_FORM_FORMATS: {
1004
- readonly regular: readonly ['', 'Uppercase', 'Lowercase', 'First capital', 'Title case'];
1005
- readonly number: readonly ['', '0', '0.00', '#,##0', '#,##0.00', '0%', '0.00%'];
1006
- readonly date: readonly ['', 'M/d/yyyy', 'MM/dd/yyyy', 'd/M/yyyy', 'dd/MM/yyyy', 'yyyy-MM-dd', 'd MMMM yyyy', 'MMMM d, yyyy'];
1007
- };
1008
-
1009
- /** A legacy text input in the shared paragraph offset space. */
1010
- interface TextFormFieldRange {
1011
- readonly fieldNodeId: string;
1012
- readonly start: number;
1013
- readonly end: number;
1014
- readonly enabled: boolean;
1015
- readonly defaultText: string;
1016
- readonly type: string;
1017
- readonly maxLength: number;
1018
- readonly format: string;
1019
- readonly chromeIds: readonly string[];
1020
- }
1021
- /** Uses the field parser and offset index; never introduces another inline walk. */
1022
- declare function textFormFieldsOf(paragraph: OoxmlParagraphNode): readonly TextFormFieldRange[];
1023
- /** Options edit for an existing legacy text form. */
1024
- interface SetTextFormFieldDefaultOp {
1025
- readonly op: 'setTextFormFieldDefault';
1026
- /** Regional conventions for new date input; defaults to en-US. */
1027
- readonly locale?: string;
1028
- readonly paragraphId: string;
1029
- readonly fieldNodeId: string;
1030
- readonly text: string;
1031
- readonly options?: TextFormFieldOptions;
1032
- }
1033
- /** Validate and format the existing result when a user finishes filling a field. */
1034
- interface CommitTextFormFieldOp {
1035
- readonly op: 'commitTextFormField';
1036
- /** Regional conventions for new date input; defaults to en-US. */
1037
- readonly locale?: string;
1038
- readonly paragraphId: string;
1039
- readonly fieldNodeId: string;
1040
- }
1041
-
1042
- /** One FORMCHECKBOX in the shared paragraph offset space. */
1043
- interface LegacyCheckboxFieldRange {
1044
- /** The begin `w:fldChar` node: what the op addresses. */
1045
- readonly fieldNodeId: string;
1046
- readonly start: number;
1047
- readonly end: number;
1048
- readonly checked: boolean;
1049
- /** `w:enabled` under `w:ffData`; a disabled field renders but refuses the toggle. */
1050
- readonly enabled: boolean;
1051
- }
1052
- /** Flip a FORMCHECKBOX's state; the only write into `w:ffData` a checkbox permits. */
1053
- interface SetLegacyCheckboxOp {
1054
- readonly op: 'setLegacyCheckbox';
1055
- readonly paragraphId: string;
1056
- readonly fieldNodeId: string;
1057
- readonly checked: boolean;
1058
- }
1059
- /** Every FORMCHECKBOX in a paragraph, in document order; uses the shared field parser. */
1060
- declare function legacyCheckboxFieldsOf(paragraph: OoxmlParagraphNode): readonly LegacyCheckboxFieldRange[];
1061
-
1062
- /** Replace a building block gallery control's content with one block's body. */
1063
- interface InsertBuildingBlockOp {
1064
- readonly op: 'insertBuildingBlock';
1065
- readonly controlId: string;
1066
- /** `w:docPartPr/w:name` of the picked block, for the journal and the host. */
1067
- readonly name: string;
1068
- /**
1069
- * Self-contained `w:docPartBody` children, cloned with fresh ids at apply.
1070
- * Resource, style, field, bookmark, note and revision references return `unsupported`.
1071
- */
1072
- readonly blocks: readonly OoxmlNode[];
1073
- }
1074
-
1075
- /**
1076
- * Why a part or relationship name was refused.
1077
- *
1078
- * Path traversal is the reason this exists: a name with `..` or a leading `/` is refused rather
1079
- * than normalized, because normalizing is how a crafted package reaches outside itself.
1080
- */
1081
- type NameRejection = 'empty' | 'control-char' | 'backslash' | 'drive-or-unc' | 'encoded-separator' | 'encoded-dot' | 'bad-encoding' | 'empty-segment' | 'dot-segment' | 'unsafe-key' | 'segment-trailing-dot' | 'traversal-escape' | 'not-absolute-uri' | 'unsafe-scheme';
1082
- /** A validated OPC name, or the typed reason it was refused. */
1083
- type NameResult = {
1084
- readonly ok: true;
1085
- readonly partName: string;
1086
- } | {
1087
- readonly ok: false;
1088
- readonly reason: NameRejection;
1089
- };
1090
- /**
1091
- * Normalize a ZIP entry name or OPC part name into a canonical part name
1092
- * (`/word/document.xml`). Accepts leading-slash and no-leading-slash inputs;
1093
- * rejects traversal, dot segments, and the attack surface. Duplicate detection
1094
- * folds ASCII case (OPC part-name equivalence).
1095
- */
1096
- declare function normalizePartName(raw: string): NameResult;
1097
- /**
1098
- * ASCII-only lowercase fold. OPC part-name/extension equivalence is US-ASCII
1099
- * case-insensitive; a locale `toLowerCase()` mis-folds e.g. Turkish `I`/`İ` and
1100
- * could let two "equivalent" part names evade duplicate detection.
1101
- */
1102
- declare function asciiFold(s: string): string;
1103
- /** Case-folded key for OPC part-name equivalence / duplicate detection. */
1104
- declare function partNameKey(partName: string): string;
1105
- /**
1106
- * Detect archive entries that collide after normalization (before inflation).
1107
- * Returns the case-folded keys that more than one raw name maps to.
1108
- */
1109
- declare function detectDuplicateNames(rawNames: readonly string[]): {
1110
- readonly duplicates: readonly string[];
1111
- readonly rejected: readonly {
1112
- raw: string;
1113
- reason: NameRejection;
1114
- }[];
1115
- };
1116
- /**
1117
- * Resolve an internal relationship target against its owner part, without
1118
- * escaping the package root. `ownerPartName` is a canonical part name; the base
1119
- * is its containing folder. A leading "/" target is package-absolute. `.`/`..`
1120
- * segments resolve on a stack; popping above root is `traversal-escape`.
1121
- */
1122
- declare function resolveInternalTarget(ownerPartName: string, rawTarget: string): NameResult;
1123
- /**
1124
- * Validate an external-mode relationship target. It MUST be an absolute URI, is
1125
- * retained verbatim by the caller, and is NEVER owner-resolved or fetched here.
1126
- * Unsafe schemes (javascript/vbscript/data/file) are rejected for runtime sinks;
1127
- * the raw lexical form is still preserved separately by the authored record.
1128
- */
1129
- declare function validateExternalTarget(raw: string): NameResult;
1130
-
1131
- /** OOXML image relationship type for embedded or linked media parts. */
1132
- declare const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
1133
- /**
1134
- * Whether a relationship points inside the package or out of it.
1135
- *
1136
- * The security-relevant distinction: an `External` target is retained VERBATIM and never
1137
- * owner-resolved or fetched, because auto-loading a file-supplied remote target is a zero-click
1138
- * external fetch.
1139
- */
1140
- type TargetMode = 'Internal' | 'External';
1141
- /**
1142
- * One authored relationship, with nothing materialized away: owner part, id, type, raw target
1143
- * lexical form, mode, and position.
1144
- */
1145
- interface RelationshipRecord {
1146
- readonly ownerPart: string;
1147
- readonly id: string;
1148
- readonly type: string;
1149
- readonly rawTarget: string;
1150
- readonly targetMode: TargetMode;
1151
- readonly order: number;
1152
- }
1153
- /** Why a relationship set is invalid. Duplicate ids within one owner fail closed. */
1154
- type RelationshipError = {
1155
- readonly code: 'duplicate-id';
1156
- readonly ownerPart: string;
1157
- readonly id: string;
1158
- };
1159
- /** The validated relationship set, or the conflict that rejected it. */
1160
- type RelationshipSetResult = {
1161
- readonly ok: true;
1162
- readonly byOwner: ReadonlyMap<string, readonly RelationshipRecord[]>;
1163
- } | {
1164
- readonly ok: false;
1165
- readonly error: RelationshipError;
1166
- };
1167
- /** Group relationships by owner in authored order; reject duplicate ids per owner. */
1168
- declare function buildRelationshipSet(records: readonly RelationshipRecord[]): RelationshipSetResult;
1169
- /**
1170
- * A relationship resolved to a part, or the reason it could not be.
1171
- *
1172
- * External targets resolve to a refusal by design: they are never followed from a file.
1173
- */
1174
- type ResolvedRelationship = {
1175
- readonly mode: 'Internal';
1176
- readonly target: NameResult;
1177
- readonly raw: string;
1178
- } | {
1179
- readonly mode: 'External';
1180
- readonly sinkSafe: NameResult;
1181
- readonly raw: string;
1182
- };
1183
- /**
1184
- * Resolve a relationship to a runtime projection while the raw target stays
1185
- * authored. Internal -> owner-relative part name; External -> sink-safe
1186
- * validation only (never owner-resolved, never fetched). `raw` is always the
1187
- * verbatim authored target.
1188
- */
1189
- declare function resolveRelationship(rec: RelationshipRecord): ResolvedRelationship;
1190
- /**
1191
- * An image relationship resolved to package bytes, or why it was refused.
1192
- *
1193
- * External-mode image rels are refused rather than fetched — the no-zero-click-external-fetch
1194
- * rule applies to images exactly as it does to links.
1195
- */
1196
- type ImageRelationshipResolution = {
1197
- readonly mode: 'internal';
1198
- readonly partName: string;
1199
- readonly raw: string;
1200
- } | {
1201
- readonly mode: 'external';
1202
- readonly sinkSafe: boolean;
1203
- readonly raw: string;
1204
- } | {
1205
- readonly mode: 'missing';
1206
- };
1207
- /**
1208
- * Resolve an image relationship id from an owner part. Internal targets resolve
1209
- * owner-relative; external targets are never fetched; a missing id is `missing`.
1210
- */
1211
- declare function resolveImageRelationship(records: readonly RelationshipRecord[] | undefined, ownerPart: string, relationshipId: string): ImageRelationshipResolution;
1212
-
1213
1164
  type ShapeSchemeColorResolver = (scheme: string) => string | null;
1214
1165
  type ShapeStyleMatrixResolver = (kind: 'fill' | 'line', index: number) => OoxmlElement | null;
1215
1166
  /**
@@ -1267,6 +1218,9 @@ interface VectorShapeComponent {
1267
1218
  readonly strokeHex: string | null;
1268
1219
  readonly strokeAlpha: number;
1269
1220
  readonly strokeWidthEmu: number;
1221
+ /** Authored line ends and joins, inherited from the selected theme line when absent. */
1222
+ readonly strokeCap?: 'butt' | 'round' | 'square';
1223
+ readonly strokeJoin?: 'round' | 'bevel';
1270
1224
  /**
1271
1225
  * The outline sits inside the closed geometry (`a:ln algn="in"`): painters draw it at twice
1272
1226
  * its width clipped to the path, so the authored width stays inside the shape and adds no
@@ -1466,150 +1420,412 @@ interface GroupPictureProjection {
1466
1420
  cx: number;
1467
1421
  cy: number;
1468
1422
  }>;
1469
- /** Canonical node id of the `pic:pic` member. The vector projection skips it. */
1470
- readonly memberNodeId: string;
1471
- /**
1472
- * Whether the group is the chosen branch of a run-level `mc:AlternateContent`. Layout then
1473
- * drops the whole group when the picture resource fails, as the projection drops other
1474
- * MC payloads it cannot draw.
1475
- */
1476
- readonly alternateContent: boolean;
1423
+ /** Canonical node id of the `pic:pic` member. The vector projection skips it. */
1424
+ readonly memberNodeId: string;
1425
+ /**
1426
+ * Whether the group is the chosen branch of a run-level `mc:AlternateContent`. Layout then
1427
+ * drops the whole group when the picture resource fails, as the projection drops other
1428
+ * MC payloads it cannot draw.
1429
+ */
1430
+ readonly alternateContent: boolean;
1431
+ }
1432
+
1433
+ /**
1434
+ * Whether a drawing sits in the text flow or is positioned against a frame.
1435
+ *
1436
+ * The distinction that decides everything downstream: an inline drawing occupies a character
1437
+ * position, while an anchored one has offsets relative to a page, margin or column.
1438
+ */
1439
+ type DrawingKind = 'inline' | 'anchored';
1440
+ /** Nine Word wrap menu targets (inline plus eight floating modes). @public */
1441
+ type ImageWrapTarget = 'inline' | 'square' | 'squareLeft' | 'squareRight' | 'tight' | 'through' | 'topAndBottom' | 'behind' | 'inFront';
1442
+ /** Every text-wrap mode a drawing may be set to, including `inline`. */
1443
+ declare const IMAGE_WRAP_TARGETS: readonly ImageWrapTarget[];
1444
+ type DrawingWrapElement = 'none' | 'square' | 'tight' | 'through' | 'topAndBottom';
1445
+ type DrawingHorizontalReferenceFrame = 'character' | 'column' | 'insideMargin' | 'leftMargin' | 'margin' | 'outsideMargin' | 'page' | 'rightMargin';
1446
+ type DrawingVerticalReferenceFrame = 'bottomMargin' | 'insideMargin' | 'line' | 'margin' | 'outsideMargin' | 'page' | 'paragraph' | 'topMargin';
1447
+ /** `a:srcRect` — how much of each edge of the source image is cropped away, as fractions. */
1448
+ interface SourceCrop {
1449
+ readonly left: number;
1450
+ readonly top: number;
1451
+ readonly right: number;
1452
+ readonly bottom: number;
1453
+ }
1454
+ interface DrawingTransform {
1455
+ readonly rotationDegrees: number;
1456
+ readonly flipHorizontal: boolean;
1457
+ readonly flipVertical: boolean;
1458
+ /** Source `a:off` in EMU; defaults to origin when absent. */
1459
+ readonly offsetEmu: Readonly<{
1460
+ x: number;
1461
+ y: number;
1462
+ }>;
1463
+ /** Source `a:ext` in EMU; zero falls back to `wp:extent` at geometry time. */
1464
+ readonly extentEmu: Readonly<{
1465
+ cx: number;
1466
+ cy: number;
1467
+ }>;
1477
1468
  }
1478
-
1479
1469
  /**
1480
- * Why a zip was refused at the trust boundary.
1470
+ * What a drawing refuses: selection, movement, resizing, aspect change.
1481
1471
  *
1482
- * `too-large` and `too-many-entries` are the zip-bomb guards; `bad-name` catches path traversal —
1483
- * an entry with `..` or a leading `/` is rejected rather than normalized.
1472
+ * Read and honoured rather than advisory — chrome that offered a handle the store will refuse
1473
+ * would promise an edit that cannot happen.
1484
1474
  */
1485
- type ZipRejection = 'too-many-entries' | 'too-large' | 'bad-name' | 'inflate-error';
1486
- /** Archive caps: entry count, total decompressed bytes, and the decompression ratio. */
1487
- interface ZipLimits {
1488
- readonly maxEntries: number;
1489
- /** Max total UNCOMPRESSED bytes across the archive. */
1490
- readonly maxTotalBytes: number;
1491
- /**
1492
- * Max ratio of the archive's total declared uncompressed bytes to the archive's own byte
1493
- * length (zip-bomb guard). Applies once that total exceeds 8 MiB, so a small archive is
1494
- * never refused for compressing well.
1495
- */
1496
- readonly maxRatio?: number;
1475
+ interface DrawingLocks {
1476
+ readonly select: boolean;
1477
+ readonly move: boolean;
1478
+ readonly resize: boolean;
1479
+ readonly changeAspect: boolean;
1480
+ }
1481
+ interface DrawingLocksInput {
1482
+ readonly select?: boolean;
1483
+ readonly move?: boolean;
1484
+ readonly resize?: boolean;
1485
+ readonly changeAspect?: boolean;
1497
1486
  }
1498
- /** The archive caps in force when a host configures none. Conservative and finite. */
1499
- declare const DEFAULT_ZIP_LIMITS: ZipLimits;
1500
- /** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
1501
- type ZipReadResult = {
1502
- readonly ok: true;
1503
- readonly entries: ReadonlyMap<string, Uint8Array>;
1504
- } | {
1505
- readonly ok: false;
1506
- readonly reason: ZipRejection;
1507
- readonly detail?: string;
1508
- readonly limit?: 'zip.maxTotalBytes' | 'zip.maxRatio';
1509
- };
1510
1487
  /**
1511
- * Inflate a ZIP archive with bounds + OPC name normalization. Entry name, count, archive
1512
- * ratio, and total-uncompressed-size limits are enforced BEFORE each entry is decompressed
1513
- * (via fflate's pre-inflation filter), so a zip bomb or a traversal name is rejected without
1514
- * ever being inflated. Keys are canonical part names.
1488
+ * An anchored drawing's position: offsets, and the frames they are relative to.
1515
1489
  *
1516
- * The budgets count each entry's DECLARED sizes, and the declared size is also a hard cap on
1517
- * what the entry may produce: fflate inflates into a buffer of exactly `originalSize` bytes
1518
- * and never grows it, so an entry whose stream holds more than it declares is truncated (or
1519
- * refused as `inflate-error`), never expanded past its budget. A stored entry is copied at
1520
- * its compressed size, so the larger of its two declared sizes is what counts.
1490
+ * The relative-to bases matter as much as the offsets. Writing an offset without preserving its
1491
+ * base re-anchors the drawing against a different reference and moves it somewhere nobody asked.
1521
1492
  */
1522
- declare function readZip(bytes: Uint8Array, limits?: ZipLimits): ZipReadResult;
1523
- /** Deflate a set of canonical-part-name -> bytes into a ZIP archive. Every part name
1524
- * is re-validated through the OPC normalization profile before writing, so a
1525
- * traversal/encoded/normalized-alias name from an untrusted serialized model can
1526
- * never be smuggled into a ZIP entry (write-side path-traversal guard). */
1527
- declare function writeZip(entries: ReadonlyMap<string, Uint8Array>): Uint8Array;
1528
-
1529
- /** One `<Default>`: a file extension mapped to a content type. */
1530
- interface DefaultRecord {
1531
- readonly extension: string;
1532
- readonly contentType: string;
1533
- readonly order: number;
1493
+ interface DrawingPositionInput {
1494
+ /**
1495
+ * `'simple'` when `@simplePos="1"`: `horizontalEmu` / `verticalEmu` are authoritative
1496
+ * `wp:simplePos` x/y. `'frame'` (default) uses positionH/V relative frames.
1497
+ */
1498
+ readonly mode?: 'frame' | 'simple';
1499
+ readonly horizontalEmu?: number;
1500
+ readonly verticalEmu?: number;
1501
+ readonly relativeToH?: DrawingHorizontalReferenceFrame;
1502
+ readonly relativeToV?: DrawingVerticalReferenceFrame;
1534
1503
  }
1535
- /** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
1536
- interface OverrideRecord {
1537
- readonly partName: string;
1538
- readonly contentType: string;
1539
- readonly order: number;
1504
+ interface DrawingProjection {
1505
+ readonly drawingNodeId: string;
1506
+ readonly ownerPartName: string;
1507
+ readonly kind: DrawingKind;
1508
+ readonly relationshipId: string | null;
1509
+ readonly docPrId: number | null;
1510
+ readonly name: string;
1511
+ readonly title: string;
1512
+ readonly description: string;
1513
+ readonly hyperlinkHref: string | null;
1514
+ readonly hidden: boolean;
1515
+ readonly extentEmu: Readonly<{
1516
+ cx: number;
1517
+ cy: number;
1518
+ }>;
1519
+ readonly effectExtentEmu: Readonly<{
1520
+ top: number;
1521
+ right: number;
1522
+ bottom: number;
1523
+ left: number;
1524
+ }>;
1525
+ readonly inlineDistancesEmu: Readonly<{
1526
+ top: number;
1527
+ right: number;
1528
+ bottom: number;
1529
+ left: number;
1530
+ }>;
1531
+ readonly wrap: ImageWrapTarget;
1532
+ readonly wrapGeometry: DrawingWrapProjection | null;
1533
+ readonly position: DrawingPositionProjection | null;
1534
+ readonly anchor: Readonly<{
1535
+ simplePos: boolean;
1536
+ relativeHeight: number;
1537
+ behindDocument: boolean;
1538
+ layoutInCell: boolean;
1539
+ allowOverlap: boolean;
1540
+ }> | null;
1541
+ readonly picture: PictureProjection | null;
1542
+ readonly vectorShape: VectorShapeProjection | null;
1543
+ /** The picture member of a `wpg:wgp` group; `picture` stays null for a group. */
1544
+ readonly groupPicture: GroupPictureProjection | null;
1545
+ readonly textboxStory: TextboxStoryProjection | null;
1546
+ /** Text box members of a `wpg:wgp` group, laid out read-only; absent when none has text. */
1547
+ readonly groupTextboxes?: readonly GroupTextboxProjection[];
1548
+ /** Read-only preview of the supported native VML subset; the canonical XML is untouched. */
1549
+ readonly legacyGraphic?: LegacyGraphicProjection;
1550
+ /** Floating VML text art (a text watermark), fitted to the box by layout. */
1551
+ readonly textArt?: LegacyTextArtProjection;
1552
+ readonly locks: DrawingLocks;
1553
+ readonly effects: DrawingImageEffects;
1554
+ readonly compatibilityBranchNodeId: string | null;
1555
+ readonly diagnostics: readonly DrawingDiagnostic[];
1556
+ /** Layout-only wrap area of an MC payload that cannot paint (`wrapFootprintProjection`). */
1557
+ readonly footprintOnly?: true;
1540
1558
  }
1541
- /**
1542
- * The authored `[Content_Types].xml` records, in significant order.
1543
- *
1544
- * Retained rather than collapsed into a lookup, because the file's lexical form and ordering are
1545
- * part of what a lossless save re-emits.
1546
- */
1547
- interface ContentTypeRecords {
1548
- readonly defaults: readonly DefaultRecord[];
1549
- readonly overrides: readonly OverrideRecord[];
1559
+ interface DrawingAccessibility {
1560
+ /**
1561
+ * The record takes part in layout only, for example the wrap area of a payload that cannot
1562
+ * paint. Outputs must not paint, hit-test, select, link, or export it.
1563
+ */
1564
+ readonly hidden: boolean;
1565
+ readonly decorative: boolean;
1566
+ readonly label: string | null;
1567
+ }
1568
+ interface DrawingPositionProjection {
1569
+ readonly simplePosition: Readonly<{
1570
+ xEmu: number;
1571
+ yEmu: number;
1572
+ }>;
1573
+ readonly horizontal: Readonly<{
1574
+ relativeFrom: DrawingHorizontalReferenceFrame;
1575
+ align: string | null;
1576
+ offsetEmu: number | null;
1577
+ }>;
1578
+ readonly vertical: Readonly<{
1579
+ relativeFrom: DrawingVerticalReferenceFrame;
1580
+ align: string | null;
1581
+ offsetEmu: number | null;
1582
+ }>;
1583
+ }
1584
+ interface DrawingWrapProjection {
1585
+ readonly element: DrawingWrapElement;
1586
+ readonly textSide: 'bothSides' | 'left' | 'right' | 'largest';
1587
+ readonly distancesEmu: Readonly<{
1588
+ top: number;
1589
+ right: number;
1590
+ bottom: number;
1591
+ left: number;
1592
+ }>;
1593
+ readonly polygon: readonly Readonly<{
1594
+ x: number;
1595
+ y: number;
1596
+ }>[];
1597
+ }
1598
+ interface PictureProjection {
1599
+ readonly embeddedRelationshipId: string | null;
1600
+ readonly linkedRelationshipId: string | null;
1601
+ readonly crop: SourceCrop;
1602
+ readonly fillMode: 'stretch' | 'tile';
1603
+ readonly transform: DrawingTransform;
1604
+ readonly presetGeometry: string | null;
1550
1605
  }
1551
1606
  /**
1552
- * Why content-type records could not be indexed.
1607
+ * Project one `w:drawing` into the resolved shape layout and chrome read.
1553
1608
  *
1554
- * All fail CLOSED: conflicting Defaults on one extension, duplicate normalized Override names, or
1555
- * invalid MIME syntax are refused rather than resolved by picking one.
1609
+ * Bounded throughout: extents, crops and nesting all come from a file. Returns a projection that
1610
+ * reports `hidden` and its locks rather than throwing, so an unusable drawing degrades to
1611
+ * something the surface can skip.
1556
1612
  */
1557
- type ContentTypeError = {
1558
- readonly code: 'invalid-mime';
1559
- readonly value: string;
1560
- } | {
1561
- readonly code: 'conflicting-default';
1562
- readonly extension: string;
1563
- } | {
1564
- readonly code: 'duplicate-override';
1565
- readonly partName: string;
1566
- } | {
1567
- readonly code: 'invalid-override-name';
1568
- readonly partName: string;
1569
- } | {
1570
- readonly code: 'too-many-records';
1571
- readonly limit: number;
1572
- };
1573
- /** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
1574
- declare function isValidMime(value: string): boolean;
1575
- /** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
1576
- declare function extensionKey(extension: string): string;
1577
- /** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
1578
- interface ContentTypeIndex {
1579
- /** ext key -> single MIME (identical duplicates collapsed). */
1580
- readonly defaults: ReadonlyMap<string, string>;
1581
- /** case-folded part name -> MIME. */
1582
- readonly overrides: ReadonlyMap<string, string>;
1583
- }
1584
- /** The built index, or the conflict that made it impossible. */
1585
- type IndexResult = {
1586
- readonly ok: true;
1587
- readonly index: ContentTypeIndex;
1588
- } | {
1589
- readonly ok: false;
1590
- readonly error: ContentTypeError;
1591
- };
1613
+ declare function projectDrawing(drawing: OoxmlDrawingNode, context: Readonly<{
1614
+ ownerPartName: string;
1615
+ supportedMcRequires: ReadonlySet<string>;
1616
+ limits: DrawingProjectionLimits;
1617
+ namespaceScope?: ReadonlyMap<string, string>;
1618
+ resolveRelationship?: RelationshipTargetResolver;
1619
+ resolveSchemeColor?: ShapeSchemeColorResolver;
1620
+ resolveStyleMatrixReference?: ShapeStyleMatrixResolver;
1621
+ }>): DrawingProjection | null;
1622
+
1623
+ /** Opaque handle — bytes are reachable only through {@link mintValidatedImageBytes}. */
1624
+ interface ValidatedImageBytesHandle {
1625
+ readonly registryId: number;
1626
+ readonly resourceKey: string;
1627
+ readonly contentId: string;
1628
+ readonly generation: number;
1629
+ }
1630
+
1592
1631
  /**
1593
- * Build a resolved content-type index, failing closed on conflict/duplicate/MIME
1594
- * errors. `maxRecords` bounds the combined record count (N/N+1 gate).
1632
+ * The engine's trust-boundary caps: recursion depth, element counts, and the rest.
1633
+ *
1634
+ * A caller may LOWER any of these but never raise or disable one — an override of `Infinity`,
1635
+ * zero, a negative or `NaN` clamps into `(0, ceiling]` rather than turning the limit off. These
1636
+ * are security ceilings, not performance budgets.
1637
+ */
1638
+ interface ResourceLimits {
1639
+ /** Max nested-structure recursion (tables/shapes/SDT/groups). */
1640
+ readonly maxRecursionDepth: number;
1641
+ /** Max total parsed element count. */
1642
+ readonly maxElementCount: number;
1643
+ /** Max package part count. */
1644
+ readonly maxPartCount: number;
1645
+ /** Max total decompressed bytes (zip-bomb guard). */
1646
+ readonly maxDecompressedBytes: number;
1647
+ /** Max total compressed input bytes. */
1648
+ readonly maxCompressedBytes: number;
1649
+ /** Max decompressed:compressed ratio per entry. */
1650
+ readonly maxCompressionRatio: number;
1651
+ /** In-memory chunk budget for streaming/spooling. */
1652
+ readonly maxChunkBytes: number;
1653
+ /** Max pagination passes before non-convergence is declared. */
1654
+ readonly maxPaginationPasses: number;
1655
+ /** Max queued items in any bounded work queue. */
1656
+ readonly maxQueueDepth: number;
1657
+ }
1658
+ /** Non-disableable hard ceilings: no resolved limit may exceed these. */
1659
+ declare const HARD_CEILINGS: ResourceLimits;
1660
+ /** Finite defaults, all <= their hard ceiling. */
1661
+ declare const DEFAULT_LIMITS: ResourceLimits;
1662
+ /**
1663
+ * Resolve caller overrides into a frozen, always-finite limit set. Each value is
1664
+ * `min(override>0 ? override : default, ceiling)`. Infinity/0/negative/NaN can
1665
+ * never disable a limit — the hard ceiling always wins.
1666
+ */
1667
+ declare function resolveLimits(overrides?: Partial<ResourceLimits>): ResourceLimits;
1668
+ /** Bounded image decode limits (typed-drawings-and-images task 4). */
1669
+ /** Trust-boundary caps specific to image decoding and embedding. */
1670
+ interface ImageResourceLimits {
1671
+ readonly maxEncodedBytes: number;
1672
+ readonly maxDecodedBytes: number;
1673
+ readonly maxPixels: number;
1674
+ readonly maxDimension: number;
1675
+ readonly maxPolygonPoints: number;
1676
+ readonly maxExternalRedirects: number;
1677
+ }
1678
+ /** Image caps nothing can raise past. A caller's override clamps into these. */
1679
+ declare const IMAGE_RESOURCE_HARD_CEILINGS: ImageResourceLimits;
1680
+ /** The image caps in force when a host configures none. Conservative and finite. */
1681
+ declare const DEFAULT_IMAGE_RESOURCE_LIMITS: ImageResourceLimits;
1682
+ /** Resolve caller overrides into frozen image limits; hard ceilings cannot be raised. */
1683
+ declare function resolveImageResourceLimits(overrides?: Partial<ImageResourceLimits>): ImageResourceLimits;
1684
+
1685
+ /**
1686
+ * Raster media the decode port measures and any authoring path may write.
1687
+ *
1688
+ * BMP and WebP are here for the same reason the other three are: an `<img>` decodes them
1689
+ * natively, so they need a signature and a structural header and nothing else. BMP is what
1690
+ * older documents carry; WebP is what current Word writes.
1595
1691
  */
1596
- declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
1692
+ type SupportedImageMime = 'image/png' | 'image/jpeg' | 'image/gif' | 'image/bmp' | 'image/webp';
1597
1693
  /**
1598
- * A part's content type, or why it has none.
1694
+ * Vector media painted straight from validated bytes. An `<img>` renders SVG in the
1695
+ * browser's secure static mode — no script, no external subresource loads — so there is
1696
+ * no decode step and no raster buffer sized by a file-supplied number.
1697
+ */
1698
+ type VectorImageMime = 'image/svg+xml';
1699
+ /** Every mime the painter can hand to an `<img>`. */
1700
+ type RenderableImageMime = SupportedImageMime | VectorImageMime;
1701
+ /**
1702
+ * Media kept in the package byte-for-byte that the painter cannot hand to an `<img>`.
1703
+ * A decode port may rasterize it; without one it paints as a labelled placeholder.
1704
+ */
1705
+ type PreservedImageMime = 'image/tiff' | 'image/x-emf' | 'image/x-wmf';
1706
+ /**
1707
+ * What is known about one embedded image: validated, refused, or still decoding.
1599
1708
  *
1600
- * An orphan record never determines a part's type — a Default with no matching part is preserved
1601
- * inertly rather than applied.
1709
+ * Content type is a CLAIM. Signature sniffing, structural header validation and the decode port
1710
+ * are authoritative, and bytes that fail them never enter public state.
1602
1711
  */
1603
- type ResolveResult = {
1604
- readonly ok: true;
1605
- readonly contentType: string;
1606
- readonly source: 'override' | 'default';
1712
+ type ImageResourceState = {
1713
+ readonly kind: 'ready';
1714
+ readonly partName: string;
1715
+ readonly contentId: string;
1716
+ readonly resourceKey: string;
1717
+ readonly validatedHandle: ValidatedImageBytesHandle;
1718
+ readonly mime: RenderableImageMime;
1719
+ readonly pixelWidth: number;
1720
+ readonly pixelHeight: number;
1721
+ readonly dpiX: number;
1722
+ readonly dpiY: number;
1607
1723
  } | {
1608
- readonly ok: false;
1609
- readonly reason: 'unknown';
1724
+ readonly kind: 'unrenderable';
1725
+ readonly partName: string | null;
1726
+ readonly mime: RenderableImageMime | PreservedImageMime | 'unknown';
1727
+ readonly reason: 'unsupported-format' | 'non-picture-graphic' | 'signature-mismatch' | 'decode-failed' | 'resource-limit';
1728
+ } | {
1729
+ readonly kind: 'external';
1730
+ readonly relationshipId: string;
1731
+ readonly sinkSafe: boolean;
1732
+ } | {
1733
+ readonly kind: 'missing';
1734
+ readonly relationshipId: string;
1735
+ } | {
1736
+ readonly kind: 'pending';
1737
+ readonly resourceKey: string;
1610
1738
  };
1611
- /** Resolve a part's content type: Override wins over Default; else unknown. */
1612
- declare function resolveContentType(index: ContentTypeIndex, partName: string): ResolveResult;
1739
+ /**
1740
+ * The injected image decoder.
1741
+ *
1742
+ * A port rather than a direct `Image`/`createImageBitmap` call, so a worker or server runtime
1743
+ * supplies its own and the engine never reaches for a browser global.
1744
+ */
1745
+ interface ImageDecodePort {
1746
+ decode(bytes: Uint8Array, mime: SupportedImageMime, limits: ImageResourceLimits,
1747
+ /** Aborted when the owning lookup/session is disposed. */
1748
+ signal?: AbortSignal): Promise<Readonly<{
1749
+ pixelWidth: number;
1750
+ pixelHeight: number;
1751
+ dpiX: number;
1752
+ dpiY: number;
1753
+ }>>;
1754
+ /**
1755
+ * Optional conversion of media an `<img>` cannot render (EMF/WMF metafiles, TIFF) into a
1756
+ * renderable raster. The returned bytes are untrusted and re-enter the full raster
1757
+ * validation path (sniff, header, pixel caps, decode) before they can become a ready
1758
+ * resource. A null return declines the format and keeps the labelled placeholder; so does
1759
+ * a throw, as `decode-failed`.
1760
+ */
1761
+ convertPreserved?(bytes: Uint8Array, mime: PreservedImageMime, limits: ImageResourceLimits,
1762
+ /** Aborted when the owning lookup/session is disposed. */
1763
+ signal?: AbortSignal): Promise<Readonly<{
1764
+ bytes: Uint8Array;
1765
+ mime: SupportedImageMime;
1766
+ }> | null>;
1767
+ }
1768
+ /** Resolves a relationship id to a validated image resource, or reports why it could not. */
1769
+ interface ImageResourceLookup {
1770
+ readonly resolveEmbedded: (ownerPartName: string, relationshipId: string) => Promise<ImageResourceState>;
1771
+ readonly resolveLinked: (ownerPartName: string, relationshipId: string) => ImageResourceState;
1772
+ readonly resolveForProjection: (projection: DrawingProjection) => Promise<ImageResourceState>;
1773
+ readonly liveReferenceCount: (partName: string) => number;
1774
+ readonly dispose: () => void;
1775
+ }
1776
+ /** Maximum prefix inspected for SVG root detection (exported for bounded-scan tests). */
1777
+ declare const MAX_SVG_SNIFF_BYTES = 512;
1778
+ /** A raster header that passed structural validation: its real MIME type and pixel extent. */
1779
+ interface ValidatedRasterHeader {
1780
+ readonly pixelWidth: number;
1781
+ readonly pixelHeight: number;
1782
+ /** Horizontal physical density when bounded header metadata supplies it. */
1783
+ readonly dpiX?: number;
1784
+ /** Vertical physical density when bounded header metadata supplies it. */
1785
+ readonly dpiY?: number;
1786
+ }
1787
+ /** Bounded scan for an `<svg` document root (optional `<?xml` prolog only). */
1788
+ declare function hasBoundedSvgRoot(bytes: Uint8Array): boolean;
1789
+ /** Signature sniffing — authoritative over declared content type. */
1790
+ declare function sniffImageMime(bytes: Uint8Array): RenderableImageMime | PreservedImageMime | 'unknown';
1791
+ /** Structural PNG IHDR validation before decode. */
1792
+ declare function validatePngHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
1793
+ /** Structural GIF logical screen descriptor validation before decode. */
1794
+ declare function validateGifHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
1795
+ /** Bounded JPEG marker scan through the first supported SOF marker. */
1796
+ declare function validateJpegHeader(bytes: Uint8Array): ValidatedRasterHeader | null;
1797
+ /**
1798
+ * Intrinsic size of an SVG, resolved the way a browser sizes one: absolute `width`/`height`
1799
+ * first, then `viewBox` for the missing axis or ratio, then the CSS 300x150 default.
1800
+ *
1801
+ * This is metadata for insert and reset-to-natural-size only. Layout uses the authored
1802
+ * `wp:extent` and the browser rasterizes into that box, so nothing here sizes an allocation
1803
+ * and an out-of-range value is clamped rather than refused.
1804
+ */
1805
+ declare function resolveSvgIntrinsicSize(bytes: Uint8Array, limits: ImageResourceLimits): ValidatedRasterHeader | null;
1806
+ /**
1807
+ * Validate a raster image's header structurally and report its real MIME type and extent.
1808
+ *
1809
+ * Content type is a CLAIM; this is what makes it a fact. A file declaring `image/png` over JPEG
1810
+ * bytes is caught here rather than at decode.
1811
+ */
1812
+ declare function validateRasterHeader(bytes: Uint8Array, mime: SupportedImageMime): ValidatedRasterHeader | null;
1813
+ /** Package-wide live drawing references to a media part name. */
1814
+ declare function liveDrawingReferenceCount(pkg: OoxmlPackage, partName: string): number;
1815
+ /** How the image cache decodes, and what it will spend doing so. */
1816
+ interface CreateImageResourceCacheOptions {
1817
+ readonly limits?: Partial<ImageResourceLimits>;
1818
+ readonly decodePort: ImageDecodePort;
1819
+ }
1820
+ /**
1821
+ * Derived cache for one immutable package snapshot. Registry identity is
1822
+ * `(package snapshot, decodePort object, normalized limits)` — the first caller
1823
+ * never imposes its decoder or limits on later callers with different options.
1824
+ */
1825
+ declare function imageResourceLookupFor(pkg: OoxmlPackage, options: CreateImageResourceCacheOptions): ImageResourceLookup;
1826
+ /** @deprecated Prefer {@link imageResourceLookupFor} — registry binds cache to package identity. */
1827
+ /** Build the per-document image cache. Validated bytes only; refusals are remembered too. */
1828
+ declare function createImageResourceCache(initialPkg: OoxmlPackage, options: CreateImageResourceCacheOptions): ImageResourceLookup;
1613
1829
 
1614
1830
  /** Caps applied while loading a package: zip, XML, part count and relationship count. */
1615
1831
  interface OoxmlPackageLimits {
@@ -1699,193 +1915,376 @@ declare function writeOoxmlPackage(pkg: OoxmlPackage): Uint8Array;
1699
1915
  /** Replace one part's tree, returning a new package. Pure, like the tree edits themselves. */
1700
1916
  declare function withPart(pkg: OoxmlPackage, part: OoxmlPart): OoxmlPackage;
1701
1917
 
1702
- /**
1703
- * Whether a drawing sits in the text flow or is positioned against a frame.
1704
- *
1705
- * The distinction that decides everything downstream: an inline drawing occupies a character
1706
- * position, while an anchored one has offsets relative to a page, margin or column.
1707
- */
1708
- type DrawingKind = 'inline' | 'anchored';
1709
- /** Nine Word wrap menu targets (inline plus eight floating modes). @public */
1710
- type ImageWrapTarget = 'inline' | 'square' | 'squareLeft' | 'squareRight' | 'tight' | 'through' | 'topAndBottom' | 'behind' | 'inFront';
1711
- /** Every text-wrap mode a drawing may be set to, including `inline`. */
1712
- declare const IMAGE_WRAP_TARGETS: readonly ImageWrapTarget[];
1713
- type DrawingWrapElement = 'none' | 'square' | 'tight' | 'through' | 'topAndBottom';
1714
- type DrawingHorizontalReferenceFrame = 'character' | 'column' | 'insideMargin' | 'leftMargin' | 'margin' | 'outsideMargin' | 'page' | 'rightMargin';
1715
- type DrawingVerticalReferenceFrame = 'bottomMargin' | 'insideMargin' | 'line' | 'margin' | 'outsideMargin' | 'page' | 'paragraph' | 'topMargin';
1716
- /** `a:srcRect` — how much of each edge of the source image is cropped away, as fractions. */
1717
- interface SourceCrop {
1718
- readonly left: number;
1719
- readonly top: number;
1720
- readonly right: number;
1721
- readonly bottom: number;
1918
+ /** A text watermark as the package stores it. */
1919
+ interface PackageTextWatermark {
1920
+ readonly kind: 'text';
1921
+ readonly text: string;
1922
+ readonly fontFamily: string;
1923
+ /** Null for Auto size, which fits the text to the shape box. */
1924
+ readonly fontSizePt: number | null;
1925
+ readonly bold: boolean;
1926
+ readonly italic: boolean;
1927
+ /** `RRGGBB`. */
1928
+ readonly colorHex: string;
1929
+ /** Fill opacity in [0, 1]; the dialog's Transparency is `1 - opacity`. */
1930
+ readonly opacity: number;
1931
+ readonly diagonal: boolean;
1932
+ readonly widthPt: number;
1933
+ readonly heightPt: number;
1934
+ }
1935
+ /** A picture watermark as the package stores it. */
1936
+ interface PackagePictureWatermark {
1937
+ readonly kind: 'picture';
1938
+ readonly washout: boolean;
1939
+ readonly widthPt: number;
1940
+ readonly heightPt: number;
1941
+ }
1942
+ /** One section's shape size, in points. */
1943
+ interface PackageWatermarkSize {
1944
+ readonly widthPt: number;
1945
+ readonly heightPt: number;
1946
+ }
1947
+ /**
1948
+ * A write may size the shape per section, indexed like the body's sections: a header part
1949
+ * takes the size of the first section that shows it, so a landscape section's watermark
1950
+ * fits its own text area. A missing or unusable entry falls back to `widthPt`/`heightPt`.
1951
+ */
1952
+ interface PackageWatermarkSectionSizes {
1953
+ readonly sectionSizes?: readonly (PackageWatermarkSize | null)[];
1954
+ }
1955
+ /** A picture watermark write carries the image bytes. */
1956
+ type PackageWatermarkWrite = (PackageTextWatermark & PackageWatermarkSectionSizes) | (PackagePictureWatermark & PackageWatermarkSectionSizes & {
1957
+ readonly image: {
1958
+ readonly bytes: Uint8Array;
1959
+ readonly mime: SupportedImageMime;
1960
+ };
1961
+ });
1962
+
1963
+ /**
1964
+ * How a tracked change is addressed: `@w:id`, `@w:author` and `@w:date` together, within a
1965
+ * part.
1966
+ *
1967
+ * All of them, always. `@w:id` is unique only within a part, so an id alone names two
1968
+ * revisions in any package with a header or a comments part — and it is not author-scoped
1969
+ * either, so `(part, id)` would merge two authors' distinct revisions. One logical revision is
1970
+ * also deliberately many elements sharing an id, as a tracked row insertion is, which no
1971
+ * uniqueness rule could express.
1972
+ */
1973
+ interface RevisionAddress {
1974
+ readonly id: string;
1975
+ readonly author: string;
1976
+ /** Absent when the file wrote no `@w:date`; part of the identity either way. */
1977
+ readonly date?: string;
1978
+ }
1979
+ /** The author and timestamp a tracked edit is recorded under. */
1980
+ interface RevisionAttributionInput {
1981
+ readonly author: string;
1982
+ /** ISO-8601. Omitted writes no `@w:date`. */
1983
+ readonly date?: string;
1984
+ }
1985
+
1986
+ type AutomationTableMutation = {
1987
+ readonly kind: 'insertRows';
1988
+ readonly rowId: string;
1989
+ readonly location: 'before' | 'after';
1990
+ readonly count: number;
1991
+ readonly values?: readonly (readonly string[])[];
1992
+ } | {
1993
+ readonly kind: 'values';
1994
+ readonly values: readonly (readonly string[])[];
1995
+ } | {
1996
+ readonly kind: 'addRows' | 'addColumns';
1997
+ readonly location: 'start' | 'end';
1998
+ readonly count: number;
1999
+ readonly values?: readonly (readonly string[])[];
2000
+ } | {
2001
+ readonly kind: 'deleteRows' | 'deleteColumns';
2002
+ readonly index: number;
2003
+ readonly count: number;
2004
+ } | {
2005
+ /** Merge the rectangle from one cell to another, by row and in-row cell index. */
2006
+ readonly kind: 'mergeCells';
2007
+ readonly topRow: number;
2008
+ readonly firstCell: number;
2009
+ readonly bottomRow: number;
2010
+ readonly lastCell: number;
2011
+ } | {
2012
+ readonly kind: 'splitCell';
2013
+ readonly cellId: string;
2014
+ readonly rowCount: number;
2015
+ readonly columnCount: number;
2016
+ } | {
2017
+ readonly kind: 'delete';
2018
+ } | {
2019
+ readonly kind: 'properties';
2020
+ readonly styleId?: string;
2021
+ readonly headerRowCount?: number;
2022
+ } | {
2023
+ readonly kind: 'cell';
2024
+ readonly cellId: string;
2025
+ readonly value?: string;
2026
+ readonly columnWidth?: number;
2027
+ readonly shadingColor?: string;
2028
+ readonly verticalAlignment?: 'Top' | 'Center' | 'Bottom';
2029
+ };
2030
+
2031
+ /** Select one declared entry of a legacy Word dropdown form field. */
2032
+ interface SetLegacyDropdownOp {
2033
+ readonly op: 'setLegacyDropdown';
2034
+ readonly paragraphId: string;
2035
+ readonly fieldNodeId: string;
2036
+ readonly selectedIndex: number;
2037
+ }
2038
+
2039
+ interface SetFieldCodeOp {
2040
+ readonly op: 'setFieldCode';
2041
+ readonly paragraphId: string;
2042
+ readonly fieldNodeId: string;
2043
+ readonly code: string;
2044
+ }
2045
+
2046
+ /**
2047
+ * Insert an allowlisted page-number complex field at a UTF-16 offset.
2048
+ *
2049
+ * `PAGE_X_OF_Y` is PAGE + literal " of " + NUMPAGES in one undoable op. Non-page
2050
+ * instructions are refused — never authored through this path.
2051
+ */
2052
+ interface InsertPageFieldOp {
2053
+ readonly op: 'insertPageField';
2054
+ readonly paragraphId: string;
2055
+ readonly offset: number;
2056
+ readonly field: 'PAGE' | 'NUMPAGES' | 'SECTIONPAGES' | 'PAGE_X_OF_Y';
2057
+ /**
2058
+ * Write this as a TRACKED insertion, on the same terms as `insertText`.
2059
+ *
2060
+ * The whole field — every `w:fldChar`, the instruction, the `PAGE_X_OF_Y` literal —
2061
+ * goes into ONE `w:ins`, because the field is one proposal: rejecting it must take
2062
+ * the complete atom back, never leave a `begin` standing without its `end`.
2063
+ */
2064
+ readonly revision?: RevisionAttributionInput;
2065
+ }
2066
+ /**
2067
+ * Insert one complex field with an empty cached result at a UTF-16 offset.
2068
+ *
2069
+ * The instruction must be one that `inertFieldInstruction` admits: a page number, a reference
2070
+ * to a bookmark, note, or style, a sequence number, or a date. It is written as text and never
2071
+ * evaluated. Every other instruction refuses with `invalidArgs`.
2072
+ */
2073
+ interface InsertComplexFieldOp {
2074
+ readonly op: 'insertComplexField';
2075
+ readonly paragraphId: string;
2076
+ readonly offset: number;
2077
+ readonly instruction: string;
2078
+ /** Write the whole field as ONE tracked insertion, on the same terms as `insertText`. */
2079
+ readonly revision?: RevisionAttributionInput;
2080
+ }
2081
+
2082
+ /** Set one field's cached result text. See the module comment for the placements. */
2083
+ interface SetFieldResultOp {
2084
+ readonly op: 'setFieldResult';
2085
+ readonly paragraphId: string;
2086
+ /** The begin `w:fldChar`, or the `w:fldSimple` element. */
2087
+ readonly fieldNodeId: string;
2088
+ /** Plain text. A tab becomes `w:tab`; other control characters refuse. */
2089
+ readonly text: string;
2090
+ /**
2091
+ * The author whose pending insertion holds the field. The result joins that insertion. The
2092
+ * op mints no revision of its own.
2093
+ */
2094
+ readonly revision?: RevisionAttributionInput;
2095
+ }
2096
+
2097
+ /** Insert one inline `m:oMath` and the plain runs beside it. */
2098
+ interface InsertEquationOp {
2099
+ readonly op: 'insertEquation';
2100
+ readonly paragraphId: string;
2101
+ readonly offset: number;
2102
+ /** Plain runs and exactly one inline `m:oMath`, in order. Receive fresh ids at apply. */
2103
+ readonly nodes: readonly OoxmlNode[];
2104
+ /** Model length of `nodes`: their text, plus one for the equation. */
2105
+ readonly length: number;
2106
+ /** Write the nodes as ONE tracked insertion, on the same terms as `insertText`. */
2107
+ readonly revision?: RevisionAttributionInput;
2108
+ }
2109
+
2110
+ type InsertTextOp = {
2111
+ readonly op: 'insertText';
2112
+ readonly paragraphId: string;
2113
+ /** Legacy text form identity for protected filling; never an inline wrapper owner. */
2114
+ readonly textFormFieldId?: string;
2115
+ readonly offset: number;
2116
+ readonly text: string;
2117
+ /**
2118
+ * Write this as a TRACKED insertion, attributed here.
2119
+ *
2120
+ * On the op rather than on the store, so suggesting stays a decision the surface makes
2121
+ * per edit and the write vocabulary stays explicit — a global "everything is tracked
2122
+ * now" flag is exactly what `DocEdits` refuses, because it makes the meaning of an op
2123
+ * depend on state the op does not carry.
2124
+ */
2125
+ readonly revision?: RevisionAttributionInput;
2126
+ /**
2127
+ * When set, the text belongs INSIDE this content control, whatever sits at the offset.
2128
+ *
2129
+ * A boundary offset is owned by the run that starts there, which at a control's trailing
2130
+ * edge is the run after the control — so an offset alone cannot say "append to this field",
2131
+ * the way it cannot say which run of a field result to format (see `targetRunIds`). A
2132
+ * caller that names the control gets the text in the control; one that does not gets the
2133
+ * plain offset rule, which is what a keystroke beside a field means.
2134
+ */
2135
+ readonly inside?: string;
2136
+ /**
2137
+ * Which side of a run BOUNDARY the text joins. Default `'left'` — Word's typing rule:
2138
+ * the next character takes the formatting of the character before the caret.
2139
+ *
2140
+ * `'right'` is for a caller that is not typing but placing text inside the run that
2141
+ * STARTS at the offset — the hyperlink editor rewriting a link's display text, where
2142
+ * landing left of the boundary would put the new text outside the link. Ignored when
2143
+ * the offset falls strictly inside a run, which has no boundary to choose.
2144
+ */
2145
+ readonly bias?: 'left' | 'right';
2146
+ };
2147
+ type DeleteTextOp = {
2148
+ readonly op: 'deleteText';
2149
+ readonly paragraphId: string;
2150
+ /** Legacy text form identity for protected filling; never an inline wrapper owner. */
2151
+ readonly textFormFieldId?: string;
2152
+ readonly start: number;
2153
+ readonly end: number;
2154
+ /** Write this as a TRACKED deletion — the characters stay, wrapped in `w:del`. */
2155
+ readonly revision?: RevisionAttributionInput;
2156
+ };
2157
+
2158
+ /** Editable legacy text input types. Other authored types remain inert. */
2159
+ type TextFormFieldType = 'regular' | 'number' | 'date';
2160
+ /** Options stored in the legacy field definition. Zero means unlimited length. */
2161
+ interface TextFormFieldOptions {
2162
+ readonly type: TextFormFieldType;
2163
+ readonly maxLength: number;
2164
+ readonly format: string;
2165
+ readonly enabled: boolean;
2166
+ }
2167
+ /** Supported format choices for legacy text input fields. @public */
2168
+ declare const TEXT_FORM_FORMATS: {
2169
+ readonly regular: readonly ['', 'Uppercase', 'Lowercase', 'First capital', 'Title case'];
2170
+ readonly number: readonly ['', '0', '0.00', '#,##0', '#,##0.00', '0%', '0.00%'];
2171
+ readonly date: readonly ['', 'M/d/yyyy', 'MM/dd/yyyy', 'd/M/yyyy', 'dd/MM/yyyy', 'yyyy-MM-dd', 'd MMMM yyyy', 'MMMM d, yyyy'];
2172
+ };
2173
+
2174
+ /** A legacy text input in the shared paragraph offset space. */
2175
+ interface TextFormFieldRange {
2176
+ readonly fieldNodeId: string;
2177
+ readonly start: number;
2178
+ readonly end: number;
2179
+ readonly enabled: boolean;
2180
+ readonly defaultText: string;
2181
+ readonly type: string;
2182
+ readonly maxLength: number;
2183
+ readonly format: string;
2184
+ readonly chromeIds: readonly string[];
2185
+ }
2186
+ /** Uses the field parser and offset index; never introduces another inline walk. */
2187
+ declare function textFormFieldsOf(paragraph: OoxmlParagraphNode): readonly TextFormFieldRange[];
2188
+ /** Options edit for an existing legacy text form. */
2189
+ interface SetTextFormFieldDefaultOp {
2190
+ readonly op: 'setTextFormFieldDefault';
2191
+ /** Regional conventions for new date input; defaults to en-US. */
2192
+ readonly locale?: string;
2193
+ readonly paragraphId: string;
2194
+ readonly fieldNodeId: string;
2195
+ readonly text: string;
2196
+ readonly options?: TextFormFieldOptions;
2197
+ }
2198
+ /** Validate and format the existing result when a user finishes filling a field. */
2199
+ interface CommitTextFormFieldOp {
2200
+ readonly op: 'commitTextFormField';
2201
+ /** Regional conventions for new date input; defaults to en-US. */
2202
+ readonly locale?: string;
2203
+ readonly paragraphId: string;
2204
+ readonly fieldNodeId: string;
2205
+ }
2206
+
2207
+ /** One FORMCHECKBOX in the shared paragraph offset space. */
2208
+ interface LegacyCheckboxFieldRange {
2209
+ /** The begin `w:fldChar` node: what the op addresses. */
2210
+ readonly fieldNodeId: string;
2211
+ readonly start: number;
2212
+ readonly end: number;
2213
+ readonly checked: boolean;
2214
+ /** `w:enabled` under `w:ffData`; a disabled field renders but refuses the toggle. */
2215
+ readonly enabled: boolean;
2216
+ }
2217
+ /** Flip a FORMCHECKBOX's state; the only write into `w:ffData` a checkbox permits. */
2218
+ interface SetLegacyCheckboxOp {
2219
+ readonly op: 'setLegacyCheckbox';
2220
+ readonly paragraphId: string;
2221
+ readonly fieldNodeId: string;
2222
+ readonly checked: boolean;
2223
+ }
2224
+ /** Every FORMCHECKBOX in a paragraph, in document order; uses the shared field parser. */
2225
+ declare function legacyCheckboxFieldsOf(paragraph: OoxmlParagraphNode): readonly LegacyCheckboxFieldRange[];
2226
+
2227
+ /** Replace a building block gallery control's content with one block's body. */
2228
+ interface InsertBuildingBlockOp {
2229
+ readonly op: 'insertBuildingBlock';
2230
+ readonly controlId: string;
2231
+ /** `w:docPartPr/w:name` of the picked block, for the journal and the host. */
2232
+ readonly name: string;
2233
+ /**
2234
+ * Self-contained `w:docPartBody` children, cloned with fresh ids at apply.
2235
+ * Resource, style, field, bookmark, note and revision references return `unsupported`.
2236
+ */
2237
+ readonly blocks: readonly OoxmlNode[];
1722
2238
  }
1723
- interface DrawingTransform {
1724
- readonly rotationDegrees: number;
1725
- readonly flipHorizontal: boolean;
1726
- readonly flipVertical: boolean;
1727
- /** Source `a:off` in EMU; defaults to origin when absent. */
1728
- readonly offsetEmu: Readonly<{
1729
- x: number;
1730
- y: number;
1731
- }>;
1732
- /** Source `a:ext` in EMU; zero falls back to `wp:extent` at geometry time. */
1733
- readonly extentEmu: Readonly<{
1734
- cx: number;
1735
- cy: number;
1736
- }>;
2239
+
2240
+ /** A text position in the op's part. */
2241
+ interface BookmarkOpPosition {
2242
+ readonly paragraphId: string;
2243
+ readonly offset: number;
1737
2244
  }
1738
2245
  /**
1739
- * What a drawing refuses: selection, movement, resizing, aspect change.
2246
+ * Add a bookmark around `start`..`end`, or at one point when the two are equal.
1740
2247
  *
1741
- * Read and honoured rather than advisory — chrome that offered a handle the store will refuse
1742
- * would promise an edit that cannot happen.
2248
+ * The name must pass `bookmarkNameProblem`. A bookmark the part already declares under the
2249
+ * same name, compared without case, is removed in the same op.
1743
2250
  */
1744
- interface DrawingLocks {
1745
- readonly select: boolean;
1746
- readonly move: boolean;
1747
- readonly resize: boolean;
1748
- readonly changeAspect: boolean;
1749
- }
1750
- interface DrawingLocksInput {
1751
- readonly select?: boolean;
1752
- readonly move?: boolean;
1753
- readonly resize?: boolean;
1754
- readonly changeAspect?: boolean;
2251
+ interface InsertBookmarkOp {
2252
+ readonly op: 'insertBookmark';
2253
+ readonly name: string;
2254
+ readonly start: BookmarkOpPosition;
2255
+ readonly end: BookmarkOpPosition;
1755
2256
  }
1756
2257
  /**
1757
- * An anchored drawing's position: offsets, and the frames they are relative to.
2258
+ * Remove every marker pair that declares this name, compared without case. The name is the
2259
+ * one the file declares, so it is not held to the authoring rules.
1758
2260
  *
1759
- * The relative-to bases matter as much as the offsets. Writing an offset without preserving its
1760
- * base re-anchors the drawing against a different reference and moves it somewhere nobody asked.
2261
+ * With `keepFirst`, remove only the copies: the pair `listBookmarks` answers for the name
2262
+ * stays where it is. Refused when the part holds no copy. Two collaborators who both remove
2263
+ * the copies remove the same nodes, so their edits converge on one bookmark.
1761
2264
  */
1762
- interface DrawingPositionInput {
1763
- /**
1764
- * `'simple'` when `@simplePos="1"`: `horizontalEmu` / `verticalEmu` are authoritative
1765
- * `wp:simplePos` x/y. `'frame'` (default) uses positionH/V relative frames.
1766
- */
1767
- readonly mode?: 'frame' | 'simple';
1768
- readonly horizontalEmu?: number;
1769
- readonly verticalEmu?: number;
1770
- readonly relativeToH?: DrawingHorizontalReferenceFrame;
1771
- readonly relativeToV?: DrawingVerticalReferenceFrame;
1772
- }
1773
- interface DrawingProjection {
1774
- readonly drawingNodeId: string;
1775
- readonly ownerPartName: string;
1776
- readonly kind: DrawingKind;
1777
- readonly relationshipId: string | null;
1778
- readonly docPrId: number | null;
2265
+ interface DeleteBookmarkOp {
2266
+ readonly op: 'deleteBookmark';
1779
2267
  readonly name: string;
1780
- readonly title: string;
1781
- readonly description: string;
1782
- readonly hyperlinkHref: string | null;
1783
- readonly hidden: boolean;
1784
- readonly extentEmu: Readonly<{
1785
- cx: number;
1786
- cy: number;
1787
- }>;
1788
- readonly effectExtentEmu: Readonly<{
1789
- top: number;
1790
- right: number;
1791
- bottom: number;
1792
- left: number;
1793
- }>;
1794
- readonly inlineDistancesEmu: Readonly<{
1795
- top: number;
1796
- right: number;
1797
- bottom: number;
1798
- left: number;
1799
- }>;
1800
- readonly wrap: ImageWrapTarget;
1801
- readonly wrapGeometry: DrawingWrapProjection | null;
1802
- readonly position: DrawingPositionProjection | null;
1803
- readonly anchor: Readonly<{
1804
- simplePos: boolean;
1805
- relativeHeight: number;
1806
- behindDocument: boolean;
1807
- layoutInCell: boolean;
1808
- allowOverlap: boolean;
1809
- }> | null;
1810
- readonly picture: PictureProjection | null;
1811
- readonly vectorShape: VectorShapeProjection | null;
1812
- /** The picture member of a `wpg:wgp` group; `picture` stays null for a group. */
1813
- readonly groupPicture: GroupPictureProjection | null;
1814
- readonly textboxStory: TextboxStoryProjection | null;
1815
- /** Text box members of a `wpg:wgp` group, laid out read-only; absent when none has text. */
1816
- readonly groupTextboxes?: readonly GroupTextboxProjection[];
1817
- /** Read-only preview of the supported native VML subset; the canonical XML is untouched. */
1818
- readonly legacyGraphic?: LegacyGraphicProjection;
1819
- readonly locks: DrawingLocks;
1820
- readonly effects: DrawingImageEffects;
1821
- readonly compatibilityBranchNodeId: string | null;
1822
- readonly diagnostics: readonly DrawingDiagnostic[];
1823
- /** Layout-only wrap area of an MC payload that cannot paint (`wrapFootprintProjection`). */
1824
- readonly footprintOnly?: true;
1825
- }
1826
- interface DrawingAccessibility {
1827
- /**
1828
- * The record takes part in layout only, for example the wrap area of a payload that cannot
1829
- * paint. Outputs must not paint, hit-test, select, link, or export it.
1830
- */
1831
- readonly hidden: boolean;
1832
- readonly decorative: boolean;
1833
- readonly label: string | null;
1834
- }
1835
- interface DrawingPositionProjection {
1836
- readonly simplePosition: Readonly<{
1837
- xEmu: number;
1838
- yEmu: number;
1839
- }>;
1840
- readonly horizontal: Readonly<{
1841
- relativeFrom: DrawingHorizontalReferenceFrame;
1842
- align: string | null;
1843
- offsetEmu: number | null;
1844
- }>;
1845
- readonly vertical: Readonly<{
1846
- relativeFrom: DrawingVerticalReferenceFrame;
1847
- align: string | null;
1848
- offsetEmu: number | null;
1849
- }>;
1850
- }
1851
- interface DrawingWrapProjection {
1852
- readonly element: DrawingWrapElement;
1853
- readonly textSide: 'bothSides' | 'left' | 'right' | 'largest';
1854
- readonly distancesEmu: Readonly<{
1855
- top: number;
1856
- right: number;
1857
- bottom: number;
1858
- left: number;
1859
- }>;
1860
- readonly polygon: readonly Readonly<{
1861
- x: number;
1862
- y: number;
1863
- }>[];
1864
- }
1865
- interface PictureProjection {
1866
- readonly embeddedRelationshipId: string | null;
1867
- readonly linkedRelationshipId: string | null;
1868
- readonly crop: SourceCrop;
1869
- readonly fillMode: 'stretch' | 'tile';
1870
- readonly transform: DrawingTransform;
1871
- readonly presetGeometry: string | null;
2268
+ readonly keepFirst?: boolean;
2269
+ /** @internal Limit a text deletion to one enclosed pair; explicit name deletion omits this. */
2270
+ readonly pair?: {
2271
+ readonly startNodeId: string;
2272
+ readonly endNodeId: string;
2273
+ };
1872
2274
  }
1873
2275
  /**
1874
- * Project one `w:drawing` into the resolved shape layout and chrome read.
1875
- *
1876
- * Bounded throughout: extents, crops and nesting all come from a file. Returns a projection that
1877
- * reports `hidden` and its locks rather than throwing, so an unusable drawing degrades to
1878
- * something the surface can skip.
2276
+ * The package with every bookmark of this name removed from one part, for moving a name out
2277
+ * of another story inside the same transaction. The package is unchanged when that part does
2278
+ * not declare the name. Protected markers refuse the whole package transaction.
1879
2279
  */
1880
- declare function projectDrawing(drawing: OoxmlDrawingNode, context: Readonly<{
1881
- ownerPartName: string;
1882
- supportedMcRequires: ReadonlySet<string>;
1883
- limits: DrawingProjectionLimits;
1884
- namespaceScope?: ReadonlyMap<string, string>;
1885
- resolveRelationship?: RelationshipTargetResolver;
1886
- resolveSchemeColor?: ShapeSchemeColorResolver;
1887
- resolveStyleMatrixReference?: ShapeStyleMatrixResolver;
1888
- }>): DrawingProjection | null;
2280
+ declare function withoutBookmarkInPart(pkg: OoxmlPackage, partName: string, name: string): OoxmlPackage;
2281
+ /**
2282
+ * The `deleteBookmark` ops for the bookmarks an untracked deletion of `from`..`to` encloses,
2283
+ * for a deletion that crosses paragraphs. `order` lists the part's paragraph ids in document
2284
+ * order. A range bookmark goes when the deletion covers it edge to edge; a point bookmark goes
2285
+ * when it is strictly inside. Applied before the text ops, so they find nothing left to drop.
2286
+ */
2287
+ declare function enclosedBookmarkDeletions(part: OoxmlPart, from: BookmarkOpPosition, to: BookmarkOpPosition, order: readonly string[]): readonly DeleteBookmarkOp[];
1889
2288
 
1890
2289
  /** The `w15` namespace: `commentsExtended.xml` — thread parent and resolved state. */
1891
2290
  declare const W15_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2012/wordml";
@@ -2554,8 +2953,18 @@ interface RevisionBatchResult {
2554
2953
  /** All pending decisions in the addressed scope, including excluded and unsupported changes. */
2555
2954
  readonly remaining: number;
2556
2955
  }
2557
- /** @internal Pure preflight; callers commit its operations through their normal write guards. */
2558
- declare function planRevisionBatch(part: OoxmlPart, action: 'accept' | 'reject', keys?: readonly string[], scopeRoot?: OoxmlNode): {
2956
+ /**
2957
+ * @internal Pure preflight; callers commit its operations through their normal write guards.
2958
+ *
2959
+ * `countRemaining: false` skips the exact count of the decisions left after the batch, and
2960
+ * reports `remaining` as the decisions not resolved here. The exact count resolves the whole
2961
+ * batch once more on a copy and lists what is left, which on a long reviewed document cost more
2962
+ * than the plan itself, and a caller that reads only the operations or the skipped changes
2963
+ * (a check, one decision, an editor that recounts its queue) paid it on every call.
2964
+ */
2965
+ declare function planRevisionBatch(part: OoxmlPart, action: 'accept' | 'reject', keys?: readonly string[], scopeRoot?: OoxmlNode, options?: {
2966
+ readonly countRemaining?: boolean;
2967
+ }): {
2559
2968
  ops: readonly TreeDocOp[];
2560
2969
  result: RevisionBatchResult;
2561
2970
  };
@@ -2864,8 +3273,9 @@ interface RunFormatting {
2864
3273
  /**
2865
3274
  * Line spacing at the selection, in the unit its rule implies — LINES for `multiple`,
2866
3275
  * points for `exact` and `atLeast`. The same vocabulary `setLineSpacing` takes, so a
2867
- * control can show what it reads and send back what it shows. Absent when the
2868
- * selection's paragraphs disagree or state no line spacing.
3276
+ * control can show what it reads and send back what it shows. The effective value: a
3277
+ * paragraph whose cascade states none reads as single spacing (`multiple`, 1). Absent
3278
+ * when the selection's paragraphs disagree.
2869
3279
  */
2870
3280
  readonly lineSpacing?: {
2871
3281
  readonly rule: 'multiple' | 'exact' | 'atLeast';
@@ -3174,10 +3584,72 @@ interface Theme {
3174
3584
  }
3175
3585
  /** Theme colour slots (`accent1`, `dk1`, `lt2`, …) to hex. */
3176
3586
  type ThemeColorScheme = Readonly<Record<string, string>>;
3177
- /** A watermark, which OOXML expresses as either text or an image — never both meaningfully. */
3587
+ /**
3588
+ * A document watermark: text or a picture drawn behind the text of every page.
3589
+ *
3590
+ * Set `text` for a text watermark or `imageData` for a picture watermark, never both. Omitted
3591
+ * options take the defaults in each field's description. The watermark goes into every header
3592
+ * the document shows; a section with no header gets one.
3593
+ *
3594
+ * Text options apply only with `text`; `scale` and `washout` apply only with `imageData`.
3595
+ * `setWatermark` refuses a mixed or out-of-range value with `invalidArgs` and a reason naming
3596
+ * the field, and writes nothing.
3597
+ *
3598
+ * @example
3599
+ * ```ts
3600
+ * // A red, horizontal text watermark at 72pt.
3601
+ * editor.exec({
3602
+ * type: 'setWatermark',
3603
+ * watermark: { text: 'CONFIDENTIAL', color: 'C00000', fontSizePt: 72, layout: 'horizontal' },
3604
+ * });
3605
+ * // A washed-out picture watermark at its natural size.
3606
+ * editor.exec({ type: 'setWatermark', watermark: { imageData: pngBytes, scale: 1 } });
3607
+ * ```
3608
+ */
3178
3609
  interface Watermark {
3610
+ /** The text of a text watermark, up to 256 characters on one line. */
3179
3611
  readonly text?: string;
3612
+ /** The PNG, JPEG, GIF, BMP or WebP bytes of a picture watermark. */
3180
3613
  readonly imageData?: Uint8Array;
3614
+ /** Text: the font family. Defaults to `Calibri`. */
3615
+ readonly fontFamily?: string;
3616
+ /** Text: the size in points, from 1 to 1000. Omitted or null is Auto, which fills the page. */
3617
+ readonly fontSizePt?: number | null;
3618
+ /** Text: bold. Defaults to false. */
3619
+ readonly bold?: boolean;
3620
+ /** Text: italic. Defaults to false. */
3621
+ readonly italic?: boolean;
3622
+ /** Text: the colour as `RRGGBB`. Defaults to `C0C0C0` (silver). */
3623
+ readonly color?: string;
3624
+ /** Text: transparency from 0 (opaque) to 1. Defaults to 0.5. */
3625
+ readonly transparency?: number;
3626
+ /** Text: the orientation. Defaults to `diagonal`. */
3627
+ readonly layout?: WatermarkLayout;
3628
+ /** Picture: a factor of the picture's natural size. Omitted or null is Auto, which fits the page. */
3629
+ readonly scale?: number | null;
3630
+ /** Picture: lighten the picture so text over it stays readable. Defaults to true. */
3631
+ readonly washout?: boolean;
3632
+ }
3633
+ /** How a text watermark crosses the page. */
3634
+ type WatermarkLayout = 'diagonal' | 'horizontal';
3635
+ /**
3636
+ * The watermark a document shows, as `Editor.getWatermark()` reads it.
3637
+ *
3638
+ * The text fields are present for a text watermark, `washout` for a picture watermark.
3639
+ */
3640
+ interface WatermarkState {
3641
+ readonly kind: 'text' | 'image';
3642
+ readonly text?: string;
3643
+ readonly fontFamily?: string;
3644
+ /** Null for Auto size. */
3645
+ readonly fontSizePt?: number | null;
3646
+ readonly bold?: boolean;
3647
+ readonly italic?: boolean;
3648
+ /** `RRGGBB`. */
3649
+ readonly color?: string;
3650
+ readonly transparency?: number;
3651
+ readonly layout?: WatermarkLayout;
3652
+ readonly washout?: boolean;
3181
3653
  }
3182
3654
  /** A size in EMUs, the unit DrawingML stores extents in. 914400 EMU = 1 inch. */
3183
3655
  interface Extent {
@@ -3401,26 +3873,7 @@ type TreeDocOp = SetFieldCodeOp | {
3401
3873
  readonly offset: number;
3402
3874
  /** Write this as a TRACKED insertion, on the same terms as `insertText`. */
3403
3875
  readonly revision?: RevisionAttributionInput;
3404
- } | {
3405
- /**
3406
- * Insert an allowlisted page-number complex field at a UTF-16 offset.
3407
- *
3408
- * `PAGE_X_OF_Y` is PAGE + literal " of " + NUMPAGES in one undoable op. Non-page
3409
- * instructions are refused — never authored through this path.
3410
- */
3411
- readonly op: 'insertPageField';
3412
- readonly paragraphId: string;
3413
- readonly offset: number;
3414
- readonly field: 'PAGE' | 'NUMPAGES' | 'SECTIONPAGES' | 'PAGE_X_OF_Y';
3415
- /**
3416
- * Write this as a TRACKED insertion, on the same terms as `insertText`.
3417
- *
3418
- * The whole field — every `w:fldChar`, the instruction, the `PAGE_X_OF_Y` literal —
3419
- * goes into ONE `w:ins`, because the field is one proposal: rejecting it must take
3420
- * the complete atom back, never leave a `begin` standing without its `end`.
3421
- */
3422
- readonly revision?: RevisionAttributionInput;
3423
- } | {
3876
+ } | InsertPageFieldOp | InsertComplexFieldOp | SetFieldResultOp | InsertEquationOp | {
3424
3877
  /**
3425
3878
  * Move a numbered paragraph to another `w:numPr/w:ilvl`.
3426
3879
  *
@@ -3709,6 +4162,8 @@ type TreeDocOp = SetFieldCodeOp | {
3709
4162
  readonly xpath: string;
3710
4163
  readonly storeItemId: string;
3711
4164
  };
4165
+ /** Propose the control as a tracked `w:ins`; rejecting removes it with its text. */
4166
+ readonly revision?: RevisionAttributionInput;
3712
4167
  } | {
3713
4168
  /** Repeating-section item insert — unsupported at this layer (out of scope). */
3714
4169
  readonly op: 'addRepeatingSectionItem';
@@ -3783,6 +4238,18 @@ type TreeDocOp = SetFieldCodeOp | {
3783
4238
  readonly op: 'deleteTableColumn';
3784
4239
  readonly tableId: string;
3785
4240
  readonly gridColumnId: string;
4241
+ } | {
4242
+ /** Merge cells covering one rectangle into its top-left cell, content in reading order. */
4243
+ readonly op: 'mergeTableCells';
4244
+ readonly tableId: string;
4245
+ readonly cellIds: readonly string[];
4246
+ } | {
4247
+ /** Split one cell into `rows` by `columns` equal cells; a one-row cell adds rows. */
4248
+ readonly op: 'splitTableCell';
4249
+ readonly tableId: string;
4250
+ readonly cellId: string;
4251
+ readonly rows: number;
4252
+ readonly columns: number;
3786
4253
  } | {
3787
4254
  /**
3788
4255
  * Resize one internal divider between two adjacent canonical grid columns.
@@ -3907,6 +4374,10 @@ type TreeDocOp = SetFieldCodeOp | {
3907
4374
  */
3908
4375
  readonly op: 'setDocumentProtection';
3909
4376
  readonly enforce: boolean;
4377
+ } | {
4378
+ /** Replace the watermark in every header a section shows; null removes it. Package-level. */
4379
+ readonly op: 'setWatermark';
4380
+ readonly watermark: PackageWatermarkWrite | null;
3910
4381
  } | {
3911
4382
  /**
3912
4383
  * Insert a footnote or endnote: body reference + notes-part body (+ create the
@@ -4110,7 +4581,7 @@ type TreeDocOp = SetFieldCodeOp | {
4110
4581
  readonly paragraphId: string;
4111
4582
  readonly pageNumberText: string;
4112
4583
  }[];
4113
- } | SetTextFormFieldDefaultOp | CommitTextFormFieldOp | SetLegacyCheckboxOp | SetLegacyDropdownOp | InsertBuildingBlockOp | {
4584
+ } | SetTextFormFieldDefaultOp | CommitTextFormFieldOp | SetLegacyCheckboxOp | SetLegacyDropdownOp | InsertBuildingBlockOp | InsertBookmarkOp | DeleteBookmarkOp | {
4114
4585
  /**
4115
4586
  * Rewrite recognized fields' cached RESULT runs in place — between the `separate` and
4116
4587
  * `end` fldChars, or a `w:fldSimple`'s content. The instruction is never modified; a
@@ -4210,6 +4681,11 @@ type TreeOpRejection = 'unknown-op' | 'unknown-paragraph' | 'not-a-paragraph' |
4210
4681
  * pointing at a part nobody created, or a part with no declared content type.
4211
4682
  */
4212
4683
  | 'package-invariant'
4684
+ /**
4685
+ * A package edit refused the package it was given, for example because an id or part name it
4686
+ * expected to allocate is taken or a definition it addresses changed. Nothing was applied.
4687
+ */
4688
+ | 'package-changed'
4213
4689
  /** No revision in this part carries the addressed `(id, author, date)` triple. */
4214
4690
  | 'unknown-revision'
4215
4691
  /**
@@ -4217,7 +4693,13 @@ type TreeOpRejection = 'unknown-op' | 'unknown-paragraph' | 'not-a-paragraph' |
4217
4693
  * implemented. Refusing is deliberate: removing the markup alone would report the decision
4218
4694
  * applied while leaving the row, cell, or section it describes untouched.
4219
4695
  */
4220
- | 'unsupported-revision' | 'tree-invariant'
4696
+ | 'unsupported-revision'
4697
+ /**
4698
+ * A tracked insertion would land inside a link, content control, or other container within
4699
+ * another author's pending insertion. The container cannot split, and nested words would
4700
+ * become part of that author's proposal.
4701
+ */
4702
+ | 'unsupported-revision:foreign-insertion' | 'tree-invariant'
4221
4703
  /** No content control in this part carries the addressed node id. */
4222
4704
  | 'unknown-content-control'
4223
4705
  /** The addressed node exists and is not a `w:sdt`. */
@@ -4247,8 +4729,18 @@ type TreeOpRejection = 'unknown-op' | 'unknown-paragraph' | 'not-a-paragraph' |
4247
4729
  * mapping cannot be trusted and the inserted row would not match it.
4248
4730
  */
4249
4731
  | 'row-hides-cell'
4250
- /** Column edit refused because the table carries horizontal or vertical merges. */
4732
+ /** The table carries a legacy `w:hMerge`, which grid edits cannot place. */
4251
4733
  | 'table-has-merge'
4734
+ /** The cells to merge do not cover one rectangle, or cover only one cell. */
4735
+ | 'cells-not-rectangle'
4736
+ /** A cell merged over several rows splits only into a divisor of them. */
4737
+ | 'split-rows-not-divisor'
4738
+ /** The cells hold a tracked cell insertion, deletion, or merge. */
4739
+ | 'cell-has-revision'
4740
+ /** The split cells would be narrower than the minimum column width. */
4741
+ | 'cell-too-narrow'
4742
+ /** Without `w:tblGrid`, a cell splits only into a divisor of the columns it spans. */
4743
+ | 'split-needs-grid'
4252
4744
  /** The addressed grid column id is missing or ambiguous without `w:tblGrid`. */
4253
4745
  | 'unknown-grid-column'
4254
4746
  /** The operation would exceed bounded table topology limits. */
@@ -4286,5 +4778,5 @@ type TreeOpResult = {
4286
4778
  readonly detail?: string;
4287
4779
  };
4288
4780
 
4289
- export { IMAGE_WRAP_TARGETS as aL, TEXT_FORM_FORMATS as aM, ACCEPTED_PARAGRAPH_PROPERTIES as b2, ACCEPTED_RUN_PROPERTIES as b3, CONTENT_CONTROL_ID_MAX as b4, CONTENT_CONTROL_PROPERTY_ORDER as b5, MAX_CONTENT_CONTROL_NESTING as bA, OFFICE_RELATIONSHIP_NAMESPACE_URI as bD, OOXML_NODE_IDENTITY_RULES as bE, DEFAULT_OOXML_PACKAGE_LIMITS as bm, DEFAULT_ZIP_LIMITS as bn, HYPERLINK_RELATIONSHIP_TYPE as bq, IMAGE_RELATIONSHIP_TYPE as bt, MAX_CONTENT_CONTROLS_PER_PART as bz, hyperlinkAnchorOf as c$, allocateContentControlId as cF, asciiFold as cG, buildContentTypeIndex as cH, buildRelationshipSet as cI, childElements as cJ, commentAnchorsOfStory as cK, commentsOfPart as cL, contentControlContentChildren as cM, contentControlContentNodeOf as cN, contentControlEndPropertiesNodeOf as cO, contentControlLevelOf as cP, contentControlPropertiesNodeOf as cQ, contentControlPropertiesOf as cR, contentControlTextOf as cS, contentControlsIn as cT, detectDuplicateNames as cU, extensionKey as cV, findContentControl as cW, findElement as cX, firstReviewRange as cY, flattenContentControls as cZ, hasAnyComment as c_, TABLE_BORDER_STYLES as co, W15_NAMESPACE_URI as cu, WML_NAMESPACE_URI as cv, XMLNS_NAMESPACE_URI as cw, XML_NAMESPACE_URI as cx, hyperlinkRelationshipIdOf as d0, hyperlinkTargetOf as d1, isContentControlContentNode as d2, isContentControlNode as d3, isContentControlWrapper as d4, isContentRevisionKind as d5, isHyperlinkNode as d6, isRangeMarkerKind as d7, isValidMime as d8, legacyCheckboxFieldsOf as d9, withPart as dA, writeOoxmlPackage as dB, writeZip as dC, activeReviewItem as dE, reviewItemPositionRank as dF, reviewItemsAt as dG, reviewThreadRootOf as dH, lockForbidsEdit as da, lockForbidsRemoval as db, normalizePartName as dc, orderedContentControlProperties as dd, parseContentControlId as de, partNameKey as df, planRevisionAuthorChange as dg, planRevisionBatch as dh, projectDrawing as di, readOnOffChild as dj, readOoxmlPackage as dk, readOoxmlPart as dl, readXml as dm, readZip as dn, resolveContentControlLock as dp, resolveContentType as dq, resolveImageRelationship as dr, resolveInternalTarget as ds, resolveRelationship as dt, reviewItemKey as du, reviewItemRanges as dv, textContent as dw, textFormFieldsOf as dx, threadStateOfPart as dy, validateExternalTarget as dz };
4290
- export type { DrawingVerticalReferenceFrame as $, ParagraphTabStop as A, Block as B, CommentRecord as C, DocxDocument as D, ExecResult as E, RevisionType as F, Section as G, HeaderFooterSet as H, InsertableContentControlType as I, SectionProperties as J, StyleDefinition as K, Theme as L, ThemeColorScheme as M, OoxmlNode as N, OoxmlPart as O, Paragraph as P, OoxmlPackage as Q, ReviewModelInput as R, StyleDefinitions as S, Table as T, OoxmlNodeId as U, OoxmlGenericElementNode as V, DocxDocumentJSON as W, DrawingHorizontalReferenceFrame as X, DrawingKind as Y, DrawingLocks as Z, DrawingPositionInput as _, ReviewItem as a, OoxmlHardBreakNode as a$, FontDefinition as a0, ImageWrapTarget as a1, NumberingRef as a2, PageMargins as a3, ParagraphDisagreements as a4, ParagraphFormatCommand as a5, Point as a6, Rect as a7, RevisionAuthorResult as a8, RevisionBatchResult as a9, OoxmlParagraphNode as aA, OoxmlNoteNode as aB, OoxmlContinuationSeparatorNode as aC, OoxmlEndnotesNode as aD, OoxmlFootnotesNode as aE, OoxmlNoteRefNode as aF, OoxmlNoteReferenceNode as aG, OoxmlSeparatorNode as aH, ImpactClass as aI, SourceCrop as aJ, TreeDocColorValue as aK, TextFormFieldRange as aN, TextFormFieldOptions as aO, DrawingTransform as aP, TableBorderStyle as aQ, DrawingAccessibility as aR, DrawingImageEffects as aS, VectorShapeProjection as aT, OoxmlDrawingNode as aU, OoxmlInvariantResult as aV, OoxmlFldCharNode as aW, OoxmlFldSimpleNode as aX, OoxmlInstrTextNode as aY, TreeOpResult as aZ, RelationshipRecord as a_, Run as aa, SelectionPin as ab, TableCell as ac, TableRow as ad, Unsubscribe as ae, Watermark as af, TreeDocOp as ag, OoxmlElement as ah, OoxmlContentControlNode as ai, OoxmlContentControlContentNode as aj, OoxmlPackageRejection as ak, DrawingProjection as al, OoxmlProperty as am, OoxmlPackageResult as an, OoxmlPackageLimits as ao, RevisionAuthorEntry as ap, RevisionAuthorSkipReason as aq, RevisionBatchEntry as ar, RevisionBatchSkipDetail as as, RevisionBatchSkipReason as at, RevisionSiteRefusal as au, TreeOpRejection as av, AutomationTableMutation as aw, RevisionAttributionInput as ax, OoxmlInvariantIssue as ay, DrawingTreeDocOp as az, ReviewRevisionItem as b, OoxmlHyperlinkNode as b$, OoxmlAttribute as b0, CommentThreadState as b1, CommentAnchor as b6, CommentPosition as b7, CommitTextFormFieldOp as b8, ContentControlCheckbox as b9, NameRejection as bB, NameResult as bC, OoxmlBodyNode as bF, OoxmlBookmarkEndNode as bG, OoxmlBookmarkStartNode as bH, OoxmlContentControlCalendarNode as bI, OoxmlContentControlCheckboxNode as bJ, OoxmlContentControlCheckedNode as bK, OoxmlContentControlCheckedStateNode as bL, OoxmlContentControlComboBoxNode as bM, OoxmlContentControlDataBindingNode as bN, OoxmlContentControlDateFormatNode as bO, OoxmlContentControlDateNode as bP, OoxmlContentControlDropDownListNode as bQ, OoxmlContentControlEndPropertiesNode as bR, OoxmlContentControlLidNode as bS, OoxmlContentControlListItemNode as bT, OoxmlContentControlPropertiesNode as bU, OoxmlContentControlStoreMappedDataAsNode as bV, OoxmlContentControlTextNode as bW, OoxmlContentControlUncheckedStateNode as bX, OoxmlDocumentNode as bY, OoxmlExternalTarget as bZ, OoxmlGenericExtensionAttribute as b_, ContentControlCheckboxState as ba, ContentControlDataBinding as bb, ContentControlDateFormat as bc, ContentControlEntry as bd, ContentControlKind as be, ContentControlLevel as bf, ContentControlListItem as bg, ContentControlLock as bh, ContentControlProperties as bi, ContentTypeError as bj, ContentTypeIndex as bk, ContentTypeRecords as bl, DefaultRecord as bo, DeleteTextOp as bp, HyperlinkKind as br, HyperlinkTarget as bs, ImageRelationshipResolution as bu, IndexResult as bv, InsertBuildingBlockOp as bw, InsertTextOp as bx, LegacyCheckboxFieldRange as by, ReviewCommentItem as c, OoxmlInvariantIssueCode as c0, OoxmlKnownNodeAttribute as c1, OoxmlNamespaceBinding as c2, OoxmlNodeIdentityRules as c3, OoxmlParagraphPropertiesNode as c4, OoxmlPartMetadata as c5, OoxmlReadRejection as c6, OoxmlReadResult as c7, OoxmlRunNode as c8, OoxmlRunPropertiesNode as c9, XmlRejection as cA, XmlResult as cB, ZipLimits as cC, ZipReadResult as cD, ZipRejection as cE, OoxmlTabNode as ca, OoxmlTextElementNode as cb, OoxmlTextNode as cc, OoxmlWmlValAttribute as cd, OoxmlXmlSpaceAttribute as ce, OverrideRecord as cf, RelationshipError as cg, RelationshipSetResult as ch, RelationshipTargetResolver as ci, ResolveResult as cj, ResolvedRelationship as ck, SetLegacyCheckboxOp as cl, SetLegacyDropdownOp as cm, SetTextFormFieldDefaultOp as cn, TabStopWrite as cp, TargetMode as cq, TextFormFieldType as cr, TreeDocOpKind as cs, TreeOpEffect as ct, XmlLimits as cy, XmlNode as cz, ReviewCustomItem as d, VectorShapeComponent as dD, ReviewPosition as e, ReviewRange as f, ReviewRevisionKind as g, RevisionAddress as h, ContentControlType as i, DocTarget as j, RunFormatting as k, Extent as l, ContainerRef as m, ContentControlFilter as n, DocRange as o, Revision as p, DocComment as q, ColorValue as r, ContentControl as s, DocAnchor as t, DocAnchorRange as u, DocLocation as v, DocumentBody as w, ExecErrorCode as x, IndentFormatting as y, ParagraphFlags as z };
4781
+ export { validateRasterHeader as a$, DEFAULT_IMAGE_RESOURCE_LIMITS as aV, IMAGE_WRAP_TARGETS as aW, TEXT_FORM_FORMATS as aX, resolveImageResourceLimits as aY, resolveSvgIntrinsicSize as aZ, sniffImageMime as a_, MAX_CONTENT_CONTROLS_PER_PART as b$, DEFAULT_LIMITS as bF, DEFAULT_OOXML_PACKAGE_LIMITS as bG, DEFAULT_ZIP_LIMITS as bH, HARD_CEILINGS as bL, HYPERLINK_RELATIONSHIP_TYPE as bM, IMAGE_RELATIONSHIP_TYPE as bP, IMAGE_RESOURCE_HARD_CEILINGS as bQ, ACCEPTED_PARAGRAPH_PROPERTIES as bj, ACCEPTED_RUN_PROPERTIES as bk, CONTENT_CONTROL_ID_MAX as bm, CONTENT_CONTROL_PROPERTY_ORDER as bn, XMLNS_NAMESPACE_URI as c$, MAX_CONTENT_CONTROL_NESTING as c0, MAX_SVG_SNIFF_BYTES as c1, OFFICE_RELATIONSHIP_NAMESPACE_URI as c4, OOXML_NODE_IDENTITY_RULES as c5, TABLE_BORDER_STYLES as cS, W15_NAMESPACE_URI as cZ, WML_NAMESPACE_URI as c_, resolveImageRelationship as d$, XML_NAMESPACE_URI as d0, allocateContentControlId as d8, asciiFold as d9, hyperlinkTargetOf as dA, imageResourceLookupFor as dB, isContentControlContentNode as dC, isContentControlNode as dD, isContentControlWrapper as dE, isContentRevisionKind as dF, isHyperlinkNode as dG, isRangeMarkerKind as dH, isValidMime as dI, legacyCheckboxFieldsOf as dJ, liveDrawingReferenceCount as dK, lockForbidsEdit as dL, lockForbidsRemoval as dM, normalizePartName as dN, orderedContentControlProperties as dO, parseContentControlId as dP, partNameKey as dQ, planRevisionAuthorChange as dR, planRevisionBatch as dS, projectDrawing as dT, readOnOffChild as dU, readOoxmlPackage as dV, readOoxmlPart as dW, readXml as dX, readZip as dY, resolveContentControlLock as dZ, resolveContentType as d_, buildContentTypeIndex as da, buildRelationshipSet as db, childElements as dc, commentAnchorsOfStory as dd, commentsOfPart as de, contentControlContentChildren as df, contentControlContentNodeOf as dg, contentControlEndPropertiesNodeOf as dh, contentControlLevelOf as di, contentControlPropertiesNodeOf as dj, contentControlPropertiesOf as dk, contentControlTextOf as dl, contentControlsIn as dm, createImageResourceCache as dn, detectDuplicateNames as dp, enclosedBookmarkDeletions as dq, extensionKey as dr, findContentControl as ds, findElement as dt, firstReviewRange as du, flattenContentControls as dv, hasAnyComment as dw, hasBoundedSvgRoot as dx, hyperlinkAnchorOf as dy, hyperlinkRelationshipIdOf as dz, resolveInternalTarget as e0, resolveLimits as e1, resolveRelationship as e2, reviewItemKey as e3, reviewItemRanges as e4, textContent as e5, textFormFieldsOf as e6, threadStateOfPart as e7, validateExternalTarget as e8, validateGifHeader as e9, validateJpegHeader as ea, validatePngHeader as eb, withPart as ec, withoutBookmarkInPart as ed, writeOoxmlPackage as ee, writeZip as ef, activeReviewItem as eh, reviewItemPositionRank as ei, reviewItemsAt as ej, reviewThreadRootOf as ek };
4782
+ export type { Table as $, ParagraphDisagreements as A, Block as B, CommentRecord as C, DocxDocument as D, ExecResult as E, ParagraphFlags as F, ParagraphTabStop as G, HeaderFooterSet as H, InsertableContentControlType as I, RevisionAuthorEntry as J, RevisionAuthorResult as K, RevisionAuthorSkipReason as L, RevisionBatchEntry as M, NumberingRef as N, OoxmlPart as O, PageMargins as P, RevisionBatchResult as Q, ReviewModelInput as R, StyleDefinitions as S, RevisionBatchSkipDetail as T, RevisionBatchSkipReason as U, RevisionSiteRefusal as V, RevisionType as W, Run as X, Section as Y, SectionProperties as Z, StyleDefinition as _, ReviewItem as a, TableCell as a0, TableRow as a1, Theme as a2, ThemeColorScheme as a3, OoxmlNode as a4, OoxmlPackage as a5, DocxDocumentJSON as a6, DrawingHorizontalReferenceFrame as a7, DrawingKind as a8, DrawingLocks as a9, OoxmlPackageResult as aA, OoxmlPackageRejection as aB, OoxmlNodeId as aC, OoxmlPackageLimits as aD, AutomationTableMutation as aE, RevisionAttributionInput as aF, TreeOpRejection as aG, PackageWatermarkWrite as aH, OoxmlInvariantIssue as aI, DrawingTreeDocOp as aJ, ImpactClass as aK, OoxmlParagraphNode as aL, OoxmlNoteNode as aM, OoxmlContinuationSeparatorNode as aN, OoxmlEndnotesNode as aO, OoxmlFootnotesNode as aP, OoxmlNoteRefNode as aQ, OoxmlNoteReferenceNode as aR, OoxmlSeparatorNode as aS, SourceCrop as aT, TreeDocColorValue as aU, DrawingPositionInput as aa, DrawingVerticalReferenceFrame as ab, FontDefinition as ac, ImageDecodePort as ad, ImageResourceLimits as ae, ImageResourceState as af, ImageWrapTarget as ag, ParagraphFormatCommand as ah, Point as ai, PreservedImageMime as aj, Rect as ak, RenderableImageMime as al, SelectionPin as am, SupportedImageMime as an, Unsubscribe as ao, ValidatedImageBytesHandle as ap, VectorImageMime as aq, Watermark as ar, WatermarkLayout as as, WatermarkState as at, TreeDocOp as au, OoxmlElement as av, OoxmlContentControlNode as aw, OoxmlGenericElementNode as ax, OoxmlContentControlContentNode as ay, OoxmlProperty as az, ReviewRevisionItem as b, TextFormFieldRange as b0, TextFormFieldOptions as b1, DrawingTransform as b2, TableBorderStyle as b3, DrawingAccessibility as b4, DrawingImageEffects as b5, VectorShapeProjection as b6, DrawingProjection as b7, OoxmlDrawingNode as b8, OoxmlInvariantResult as b9, ContentControlProperties as bA, ContentTypeError as bB, ContentTypeIndex as bC, ContentTypeRecords as bD, CreateImageResourceCacheOptions as bE, DefaultRecord as bI, DeleteBookmarkOp as bJ, DeleteTextOp as bK, HyperlinkKind as bN, HyperlinkTarget as bO, ImageRelationshipResolution as bR, ImageResourceLookup as bS, IndexResult as bT, InsertBookmarkOp as bU, InsertBuildingBlockOp as bV, InsertComplexFieldOp as bW, InsertEquationOp as bX, InsertPageFieldOp as bY, InsertTextOp as bZ, LegacyCheckboxFieldRange as b_, OoxmlFldCharNode as ba, OoxmlFldSimpleNode as bb, OoxmlInstrTextNode as bc, TreeOpResult as bd, RelationshipRecord as be, OoxmlHardBreakNode as bf, OoxmlAttribute as bg, ResourceLimits as bh, CommentThreadState as bi, BookmarkOpPosition as bl, CommentAnchor as bo, CommentPosition as bp, CommitTextFormFieldOp as bq, ContentControlCheckbox as br, ContentControlCheckboxState as bs, ContentControlDataBinding as bt, ContentControlDateFormat as bu, ContentControlEntry as bv, ContentControlKind as bw, ContentControlLevel as bx, ContentControlListItem as by, ContentControlLock as bz, ReviewCommentItem as c, NameRejection as c2, NameResult as c3, OoxmlBodyNode as c6, OoxmlBookmarkEndNode as c7, OoxmlBookmarkStartNode as c8, OoxmlContentControlCalendarNode as c9, OoxmlReadResult as cA, OoxmlRunNode as cB, OoxmlRunPropertiesNode as cC, OoxmlTabNode as cD, OoxmlTextElementNode as cE, OoxmlTextNode as cF, OoxmlWmlValAttribute as cG, OoxmlXmlSpaceAttribute as cH, OverrideRecord as cI, RelationshipError as cJ, RelationshipSetResult as cK, RelationshipTargetResolver as cL, ResolveResult as cM, ResolvedRelationship as cN, SetFieldResultOp as cO, SetLegacyCheckboxOp as cP, SetLegacyDropdownOp as cQ, SetTextFormFieldDefaultOp as cR, TabStopWrite as cT, TargetMode as cU, TextFormFieldType as cV, TreeDocOpKind as cW, TreeOpEffect as cX, ValidatedRasterHeader as cY, OoxmlContentControlCheckboxNode as ca, OoxmlContentControlCheckedNode as cb, OoxmlContentControlCheckedStateNode as cc, OoxmlContentControlComboBoxNode as cd, OoxmlContentControlDataBindingNode as ce, OoxmlContentControlDateFormatNode as cf, OoxmlContentControlDateNode as cg, OoxmlContentControlDropDownListNode as ch, OoxmlContentControlEndPropertiesNode as ci, OoxmlContentControlLidNode as cj, OoxmlContentControlListItemNode as ck, OoxmlContentControlPropertiesNode as cl, OoxmlContentControlStoreMappedDataAsNode as cm, OoxmlContentControlTextNode as cn, OoxmlContentControlUncheckedStateNode as co, OoxmlDocumentNode as cp, OoxmlExternalTarget as cq, OoxmlGenericExtensionAttribute as cr, OoxmlHyperlinkNode as cs, OoxmlInvariantIssueCode as ct, OoxmlKnownNodeAttribute as cu, OoxmlNamespaceBinding as cv, OoxmlNodeIdentityRules as cw, OoxmlParagraphPropertiesNode as cx, OoxmlPartMetadata as cy, OoxmlReadRejection as cz, ReviewCustomItem as d, XmlLimits as d1, XmlNode as d2, XmlRejection as d3, XmlResult as d4, ZipLimits as d5, ZipReadResult as d6, ZipRejection as d7, ReviewPosition as e, VectorShapeComponent as eg, ReviewRange as f, ReviewRevisionKind as g, RevisionAddress as h, ContentControlType as i, DocTarget as j, RunFormatting as k, Extent as l, ContainerRef as m, ContentControlFilter as n, DocRange as o, Revision as p, DocComment as q, ColorValue as r, ContentControl as s, DocAnchor as t, DocAnchorRange as u, DocLocation as v, DocumentBody as w, ExecErrorCode as x, IndentFormatting as y, Paragraph as z };