@coco-vexel/coco-office 0.0.0-stage → 1.0.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 (76) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +120 -2
  3. package/THIRD_PARTY_NOTICES.md +1188 -0
  4. package/dist/excel-worker-browser.cjs +6544 -0
  5. package/dist/excel-worker-browser.cjs.map +1 -0
  6. package/dist/excel-worker-browser.d.cts +2 -0
  7. package/dist/excel-worker-browser.d.ts +2 -0
  8. package/dist/excel-worker-browser.js +6523 -0
  9. package/dist/excel-worker-browser.js.map +1 -0
  10. package/dist/excel-worker.cjs +6547 -0
  11. package/dist/excel-worker.cjs.map +1 -0
  12. package/dist/excel-worker.d.cts +2 -0
  13. package/dist/excel-worker.d.ts +2 -0
  14. package/dist/excel-worker.js +6526 -0
  15. package/dist/excel-worker.js.map +1 -0
  16. package/dist/excel.cjs +12523 -0
  17. package/dist/excel.cjs.map +1 -0
  18. package/dist/excel.d.cts +2252 -0
  19. package/dist/excel.d.ts +2252 -0
  20. package/dist/excel.js +12368 -0
  21. package/dist/excel.js.map +1 -0
  22. package/dist/index.cjs +19 -0
  23. package/dist/index.cjs.map +1 -0
  24. package/dist/index.d.cts +2 -0
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.js +1 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/kernel-worker-browser.cjs +12304 -0
  29. package/dist/kernel-worker-browser.cjs.map +1 -0
  30. package/dist/kernel-worker-browser.d.cts +2 -0
  31. package/dist/kernel-worker-browser.d.ts +2 -0
  32. package/dist/kernel-worker-browser.js +12283 -0
  33. package/dist/kernel-worker-browser.js.map +1 -0
  34. package/dist/kernel-worker.cjs +12309 -0
  35. package/dist/kernel-worker.cjs.map +1 -0
  36. package/dist/kernel-worker.d.cts +2 -0
  37. package/dist/kernel-worker.d.ts +2 -0
  38. package/dist/kernel-worker.js +12288 -0
  39. package/dist/kernel-worker.js.map +1 -0
  40. package/dist/pack.cjs +459 -0
  41. package/dist/pack.cjs.map +1 -0
  42. package/dist/pack.d.cts +119 -0
  43. package/dist/pack.d.ts +119 -0
  44. package/dist/pack.js +408 -0
  45. package/dist/pack.js.map +1 -0
  46. package/dist/ppt.cjs +7427 -0
  47. package/dist/ppt.cjs.map +1 -0
  48. package/dist/ppt.d.cts +1432 -0
  49. package/dist/ppt.d.ts +1432 -0
  50. package/dist/ppt.js +7355 -0
  51. package/dist/ppt.js.map +1 -0
  52. package/dist/shared.cjs +105 -0
  53. package/dist/shared.cjs.map +1 -0
  54. package/dist/shared.d.cts +31 -0
  55. package/dist/shared.d.ts +31 -0
  56. package/dist/shared.js +81 -0
  57. package/dist/shared.js.map +1 -0
  58. package/dist/types-BVkkdcfh.d.cts +54 -0
  59. package/dist/types-BVkkdcfh.d.ts +54 -0
  60. package/dist/types-C2vQfM-b.d.cts +102 -0
  61. package/dist/types-C2vQfM-b.d.ts +102 -0
  62. package/dist/view-DAkeR0RW.d.ts +1199 -0
  63. package/dist/view-DX2YAG5A.d.cts +1199 -0
  64. package/dist/word-view.cjs +1824 -0
  65. package/dist/word-view.cjs.map +1 -0
  66. package/dist/word-view.d.cts +2 -0
  67. package/dist/word-view.d.ts +2 -0
  68. package/dist/word-view.js +1791 -0
  69. package/dist/word-view.js.map +1 -0
  70. package/dist/word.cjs +14106 -0
  71. package/dist/word.cjs.map +1 -0
  72. package/dist/word.d.cts +3042 -0
  73. package/dist/word.d.ts +3042 -0
  74. package/dist/word.js +14011 -0
  75. package/dist/word.js.map +1 -0
  76. package/package.json +103 -3
@@ -0,0 +1,1199 @@
1
+ import { a as Package } from './types-BVkkdcfh.cjs';
2
+
3
+ /**
4
+ * OOXML 常用命名空间 URI 常量。
5
+ *
6
+ * 所有 XPath / DOM 查询必须按 URI 比较(不依赖前缀)—— serializer 可能改前缀,URI 不变。
7
+ * 来源:docs/01 附录 A。
8
+ */
9
+ /** Word 正文命名空间 */
10
+ declare const W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
11
+ /** 关系(.rels 文件 / r:id 引用) */
12
+ declare const R_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
13
+ /** DrawingML(Word / Excel / PPT 共用) */
14
+ declare const A_NS = "http://schemas.openxmlformats.org/drawingml/2006/main";
15
+ /** DrawingML wordprocessing 容器(wp:inline / wp:anchor / wp:extent / wp:wrap*) */
16
+ declare const WP_NS = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
17
+ /** DrawingML picture(pic:pic) */
18
+ declare const PIC_NS = "http://schemas.openxmlformats.org/drawingml/2006/picture";
19
+ /** DrawingML chart(c:chart 引用) */
20
+ declare const CHART_NS = "http://schemas.openxmlformats.org/drawingml/2006/chart";
21
+ /** DrawingML diagram(SmartArt;dgm:relIds) */
22
+ declare const DGM_NS = "http://schemas.openxmlformats.org/drawingml/2006/diagram";
23
+ /** Word 2010+ wordprocessing shape(wps:wsp / wps:txbx) */
24
+ declare const WPS_NS = "http://schemas.microsoft.com/office/word/2010/wordprocessingShape";
25
+ /** Word 2010+ wordprocessing group(wpg:wgp) */
26
+ declare const WPG_NS = "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup";
27
+ /** Word 2010+ wordprocessing canvas(wpc:wpc) */
28
+ declare const WPC_NS = "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas";
29
+ /** Markup Compatibility(Choice / Fallback) */
30
+ declare const MC_NS = "http://schemas.openxmlformats.org/markup-compatibility/2006";
31
+ /** VML(旧版形状降级;v:line / v:rect / v:shape,多见于 mc:Fallback) */
32
+ declare const VML_NS = "urn:schemas-microsoft-com:vml";
33
+ /** Word 2010+ 扩展(w14:paraId / w14:textId) */
34
+ declare const W14_NS = "http://schemas.microsoft.com/office/word/2010/wordml";
35
+ /** Flat OPC 包格式 */
36
+ declare const PKG_NS = "http://schemas.microsoft.com/office/2006/xmlPackage";
37
+ /** xml:space 等 xml 标准命名空间 */
38
+ declare const XML_NS = "http://www.w3.org/XML/1998/namespace";
39
+
40
+ /**
41
+ * `getRunText` / `getParagraphText` 可选参数(task-20260623-core-tab-faithful-read)。
42
+ *
43
+ * - `structuralWhitespace: true`:保真读模式——按 appendSegmentsToRun 的精确逆运算,
44
+ * `<w:tab/>` → `\t`、`<w:br/>` (无 w:type 或 w:type="textWrapping")→ `\n`。
45
+ * - 缺省 / `false`:现行为(只拼 `<w:t>`),**偏移算术安全**。
46
+ */
47
+ interface RunTextOptions {
48
+ /**
49
+ * 启用结构空白保真读:`<w:tab/>` → `\t`,`<w:br/>` → `\n`。
50
+ * **仅用于内容读取**,不得用于偏移算术(bookmark/comment/replaceText 等)。
51
+ */
52
+ structuralWhitespace?: boolean;
53
+ }
54
+ /** 段落 `<w:p>` 下所有直接 `<w:r>` 子元素(不递归到嵌套段落 / smartTag 等) */
55
+ declare function getParagraphRuns(paragraph: Element): Element[];
56
+ /**
57
+ * 取 run 的文本。
58
+ *
59
+ * - 默认(opts 缺省 / `structuralWhitespace: false`):只拼 `<w:t>` 文本,忽略 `<w:br>` / `<w:tab>`。
60
+ * **偏移算术安全**:`<w:tab/>` 算 0 长,保持 bookmark/comment/replaceText 偏移稳定。
61
+ * - `structuralWhitespace: true`:保真读——按文档顺序遍历子节点:
62
+ * `<w:t>` → textContent、`<w:tab/>` → `\t`、`<w:br/>` (无 w:type 或 textWrapping)→ `\n`。
63
+ * 这是 `appendSegmentsToRun` 的精确逆运算。
64
+ */
65
+ declare function getRunText(run: Element, opts?: RunTextOptions): string;
66
+ /**
67
+ * 段落的纯文本(所有直接 run 的文本拼接)。
68
+ *
69
+ * - 默认(opts 缺省):只拼 `<w:t>`,偏移算术安全。
70
+ * - `structuralWhitespace: true`:保真读,透传到 `getRunText`。
71
+ */
72
+ declare function getParagraphText(paragraph: Element, opts?: RunTextOptions): string;
73
+ /** splitRunAt 返回值 */
74
+ interface SplitResult {
75
+ /** 原 run,文本截取到 [0, offset) */
76
+ before: Element;
77
+ /**
78
+ * 分裂出的新 run,文本为 [offset, end)。
79
+ * 与 `before` 共享 `<w:rPr>` 结构(深拷贝,不共享对象引用)。
80
+ * offset=0 或 offset=runLen 时为 null(未发生分裂)
81
+ */
82
+ after: Element | null;
83
+ }
84
+ /**
85
+ * 在 run 的文本 offset 处拆分。
86
+ *
87
+ * - `offset === 0` 或 `offset === getRunText(run).length` → 不拆,返回 { before: run, after: null }
88
+ * - 其它情况 → 新 run 插入到原 run 的 nextSibling 位置,返回 { before: run, after: newRun }
89
+ *
90
+ * 本期限制:run 必须恰有 1 个 `<w:t>` 子;否则抛错(多 <w:t>、<w:br>、<w:tab> 等复杂结构交给
91
+ * 后续 #28 的扩展实现)。
92
+ */
93
+ declare function splitRunAt(run: Element, offset: number): SplitResult;
94
+
95
+ /**
96
+ * style-queries —— styles.xml 解析与样式索引构建(#181)。
97
+ *
98
+ * 职责:
99
+ * - `buildStylesIndex(pkg)`:扫 Package 找 styles.xml,构建 Map<styleId, StyleInfo>
100
+ * - `listStyles(stylesIdx, opts?)`:按可选 type 过滤后返回数组
101
+ * - `getStyleById(stylesIdx, styleId)`:O(1) 精确查找
102
+ *
103
+ * 健壮性契约:
104
+ * - styles.xml 不存在 → 返回空 Map,不抛错
105
+ * - `w:type` 未知值 → fallback 到 'paragraph'(OOXML 规范默认)
106
+ * - `w:name` 子元素缺失 → name fallback 到 styleId 本身
107
+ * - 同一 styleId 重复定义 → 后者覆盖前者(与 Word 行为一致)
108
+ * - basedOn 环路 → SDK 不检测,消费方遍历时须自行防环
109
+ *
110
+ * 不暴露 `builtIn` 字段:`<w:builtIn/>` 元素在实际文档中不一致(Word 某些版本省略),
111
+ * 单向可信(存在则肯定是内置,不存在不代表是自定义)会误导消费方。
112
+ * 消费方应通过 `name` + basedOn 链判断语义角色。
113
+ */
114
+
115
+ /** OOXML 定义的四种样式类型(`w:style@w:type`)。 */
116
+ type StyleType = 'paragraph' | 'character' | 'table' | 'numbering';
117
+ interface StyleInfo {
118
+ /** `w:style@w:styleId`。段落 `w:pStyle@w:val` 引用的 key,大小写敏感。 */
119
+ styleId: string;
120
+ /**
121
+ * `w:name@w:val`。
122
+ * - OOXML 规范:内置样式(如 Heading 1、Normal)的 name 永远是英文规范名,
123
+ * 不随文档语言变化。消费方可据此判断语义角色。
124
+ * - 自定义样式:name 为用户输入,可能是中文或任意字符串。
125
+ * - 若 `<w:name>` 元素缺失(非规范文档),fallback 到 `styleId`。
126
+ */
127
+ name: string;
128
+ /**
129
+ * `w:style@w:type`。
130
+ * 未知值 fallback 到 `'paragraph'`(OOXML 规范默认类型)。
131
+ */
132
+ type: StyleType;
133
+ /**
134
+ * 父样式的 `styleId`(`w:basedOn@w:val`)。
135
+ * 根样式(如 Normal)无继承关系,此字段不存在。
136
+ *
137
+ * ⚠ 消费方遍历 basedOn 链时须自行防环,SDK 不检测循环继承。
138
+ */
139
+ basedOn?: string;
140
+ /**
141
+ * 样式定义中的大纲级别(`w:style/w:pPr/w:outlineLvl@w:val`),0–8。
142
+ * 0 = 标题 1,1 = 标题 2,…,8 = 标题 9;9 表示正文(不视为标题)。
143
+ *
144
+ * WPS / Word 的自定义标题样式(如"公文-一级标题")通常不 basedOn heading 1,
145
+ * 而是在此字段直接编码级别。消费方可将其作为 basedOn 链之外的第二信号。
146
+ *
147
+ * 字段不存在 = 样式未设置大纲级别(继承自父样式或使用默认值)。
148
+ */
149
+ outlineLevel?: number;
150
+ }
151
+ interface ListStylesOptions {
152
+ /** 按样式类型过滤。不传则返回全部样式(含所有类型)。 */
153
+ type?: StyleType;
154
+ }
155
+ /**
156
+ * 扫 Package 构建样式索引。
157
+ *
158
+ * - styles.xml 不存在 → 返回空 Map,不抛错
159
+ * - 同一 styleId 重复出现 → 后者覆盖(与 Word 行为一致)
160
+ */
161
+ declare function buildStylesIndex(pkg: Package): Map<string, StyleInfo>;
162
+ /**
163
+ * 列出样式索引中的所有样式。
164
+ *
165
+ * @param stylesIdx 由 `buildStylesIndex` 构建的 Map
166
+ * @param opts 可选过滤(目前支持按 type 过滤)
167
+ */
168
+ declare function listStyles(stylesIdx: Map<string, StyleInfo>, opts?: ListStylesOptions): StyleInfo[];
169
+ /**
170
+ * 按 styleId 精确查找,O(1)。
171
+ * styleId 大小写敏感(与 OOXML 规范一致)。
172
+ */
173
+ declare function getStyleById(stylesIdx: Map<string, StyleInfo>, styleId: string): StyleInfo | null;
174
+
175
+ /**
176
+ * Word 装载期三索引(docs/03 §13.1 / §13.6)。
177
+ *
178
+ * - paraIdx:paraId(大写 8 hex)→ <w:p> Element
179
+ * - bookmarkIdx:name → { start: <w:bookmarkStart>; end: <w:bookmarkEnd>; partPath }
180
+ * - commentIdx:id(number)→ { comment?: <w:comment>; anchors: { start?, end?, ref? } }
181
+ *
182
+ * 同时完成装载期书签校验:**空名抛错**;**重名容错**(保留第一个、忽略后续,绝不崩 ——
183
+ * 真实文档常见重复的 `_GoBack` 等编辑痕迹书签)。未来由 #15 WordError 统一,先用 Error + code。
184
+ *
185
+ * 性能目标:10 万段落 < 100ms(Chrome/Node;WPS WebView 宽松到 < 300ms)。由 `ensureParaIds`
186
+ * 同样走 getElementsByTagNameNS 保证,这里复用同一枚举路径。
187
+ */
188
+
189
+ /** 书签校验错误 code(暂不挂 WordError;#15 会统一到 WordErrorCode) */
190
+ type BookmarkLoadErrorCode = 'BOOKMARK_NAME_DUPLICATE_ON_LOAD' | 'BOOKMARK_NAME_EMPTY_ON_LOAD';
191
+ /** 装载期抛出的书签错误 */
192
+ declare class BookmarkLoadError extends Error {
193
+ readonly code: BookmarkLoadErrorCode;
194
+ readonly details: Record<string, unknown>;
195
+ constructor(code: BookmarkLoadErrorCode, message: string, details?: Record<string, unknown>);
196
+ }
197
+ interface BookmarkEntry {
198
+ /** `<w:bookmarkStart>` 元素 */
199
+ start: Element;
200
+ /** `<w:bookmarkEnd>` 元素;若装载数据里缺失可能为 null */
201
+ end: Element | null;
202
+ /** 所在 part 的 path(如 'word/document.xml') */
203
+ partPath: string;
204
+ }
205
+ interface CommentEntry {
206
+ /** `<w:comment>` 元素(来自 comments.xml);若无 comments.xml 可能为 null */
207
+ comment: Element | null;
208
+ /** 锚点三件套(在 document.xml / headers / footers 等 body-side part 上) */
209
+ anchors: {
210
+ start: Element | null;
211
+ end: Element | null;
212
+ ref: Element | null;
213
+ };
214
+ }
215
+ interface PackageIndices {
216
+ /** paraId → <w:p> */
217
+ paraIdx: Map<string, Element>;
218
+ /** bookmark name → entry(含 start/end/partPath) */
219
+ bookmarkIdx: Map<string, BookmarkEntry>;
220
+ /** comment id → entry(comment 主体 + 三锚点) */
221
+ commentIdx: Map<number, CommentEntry>;
222
+ /**
223
+ * styleId → StyleInfo(来自 styles.xml)。
224
+ * styles.xml 不存在时为空 Map。
225
+ * 消费方按 styleId 做 O(1) 查找,沿 basedOn 链判断语义角色时须自行防环。
226
+ */
227
+ stylesIdx: Map<string, StyleInfo>;
228
+ /**
229
+ * tableId('tbl-NNNN')→ <w:tbl> Element(#185)。
230
+ * 装载期按文档顺序分配,包含所有 part 的所有表格(含嵌套)。
231
+ * 供 listTables / getTableById / plan executor(deleteTable)使用。
232
+ */
233
+ tblIdx: Map<string, Element>;
234
+ /**
235
+ * drawingId('dr-NNNN')→ <w:drawing> Element(#189)。
236
+ * 装载期按文档顺序分配,包含所有 Word 内容 part 的所有 drawing。
237
+ * 供 listDrawings / getDrawingById / 占位图替换(#190)使用。
238
+ *
239
+ * 注意:嵌套在 group / canvas 内的子 drawing 也会被收入(保持枚举层完整暴露),
240
+ * 上层(#191 / #192)按需用 hasDrawingAncestor 自行决定合并策略。
241
+ */
242
+ drawingIdx: Map<string, Element>;
243
+ }
244
+
245
+ /**
246
+ * 扫 Package 构建三索引。
247
+ *
248
+ * - **装载期书签校验**:遇空名抛 `BookmarkLoadError`(code = BOOKMARK_NAME_EMPTY_ON_LOAD);
249
+ * 遇重名**容错**(保留第一个、忽略后续,不抛错 —— `_GoBack` 等编辑痕迹书签可安全忽略)
250
+ * - 孤儿 `bookmarkEnd`(无匹配 start)忽略
251
+ * - 缺 `bookmarkEnd` 的书签仍入索引,`entry.end` 为 null
252
+ * - 不抛错的其它不一致(comment 无 <w:comment> 主体、anchors 不全)进索引,由调用方决定是否告警
253
+ */
254
+ declare function buildIndices(pkg: Package): PackageIndices;
255
+
256
+ /**
257
+ * Word 跨 stories 枚举(docs/03 §10)。
258
+ *
259
+ * 一个 Word 文档可能包含 6 类 story:
260
+ * | 类型 | contentType 尾缀 | 根元素 | 数量 |
261
+ * | body | .document.main+xml | <w:document>/<w:body> | 1 |
262
+ * | header | .header+xml | <w:hdr> | 0..N |
263
+ * | footer | .footer+xml | <w:ftr> | 0..N |
264
+ * | footnote | .footnotes+xml 内每个 | 单个 <w:footnote>(该 part 多个) | 0..M |
265
+ * | endnote | .endnotes+xml 内每个 | 单个 <w:endnote> | 0..M |
266
+ * | comment | .comments+xml 内每个 | 单个 <w:comment> | 0..M |
267
+ *
268
+ * **关键约束**:枚举实现**必须**走 `Document#getElementsByTagNameNS`。
269
+ * `fontoxpath` 的 `//w:p` 无谓词 XPath 在 10 万段落上慢 460×(见 bench/xml-stack-worker)。
270
+ * CI 的 `pnpm check:xpath` 会在源码里扫到此类调用即失败(scripts/check-no-unqualified-xpath.mjs)。
271
+ */
272
+
273
+ type StoryKind = 'body' | 'header' | 'footer' | 'footnote' | 'endnote' | 'comment';
274
+ /**
275
+ * Story 唯一标识:
276
+ * - 'body' — 唯一主 body
277
+ * - 'header:<part path>' / 'footer:<part path>' — 1 part 1 story
278
+ * - 'footnote:<id>' / 'endnote:<id>' / 'comment:<id>' — 多 sub-story 按 w:id 区分
279
+ */
280
+ type StoryId = 'body' | `header:${string}` | `footer:${string}` | `footnote:${number}` | `endnote:${number}` | `comment:${number}`;
281
+ interface Story {
282
+ id: StoryId;
283
+ kind: StoryKind;
284
+ /** story 的根 Element(body = <w:body>,footnote = 单个 <w:footnote>,依此类推) */
285
+ root: Element;
286
+ /** 所在 part 的 path */
287
+ partPath: string;
288
+ }
289
+ interface ListStoriesOptions {
290
+ /** 仅枚举指定 kinds(默认全枚举)*/
291
+ kinds?: StoryKind[];
292
+ }
293
+ /**
294
+ * 枚举 Package 内所有 stories。
295
+ *
296
+ * 按 contentType 尾缀识别 part,内部用 `getElementsByTagNameNS` 提取根元素或
297
+ * sub-story 元素。**不做**任何带谓词/路径的 XPath。
298
+ */
299
+ declare function listStories(pkg: Package, opts?: ListStoriesOptions): Story[];
300
+ /**
301
+ * 取 story 根下的所有 <w:p> 元素。
302
+ *
303
+ * - body / header / footer:story root 整个子树的 w:p
304
+ * - footnote / endnote / comment:单个 sub-story root 下的 w:p(不跨 sub-story)
305
+ */
306
+ declare function getStoryParagraphs(story: Story): Element[];
307
+ /**
308
+ * 反查元素所属 story(#25)。用 `Node.contains()` 逐个比对,命中首个返回。
309
+ *
310
+ * 一个 pkg 内 stories 数量通常 <20,contains 是 ~O(depth) 的祖先遍历,整体代价
311
+ * 可忽略。找不到(元素不在任何已识别 story 的子树里)返回 null 。
312
+ */
313
+ declare function findStoryFor(pkg: Package, el: Element): Story | null;
314
+ /**
315
+ * scope 枚举解析为 Story 列表(#24 / #26 共用)。
316
+ *
317
+ * - `'body'` —— 只枚举 body
318
+ * - `'all'` —— 全部 6 类 story
319
+ * - `StoryId[]` —— 精确筛选;**未命中的 id 忽略**(调用方自己负责正确性)
320
+ */
321
+ declare function resolveScope(pkg: Package, scope: 'body' | 'all' | StoryId[]): Story[];
322
+
323
+ /**
324
+ * listParagraphs —— 段落查询纯工具(docs/03 §9 / docs/03.1 §1.6,#24)。
325
+ *
326
+ * 职责:按 scope / filter / textFormat / pagination 返回 ParagraphInfo 列表。
327
+ *
328
+ * 架构:**纯函数**,拿 pkg 给结果,不知道文档尺寸、不做智能默认。"默认分页"
329
+ * 是 `{ mode: 'byCount', pageSize: 25, pageIndex: 0 }`,要全量请显式传
330
+ * `{ pagination: { mode: 'all' } }`(2026-04-22 从早期"≤500 段自动 all"的智能
331
+ * 默认撤回;见 docs/03 §9.2 的历史说明)。
332
+ *
333
+ * 实现约束:
334
+ * - 段落枚举走 `getStoryParagraphs`(基于 `getElementsByTagNameNS`),**不**用
335
+ * fontoxpath。10 万段落上 `//w:p` 慢 460× —— CI 的 `pnpm check:xpath` 会在
336
+ * 源码里扫到此类无谓词 XPath 即失败。
337
+ * - `filter.contains` 是 O(N) 子串匹配,大档慢(docs 已标注)。
338
+ * - `hasComments` / `hasRevisions` / `hasBookmarks` 用 `el.getElementsByTagNameNS(...).length > 0`
339
+ * 检测段内是否存在对应标记元素,不递归手遍。
340
+ */
341
+
342
+ /** list scope —— 'body' / 'all' 或显式 StoryId 列表 */
343
+ type ListParagraphsScope = 'body' | 'all' | StoryId[];
344
+ /** text 返回格式。'preview' = 首 100 字 */
345
+ type ListParagraphsTextFormat = 'full' | 'preview';
346
+ interface ListParagraphsFilter {
347
+ /** 等值匹配 `<w:pPr>/<w:pStyle w:val>` */
348
+ styleId?: string;
349
+ /** **O(N) 子串匹配**,区分大小写。大档谨慎使用。 */
350
+ contains?: string;
351
+ /** 段内是否含 comment 标记(commentRangeStart / commentReference / commentRangeEnd) */
352
+ hasComments?: boolean;
353
+ /** 段内是否含 revision 标记(Tier 1 只看 w:ins / w:del,不含 rPrChange/pPrChange) */
354
+ hasRevisions?: boolean;
355
+ /**
356
+ * 排除位于表格单元格(`<w:tc>`)内的段落。
357
+ *
358
+ * 表格内容由独立的 tables phase 处理,段落 phase 只关心主文本流段落。
359
+ * 开启后会对每个段落向上遍历祖先链(深度通常 ≤5),找到 `<w:tc>` 即排除。
360
+ */
361
+ excludeTableCells?: boolean;
362
+ }
363
+ type ListParagraphsPagination = {
364
+ mode: 'all';
365
+ } | {
366
+ mode: 'byCount';
367
+ pageSize: number;
368
+ pageIndex: number;
369
+ } | {
370
+ mode: 'byChar';
371
+ charPerPage: number;
372
+ pageIndex: number;
373
+ };
374
+ /**
375
+ * 段落直接格式属性(#182)。
376
+ *
377
+ * 仅包含在 `<w:pPr>` 上**直接设置**的值,不做样式继承计算。
378
+ * 消费方(如骨架化引擎)可将这些值与 styleId 组合为聚类 key,
379
+ * 区分同一样式但有手工格式覆盖的段落。
380
+ *
381
+ * 所有字段均为可选——未直接设置的属性不出现在结果中(继承自样式或默认值)。
382
+ */
383
+ interface ParagraphFormat {
384
+ /**
385
+ * 水平对齐(`w:pPr/w:jc@w:val`)。
386
+ * `'both'` 对应 OOXML 的 "both"(两端对齐)。
387
+ */
388
+ alignment?: 'left' | 'center' | 'right' | 'both' | 'distribute';
389
+ /**
390
+ * 缩进(`w:pPr/w:ind`),单位 twips(1/20 磅)。
391
+ * `firstLine` 正值为首行缩进,负值为悬挂缩进(来自 `w:hanging`)。
392
+ */
393
+ indent?: {
394
+ left?: number;
395
+ right?: number;
396
+ /** 首行缩进(正)或悬挂缩进(负,源自 `w:hanging`) */
397
+ firstLine?: number;
398
+ };
399
+ /**
400
+ * 段间距(`w:pPr/w:spacing`),单位 twips(line 例外:受 lineRule 影响)。
401
+ */
402
+ spacing?: {
403
+ before?: number;
404
+ after?: number;
405
+ line?: number;
406
+ lineRule?: 'auto' | 'exact' | 'atLeast';
407
+ };
408
+ /**
409
+ * 段落级默认字体大小(`w:pPr/w:rPr/w:sz@w:val ÷ 2`),单位磅。
410
+ * 仅当段落属性中显式设置了 `w:rPr/w:sz` 时有值;继承自样式的字号不在此字段。
411
+ */
412
+ fontSize?: number;
413
+ /**
414
+ * 段落级默认粗体(`w:pPr/w:rPr/w:b`)。
415
+ * `true` = 显式开启;`false` = 显式关闭(`w:val="0"`);
416
+ * 字段不存在 = 未直接设置(继承自样式)。
417
+ */
418
+ bold?: boolean;
419
+ /**
420
+ * 大纲级别(`w:pPr/w:outlineLvl@w:val`),0–8 对应标题 1–9,9 表示正文。
421
+ * WPS / Word 的自定义标题样式通常在此字段直接编码级别,即使 basedOn 是 Normal。
422
+ * 字段不存在 = 未在段落级直接设置(继承自样式或默认值)。
423
+ */
424
+ outlineLevel?: number;
425
+ /**
426
+ * 段落是否直接挂有编号属性(`w:pPr/w:numPr` 存在且含 `w:numId@w:val != "0"`)。
427
+ * 用于列表检测:有编号属性的段落通常是列表项。
428
+ */
429
+ hasNumbering?: boolean;
430
+ /**
431
+ * 段落是否强制从新页起始(`w:pPr/w:pageBreakBefore`,#211)。
432
+ * true = 渲染该段时从新页开始(封面段的强信号之一)。
433
+ * 字段不存在 = 未在段落级直接设置(继承自样式或默认 false)。
434
+ */
435
+ pageBreakBefore?: boolean;
436
+ /**
437
+ * 段落是否承载节属性(`w:pPr/w:sectPr` 存在,#211)。
438
+ * true = 该段是其所属节的最后一段,节边界在此结束。
439
+ * 与 doc.sections.list() 的 lastParaId 字段对应。
440
+ */
441
+ hasSectionBreak?: boolean;
442
+ /**
443
+ * 段落内是否含手工分页符(`w:r/w:br[@w:type="page"]`,#211)。
444
+ * 与 pageBreakBefore 互补 —— 后者作用于段首,前者可出现在段中/段尾。
445
+ * 字段不存在 = 段内无手工分页符。
446
+ */
447
+ hasManualPageBreak?: boolean;
448
+ /**
449
+ * 段落级默认字体颜色(`w:pPr/w:rPr/w:color@w:val`,task-20260615-redhead-fingerprint)。
450
+ * 段标 run 颜色,作用于无独立 rPr 的 run。值为 6 位十六进制 `RRGGBB`(如 `FF0000`)或 `auto`。
451
+ * 仅当段落属性中显式设置了 `w:pPr/w:rPr/w:color` 时有值;继承自样式的颜色不在此字段。
452
+ *
453
+ * 用途(骨架化 / 排版的视觉簇判据):判定"封面式文头"等需区分色异段(如红头)。
454
+ * 注意:行内首 run 的颜色单独由 {@link firstRunColor} 提供——很多文档把红色编码在 run 级
455
+ * 而非段标级,两者互补使用。
456
+ */
457
+ color?: string;
458
+ /**
459
+ * 段落**首个**直属 run(`w:r/w:rPr/w:color@w:val`)的字体颜色(task-20260615-redhead-fingerprint)。
460
+ * 值为 6 位十六进制 `RRGGBB` 或 `auto`。仅当首个直属 run 显式设了 `w:color` 时有值。
461
+ *
462
+ * 与 {@link color}(段标级)互补:红头/标题等视觉显著段的颜色常落在 run 级 rPr 而非段标 rPr,
463
+ * 需读首 run 才能拿到。取**首个直属 run**(非表格/文本框下钻),与 getParagraphText 的直属 run
464
+ * 语义对齐;段内多 run 颜色不一致时只反映首 run(满足"段首视觉身份"判据,不做整段聚合)。
465
+ */
466
+ firstRunColor?: string;
467
+ }
468
+ interface ListParagraphsOptions {
469
+ /** 默认 'body' */
470
+ scope?: ListParagraphsScope;
471
+ filter?: ListParagraphsFilter;
472
+ /** 默认 'full' */
473
+ textFormat?: ListParagraphsTextFormat;
474
+ /** 默认 `{ mode: 'byCount', pageSize: 25, pageIndex: 0 }`(不再有"智能默认") */
475
+ pagination?: ListParagraphsPagination;
476
+ /**
477
+ * 是否在结果中包含段落直接格式属性(`ParagraphFormat`)。
478
+ * 默认 `false`。开启后每个 `ParagraphInfo.format` 会携带从 `<w:pPr>` 读取的直接设置值。
479
+ * 仅包含直接设置的属性,不做样式继承计算。
480
+ */
481
+ includeFormat?: boolean;
482
+ /**
483
+ * 启用结构空白保真读(task-20260623-core-tab-faithful-read)。
484
+ * `true` 时 `ParagraphInfo.text` 含 `\t`(制表符)和 `\n`(软换行),
485
+ * 是 `appendSegmentsToRun` 的精确逆运算。
486
+ * 默认 `false`:只拼 `<w:t>`,偏移算术安全(与历史行为完全一致)。
487
+ */
488
+ structuralWhitespace?: boolean;
489
+ /**
490
+ * 是否在结果中包含段落所在表格的坐标信息(task-20260625-para-table-info)。
491
+ * 默认 `false`。
492
+ *
493
+ * 开启后,位于表格单元格内的段落会携带 `ParagraphInfo.table`(tableId / row / col)。
494
+ * 表格外段落的 `table` 字段不出现。
495
+ *
496
+ * 与 `includeFormat` 是独立开关:表格归属是结构信息,不是格式。
497
+ * 开启时会对每个段落做一次祖先链遍历(深度 ≤ 5),
498
+ * 并在首次调用时构建 `<w:tbl> Element → tableId` 反查映射(O(表格数))。
499
+ */
500
+ includeTableInfo?: boolean;
501
+ }
502
+ interface ParagraphInfo {
503
+ paraId: string;
504
+ story: StoryId;
505
+ /** textFormat='preview' 时为首 100 字 */
506
+ text: string;
507
+ /** preview 模式被截断时为 true;full 模式/未截断不给 */
508
+ truncated?: boolean;
509
+ /** `<w:pStyle w:val>` 未设则缺 */
510
+ styleId?: string;
511
+ hasRevisions?: boolean;
512
+ hasComments?: boolean;
513
+ hasBookmarks?: boolean;
514
+ /**
515
+ * 段落子树是否含 OMML 公式对象(`<m:oMath>`,math namespace)。
516
+ * Word「插入→公式」生成的公式对象。纯文字写的"公式"(如 "F=ma")不算。
517
+ * 含则为 true;不含时不给(与 hasComments 等同风格)。
518
+ */
519
+ hasMath?: boolean;
520
+ /**
521
+ * 段落直接格式属性。仅在 `listParagraphs` 传入 `includeFormat: true` 时存在。
522
+ * 不包含从样式继承的属性值。
523
+ */
524
+ format?: ParagraphFormat;
525
+ /**
526
+ * 段落所在表格坐标。仅当 `includeTableInfo=true` 且段落位于表格单元格内时存在。
527
+ *
528
+ * - `tableId`:与 `doc.tables.list()` / `getTable()` 使用的 id 完全一致(装载期
529
+ * `buildIndices` 分配的 `tbl-NNNN`)。
530
+ * - `row`:所在 `<w:tr>` 在该表中的 0 基行号。
531
+ * - `col`:所在 `<w:tc>` 在该行中的 0 基列号(物理序号)。
532
+ *
533
+ * 注:`col` 是物理 `<w:tc>` 序号,**不**做 gridSpan / vMerge 的逻辑列号校正——
534
+ * 含合并单元格的表格中,物理序号与逻辑列号可能不同。v1 取物理序号已能满足
535
+ * "区分表格内/外编号序列"的主场景;如需精确逻辑列号,可在 v2 补充。
536
+ *
537
+ * 嵌套表格时报**最内层**的表格。
538
+ */
539
+ table?: {
540
+ tableId: string;
541
+ row: number;
542
+ col: number;
543
+ };
544
+ }
545
+ interface ListResult {
546
+ paragraphs: ParagraphInfo[];
547
+ pagination: {
548
+ mode: 'all' | 'byCount' | 'byChar';
549
+ pageIndex: number;
550
+ totalPages: number;
551
+ totalParagraphs: number;
552
+ hasNext: boolean;
553
+ /**
554
+ * 保留字段,当前实现恒不填(#24 把"≤500 段自动 all"的智能默认撤回,改为恒定
555
+ * byCount(25,0)默认;docs/03 §9.2)。调用方不应依赖。
556
+ */
557
+ autoPaginated?: boolean;
558
+ };
559
+ }
560
+ /** 默认分页:首页、25 条 */
561
+ declare const DEFAULT_PAGINATION: ListParagraphsPagination;
562
+ /** preview 截断字数 */
563
+ declare const PREVIEW_CHAR_LIMIT = 100;
564
+ declare function listParagraphs(pkg: Package, opts?: ListParagraphsOptions): ListResult;
565
+ /**
566
+ * 按 paraId 精确取段。走 paraIdx → O(1) 命中后反查 story。不存在或所属 story 识别
567
+ * 不出(理论上只在 pkg 与 indices 脱钩时发生)返回 null。
568
+ *
569
+ * 总是返回 full 文本(无 textFormat/preview 选项,与 docs/03.1 §2 的签名一致)。
570
+ */
571
+ declare function getParagraphByParaId(pkg: Package, indices: PackageIndices, paraId: string): ParagraphInfo | null;
572
+ /**
573
+ * 从单个 `<w:p>` Element 构建 ParagraphInfo。
574
+ *
575
+ * 在 listParagraphs 内部给每个命中段落调用;**也供 `getParagraph`(#25)复用** ——
576
+ * 它通过 paraIdx 拿到 Element 后,用 `findStoryFor` 找到 story,再调这里组装。
577
+ */
578
+ declare function buildParagraphInfo(story: StoryId, p: Element, textFormat?: ListParagraphsTextFormat, includeFormat?: boolean, runTextOpts?: RunTextOptions): ParagraphInfo;
579
+
580
+ /**
581
+ * Comment 只读查询(docs/03.1 §1.5 / §2,#26)。
582
+ *
583
+ * 批注由两部分组成:
584
+ * - **主体**(`<w:comment>` in comments.xml):id / author / date / 批注正文
585
+ * - **锚点**(`<w:commentRangeStart>` / `<w:commentRangeEnd>` / `<w:commentReference>`
586
+ * in body / headers / footers 等):标识被批注的范围
587
+ *
588
+ * `PackageIndices.commentIdx` 已在装载期把两边按 `w:id`(数字)串联。这里做:
589
+ * - 读主体拿 author / date / text
590
+ * - 用锚点 start / end 判 rangeKind(复用 [range-kind.ts](./range-kind.ts) 的
591
+ * `classifyRange`)
592
+ * - 由 start 元素反查 story(`findStoryFor`)
593
+ *
594
+ * 跟 bookmark 的字段差异:
595
+ * - BookmarkInfo 的 `text` 字段 → CommentInfo 的 `anchorText` 字段(语义更明确)
596
+ * - 没有 `hidden` 概念
597
+ */
598
+
599
+ type CommentId = number;
600
+ interface CommentInfo {
601
+ id: CommentId;
602
+ /** w:author,缺则 '' */
603
+ author: string;
604
+ /** w:date(ISO 8601);缺则 '' */
605
+ date: string;
606
+ /** 批注正文:`<w:comment>` 内所有 `<w:t>` 拼接 */
607
+ text: string;
608
+ rangeKind: 'paragraph' | 'text' | 'complex';
609
+ /** rangeKind = 'paragraph' | 'text' 时给(批注锚定的段落 paraId) */
610
+ paraId?: string;
611
+ /** rangeKind = 'text' 时给(start/end 之间的正文片段) */
612
+ anchorText?: string;
613
+ }
614
+ /**
615
+ * 枚举所有批注。
616
+ *
617
+ * 顺序按 `commentIdx` 的迭代序(Map 插入序;装载期按 part 遍历 + w:id 升序扫到)。
618
+ *
619
+ * 主体缺失(`entry.comment === null`)或锚点无 start/end 的批注 **被跳过** ——
620
+ * 调用方看到的永远是"主体 + 至少一个锚点"都有的条目。
621
+ */
622
+ declare function listComments(indices: PackageIndices): CommentInfo[];
623
+ /** 按 id 取单条批注。不存在或主体缺失返回 null */
624
+ declare function getComment(indices: PackageIndices, id: CommentId): CommentInfo | null;
625
+
626
+ /**
627
+ * Revision(修订)只读查询(docs/03.1 §1.5 / §2,#26 + #33)。
628
+ *
629
+ * **Tier 1 覆盖面**:只看 `<w:ins>` / `<w:del>` —— 这是 run 级的插入/删除修订,
630
+ * 承载 w:id / w:author / w:date 属性,以及子树内的 `<w:t>`(ins)/ `<w:delText>`(del)
631
+ * 作为涉及文本。
632
+ *
633
+ * **Tier 2 属性级修订**(#33 起显式拒绝):
634
+ * - `<w:rPrChange>`(run 属性变更,在 `<w:rPr>` 里)
635
+ * - `<w:pPrChange>`(段落属性变更,在 `<w:pPr>` 里)
636
+ * - `<w:sectPrChange>` / `<w:tblPrChange>` / `<w:trPrChange>` / `<w:tcPrChange>` 等
637
+ * - `<w:numberingChange>` / `<w:moveFrom>` / `<w:moveTo>` 等
638
+ *
639
+ * 扫到任一 Tier 2 元素即抛 `UNSUPPORTED_OOXML_FEATURE`(`listRevisions` 与
640
+ * `acceptRevisions` / `rejectRevisions` 共用此守护,保证读写一致)。
641
+ *
642
+ * scope 控制枚举的 story 集合(与 `listParagraphs` 共用 `resolveScope`)。
643
+ */
644
+
645
+ type RevisionId = string;
646
+ interface RevisionInfo {
647
+ revId: RevisionId;
648
+ kind: 'insert' | 'delete';
649
+ author: string;
650
+ date: string;
651
+ story: StoryId;
652
+ /** 修订归属的段落(若 ins/del 嵌在 `<w:p>` 里才有;极少数嵌在 `<w:body>` 直子层位的则缺) */
653
+ paraId?: string;
654
+ /** 涉及的文本(ins:全部 `<w:t>` 拼接;del:全部 `<w:delText>` 拼接)。为空串时省略 */
655
+ text?: string;
656
+ }
657
+ interface ListRevisionsOptions {
658
+ /** 默认 'body' */
659
+ scope?: 'body' | 'all' | StoryId[];
660
+ }
661
+ declare function listRevisions(pkg: Package, opts?: ListRevisionsOptions): RevisionInfo[];
662
+
663
+ /**
664
+ * Section(节)查询(#211 / docs/03.1 §2)。
665
+ *
666
+ * 节边界由"承载 `<w:sectPr>` 的段"标定:
667
+ * - 主 body 的最后一个 `<w:sectPr>` 是 body 直接子元素(不属于任何段),是最后一节
668
+ * - 其余节的 sectPr 嵌在 `<w:p>/<w:pPr>/<w:sectPr>`,该段是节的最后一段
669
+ *
670
+ * 算法:遍历 body 直属节点(doc-order),收集 `<w:p>`,遇含 sectPr 的段闭合一节
671
+ * (lastParaId = 该段 paraId);body 末尾的散 sectPr 闭合最后一节。
672
+ *
673
+ * 节信息字段(消费方主要诉求来自 skeleton #195 封面检测):
674
+ * - sectionIndex / firstParaId / lastParaId:边界
675
+ * - type:'nextPage' / 'continuous' / 'evenPage' / 'oddPage' / 'nextColumn'(缺省 = nextPage,OOXML 默认)
676
+ * - headerRefs / footerRefs:resolve 到 partName,跨节比对页眉页脚是否相同
677
+ * - titlePage:'首页不同' 设置(封面强信号)
678
+ */
679
+
680
+ type SectionType = 'nextPage' | 'continuous' | 'evenPage' | 'oddPage' | 'nextColumn';
681
+ type HeaderFooterType = 'default' | 'first' | 'even';
682
+ interface HeaderFooterRef {
683
+ type: HeaderFooterType;
684
+ /** rels 目标 part 路径(如 'word/header1.xml') */
685
+ partName: string;
686
+ }
687
+ interface SectionInfo {
688
+ sectionIndex: number;
689
+ firstParaId: string;
690
+ /** 节末段的 paraId(承载 sectPr 的段;最后一节为 body 末尾散 sectPr 时回退到 body 最后段)*/
691
+ lastParaId: string;
692
+ type?: SectionType;
693
+ headerRefs?: HeaderFooterRef[];
694
+ footerRefs?: HeaderFooterRef[];
695
+ /** w:sectPr/w:titlePg 存在 = 首页不同(封面强信号)*/
696
+ titlePage?: boolean;
697
+ }
698
+ declare function listSections(pkg: Package): SectionInfo[];
699
+
700
+ /**
701
+ * 表格枚举与结构分析(#185)
702
+ *
703
+ * 为骨架化 M2 阶段(表格分类/取样/域化)提供表格数据。
704
+ *
705
+ * 设计原则:
706
+ * - 只走 getElementsByTagNameNS,禁用 XPath(性能约束,同 list-paragraphs.ts)
707
+ * - tableId 由 buildIndices 在装载期分配(tbl-0001 起),存入 tblIdx
708
+ * - 默认只枚举主文档 body(scope: 'body'),不含嵌套表格(includeNested: false)
709
+ * - 前后邻段落(prevParaId / nextParaId)只取紧邻兄弟 <w:p>,供题注绑定(#193)
710
+ */
711
+
712
+ /**
713
+ * 行高(对照 columnWidths)。w:tr/w:trPr/w:trHeight。
714
+ *
715
+ * 空行塌缩正是 hRule+val 没带过去所致,两者必须一起读/写。
716
+ */
717
+ interface RowHeight {
718
+ /** w:trHeight/@w:val,行高 twips(1 twip = 1/20 磅)*/
719
+ val: number;
720
+ /** w:trHeight/@w:hRule:auto(默认,最小高度) / atLeast(至少) / exact(精确)。
721
+ * 缺省(无 hRule 属性)按 OOXML 默认 'auto'。*/
722
+ hRule: 'auto' | 'atLeast' | 'exact';
723
+ }
724
+ /**
725
+ * 单个物理 <w:tc> 的 span 信息,携带文本与合并状态。
726
+ * cellGrid[i][j] 对应第 i 行第 j 个物理 <w:tc>。
727
+ */
728
+ interface TableCellInfo {
729
+ /** 单元格纯文本(多段以 \n 连接),与 cells[i][j] 完全一致 */
730
+ text: string;
731
+ /** 水平合并跨列数(<w:gridSpan w:val>,无则默认 1) */
732
+ gridSpan: number;
733
+ /**
734
+ * 垂直合并状态:
735
+ * 'restart' = 纵向合并的起始格(<w:vMerge w:val="restart"/>)
736
+ * 'continue' = 被并入上方格的续行占位格(<w:vMerge/> 无 val 或 val="continue")
737
+ * null = 无纵向合并
738
+ */
739
+ vMerge: 'restart' | 'continue' | null;
740
+ /** Direct cell width from w:tcPr/w:tcW, in twips. */
741
+ width?: number;
742
+ /** Direct cell shading from w:tcPr/w:shd. */
743
+ shading?: {
744
+ fill?: string;
745
+ color?: string;
746
+ val?: string;
747
+ };
748
+ /** Direct vertical alignment from w:tcPr/w:vAlign. */
749
+ verticalAlignment?: 'top' | 'center' | 'bottom' | 'both';
750
+ /**
751
+ * 单元格首段(首个直属 `<w:p>`)的 paraId(w14:paraId)。无首段或首段缺 paraId 时 undefined。
752
+ *
753
+ * 用途(task-bug2-cell-image,决策点 C):merge 重建表后要往**正确 cell** 插单元格图,
754
+ * 而 clone 出来的表 cell 段 paraId 是 cloneTableAfter 重分配的新值——调用方拿不到。
755
+ * 暴露 firstParaId 后,调用方对 clone 表再 `tables.list({includeCellTexts:true})` 即可拿到
756
+ * 每个 cell 首段 paraId,用 `plan.insertImageAfter(firstParaId)` 把图插进该 cell(insertImageAfter
757
+ * 在 anchor 的 parentNode 内插段——anchor 在 `<w:tc>` 里,新图段就落在该 cell 内)。
758
+ *
759
+ * 与 replaceTableCellText 无冲突:后者只动 cell **首段**的 run,插在首段之后的独立图段不受影响。
760
+ */
761
+ firstParaId?: string;
762
+ /**
763
+ * Direct paragraph ids in this cell, in cell content order.
764
+ *
765
+ * Nested table paragraphs are not included.
766
+ */
767
+ paragraphIds: string[];
768
+ /**
769
+ * Direct content blocks in this cell, in OOXML child-node order.
770
+ *
771
+ * Paragraph drawings are emitted as drawing blocks as well, so callers can
772
+ * preserve flows such as text paragraphs, then an image, then more text.
773
+ */
774
+ blocks: TableCellBlockInfo[];
775
+ /**
776
+ * 本单元格内直属 `<w:drawing>`(图片/形状等)的 drawingId 列表(与 drawingIdx 同 ID 空间)。
777
+ *
778
+ * 用途(task-bug2-cell-image,决策点 A1):表格单元格内的图此前在 cellGrid 这层就丢了
779
+ * (cellGrid 只搬 cell 文字),导致单元格图在 structure 抽取阶段成孤儿(图字节在 word/media
780
+ * 但 body 无 blip 引用)。收录 drawingId 后,typeset 抽表时把 cell 图当 content 带出、merge
781
+ * 重建时用 `drawing.getImageBytes()` + `insertImageAfter(firstParaId)` 把图插回对应 cell。
782
+ *
783
+ * 收录范围:只取**本 cell 子树内、且不在嵌套表/嵌套 cell 内**的 drawing(嵌套表 cell 的图归属
784
+ * 嵌套表自己的 cellGrid,不上浮污染外层)。空(无图)时为 `[]`(与 cells 同条件填充,
785
+ * 字段恒在便于下游免判 undefined)。
786
+ */
787
+ imageDrawingIds: string[];
788
+ }
789
+ type TableCellBlockInfo = {
790
+ type: 'paragraph';
791
+ paraId: string;
792
+ text: string;
793
+ } | {
794
+ type: 'drawing';
795
+ drawingId: string;
796
+ paraId?: string;
797
+ } | {
798
+ type: 'table';
799
+ tableId: string;
800
+ };
801
+ interface TableInfo {
802
+ /** 分配的表格 ID(装载期顺序,'tbl-0001' 起),供 plan executor 引用 */
803
+ tableId: string;
804
+ /** 所在 part 路径(如 'word/document.xml')*/
805
+ partPath: string;
806
+ /** 在本次枚举结果中的顺序(1-based)*/
807
+ index: number;
808
+ /** 是否嵌套在另一个表格内(祖先链上存在 <w:tbl>)*/
809
+ isNested: boolean;
810
+ /** 行数(w:tr 直接子元素数量)*/
811
+ rowCount: number;
812
+ /** 列数(w:tblGrid/w:gridCol 数量;无 tblGrid 时为 0)*/
813
+ colCount: number;
814
+ /** 是否有合并单元格(gridSpan > 1 或存在 vMerge)*/
815
+ hasMerge: boolean;
816
+ /** 表格样式 ID(w:tblPr/w:tblStyle @w:val),未设时 undefined */
817
+ tableStyleId?: string;
818
+ /** 是否包含图片(w:drawing 元素)*/
819
+ hasImages: boolean;
820
+ /** 是否包含嵌套表格(直接子孙 <w:tbl>)*/
821
+ hasNestedTables: boolean;
822
+ /**
823
+ * 紧邻前一个兄弟 <w:p> 的 paraId,用于题注绑定(#193)。
824
+ * 仅检查紧邻兄弟:若前一个兄弟不是 <w:p>(如另一个 <w:tbl>)则为 undefined。
825
+ */
826
+ prevParaId?: string;
827
+ /**
828
+ * 紧邻后一个兄弟 <w:p> 的 paraId,用于题注绑定(#193)。
829
+ * 仅检查紧邻兄弟。
830
+ */
831
+ nextParaId?: string;
832
+ /**
833
+ * 每列的列宽(twips,来自 `<w:tblGrid>/<w:gridCol w:w="...">`)。
834
+ *
835
+ * - `columnWidths[i]` = 第 i 列的 `w:w` 值(1 twip = 1/20 磅)
836
+ * - 无 `<w:tblGrid>` 时为 `[]`(空数组)
837
+ * - `tblLayout=fixed` 的表格列宽完全由此决定;`auto` 布局表格也记录但仅供参考
838
+ * - 供 merger 套用源表列宽(task-core-table-grid:克隆模板时保真列宽)
839
+ */
840
+ columnWidths: number[];
841
+ /**
842
+ * 每行行高,doc 序,每行一个;该行无 <w:trHeight> 则为 null。
843
+ *
844
+ * - `rowHeights[i]` = 第 i 行的 w:trPr/w:trHeight val+hRule
845
+ * - 恒填(不依赖 includeCellTexts)
846
+ * - 只取直属 <w:tr>,不误抓嵌套表行
847
+ * - 供 merger 套用源表行高(空行塌缩修复)
848
+ */
849
+ rowHeights: (RowHeight | null)[];
850
+ /**
851
+ * 单元格文本网格(#186)。仅当 `includeCellTexts: true` 时填充。
852
+ *
853
+ * - `cells[i][j]` = 第 i 行第 j 列单元格的纯文本
854
+ * - 单元格内含多段时用 `\n` 连接(保留分段信号,供 has-multi-content 判定)
855
+ * - 嵌套表格内的段落不展开(不污染外层网格)
856
+ */
857
+ cells?: string[][];
858
+ /**
859
+ * 单元格网格(span-aware),仅当 `includeCellTexts: true` 时填充(与 cells 同条件)。
860
+ *
861
+ * - `cellGrid[i][j]` 对应第 i 行第 j 个**物理** `<w:tc>`,携带 gridSpan/vMerge
862
+ * - 与 cells 同源同序:`cells[i][j] === cellGrid[i][j].text`
863
+ * - 嵌套表内段落不展开(与 extractCellTexts 一致)
864
+ */
865
+ cellGrid?: TableCellInfo[][];
866
+ }
867
+ interface ListTablesOptions {
868
+ /** 枚举范围(默认 'body')*/
869
+ scope?: 'body' | 'all';
870
+ /** 是否包含嵌套在其他表格内的表格(默认 false,只返回顶层表格)*/
871
+ includeNested?: boolean;
872
+ /**
873
+ * 是否抽取单元格文本(#186)。默认 false(保持 #185 默认行为)。
874
+ *
875
+ * 开启后每张 TableInfo 会带 `cells: string[][]`,用于关键词匹配/分类。
876
+ * 性能:每张表会枚举所有 <w:tc> 及其直属 <w:p>,按需开启。
877
+ */
878
+ includeCellTexts?: boolean;
879
+ }
880
+ /**
881
+ * 枚举文档表格,按文档顺序返回(与 tblIdx 插入顺序一致)。
882
+ *
883
+ * - `scope: 'body'`(默认)—— 仅主文档 <w:body>
884
+ * - `includeNested: false`(默认)—— 跳过嵌套在其他表格内的表格
885
+ */
886
+ declare function listTables(pkg: Package, indices: PackageIndices, opts?: ListTablesOptions): TableInfo[];
887
+ /**
888
+ * 按 tableId 精确取单个表格,O(1)。不存在返回 null。
889
+ * 入参 `includeCellTexts` 与 `listTables` 同义(默认 false)。
890
+ */
891
+ declare function getTableById(pkg: Package, indices: PackageIndices, tableId: string, opts?: {
892
+ includeCellTexts?: boolean;
893
+ }): TableInfo | null;
894
+ /** 一张格内图的预解析字节(按源 <a:blip @r:embed> 原始 rId 索引)。 */
895
+ interface TableVerbatimImage {
896
+ originalRId: string;
897
+ bytes: Uint8Array;
898
+ contentType: string;
899
+ }
900
+ /** verbatim 取一张表的自包含 payload(供跨文档搬表 insertTableFrom)。 */
901
+ interface TableVerbatim {
902
+ /** `<w:tbl>` 子树序列化字符串(命名空间随子树带入)。 */
903
+ tableXml: string;
904
+ /** 表内所有格内图的预解析字节(按原 rId)。原 rId 解析不到字节的图不收(搬入时 warn 降级)。 */
905
+ images: TableVerbatimImage[];
906
+ }
907
+ /**
908
+ * 按 tableId verbatim 取一张表的 OOXML 子树 + 其格内图字节,打包成自包含 payload。
909
+ *
910
+ * 这是"数据表 = 内容块"(§13.9)的**源侧读取**:调用方(typeset)拿到此 payload 后用
911
+ * `plan.insertTableFrom(...)` 把整表 verbatim 搬进输出文档(与图片 getImageBytes→insertImageAfter
912
+ * 同构)。表的行/列/值/合并/嵌套/格内图全保真——这里只做读取 + 序列化 + 解析格内图字节,
913
+ * **不裁剪、不重建**。
914
+ *
915
+ * tableId 不存在 → 返回 null。
916
+ */
917
+ declare function getTableVerbatim(pkg: Package, indices: PackageIndices, tableId: string): TableVerbatim | null;
918
+
919
+ /**
920
+ * Drawing 对象枚举(#189)
921
+ *
922
+ * 为骨架化 M3 阶段(图片分类/Shape 分类/占位图替换)提供 drawing 数据。
923
+ *
924
+ * 边界(实施前澄清,见 #189 评论):
925
+ * - **本模块只做"枚举 + 形态信号"**,不下 A / B / C 业务分类结论
926
+ * - C 类细分(水印 / 装饰线 / 背景图)需语义判断,属于 #191
927
+ * - 分组键计算、代表样本选取属于 #191 / #192
928
+ * - 占位图替换属于 #190
929
+ *
930
+ * 设计原则(对齐 #185 list-tables.ts):
931
+ * - 只走 getElementsByTagNameNS / 直接子节点遍历,禁用 XPath(性能约束)
932
+ * - drawingId 由 buildIndices 装载期分配('dr-0001' 起),存入 drawingIdx
933
+ * - 默认枚举主文档 body(scope: 'body')
934
+ * - 提供 isInHeaderFooter 字段,让 #191 直接识别 C 类页眉页脚 logo(无需自己查 part 路径)
935
+ */
936
+
937
+ /** 锚定方式:inline(行内嵌入)/ anchor(浮动定位)*/
938
+ type DrawingAnchoringMode = 'inline' | 'anchor';
939
+ /**
940
+ * Drawing 内容形态(**OOXML 子树类型**,非 A/B/C 业务分类)。
941
+ *
942
+ * 识别优先级:a:graphicData @uri → 命中预设 URI 之一时按表分发;都不命中时落 'other'。
943
+ * 'textBox' 是 'shape' 的特化(wps:wsp 内含 w:txbxContent),单独抽出便于 #192 处理。
944
+ *
945
+ * | kind | URI 或子元素信号 | 典型场景 |
946
+ * |----------|---------------------------------------------------------------------------|----------|
947
+ * | picture | uri = .../picture | 嵌入/浮动图片 |
948
+ * | chart | uri = .../chart | Word 原生图表 |
949
+ * | smartArt | uri = .../diagram | SmartArt(1.0/2010+)|
950
+ * | shape | uri = .../wordprocessingShape,且 **无** w:txbxContent | 形状(无文字) |
951
+ * | textBox | uri = .../wordprocessingShape,且 **有** w:txbxContent | 文本框 / 标注 |
952
+ * | group | uri = .../wordprocessingGroup | 形状组合 |
953
+ * | canvas | uri = .../wordprocessingCanvas | 绘图画布 |
954
+ * | other | 都不命中 | 未来扩展占位 |
955
+ */
956
+ type DrawingKind = 'picture' | 'chart' | 'smartArt' | 'shape' | 'textBox' | 'group' | 'canvas' | 'other';
957
+ type TextBoxBlockInfo = {
958
+ type: 'paragraph';
959
+ paraId: string;
960
+ text: string;
961
+ } | {
962
+ type: 'drawing';
963
+ drawingId: string;
964
+ paraId?: string;
965
+ } | {
966
+ type: 'table';
967
+ tableId: string;
968
+ };
969
+ /**
970
+ * 文字环绕方式(仅 anchor 有)。
971
+ *
972
+ * - none:wp:wrapNone(不环绕;配合 behindDoc 形成"衬于文字下方/上方")
973
+ * - square:wp:wrapSquare(四周型 / 矩形环绕)
974
+ * - tight:wp:wrapTight(紧密型)
975
+ * - through:wp:wrapThrough(穿越型)
976
+ * - topAndBottom:wp:wrapTopAndBottom(上下型)
977
+ * - behind:wp:wrapNone + behindDoc="1"(衬于文字下方)
978
+ * - inFront:wp:wrapNone + behindDoc="0"(浮于文字上方)
979
+ */
980
+ type DrawingWrapType = 'none' | 'square' | 'tight' | 'through' | 'topAndBottom' | 'behind' | 'inFront';
981
+ /** 浮动定位的单方向描述(原值透传,由 #191 自行二次解释)*/
982
+ interface DrawingPositionAxis {
983
+ /** wp:positionH/V @relativeFrom 原值(如 'page' / 'margin' / 'column' / 'character' / 'paragraph' / 'line')*/
984
+ relativeFrom?: string;
985
+ /** wp:posOffset 文本内容(EMU 整数)。和 align 二选一。*/
986
+ posOffset?: number;
987
+ /** wp:align 文本内容('left' / 'center' / 'right' / 'top' / 'bottom' / 'inside' / 'outside')。和 posOffset 二选一。*/
988
+ align?: string;
989
+ }
990
+ /** 浮动位置(仅 anchor 有)*/
991
+ interface DrawingPosition {
992
+ horizontal?: DrawingPositionAxis;
993
+ vertical?: DrawingPositionAxis;
994
+ }
995
+ interface DrawingInfo {
996
+ /** 装载期分配的 ID('dr-NNNN',从 0001 起),供 #190 / #191 / #192 引用 */
997
+ drawingId: string;
998
+ /** 所在 part 路径('word/document.xml' / 'word/header1.xml' 等)*/
999
+ partPath: string;
1000
+ /** 枚举结果顺序(1-based,与文档顺序一致)*/
1001
+ index: number;
1002
+ /** 锚定方式:inline 行内嵌入 / anchor 浮动定位 */
1003
+ anchoringMode: DrawingAnchoringMode;
1004
+ /** 内容形态(OOXML 层级,非业务分类)*/
1005
+ kind: DrawingKind;
1006
+ /**
1007
+ * 显示尺寸(EMU;1 inch = 914400 EMU)。
1008
+ * 来源:wp:extent @cx @cy。
1009
+ * 未声明或解析失败时为 { cx: 0, cy: 0 }(保持字段必存在,避免下游需要判 undefined)。
1010
+ */
1011
+ extentEMU: {
1012
+ cx: number;
1013
+ cy: number;
1014
+ };
1015
+ /** 文字环绕方式(仅 anchor,inline 不含此字段)*/
1016
+ wrap?: DrawingWrapType;
1017
+ /** 浮动位置(仅 anchor,inline 不含此字段)*/
1018
+ position?: DrawingPosition;
1019
+ /**
1020
+ * 承载此 drawing 的段落 paraId(w:p @w14:paraId)。
1021
+ *
1022
+ * 多数情况下,drawing 挂在 w:r 下、该 w:r 属于某个 w:p,本字段就是这个 w:p 的 paraId。
1023
+ *
1024
+ * **关键例外(CR 设计说明)**:嵌套在 **TextBox 内**(即位于 `w:txbxContent` 子树)
1025
+ * 的 drawing,本字段为 `undefined`。这是**主动设计**:textBox 内段落与外层段落是两套
1026
+ * 独立的段落流,把外层段落 paraId 挂给文本框内 drawing 会让"删段落 → 顺带删图"等
1027
+ * 操作误伤外层段落。下游需要文本框内图片的段落引用时,应:
1028
+ * 1. 用 `runIndex === undefined && anchorParaId === undefined` 识别该情形
1029
+ * 2. 自行向上找最近的 `w:txbxContent`,再用其外层 anchor 段落定位
1030
+ *
1031
+ * 缺 paraId 时也为 undefined(合法但少见;由 ensureParaIds 在装载期补齐,但本字段
1032
+ * 不依赖这一保证)。
1033
+ */
1034
+ anchorParaId?: string;
1035
+ /**
1036
+ * 在所在段落里的 run 序号(0-based,承载 drawing 的 w:r 在父 w:p 直接子 w:r 中的位置)。
1037
+ * 同段多 drawing 时用于区分;用于题注绑定(#193)/ 占位图替换(#190)的精确引用。
1038
+ */
1039
+ runIndex?: number;
1040
+ /**
1041
+ * 是否位于页眉页脚 part(contentType 以 .header+xml / .footer+xml 结尾)。
1042
+ *
1043
+ * 这是**形态信号**,不是 C 类结论。#191 在做 A/B/C 业务分类时:
1044
+ * - true + kind = picture → 大概率 C 类页眉页脚 logo,由 .dot 原生保留
1045
+ * - 其余情况由 #191 自行判断
1046
+ */
1047
+ isInHeaderFooter: boolean;
1048
+ /**
1049
+ * 形态信号:是否含 pic:pic 子树(A 类正向信号)。
1050
+ * - kind = 'picture' 时必为 true
1051
+ * - 理论上 chart/shape 也可能套 pic:pic,此时 kind 不变但本字段为 true
1052
+ */
1053
+ hasPicReference: boolean;
1054
+ /**
1055
+ * Shape 专属:是否为「线条 / 连接线(line / connector)」几何。仅 kind = 'shape' 时可能为 true,
1056
+ * 其余 kind(picture/chart/.../textBox/group/canvas/other)一律 undefined。
1057
+ *
1058
+ * **形态信号,非业务结论**。下游(skeleton #192 shape-role)用它把版记横线一类「纯几何线条」
1059
+ * 与矩形/椭圆等装饰噪声区分开:线条原样保留,其余几何仍按现状裁掉。
1060
+ *
1061
+ * 识别(命中任一即 true,从强到弱):
1062
+ * 1. DrawingML 预设几何:`<a:prstGeom prst="...">` 的 prst 命中线条/连接线预设
1063
+ * (line / straightConnector1 / bentConnectorN / curvedConnectorN,N=2..5;见 LINE_CONNECTOR_PRESETS)
1064
+ * 2. 连接线非可视属性:wps:wsp 内含 `<wps:cNvCnPr>`(connector non-visual props;
1065
+ * 普通 shape 用 wps:cNvSpPr,连接线用 wps:cNvCnPr)
1066
+ * 3. VML 回退:子树含 `<v:line>`(mc:Fallback 内的旧版降级线条)
1067
+ *
1068
+ * 母版实测(生成的公文__会议纪要.docx):版记 3 根横线均 prst="line" + wps:cNvCnPr + v:line 三信号齐全;
1069
+ * 红头艺术字文本框是 prst="rect" + wps:cNvSpPr,不命中。
1070
+ */
1071
+ isLineOrConnector?: boolean;
1072
+ /**
1073
+ * Shape / TextBox 专属:是否有边框(a:spPr/a:ln 存在且未声明 a:noFill)。
1074
+ * 非 shape/textBox 一律 undefined。
1075
+ */
1076
+ hasBorder?: boolean;
1077
+ /**
1078
+ * Shape / TextBox 专属:是否有填充(a:spPr 下含 a:solidFill / a:gradFill / a:blipFill / a:pattFill)。
1079
+ * 显式 a:noFill 视作无填充。非 shape/textBox 一律 undefined。
1080
+ */
1081
+ hasFill?: boolean;
1082
+ /**
1083
+ * TextBox 专属:是否含实质内部文字(w:txbxContent 内 w:t 文本拼接后非空)。
1084
+ * 非 textBox 一律 undefined。
1085
+ */
1086
+ hasInnerText?: boolean;
1087
+ /**
1088
+ * TextBox 专属:内部文字原文(w:txbxContent 内全部 w:t 文本按文档顺序拼接后 trim)。
1089
+ *
1090
+ * 供下游(skeleton #192 / typeset 投影)读取红头艺术字等内容型文本框的原文做语义命名/字段化
1091
+ * (如「江临市滨河区人民政府」「专题会议纪要」)。
1092
+ *
1093
+ * 语义:
1094
+ * - 仅 kind = 'textBox' 时可能有值;非 textBox 一律 undefined。
1095
+ * - trim 后为空(无文字 / 仅空白)→ undefined(与 hasInnerText=false 对应)。
1096
+ * - 多段 / 多 run 文本框按 w:t 出现顺序直接拼接,**不插入换行/空格**(保持与 hasInnerText
1097
+ * 同源的拼接口径);下游需要分段语义时应自行用 paragraphs API 处理,本字段只给原文快照。
1098
+ */
1099
+ innerText?: string;
1100
+ /**
1101
+ * TextBox 专属:文本框内容流里的段落 paraId,按文档顺序排列。
1102
+ *
1103
+ * 这些 paraId 指向 `w:txbxContent` 内部段落。调用方可通过
1104
+ * `doc.paragraphs.get(paraId)` 或 `TextBoxDrawing.getParagraphs()` 继续进行段落/文字级操作。
1105
+ * 非 textBox 一律 undefined。
1106
+ */
1107
+ innerParagraphIds?: string[];
1108
+ /**
1109
+ * TextBox 专属:文本框内容流的直接内容块,按 OOXML child-node 顺序排列。
1110
+ *
1111
+ * 目前包含 direct paragraph、paragraph 内 direct drawing,以及 direct table。
1112
+ * 非 textBox 一律 undefined。
1113
+ */
1114
+ innerBlocks?: TextBoxBlockInfo[];
1115
+ /**
1116
+ * TextBox 专属:首个内部段落的对齐(w:txbxContent 第一段 w:pPr/w:jc @val)。
1117
+ *
1118
+ * 注:文本框内可能多段且对齐不同,#192 需自行决定如何取代表值;本字段只提供首段值便于快速分组。
1119
+ * 非 textBox 或无 jc 设置一律 undefined。
1120
+ */
1121
+ innerTextAlign?: string;
1122
+ }
1123
+ interface ListDrawingsOptions {
1124
+ /**
1125
+ * 枚举范围(默认 'body')。
1126
+ * - 'body':仅主文档 body(不含页眉页脚 / 注释 / 脚注尾注)
1127
+ * - 'all':所有 stories(body + headers + footers + footnotes + endnotes + comments)
1128
+ *
1129
+ * 注意:#189 的 isInHeaderFooter 字段只在 'all' 模式下才可能为 true;
1130
+ * 'body' 模式下页眉页脚 drawing 不会被枚出。
1131
+ */
1132
+ scope?: 'body' | 'all';
1133
+ /**
1134
+ * 启用结构空白保真读(task-20260623-core-tab-faithful-read)。
1135
+ * `true` 时 TextBox 的 `innerText` 含 `\t`(制表符)和 `\n`(软换行)——
1136
+ * 是 `appendSegmentsToRun` 的精确逆运算。
1137
+ * 默认 `false`:只拼 `<w:t>`(与历史行为一致)。
1138
+ */
1139
+ structuralWhitespace?: boolean;
1140
+ }
1141
+ /** 判断 drawing 是否嵌套在另一个 drawing 内(用于 group / canvas 内子图过滤的预判)*/
1142
+ declare function hasDrawingAncestor(drawing: Element): boolean;
1143
+ /**
1144
+ * 枚举文档 drawing 对象,按文档顺序返回(与 drawingIdx 插入顺序一致)。
1145
+ *
1146
+ * - `scope: 'body'`(默认)—— 仅主文档 body 内的 drawing
1147
+ * - `scope: 'all'` —— 包含 headers / footers / footnotes / endnotes / comments
1148
+ *
1149
+ * **不做**业务分类(A/B/C)/ 分组键计算 / 代表样本选取 —— 这些属于 #191/#192。
1150
+ * 嵌套在另一个 drawing 内的子 drawing(如 group 的成员、canvas 的成员)**会被一并枚出**,
1151
+ * 由调用方按 hasDrawingAncestor 自行决定是否合并到外层(保持枚举层"完整暴露"的原则)。
1152
+ */
1153
+ declare function listDrawings(pkg: Package, indices: PackageIndices, opts?: ListDrawingsOptions): DrawingInfo[];
1154
+ /**
1155
+ * 按 drawingId 精确取单个 drawing。不存在返回 null。
1156
+ *
1157
+ * **index 字段语义**:返回 drawing 在 **全局 drawingIdx 插入顺序**中的 1-based 位置
1158
+ * —— 与 `listDrawings({ scope: 'all' })` 的 index 一致;与 `listDrawings({ scope: 'body' })`
1159
+ * 的 1-based 位置**不一定**相等(后者可能过滤掉了页眉页脚 drawing)。
1160
+ *
1161
+ * 复杂度:drawingIdx 查找 O(1);全局序号扫描 O(N),N = 包内 drawing 总数。
1162
+ * 调用方需要严格按 scope 取序号时应直接走 listDrawings。
1163
+ *
1164
+ * 旧实现复用了 list-tables.ts 的 `index: 0` 哨兵,下游用 `index` 排序/引用会拿到
1165
+ * 错误值(CR BUG-1)—— 改为真实序号。
1166
+ */
1167
+ declare function getDrawingById(pkg: Package, indices: PackageIndices, drawingId: string): DrawingInfo | null;
1168
+ /**
1169
+ * 装载期构建 drawingIdx:枚举 Package 中所有 Word 内容 part 的 <w:drawing>,
1170
+ * 按文档顺序分配 'dr-NNNN' ID。由 buildIndices 调用。
1171
+ *
1172
+ * 内部函数风格对齐 buildTableIndex(list-tables.ts)。
1173
+ */
1174
+ declare function buildDrawingIndex(parts: Iterable<{
1175
+ contentType: string;
1176
+ xmlDom?: {
1177
+ getElementsByTagNameNS(ns: string, local: string): {
1178
+ length: number;
1179
+ } & Record<number, Element>;
1180
+ };
1181
+ }>): Map<string, Element>;
1182
+
1183
+ interface ImageBytesResult {
1184
+ bytes: Uint8Array;
1185
+ contentType: string;
1186
+ extentEMU: {
1187
+ cx: number;
1188
+ cy: number;
1189
+ };
1190
+ }
1191
+ /**
1192
+ * 读取 drawingId 对应 picture 的原始图片字节。
1193
+ * drawingId 不存在 / 非 picture / media 找不到 → 返回 null(不抛)。
1194
+ */
1195
+ declare function getImageBytesSync(pkg: Package, indices: {
1196
+ drawingIdx: Map<string, Element>;
1197
+ }, drawingId: string): ImageBytesResult | null;
1198
+
1199
+ export { type TableVerbatimImage as $, A_NS as A, type BookmarkEntry as B, type CommentInfo as C, type DrawingInfo as D, type ListParagraphsScope as E, type ListParagraphsTextFormat as F, type ListStoriesOptions as G, type HeaderFooterRef as H, type ImageBytesResult as I, PIC_NS as J, PKG_NS as K, type ListParagraphsOptions as L, MC_NS as M, PREVIEW_CHAR_LIMIT as N, type ParagraphFormat as O, type PackageIndices as P, R_NS as Q, type RevisionInfo as R, type StoryId as S, type TableInfo as T, type RunTextOptions as U, type SectionType as V, type SplitResult as W, type Story as X, type StoryKind as Y, type StyleType as Z, type TableCellBlockInfo as _, type ListResult as a, VML_NS as a0, W14_NS as a1, WPC_NS as a2, WPG_NS as a3, WPS_NS as a4, WP_NS as a5, W_NS as a6, XML_NS as a7, buildDrawingIndex as a8, buildIndices as a9, buildParagraphInfo as aa, buildStylesIndex as ab, findStoryFor as ac, getComment as ad, getDrawingById as ae, getParagraphByParaId as af, getParagraphRuns as ag, getParagraphText as ah, getRunText as ai, getStoryParagraphs as aj, getStyleById as ak, getTableById as al, getTableVerbatim as am, hasDrawingAncestor as an, listComments as ao, listDrawings as ap, listParagraphs as aq, listRevisions as ar, listSections as as, listStories as at, listStyles as au, listTables as av, resolveScope as aw, splitRunAt as ax, getImageBytesSync as ay, type ParagraphInfo as b, type CommentId as c, type ListRevisionsOptions as d, type ListStylesOptions as e, type StyleInfo as f, type ListTablesOptions as g, type TableVerbatim as h, type ListDrawingsOptions as i, type SectionInfo as j, type RowHeight as k, type TableCellInfo as l, BookmarkLoadError as m, type BookmarkLoadErrorCode as n, CHART_NS as o, type CommentEntry as p, DEFAULT_PAGINATION as q, DGM_NS as r, type DrawingAnchoringMode as s, type DrawingKind as t, type DrawingPosition as u, type DrawingPositionAxis as v, type DrawingWrapType as w, type HeaderFooterType as x, type ListParagraphsFilter as y, type ListParagraphsPagination as z };