@courtifyai/docx-render 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2915 @@
1
+ var z = Object.defineProperty;
2
+ var O = (o, e, t) => e in o ? z(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
+ var g = (o, e, t) => O(o, typeof e != "symbol" ? e + "" : e, t);
4
+ import G from "jszip";
5
+ var m = /* @__PURE__ */ ((o) => (o.Document = "document", o.Paragraph = "paragraph", o.Run = "run", o.Text = "text", o.Break = "break", o.Table = "table", o.TableRow = "tableRow", o.TableCell = "tableCell", o.Hyperlink = "hyperlink", o.Drawing = "drawing", o.Image = "image", o.BookmarkStart = "bookmarkStart", o.BookmarkEnd = "bookmarkEnd", o.Comment = "comment", o.CommentRangeStart = "commentRangeStart", o.CommentRangeEnd = "commentRangeEnd", o.CommentReference = "commentReference", o.Section = "section", o.Header = "header", o.Footer = "footer", o.Tab = "tab", o.Symbol = "symbol", o.SimpleField = "simpleField", o.ComplexField = "complexField", o.FieldInstruction = "fieldInstruction", o.Footnote = "footnote", o.Endnote = "endnote", o.FootnoteReference = "footnoteReference", o.EndnoteReference = "endnoteReference", o))(m || {});
6
+ const U = {
7
+ W: "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
8
+ W14: "http://schemas.microsoft.com/office/word/2010/wordml",
9
+ W15: "http://schemas.microsoft.com/office/word/2012/wordml",
10
+ R: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
11
+ A: "http://schemas.openxmlformats.org/drawingml/2006/main",
12
+ WP: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
13
+ PIC: "http://schemas.openxmlformats.org/drawingml/2006/picture"
14
+ }, C = {
15
+ DOCUMENT: "word/document.xml",
16
+ COMMENTS: "word/comments.xml",
17
+ COMMENTS_EXTENDED: "word/commentsExtended.xml",
18
+ STYLES: "word/styles.xml",
19
+ NUMBERING: "word/numbering.xml",
20
+ THEME: "word/theme/theme1.xml",
21
+ FOOTNOTES: "word/footnotes.xml",
22
+ ENDNOTES: "word/endnotes.xml",
23
+ FONT_TABLE: "word/fontTable.xml",
24
+ FONT_TABLE_RELS: "word/_rels/fontTable.xml.rels",
25
+ RELS: "word/_rels/document.xml.rels",
26
+ CONTENT_TYPES: "[Content_Types].xml",
27
+ HEADER_PREFIX: "word/header",
28
+ FOOTER_PREFIX: "word/footer"
29
+ }, F = {
30
+ IMAGE: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
31
+ HEADER: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
32
+ FOOTER: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
33
+ FONT: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font"
34
+ };
35
+ class _ {
36
+ /**
37
+ * 获取元素的所有子元素
38
+ */
39
+ elements(e, t) {
40
+ const n = [];
41
+ for (let r = 0; r < e.childNodes.length; r++) {
42
+ const i = e.childNodes[r];
43
+ i.nodeType === Node.ELEMENT_NODE && (!t || i.localName === t) && n.push(i);
44
+ }
45
+ return n;
46
+ }
47
+ /**
48
+ * 获取第一个匹配的子元素
49
+ */
50
+ element(e, t) {
51
+ for (let n = 0; n < e.childNodes.length; n++) {
52
+ const r = e.childNodes[n];
53
+ if (r.nodeType === Node.ELEMENT_NODE && r.localName === t)
54
+ return r;
55
+ }
56
+ return null;
57
+ }
58
+ /**
59
+ * 获取元素属性值
60
+ */
61
+ attr(e, t) {
62
+ if (!e) return;
63
+ for (const r of Object.values(U)) {
64
+ const i = e.getAttributeNS(r, t);
65
+ if (i) return i;
66
+ }
67
+ const n = e.getAttribute(`w:${t}`);
68
+ return n || e.getAttribute(t) || void 0;
69
+ }
70
+ /**
71
+ * 获取布尔属性
72
+ */
73
+ boolAttr(e, t, n = !1) {
74
+ if (!e) return n;
75
+ const r = this.attr(e, t);
76
+ return r === void 0 ? n : r === "1" || r === "true" || r === "on";
77
+ }
78
+ /**
79
+ * 获取整数属性
80
+ */
81
+ intAttr(e, t) {
82
+ if (!e) return;
83
+ const n = this.attr(e, t);
84
+ if (n)
85
+ return parseInt(n, 10);
86
+ }
87
+ /**
88
+ * 获取长度属性并转换单位
89
+ */
90
+ lengthAttr(e, t, n = T.Dxa) {
91
+ if (!e) return;
92
+ const r = this.attr(e, t);
93
+ return this.convertLength(r, n);
94
+ }
95
+ /**
96
+ * 转换长度单位
97
+ */
98
+ convertLength(e, t = T.Dxa) {
99
+ return e ? /[a-z%]+$/i.test(e) ? e : `${(parseFloat(e) * t.mul).toFixed(2)}${t.unit}` : void 0;
100
+ }
101
+ /**
102
+ * 获取元素的文本内容
103
+ */
104
+ textContent(e) {
105
+ return e && e.textContent || "";
106
+ }
107
+ }
108
+ const T = {
109
+ /** 1/20 点 (twip) */
110
+ Dxa: { mul: 0.05, unit: "pt" },
111
+ /** EMU (English Metric Unit) */
112
+ Emu: { mul: 1 / 12700, unit: "pt" },
113
+ /** 半点 */
114
+ FontSize: { mul: 0.5, unit: "pt" },
115
+ /** 1/8 点 */
116
+ Border: { mul: 0.125, unit: "pt" }
117
+ };
118
+ function w(o) {
119
+ o.charCodeAt(0) === 65279 && (o = o.substring(1)), o = o.replace(/<\?xml[^?]*\?>/g, "");
120
+ const t = new DOMParser().parseFromString(o, "application/xml"), n = t.getElementsByTagName("parsererror")[0];
121
+ if (n)
122
+ throw new Error(`XML 解析错误: ${n.textContent}`);
123
+ return t;
124
+ }
125
+ const s = new _();
126
+ function j(o) {
127
+ const e = {
128
+ colorScheme: { name: "", colors: {} },
129
+ fontScheme: { name: "", majorFont: {}, minorFont: {} }
130
+ }, t = $(o, "themeElements");
131
+ if (!t) return e;
132
+ for (const n of R(t)) {
133
+ const r = n.localName;
134
+ r === "clrScheme" ? e.colorScheme = V(n) : r === "fontScheme" && (e.fontScheme = X(n));
135
+ }
136
+ return e;
137
+ }
138
+ function V(o) {
139
+ const e = {
140
+ name: o.getAttribute("name") || "",
141
+ colors: {}
142
+ };
143
+ for (const t of R(o)) {
144
+ const n = t.localName, r = W(t);
145
+ r && (e.colors[n] = r);
146
+ }
147
+ return e;
148
+ }
149
+ function W(o) {
150
+ const e = $(o, "srgbClr");
151
+ if (e) {
152
+ const n = e.getAttribute("val");
153
+ return n ? `#${n}` : null;
154
+ }
155
+ const t = $(o, "sysClr");
156
+ if (t) {
157
+ const n = t.getAttribute("lastClr");
158
+ return n ? `#${n}` : null;
159
+ }
160
+ return null;
161
+ }
162
+ function X(o) {
163
+ const e = {
164
+ name: o.getAttribute("name") || "",
165
+ majorFont: {},
166
+ minorFont: {}
167
+ };
168
+ for (const t of R(o)) {
169
+ const n = t.localName;
170
+ n === "majorFont" ? e.majorFont = I(t) : n === "minorFont" && (e.minorFont = I(t));
171
+ }
172
+ return e;
173
+ }
174
+ function I(o) {
175
+ const e = {};
176
+ for (const t of R(o)) {
177
+ const n = t.localName, r = t.getAttribute("typeface");
178
+ r && (n === "latin" ? e.latin = r : n === "ea" ? e.ea = r : n === "cs" && (e.cs = r));
179
+ }
180
+ return e;
181
+ }
182
+ function $(o, e) {
183
+ for (let t = 0; t < o.childNodes.length; t++) {
184
+ const n = o.childNodes[t];
185
+ if (n.nodeType === Node.ELEMENT_NODE) {
186
+ const r = n;
187
+ if (r.localName === e)
188
+ return r;
189
+ }
190
+ }
191
+ return null;
192
+ }
193
+ function R(o) {
194
+ const e = [];
195
+ for (let t = 0; t < o.childNodes.length; t++) {
196
+ const n = o.childNodes[t];
197
+ n.nodeType === Node.ELEMENT_NODE && e.push(n);
198
+ }
199
+ return e;
200
+ }
201
+ const q = {
202
+ // 标准映射
203
+ dark1: "dk1",
204
+ dark2: "dk2",
205
+ light1: "lt1",
206
+ light2: "lt2",
207
+ accent1: "accent1",
208
+ accent2: "accent2",
209
+ accent3: "accent3",
210
+ accent4: "accent4",
211
+ accent5: "accent5",
212
+ accent6: "accent6",
213
+ hyperlink: "hlink",
214
+ followedHyperlink: "folHlink",
215
+ // 直接映射(XML 中的原始名称)
216
+ dk1: "dk1",
217
+ dk2: "dk2",
218
+ lt1: "lt1",
219
+ lt2: "lt2",
220
+ hlink: "hlink",
221
+ folHlink: "folHlink",
222
+ // 文本颜色别名
223
+ text1: "dk1",
224
+ text2: "dk2",
225
+ background1: "lt1",
226
+ background2: "lt2"
227
+ };
228
+ function Y(o, e) {
229
+ var i;
230
+ if (!((i = o == null ? void 0 : o.colorScheme) != null && i.colors)) return;
231
+ const t = e.themeColor, n = q[t] || t, r = o.colorScheme.colors[n];
232
+ if (r)
233
+ return e.themeTint !== void 0 || e.themeShade !== void 0 ? K(r, e.themeTint, e.themeShade) : r;
234
+ }
235
+ function K(o, e, t) {
236
+ const n = o.replace("#", ""), r = parseInt(n.substr(0, 2), 16), i = parseInt(n.substr(2, 2), 16), a = parseInt(n.substr(4, 2), 16);
237
+ let c = r, l = i, d = a;
238
+ if (e !== void 0 && e > 0) {
239
+ const h = e / 255;
240
+ c = Math.round(r + (255 - r) * h), l = Math.round(i + (255 - i) * h), d = Math.round(a + (255 - a) * h);
241
+ }
242
+ if (t !== void 0 && t > 0) {
243
+ const h = 1 - t / 255;
244
+ c = Math.round(c * h), l = Math.round(l * h), d = Math.round(d * h);
245
+ }
246
+ return c = Math.max(0, Math.min(255, c)), l = Math.max(0, Math.min(255, l)), d = Math.max(0, Math.min(255, d)), `#${N(c)}${N(l)}${N(d)}`;
247
+ }
248
+ function N(o) {
249
+ const e = o.toString(16);
250
+ return e.length === 1 ? "0" + e : e;
251
+ }
252
+ function Te(o, e, t = "latin") {
253
+ return o != null && o.fontScheme ? (e === "major" ? o.fontScheme.majorFont : o.fontScheme.minorFont)[t] : void 0;
254
+ }
255
+ const Z = {
256
+ embedRegular: "regular",
257
+ embedBold: "bold",
258
+ embedItalic: "italic",
259
+ embedBoldItalic: "boldItalic"
260
+ };
261
+ function J(o) {
262
+ const t = w(o).documentElement, n = Q(t), r = new Map(n.map((a) => [a.name, a])), i = re(n);
263
+ return {
264
+ fonts: n,
265
+ fontMap: r,
266
+ substitutionMap: i
267
+ };
268
+ }
269
+ function Q(o) {
270
+ return s.elements(o, "font").map((e) => ee(e));
271
+ }
272
+ function ee(o) {
273
+ const e = {
274
+ name: s.attr(o, "name") || "",
275
+ embedFontRefs: []
276
+ };
277
+ for (const t of s.elements(o))
278
+ switch (t.localName) {
279
+ case "family":
280
+ e.family = s.attr(t, "val");
281
+ break;
282
+ case "altName":
283
+ e.altName = s.attr(t, "val");
284
+ break;
285
+ case "charset":
286
+ e.charset = s.attr(t, "val");
287
+ break;
288
+ case "panose1":
289
+ e.panose1 = s.attr(t, "val");
290
+ break;
291
+ case "sig":
292
+ e.sig = te(t);
293
+ break;
294
+ case "embedRegular":
295
+ case "embedBold":
296
+ case "embedItalic":
297
+ case "embedBoldItalic":
298
+ const n = ne(t);
299
+ n && e.embedFontRefs.push(n);
300
+ break;
301
+ }
302
+ return e;
303
+ }
304
+ function te(o) {
305
+ return {
306
+ usb0: s.attr(o, "usb0"),
307
+ usb1: s.attr(o, "usb1"),
308
+ usb2: s.attr(o, "usb2"),
309
+ usb3: s.attr(o, "usb3"),
310
+ csb0: s.attr(o, "csb0"),
311
+ csb1: s.attr(o, "csb1")
312
+ };
313
+ }
314
+ function ne(o) {
315
+ const e = s.attr(o, "id");
316
+ if (!e) return null;
317
+ const t = Z[o.localName];
318
+ return t ? {
319
+ id: e,
320
+ key: s.attr(o, "fontKey"),
321
+ subsetted: s.boolAttr(o, "subsetted"),
322
+ type: t
323
+ } : null;
324
+ }
325
+ function re(o) {
326
+ const e = /* @__PURE__ */ new Map();
327
+ for (const t of o)
328
+ t.altName && e.set(t.name, t.altName);
329
+ return e;
330
+ }
331
+ function Pe(o, e) {
332
+ return o.substitutionMap.get(e) || e;
333
+ }
334
+ function Fe(o, e) {
335
+ return o.fontMap.get(e);
336
+ }
337
+ function Re(o, e) {
338
+ const t = o.fontMap.get(e);
339
+ return t ? t.embedFontRefs.length > 0 : !1;
340
+ }
341
+ function Ne(o, e, t) {
342
+ const n = o.fontMap.get(e);
343
+ return n ? t ? n.embedFontRefs.filter((r) => r.type === t) : n.embedFontRefs : [];
344
+ }
345
+ function $e(o, e) {
346
+ const t = [], n = o.fontMap.get(e);
347
+ if (t.push(B(e)), n != null && n.altName && t.push(B(n.altName)), n != null && n.family) {
348
+ const r = se(n.family);
349
+ r && t.push(r);
350
+ }
351
+ return t.join(", ");
352
+ }
353
+ function B(o) {
354
+ return /[\s,'"()]/.test(o) ? `"${o.replace(/"/g, '\\"')}"` : o;
355
+ }
356
+ function se(o) {
357
+ switch (o.toLowerCase()) {
358
+ case "roman":
359
+ return "serif";
360
+ case "swiss":
361
+ return "sans-serif";
362
+ case "modern":
363
+ return "monospace";
364
+ case "script":
365
+ return "cursive";
366
+ case "decorative":
367
+ return "fantasy";
368
+ default:
369
+ return null;
370
+ }
371
+ }
372
+ const L = {
373
+ injectStyles: !0,
374
+ timeout: 1e4
375
+ };
376
+ async function oe(o, e, t, n = {}) {
377
+ const r = { ...L, ...n }, i = [];
378
+ for (const a of e.fonts)
379
+ if (a.embedFontRefs.length !== 0)
380
+ for (const c of a.embedFontRefs)
381
+ try {
382
+ const l = await ie(
383
+ o,
384
+ a,
385
+ c,
386
+ t,
387
+ r.timeout || L.timeout
388
+ );
389
+ l && i.push(l);
390
+ } catch (l) {
391
+ console.warn(`加载嵌入字体失败: ${a.name} (${c.type})`, l);
392
+ }
393
+ return r.injectStyles && i.length > 0 && de(i, r.styleContainer), i;
394
+ }
395
+ async function ie(o, e, t, n, r) {
396
+ const i = n.find((b) => b.id === t.id);
397
+ if (!i)
398
+ return console.warn(`找不到嵌入字体关系: ${t.id}`), null;
399
+ const a = `word/${i.target}`, c = o.file(a);
400
+ if (!c)
401
+ return console.warn(`找不到嵌入字体文件: ${a}`), null;
402
+ const l = await Promise.race([
403
+ c.async("arraybuffer"),
404
+ new Promise(
405
+ (b, y) => setTimeout(() => y(new Error("字体加载超时")), r)
406
+ )
407
+ ]);
408
+ let d = l;
409
+ t.key && (d = ae(l, t.key));
410
+ const h = ce(new Uint8Array(d)), p = le(h), u = new Blob([d], { type: p }), f = await he(u);
411
+ return {
412
+ fontName: e.name,
413
+ type: t.type,
414
+ dataUrl: f,
415
+ format: h
416
+ };
417
+ }
418
+ function ae(o, e) {
419
+ const t = e.replace(/[{}-]/g, "");
420
+ if (t.length !== 32)
421
+ return console.warn("无效的字体密钥格式:", e), o;
422
+ const n = new Uint8Array(16);
423
+ for (let c = 0; c < 4; c++)
424
+ n[3 - c] = parseInt(t.substr(c * 2, 2), 16);
425
+ for (let c = 0; c < 2; c++)
426
+ n[5 - c] = parseInt(t.substr(8 + c * 2, 2), 16);
427
+ for (let c = 0; c < 2; c++)
428
+ n[7 - c] = parseInt(t.substr(12 + c * 2, 2), 16);
429
+ for (let c = 0; c < 8; c++)
430
+ n[8 + c] = parseInt(t.substr(16 + c * 2, 2), 16);
431
+ const r = new Uint8Array(o), i = new Uint8Array(r.length), a = Math.min(32, r.length);
432
+ for (let c = 0; c < a; c++)
433
+ i[c] = r[c] ^ n[c % 16];
434
+ for (let c = a; c < r.length; c++)
435
+ i[c] = r[c];
436
+ return i.buffer;
437
+ }
438
+ function ce(o) {
439
+ return o.length < 4 ? "truetype" : o[0] === 79 && o[1] === 84 && o[2] === 84 && o[3] === 79 ? "opentype" : o[0] === 0 && o[1] === 1 && o[2] === 0 && o[3] === 0 || o[0] === 116 && o[1] === 114 && o[2] === 117 && o[3] === 101 ? "truetype" : o[0] === 0 && o[1] === 0 && o[2] === 1 ? "embedded-opentype" : "truetype";
440
+ }
441
+ function le(o) {
442
+ switch (o) {
443
+ case "opentype":
444
+ return "font/otf";
445
+ case "truetype":
446
+ return "font/ttf";
447
+ case "embedded-opentype":
448
+ return "application/vnd.ms-fontobject";
449
+ default:
450
+ return "font/ttf";
451
+ }
452
+ }
453
+ function he(o) {
454
+ return new Promise((e, t) => {
455
+ const n = new FileReader();
456
+ n.onloadend = () => e(n.result), n.onerror = t, n.readAsDataURL(o);
457
+ });
458
+ }
459
+ function de(o, e) {
460
+ const t = document.createElement("style");
461
+ t.setAttribute("data-docx-fonts", "true");
462
+ const n = o.map((a) => me(a)).join(`
463
+ `);
464
+ t.textContent = n;
465
+ const r = e || document.head, i = r.querySelector("style[data-docx-fonts]");
466
+ i && i.remove(), r.appendChild(t);
467
+ }
468
+ function me(o) {
469
+ const e = ue(o.type), t = fe(o.type), n = pe(o.format);
470
+ return `@font-face {
471
+ font-family: "${ge(o.fontName)}";
472
+ src: url("${o.dataUrl}") format("${n}");
473
+ font-weight: ${e};
474
+ font-style: ${t};
475
+ font-display: swap;
476
+ }`;
477
+ }
478
+ function ue(o) {
479
+ switch (o) {
480
+ case "bold":
481
+ case "boldItalic":
482
+ return "700";
483
+ default:
484
+ return "400";
485
+ }
486
+ }
487
+ function fe(o) {
488
+ switch (o) {
489
+ case "italic":
490
+ case "boldItalic":
491
+ return "italic";
492
+ default:
493
+ return "normal";
494
+ }
495
+ }
496
+ function pe(o) {
497
+ switch (o) {
498
+ case "opentype":
499
+ return "opentype";
500
+ case "truetype":
501
+ return "truetype";
502
+ case "embedded-opentype":
503
+ return "embedded-opentype";
504
+ default:
505
+ return "truetype";
506
+ }
507
+ }
508
+ function ge(o) {
509
+ return o.replace(/"/g, '\\"');
510
+ }
511
+ function Ae(o) {
512
+ const t = (o || document.head).querySelector("style[data-docx-fonts]");
513
+ t && t.remove();
514
+ }
515
+ function be(o) {
516
+ const n = new DOMParser().parseFromString(o, "application/xml").documentElement, r = [], i = n.getElementsByTagName("Relationship");
517
+ for (let a = 0; a < i.length; a++) {
518
+ const c = i[a], l = c.getAttribute("Type") || "";
519
+ l === F.FONT && r.push({
520
+ id: c.getAttribute("Id") || "",
521
+ type: l,
522
+ target: c.getAttribute("Target") || "",
523
+ targetMode: c.getAttribute("TargetMode") || void 0
524
+ });
525
+ }
526
+ return r;
527
+ }
528
+ const D = "http://schemas.microsoft.com/office/word/2012/wordml";
529
+ function ye(o) {
530
+ const e = /* @__PURE__ */ new Map();
531
+ if (!o)
532
+ return e;
533
+ try {
534
+ const n = w(o).documentElement, r = n.getElementsByTagNameNS(D, "commentEx"), i = r.length > 0 ? Array.from(r) : Array.from(n.getElementsByTagName("commentEx"));
535
+ for (const a of i) {
536
+ const c = A(a, "paraId");
537
+ if (!c) continue;
538
+ const l = {
539
+ paraId: c,
540
+ paraIdParent: A(a, "paraIdParent"),
541
+ done: Ce(a, "done")
542
+ };
543
+ e.set(c, l);
544
+ }
545
+ console.log("[DEBUG] parseCommentsExtended: found", e.size, "extended comments");
546
+ } catch (t) {
547
+ console.warn("解析 commentsExtended.xml 失败:", t);
548
+ }
549
+ return e;
550
+ }
551
+ function Ee(o, e) {
552
+ const t = /* @__PURE__ */ new Map();
553
+ for (const r of o)
554
+ r.paraId && t.set(r.paraId, r);
555
+ for (const r of o)
556
+ r.replies = [];
557
+ for (const [r, i] of e) {
558
+ const a = t.get(r);
559
+ if (a && (a.done = i.done, i.paraIdParent)) {
560
+ const c = t.get(i.paraIdParent);
561
+ c && (a.parentId = c.id, c.replies.push(a));
562
+ }
563
+ }
564
+ const n = o.filter((r) => !r.parentId);
565
+ return n.sort((r, i) => {
566
+ const a = new Date(r.date).getTime(), c = new Date(i.date).getTime();
567
+ return a - c;
568
+ }), H(n), console.log(
569
+ "[DEBUG] buildCommentTree: root comments:",
570
+ n.length,
571
+ "total comments:",
572
+ o.length
573
+ ), n;
574
+ }
575
+ function H(o) {
576
+ for (const e of o)
577
+ e.replies && e.replies.length > 0 && (e.replies.sort((t, n) => {
578
+ const r = new Date(t.date).getTime(), i = new Date(n.date).getTime();
579
+ return r - i;
580
+ }), H(e.replies));
581
+ }
582
+ function A(o, e) {
583
+ let t = o.getAttributeNS(D, e);
584
+ return t || (t = o.getAttribute(e), t) ? t : (t = o.getAttribute(`w15:${e}`), t || void 0);
585
+ }
586
+ function Ce(o, e) {
587
+ const t = A(o, e);
588
+ return t ? t === "1" || t === "true" : !1;
589
+ }
590
+ class we {
591
+ constructor() {
592
+ g(this, "zip", null);
593
+ g(this, "relationships", []);
594
+ g(this, "images", /* @__PURE__ */ new Map());
595
+ g(this, "theme");
596
+ g(this, "fontTable");
597
+ g(this, "embeddedFonts", []);
598
+ g(this, "bookmarks", /* @__PURE__ */ new Map());
599
+ }
600
+ /**
601
+ * 解析 DOCX 文件
602
+ */
603
+ async parse(e) {
604
+ const t = e instanceof ArrayBuffer ? e : await e.arrayBuffer();
605
+ this.zip = await G.loadAsync(t), this.bookmarks = /* @__PURE__ */ new Map(), await this.parseRelationships(), await this.loadImages();
606
+ const n = await this.parseStyles(), r = new Map(n.map((k) => [k.id, k])), i = await this.parseComments(), a = new Map(i.map((k) => [k.id, k])), c = await this.parseCommentsExtended(), l = Ee(i, c), { numberings: d, abstractNumberings: h, numberingMap: p } = await this.parseNumberings();
607
+ this.theme = await this.parseTheme();
608
+ const u = await this.parseHeadersFooters("header"), f = await this.parseHeadersFooters("footer"), b = await this.parseFootnotes(), y = await this.parseEndnotes();
609
+ return this.fontTable = await this.parseFontTable(), this.embeddedFonts = await this.loadEmbeddedFonts(), {
610
+ body: await this.parseDocument(),
611
+ comments: i,
612
+ commentMap: a,
613
+ rootComments: l,
614
+ commentsExtendedMap: c,
615
+ styles: n,
616
+ styleMap: r,
617
+ numberings: d,
618
+ numberingMap: p,
619
+ abstractNumberings: h,
620
+ images: this.images,
621
+ relationships: this.relationships,
622
+ headers: u,
623
+ footers: f,
624
+ theme: this.theme,
625
+ footnotes: b,
626
+ endnotes: y,
627
+ fontTable: this.fontTable,
628
+ embeddedFonts: this.embeddedFonts,
629
+ bookmarks: this.bookmarks
630
+ };
631
+ }
632
+ /**
633
+ * 获取 ZIP 实例
634
+ */
635
+ getZip() {
636
+ return this.zip;
637
+ }
638
+ /**
639
+ * 解析关系文件
640
+ */
641
+ async parseRelationships() {
642
+ var r, i;
643
+ const e = await ((i = (r = this.zip) == null ? void 0 : r.file(C.RELS)) == null ? void 0 : i.async("string"));
644
+ if (!e) return;
645
+ const n = w(e).documentElement;
646
+ this.relationships = s.elements(n, "Relationship").map((a) => ({
647
+ id: s.attr(a, "Id") || "",
648
+ type: s.attr(a, "Type") || "",
649
+ target: s.attr(a, "Target") || "",
650
+ targetMode: s.attr(a, "TargetMode")
651
+ }));
652
+ }
653
+ /**
654
+ * 加载图片资源
655
+ */
656
+ async loadImages() {
657
+ var e;
658
+ for (const t of this.relationships)
659
+ if (t.type === F.IMAGE) {
660
+ const n = `word/${t.target}`, r = (e = this.zip) == null ? void 0 : e.file(n);
661
+ if (r) {
662
+ const i = await r.async("blob"), a = await this.blobToBase64(i);
663
+ this.images.set(t.id, a);
664
+ }
665
+ }
666
+ }
667
+ /**
668
+ * Blob 转 Base64
669
+ */
670
+ blobToBase64(e) {
671
+ return new Promise((t, n) => {
672
+ const r = new FileReader();
673
+ r.onloadend = () => t(r.result), r.onerror = n, r.readAsDataURL(e);
674
+ });
675
+ }
676
+ /**
677
+ * 解析样式
678
+ */
679
+ async parseStyles() {
680
+ var i, a;
681
+ const e = await ((a = (i = this.zip) == null ? void 0 : i.file(C.STYLES)) == null ? void 0 : a.async("string"));
682
+ if (!e) return [];
683
+ const t = w(e), n = [], r = t.getElementsByTagNameNS(
684
+ "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
685
+ "style"
686
+ );
687
+ for (let c = 0; c < r.length; c++) {
688
+ const l = r[c], d = s.element(l, "name"), h = s.element(l, "basedOn"), p = {
689
+ id: s.attr(l, "styleId") || "",
690
+ name: d ? s.attr(d, "val") : void 0,
691
+ type: s.attr(l, "type") || "paragraph",
692
+ basedOn: h ? s.attr(h, "val") : void 0
693
+ }, u = s.element(l, "pPr");
694
+ u && (p.paragraphProps = this.parseParagraphProperties(u));
695
+ const f = s.element(l, "rPr");
696
+ f && (p.runProps = this.parseRunProperties(f)), n.push(p);
697
+ }
698
+ return n;
699
+ }
700
+ /**
701
+ * 解析主题(word/theme/theme1.xml)
702
+ */
703
+ async parseTheme() {
704
+ var t, n;
705
+ const e = await ((n = (t = this.zip) == null ? void 0 : t.file(C.THEME)) == null ? void 0 : n.async("string"));
706
+ if (e)
707
+ try {
708
+ const r = w(e);
709
+ return j(r.documentElement);
710
+ } catch (r) {
711
+ console.warn("主题解析失败:", r);
712
+ return;
713
+ }
714
+ }
715
+ /**
716
+ * 解析字体表(word/fontTable.xml)
717
+ */
718
+ async parseFontTable() {
719
+ var t, n;
720
+ const e = await ((n = (t = this.zip) == null ? void 0 : t.file(C.FONT_TABLE)) == null ? void 0 : n.async("string"));
721
+ if (e)
722
+ try {
723
+ return J(e);
724
+ } catch (r) {
725
+ console.warn("字体表解析失败:", r);
726
+ return;
727
+ }
728
+ }
729
+ /**
730
+ * 加载嵌入字体
731
+ */
732
+ async loadEmbeddedFonts() {
733
+ var t;
734
+ if (!this.fontTable || !this.zip) return [];
735
+ if (!this.fontTable.fonts.some((n) => n.embedFontRefs.length > 0)) return [];
736
+ try {
737
+ const n = await ((t = this.zip.file(C.FONT_TABLE_RELS)) == null ? void 0 : t.async("string"));
738
+ if (!n)
739
+ return console.warn("找不到字体表关系文件"), [];
740
+ const r = be(n);
741
+ return await oe(this.zip, this.fontTable, r, {
742
+ injectStyles: !0
743
+ });
744
+ } catch (n) {
745
+ return console.warn("嵌入字体加载失败:", n), [];
746
+ }
747
+ }
748
+ /**
749
+ * 解析脚注(word/footnotes.xml)
750
+ */
751
+ async parseFootnotes() {
752
+ var t, n;
753
+ const e = await ((n = (t = this.zip) == null ? void 0 : t.file(C.FOOTNOTES)) == null ? void 0 : n.async("string"));
754
+ if (!e) return /* @__PURE__ */ new Map();
755
+ try {
756
+ const r = w(e);
757
+ return this.parseNotes(r.documentElement, "footnote", m.Footnote);
758
+ } catch (r) {
759
+ return console.warn("脚注解析失败:", r), /* @__PURE__ */ new Map();
760
+ }
761
+ }
762
+ /**
763
+ * 解析尾注(word/endnotes.xml)
764
+ */
765
+ async parseEndnotes() {
766
+ var t, n;
767
+ const e = await ((n = (t = this.zip) == null ? void 0 : t.file(C.ENDNOTES)) == null ? void 0 : n.async("string"));
768
+ if (!e) return /* @__PURE__ */ new Map();
769
+ try {
770
+ const r = w(e);
771
+ return this.parseNotes(r.documentElement, "endnote", m.Endnote);
772
+ } catch (r) {
773
+ return console.warn("尾注解析失败:", r), /* @__PURE__ */ new Map();
774
+ }
775
+ }
776
+ /**
777
+ * 解析注释(脚注/尾注通用)
778
+ */
779
+ parseNotes(e, t, n) {
780
+ const r = /* @__PURE__ */ new Map(), i = e.getElementsByTagNameNS(
781
+ "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
782
+ t
783
+ );
784
+ for (let a = 0; a < i.length; a++) {
785
+ const c = i[a], l = s.attr(c, "id") || "", d = s.attr(c, "type");
786
+ if (d === "separator" || d === "continuationSeparator")
787
+ continue;
788
+ const h = {
789
+ type: n,
790
+ id: l,
791
+ noteType: d,
792
+ children: this.parseChildren(c)
793
+ };
794
+ r.set(l, h);
795
+ }
796
+ return r;
797
+ }
798
+ /**
799
+ * 解析编号(word/numbering.xml)
800
+ */
801
+ async parseNumberings() {
802
+ var l, d;
803
+ const e = await ((d = (l = this.zip) == null ? void 0 : l.file(C.NUMBERING)) == null ? void 0 : d.async("string"));
804
+ if (!e)
805
+ return {
806
+ numberings: [],
807
+ abstractNumberings: [],
808
+ numberingMap: /* @__PURE__ */ new Map()
809
+ };
810
+ const n = w(e).documentElement, r = [], i = /* @__PURE__ */ new Map();
811
+ for (const h of s.elements(n))
812
+ switch (h.localName) {
813
+ case "abstractNum":
814
+ r.push(this.parseAbstractNumbering(h));
815
+ break;
816
+ case "num":
817
+ const p = s.attr(h, "numId") || "", u = s.element(h, "abstractNumId");
818
+ if (u) {
819
+ const f = s.attr(u, "val") || "";
820
+ i.set(p, f);
821
+ }
822
+ break;
823
+ }
824
+ const a = [], c = /* @__PURE__ */ new Map();
825
+ for (const [h, p] of i) {
826
+ const u = r.find((f) => f.id === p);
827
+ if (u) {
828
+ const f = {
829
+ id: h,
830
+ abstractNumId: p,
831
+ levels: u.levels.map((b) => ({ ...b }))
832
+ };
833
+ a.push(f), c.set(h, f);
834
+ }
835
+ }
836
+ return { numberings: a, abstractNumberings: r, numberingMap: c };
837
+ }
838
+ /**
839
+ * 解析抽象编号定义
840
+ */
841
+ parseAbstractNumbering(e) {
842
+ const t = {
843
+ id: s.attr(e, "abstractNumId") || "",
844
+ levels: []
845
+ };
846
+ for (const n of s.elements(e))
847
+ switch (n.localName) {
848
+ case "name":
849
+ t.name = s.attr(n, "val");
850
+ break;
851
+ case "multiLevelType":
852
+ t.multiLevelType = s.attr(n, "val");
853
+ break;
854
+ case "numStyleLink":
855
+ t.numberingStyleLink = s.attr(n, "val");
856
+ break;
857
+ case "styleLink":
858
+ t.styleLink = s.attr(n, "val");
859
+ break;
860
+ case "lvl":
861
+ t.levels.push(this.parseNumberingLevel(n));
862
+ break;
863
+ }
864
+ return t;
865
+ }
866
+ /**
867
+ * 解析编号级别
868
+ */
869
+ parseNumberingLevel(e) {
870
+ const t = {
871
+ level: s.intAttr(e, "ilvl") ?? 0,
872
+ format: "decimal",
873
+ text: "",
874
+ start: 1,
875
+ suffix: "tab"
876
+ };
877
+ for (const n of s.elements(e))
878
+ switch (n.localName) {
879
+ case "start":
880
+ t.start = s.intAttr(n, "val") ?? 1;
881
+ break;
882
+ case "numFmt":
883
+ t.format = s.attr(n, "val") || "decimal";
884
+ break;
885
+ case "lvlText":
886
+ t.text = s.attr(n, "val") || "";
887
+ break;
888
+ case "suff":
889
+ t.suffix = s.attr(n, "val") || "tab";
890
+ break;
891
+ case "pStyle":
892
+ t.pStyleName = s.attr(n, "val");
893
+ break;
894
+ case "pPr":
895
+ t.paragraphProps = this.parseParagraphProperties(n);
896
+ break;
897
+ case "rPr":
898
+ t.runProps = this.parseRunProperties(n);
899
+ break;
900
+ }
901
+ return t;
902
+ }
903
+ /**
904
+ * 解析评论
905
+ */
906
+ async parseComments() {
907
+ var a, c, l;
908
+ const e = await ((c = (a = this.zip) == null ? void 0 : a.file(C.COMMENTS)) == null ? void 0 : c.async("string"));
909
+ if (!e) return [];
910
+ const t = w(e), n = [], r = t.getElementsByTagNameNS(
911
+ "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
912
+ "comment"
913
+ ), i = "http://schemas.microsoft.com/office/word/2010/wordml";
914
+ for (let d = 0; d < r.length; d++) {
915
+ const h = r[d], p = ((l = h.textContent) == null ? void 0 : l.trim()) || "";
916
+ let u = h.getAttributeNS(i, "paraId");
917
+ u || (u = h.getAttribute("w14:paraId") || null);
918
+ const f = {
919
+ type: m.Comment,
920
+ id: s.attr(h, "id") || "",
921
+ author: s.attr(h, "author") || "未知",
922
+ date: s.attr(h, "date") || (/* @__PURE__ */ new Date()).toISOString(),
923
+ initials: s.attr(h, "initials"),
924
+ children: this.parseChildren(h),
925
+ rawText: p,
926
+ paraId: u || void 0
927
+ };
928
+ n.push(f);
929
+ }
930
+ return console.log("[DEBUG] parseComments: found", n.length, "comments"), n;
931
+ }
932
+ /**
933
+ * 解析扩展评论(word/commentsExtended.xml)
934
+ * 包含评论的父子关系信息
935
+ */
936
+ async parseCommentsExtended() {
937
+ var t, n;
938
+ const e = await ((n = (t = this.zip) == null ? void 0 : t.file(C.COMMENTS_EXTENDED)) == null ? void 0 : n.async("string"));
939
+ return e ? (console.log("[DEBUG] commentsExtended.xml found, length:", e.length), ye(e)) : (console.log("[DEBUG] commentsExtended.xml not found"), /* @__PURE__ */ new Map());
940
+ }
941
+ /**
942
+ * 解析文档主体
943
+ */
944
+ async parseDocument() {
945
+ var d, h;
946
+ const e = await ((h = (d = this.zip) == null ? void 0 : d.file(C.DOCUMENT)) == null ? void 0 : h.async("string"));
947
+ if (!e)
948
+ return { type: m.Document, children: [] };
949
+ const t = w(e), n = t.getElementsByTagNameNS(
950
+ "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
951
+ "body"
952
+ )[0];
953
+ if (!n)
954
+ return { type: m.Document, children: [] };
955
+ const r = s.element(n, "sectPr"), i = r ? this.parseSectionProperties(r) : void 0, a = t.getElementsByTagNameNS(
956
+ "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
957
+ "document"
958
+ )[0], c = a ? s.element(a, "background") : null, l = c ? this.parseBackground(c) : void 0;
959
+ return {
960
+ type: m.Document,
961
+ children: this.parseChildren(n),
962
+ sectionProps: i,
963
+ background: l
964
+ };
965
+ }
966
+ /**
967
+ * 解析页眉页脚
968
+ */
969
+ async parseHeadersFooters(e) {
970
+ var r, i;
971
+ const t = /* @__PURE__ */ new Map(), n = e === "header" ? F.HEADER : F.FOOTER;
972
+ for (const a of this.relationships)
973
+ if (a.type === n) {
974
+ const c = `word/${a.target}`, l = await ((i = (r = this.zip) == null ? void 0 : r.file(c)) == null ? void 0 : i.async("string"));
975
+ if (l) {
976
+ const h = w(l).getElementsByTagNameNS(
977
+ "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
978
+ e === "header" ? "hdr" : "ftr"
979
+ )[0];
980
+ if (h) {
981
+ const p = {
982
+ type: e === "header" ? m.Header : m.Footer,
983
+ children: this.parseChildren(h)
984
+ };
985
+ t.set(a.id, p);
986
+ }
987
+ }
988
+ }
989
+ return t;
990
+ }
991
+ /**
992
+ * 解析背景
993
+ */
994
+ parseBackground(e) {
995
+ const t = {}, n = s.attr(e, "color");
996
+ return n && n !== "auto" && (t["background-color"] = `#${n}`), t;
997
+ }
998
+ /**
999
+ * 解析 Section 属性
1000
+ */
1001
+ parseSectionProperties(e) {
1002
+ const t = {};
1003
+ for (const n of s.elements(e))
1004
+ switch (n.localName) {
1005
+ case "pgSz":
1006
+ t.pageSize = this.parsePageSize(n);
1007
+ break;
1008
+ case "pgMar":
1009
+ t.pageMargins = this.parsePageMargins(n);
1010
+ break;
1011
+ case "type":
1012
+ t.type = s.attr(n, "val") || "nextPage";
1013
+ break;
1014
+ case "cols":
1015
+ t.columns = this.parseColumns(n);
1016
+ break;
1017
+ case "pgBorders":
1018
+ t.pageBorders = this.parseBorders(n);
1019
+ break;
1020
+ case "pgNumType":
1021
+ t.pageNumber = {
1022
+ start: s.intAttr(n, "start"),
1023
+ format: s.attr(n, "fmt"),
1024
+ chapSep: s.attr(n, "chapSep"),
1025
+ chapStyle: s.attr(n, "chapStyle")
1026
+ };
1027
+ break;
1028
+ case "headerReference":
1029
+ t.headerRefs || (t.headerRefs = []), t.headerRefs.push({
1030
+ id: s.attr(n, "id") || "",
1031
+ type: s.attr(n, "type") || "default"
1032
+ });
1033
+ break;
1034
+ case "footerReference":
1035
+ t.footerRefs || (t.footerRefs = []), t.footerRefs.push({
1036
+ id: s.attr(n, "id") || "",
1037
+ type: s.attr(n, "type") || "default"
1038
+ });
1039
+ break;
1040
+ case "titlePg":
1041
+ t.titlePage = s.boolAttr(n, "val") !== !1;
1042
+ break;
1043
+ }
1044
+ return t;
1045
+ }
1046
+ /**
1047
+ * 解析页面尺寸
1048
+ */
1049
+ parsePageSize(e) {
1050
+ return {
1051
+ width: s.lengthAttr(e, "w"),
1052
+ height: s.lengthAttr(e, "h"),
1053
+ orientation: s.attr(e, "orient")
1054
+ };
1055
+ }
1056
+ /**
1057
+ * 解析页边距
1058
+ */
1059
+ parsePageMargins(e) {
1060
+ return {
1061
+ top: s.lengthAttr(e, "top"),
1062
+ right: s.lengthAttr(e, "right"),
1063
+ bottom: s.lengthAttr(e, "bottom"),
1064
+ left: s.lengthAttr(e, "left"),
1065
+ header: s.lengthAttr(e, "header"),
1066
+ footer: s.lengthAttr(e, "footer"),
1067
+ gutter: s.lengthAttr(e, "gutter")
1068
+ };
1069
+ }
1070
+ /**
1071
+ * 解析分栏
1072
+ */
1073
+ parseColumns(e) {
1074
+ const t = {
1075
+ numberOfColumns: s.intAttr(e, "num"),
1076
+ space: s.lengthAttr(e, "space"),
1077
+ separator: s.boolAttr(e, "sep"),
1078
+ equalWidth: s.boolAttr(e, "equalWidth") !== !1,
1079
+ columns: []
1080
+ };
1081
+ for (const n of s.elements(e, "col"))
1082
+ t.columns.push({
1083
+ width: s.lengthAttr(n, "w"),
1084
+ space: s.lengthAttr(n, "space")
1085
+ });
1086
+ return t;
1087
+ }
1088
+ /**
1089
+ * 解析边框
1090
+ */
1091
+ parseBorders(e) {
1092
+ const t = {};
1093
+ for (const n of s.elements(e)) {
1094
+ const r = this.parseBorder(n);
1095
+ switch (n.localName) {
1096
+ case "top":
1097
+ t.top = r;
1098
+ break;
1099
+ case "bottom":
1100
+ t.bottom = r;
1101
+ break;
1102
+ case "left":
1103
+ case "start":
1104
+ t.left = r;
1105
+ break;
1106
+ case "right":
1107
+ case "end":
1108
+ t.right = r;
1109
+ break;
1110
+ }
1111
+ }
1112
+ return t;
1113
+ }
1114
+ /**
1115
+ * 解析单个边框
1116
+ */
1117
+ parseBorder(e) {
1118
+ const t = s.attr(e, "color");
1119
+ return {
1120
+ style: s.attr(e, "val"),
1121
+ width: s.lengthAttr(e, "sz", T.Border),
1122
+ color: t && t !== "auto" ? `#${t}` : void 0
1123
+ };
1124
+ }
1125
+ /**
1126
+ * 解析子元素
1127
+ */
1128
+ parseChildren(e, t = !1) {
1129
+ const n = [];
1130
+ for (const r of s.elements(e)) {
1131
+ const i = this.parseElement(r);
1132
+ i && n.push(i);
1133
+ }
1134
+ return t && n.length === 0 && console.log(
1135
+ "[DEBUG] parseChildren: no children parsed from",
1136
+ e.localName,
1137
+ "childNodes:",
1138
+ e.childNodes.length,
1139
+ "elements:",
1140
+ s.elements(e).map((r) => r.localName)
1141
+ ), n;
1142
+ }
1143
+ /**
1144
+ * 解析单个元素
1145
+ */
1146
+ parseElement(e) {
1147
+ var n;
1148
+ const t = e.localName;
1149
+ switch (t) {
1150
+ case "p":
1151
+ return this.parseParagraph(e);
1152
+ case "r":
1153
+ return this.parseRun(e);
1154
+ case "t":
1155
+ return this.parseText(e);
1156
+ case "br":
1157
+ return this.parseBreak(e);
1158
+ case "tab":
1159
+ return this.parseTab();
1160
+ case "sym":
1161
+ return this.parseSymbol(e);
1162
+ case "lastRenderedPageBreak":
1163
+ return { type: m.Break, breakType: "lastRenderedPageBreak" };
1164
+ case "fldSimple":
1165
+ return this.parseSimpleField(e);
1166
+ case "fldChar":
1167
+ return this.parseComplexField(e);
1168
+ case "instrText":
1169
+ return this.parseFieldInstruction(e);
1170
+ case "tbl":
1171
+ return this.parseTable(e);
1172
+ case "tr":
1173
+ return this.parseTableRow(e);
1174
+ case "tc":
1175
+ return this.parseTableCell(e);
1176
+ case "hyperlink":
1177
+ return this.parseHyperlink(e);
1178
+ case "drawing":
1179
+ return this.parseDrawing(e);
1180
+ case "commentRangeStart":
1181
+ return this.parseCommentRangeStart(e);
1182
+ case "commentRangeEnd":
1183
+ return this.parseCommentRangeEnd(e);
1184
+ case "commentReference":
1185
+ return this.parseCommentReference(e);
1186
+ case "footnoteReference":
1187
+ return this.parseFootnoteReference(e);
1188
+ case "endnoteReference":
1189
+ return this.parseEndnoteReference(e);
1190
+ case "bookmarkStart":
1191
+ return this.parseBookmarkStart(e);
1192
+ case "bookmarkEnd":
1193
+ return this.parseBookmarkEnd(e);
1194
+ default:
1195
+ console.log("[DEBUG] parseElement default branch for:", t);
1196
+ const r = this.parseChildren(e);
1197
+ if (r.length > 0)
1198
+ return console.log("[DEBUG] -> found children:", r.length), r.length === 1 ? r[0] : {
1199
+ type: m.Run,
1200
+ children: r
1201
+ };
1202
+ const i = (n = e.textContent) == null ? void 0 : n.trim();
1203
+ return i ? (console.log("[DEBUG] -> using textContent:", i.substring(0, 50)), {
1204
+ type: m.Text,
1205
+ text: i
1206
+ }) : null;
1207
+ }
1208
+ }
1209
+ /**
1210
+ * 解析段落
1211
+ */
1212
+ parseParagraph(e) {
1213
+ const t = s.element(e, "pPr");
1214
+ return {
1215
+ type: m.Paragraph,
1216
+ props: t ? this.parseParagraphProperties(t) : void 0,
1217
+ children: this.parseChildren(e).filter((n) => n.type !== m.Paragraph)
1218
+ };
1219
+ }
1220
+ /**
1221
+ * 解析段落属性
1222
+ */
1223
+ parseParagraphProperties(e) {
1224
+ const t = {}, n = s.element(e, "pStyle");
1225
+ n && (t.styleId = s.attr(n, "val"));
1226
+ const r = s.element(e, "jc");
1227
+ if (r) {
1228
+ const p = s.attr(r, "val");
1229
+ (p === "left" || p === "center" || p === "right" || p === "both") && (t.justification = p);
1230
+ }
1231
+ const i = s.element(e, "ind");
1232
+ i && (t.indentation = {
1233
+ left: s.lengthAttr(i, "left"),
1234
+ right: s.lengthAttr(i, "right"),
1235
+ firstLine: s.lengthAttr(i, "firstLine"),
1236
+ hanging: s.lengthAttr(i, "hanging")
1237
+ });
1238
+ const a = s.element(e, "spacing");
1239
+ a && (t.spacing = {
1240
+ before: s.lengthAttr(a, "before"),
1241
+ after: s.lengthAttr(a, "after"),
1242
+ // line 保存原始数值(twip),由渲染器根据 lineRule 计算
1243
+ line: s.intAttr(a, "line"),
1244
+ lineRule: s.attr(a, "lineRule")
1245
+ });
1246
+ const c = s.element(e, "pageBreakBefore");
1247
+ c && (t.pageBreakBefore = s.boolAttr(c, "val") !== !1);
1248
+ const l = s.element(e, "pBdr");
1249
+ l && (t.borders = this.parseBorders(l));
1250
+ const d = s.element(e, "sectPr");
1251
+ d && (t.sectionProps = this.parseSectionProperties(d));
1252
+ const h = s.element(e, "numPr");
1253
+ return h && (t.numbering = this.parseParagraphNumbering(h)), t;
1254
+ }
1255
+ /**
1256
+ * 解析段落编号引用
1257
+ */
1258
+ parseParagraphNumbering(e) {
1259
+ const t = {
1260
+ id: "",
1261
+ level: 0
1262
+ };
1263
+ for (const n of s.elements(e))
1264
+ switch (n.localName) {
1265
+ case "numId":
1266
+ t.id = s.attr(n, "val") || "";
1267
+ break;
1268
+ case "ilvl":
1269
+ t.level = s.intAttr(n, "val") ?? 0;
1270
+ break;
1271
+ }
1272
+ if (t.id)
1273
+ return t;
1274
+ }
1275
+ /**
1276
+ * 解析 Run
1277
+ */
1278
+ parseRun(e) {
1279
+ const t = s.element(e, "rPr");
1280
+ return {
1281
+ type: m.Run,
1282
+ props: t ? this.parseRunProperties(t) : void 0,
1283
+ children: this.parseChildren(e)
1284
+ };
1285
+ }
1286
+ /**
1287
+ * 解析 Run 属性
1288
+ */
1289
+ parseRunProperties(e) {
1290
+ var b, y, v, k;
1291
+ const t = {}, n = s.element(e, "rStyle");
1292
+ n && (t.styleId = s.attr(n, "val"));
1293
+ const r = s.element(e, "b");
1294
+ r && (t.bold = s.attr(r, "val") !== "0");
1295
+ const i = s.element(e, "i");
1296
+ i && (t.italic = s.attr(i, "val") !== "0");
1297
+ const a = s.element(e, "u");
1298
+ a && (t.underline = s.attr(a, "val") || "single");
1299
+ const c = s.element(e, "strike");
1300
+ c && (t.strike = s.attr(c, "val") !== "0");
1301
+ const l = s.element(e, "dstrike");
1302
+ l && (t.dstrike = s.attr(l, "val") !== "0");
1303
+ const d = s.element(e, "vertAlign");
1304
+ if (d) {
1305
+ const E = s.attr(d, "val");
1306
+ (E === "superscript" || E === "subscript") && (t.vertAlign = E);
1307
+ }
1308
+ const h = s.element(e, "color");
1309
+ if (h) {
1310
+ const E = s.attr(h, "val"), P = s.attr(h, "themeColor");
1311
+ if (P) {
1312
+ const S = s.attr(h, "themeTint"), x = s.attr(h, "themeShade");
1313
+ if (t.themeColor = {
1314
+ themeColor: P,
1315
+ themeTint: S ? parseInt(S, 16) : void 0,
1316
+ themeShade: x ? parseInt(x, 16) : void 0
1317
+ }, this.theme) {
1318
+ const M = Y(this.theme, t.themeColor);
1319
+ M && (t.color = M);
1320
+ }
1321
+ } else E && E !== "auto" && (t.color = `#${E}`);
1322
+ }
1323
+ const p = s.element(e, "sz");
1324
+ p && (t.fontSize = s.lengthAttr(p, "val", T.FontSize));
1325
+ const u = s.element(e, "rFonts");
1326
+ if (u) {
1327
+ const E = s.attr(u, "asciiTheme"), P = s.attr(u, "eastAsiaTheme");
1328
+ if (E || P) {
1329
+ const S = E || P || "";
1330
+ if (S.startsWith("major")) {
1331
+ if (t.themeFontFamily = "major", (y = (b = this.theme) == null ? void 0 : b.fontScheme) != null && y.majorFont) {
1332
+ const x = S.includes("EastAsia") ? this.theme.fontScheme.majorFont.ea : this.theme.fontScheme.majorFont.latin;
1333
+ x && (t.fontFamily = x);
1334
+ }
1335
+ } else if (S.startsWith("minor") && (t.themeFontFamily = "minor", (k = (v = this.theme) == null ? void 0 : v.fontScheme) != null && k.minorFont)) {
1336
+ const x = S.includes("EastAsia") ? this.theme.fontScheme.minorFont.ea : this.theme.fontScheme.minorFont.latin;
1337
+ x && (t.fontFamily = x);
1338
+ }
1339
+ }
1340
+ t.fontFamily || (t.fontFamily = s.attr(u, "ascii") || s.attr(u, "eastAsia") || s.attr(u, "hAnsi"));
1341
+ }
1342
+ const f = s.element(e, "highlight");
1343
+ return f && (t.highlight = s.attr(f, "val")), t;
1344
+ }
1345
+ /**
1346
+ * 解析文本
1347
+ */
1348
+ parseText(e) {
1349
+ return {
1350
+ type: m.Text,
1351
+ text: e.textContent || ""
1352
+ };
1353
+ }
1354
+ /**
1355
+ * 解析换行
1356
+ */
1357
+ parseBreak(e) {
1358
+ const t = s.attr(e, "type");
1359
+ return {
1360
+ type: m.Break,
1361
+ breakType: t || "textWrapping"
1362
+ };
1363
+ }
1364
+ /**
1365
+ * 解析 Tab
1366
+ */
1367
+ parseTab() {
1368
+ return {
1369
+ type: m.Tab
1370
+ };
1371
+ }
1372
+ /**
1373
+ * 解析符号字符 - <w:sym w:font="Symbol" w:char="F0B7"/>
1374
+ * Symbol 字体中的特殊字符,如箭头、符号等
1375
+ */
1376
+ parseSymbol(e) {
1377
+ const t = s.attr(e, "font"), n = s.attr(e, "char");
1378
+ let r;
1379
+ if (n) {
1380
+ const i = parseInt(n, 16);
1381
+ isNaN(i) || (r = String.fromCharCode(i));
1382
+ }
1383
+ return {
1384
+ type: m.Symbol,
1385
+ font: t,
1386
+ char: r
1387
+ };
1388
+ }
1389
+ /**
1390
+ * 解析简单域 - <w:fldSimple w:instr="PAGE">...</w:fldSimple>
1391
+ */
1392
+ parseSimpleField(e) {
1393
+ return {
1394
+ type: m.SimpleField,
1395
+ instruction: s.attr(e, "instr") || "",
1396
+ children: this.parseChildren(e)
1397
+ };
1398
+ }
1399
+ /**
1400
+ * 解析复杂域字符 - <w:fldChar w:fldCharType="begin"/>
1401
+ */
1402
+ parseComplexField(e) {
1403
+ return {
1404
+ type: m.ComplexField,
1405
+ charType: s.attr(e, "fldCharType") || ""
1406
+ };
1407
+ }
1408
+ /**
1409
+ * 解析域指令 - <w:instrText>PAGE</w:instrText>
1410
+ */
1411
+ parseFieldInstruction(e) {
1412
+ return {
1413
+ type: m.FieldInstruction,
1414
+ text: e.textContent || ""
1415
+ };
1416
+ }
1417
+ /**
1418
+ * 解析表格
1419
+ */
1420
+ parseTable(e) {
1421
+ const t = {
1422
+ type: m.Table,
1423
+ children: []
1424
+ };
1425
+ for (const n of s.elements(e))
1426
+ switch (n.localName) {
1427
+ case "tr":
1428
+ t.children.push(this.parseTableRow(n));
1429
+ break;
1430
+ case "tblGrid":
1431
+ t.columns = this.parseTableGrid(n);
1432
+ break;
1433
+ case "tblPr":
1434
+ t.props = this.parseTableProperties(n);
1435
+ break;
1436
+ }
1437
+ return t;
1438
+ }
1439
+ /**
1440
+ * 解析表格列宽度
1441
+ */
1442
+ parseTableGrid(e) {
1443
+ const t = [];
1444
+ for (const n of s.elements(e))
1445
+ n.localName === "gridCol" && t.push({
1446
+ width: s.lengthAttr(n, "w")
1447
+ });
1448
+ return t;
1449
+ }
1450
+ /**
1451
+ * 解析表格属性
1452
+ */
1453
+ parseTableProperties(e) {
1454
+ const t = {};
1455
+ for (const n of s.elements(e))
1456
+ switch (n.localName) {
1457
+ case "tblW":
1458
+ t.width = s.lengthAttr(n, "w");
1459
+ const r = s.attr(n, "type");
1460
+ (r === "auto" || r === "dxa" || r === "pct") && (t.widthType = r);
1461
+ break;
1462
+ case "jc":
1463
+ t.justification = s.attr(n, "val");
1464
+ break;
1465
+ case "tblBorders":
1466
+ t.borders = this.parseTableBorders(n);
1467
+ break;
1468
+ case "tblCellSpacing":
1469
+ t.cellSpacing = s.lengthAttr(n, "w");
1470
+ break;
1471
+ case "tblCellMar":
1472
+ t.cellMargin = {
1473
+ top: s.lengthAttr(s.element(n, "top"), "w"),
1474
+ bottom: s.lengthAttr(s.element(n, "bottom"), "w"),
1475
+ left: s.lengthAttr(s.element(n, "left"), "w") || s.lengthAttr(s.element(n, "start"), "w"),
1476
+ right: s.lengthAttr(s.element(n, "right"), "w") || s.lengthAttr(s.element(n, "end"), "w")
1477
+ };
1478
+ break;
1479
+ }
1480
+ return t;
1481
+ }
1482
+ /**
1483
+ * 解析表格边框(包含内部边框 insideH/insideV)
1484
+ */
1485
+ parseTableBorders(e) {
1486
+ const t = {};
1487
+ for (const n of s.elements(e)) {
1488
+ const r = this.parseBorder(n);
1489
+ switch (n.localName) {
1490
+ case "top":
1491
+ t.top = r;
1492
+ break;
1493
+ case "bottom":
1494
+ t.bottom = r;
1495
+ break;
1496
+ case "left":
1497
+ case "start":
1498
+ t.left = r;
1499
+ break;
1500
+ case "right":
1501
+ case "end":
1502
+ t.right = r;
1503
+ break;
1504
+ case "insideH":
1505
+ t.insideH = r;
1506
+ break;
1507
+ case "insideV":
1508
+ t.insideV = r;
1509
+ break;
1510
+ }
1511
+ }
1512
+ return t;
1513
+ }
1514
+ /**
1515
+ * 解析表格行
1516
+ */
1517
+ parseTableRow(e) {
1518
+ return {
1519
+ type: m.TableRow,
1520
+ children: s.elements(e).filter((t) => t.localName === "tc").map((t) => this.parseTableCell(t))
1521
+ };
1522
+ }
1523
+ /**
1524
+ * 解析表格单元格
1525
+ */
1526
+ parseTableCell(e) {
1527
+ const t = {
1528
+ type: m.TableCell,
1529
+ children: []
1530
+ };
1531
+ for (const n of s.elements(e))
1532
+ if (n.localName === "tcPr")
1533
+ t.props = this.parseTableCellProperties(n);
1534
+ else {
1535
+ const r = this.parseElement(n);
1536
+ r && t.children.push(r);
1537
+ }
1538
+ return t;
1539
+ }
1540
+ /**
1541
+ * 解析表格单元格属性
1542
+ */
1543
+ parseTableCellProperties(e) {
1544
+ const t = {};
1545
+ for (const n of s.elements(e))
1546
+ switch (n.localName) {
1547
+ case "tcW":
1548
+ t.width = s.lengthAttr(n, "w");
1549
+ break;
1550
+ case "gridSpan":
1551
+ t.gridSpan = s.intAttr(n, "val");
1552
+ break;
1553
+ case "vMerge":
1554
+ const r = s.attr(n, "val");
1555
+ t.verticalMerge = r === "restart" ? "restart" : "continue";
1556
+ break;
1557
+ case "vAlign":
1558
+ t.verticalAlign = s.attr(n, "val");
1559
+ break;
1560
+ case "shd":
1561
+ const i = s.attr(n, "fill");
1562
+ i && i !== "auto" && (t.shading = `#${i}`);
1563
+ break;
1564
+ case "tcBorders":
1565
+ t.borders = this.parseBorders(n);
1566
+ break;
1567
+ }
1568
+ return t;
1569
+ }
1570
+ /**
1571
+ * 解析超链接
1572
+ */
1573
+ parseHyperlink(e) {
1574
+ const t = s.attr(e, "id");
1575
+ let n;
1576
+ if (t) {
1577
+ const r = this.relationships.find((i) => i.id === t);
1578
+ r && (n = r.target);
1579
+ }
1580
+ return {
1581
+ type: m.Hyperlink,
1582
+ href: n,
1583
+ anchor: s.attr(e, "anchor"),
1584
+ children: this.parseChildren(e)
1585
+ };
1586
+ }
1587
+ /**
1588
+ * 解析绘图(图片等)
1589
+ */
1590
+ parseDrawing(e) {
1591
+ const t = [], n = e.getElementsByTagNameNS(
1592
+ "http://schemas.openxmlformats.org/drawingml/2006/main",
1593
+ "blip"
1594
+ );
1595
+ for (let r = 0; r < n.length; r++) {
1596
+ const a = n[r].getAttributeNS(
1597
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
1598
+ "embed"
1599
+ );
1600
+ if (a && this.images.has(a)) {
1601
+ const c = e.getElementsByTagNameNS(
1602
+ "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
1603
+ "extent"
1604
+ )[0];
1605
+ let l, d;
1606
+ if (c) {
1607
+ const h = c.getAttribute("cx"), p = c.getAttribute("cy");
1608
+ h && (l = s.convertLength(h, T.Emu)), p && (d = s.convertLength(p, T.Emu));
1609
+ }
1610
+ t.push({
1611
+ type: m.Image,
1612
+ src: this.images.get(a),
1613
+ width: l,
1614
+ height: d
1615
+ });
1616
+ }
1617
+ }
1618
+ return {
1619
+ type: m.Drawing,
1620
+ children: t
1621
+ };
1622
+ }
1623
+ /**
1624
+ * 解析评论范围开始
1625
+ */
1626
+ parseCommentRangeStart(e) {
1627
+ return {
1628
+ type: m.CommentRangeStart,
1629
+ id: s.attr(e, "id") || ""
1630
+ };
1631
+ }
1632
+ /**
1633
+ * 解析评论范围结束
1634
+ */
1635
+ parseCommentRangeEnd(e) {
1636
+ return {
1637
+ type: m.CommentRangeEnd,
1638
+ id: s.attr(e, "id") || ""
1639
+ };
1640
+ }
1641
+ /**
1642
+ * 解析评论引用
1643
+ */
1644
+ parseCommentReference(e) {
1645
+ return {
1646
+ type: m.CommentReference,
1647
+ id: s.attr(e, "id") || ""
1648
+ };
1649
+ }
1650
+ /**
1651
+ * 解析脚注引用
1652
+ */
1653
+ parseFootnoteReference(e) {
1654
+ return {
1655
+ type: m.FootnoteReference,
1656
+ id: s.attr(e, "id") || ""
1657
+ };
1658
+ }
1659
+ /**
1660
+ * 解析尾注引用
1661
+ */
1662
+ parseEndnoteReference(e) {
1663
+ return {
1664
+ type: m.EndnoteReference,
1665
+ id: s.attr(e, "id") || ""
1666
+ };
1667
+ }
1668
+ /**
1669
+ * 解析书签开始
1670
+ * <w:bookmarkStart w:id="0" w:name="bookmark1"/>
1671
+ */
1672
+ parseBookmarkStart(e) {
1673
+ const t = {
1674
+ type: m.BookmarkStart,
1675
+ id: s.attr(e, "id") || "",
1676
+ name: s.attr(e, "name") || "",
1677
+ colFirst: s.intAttr(e, "colFirst"),
1678
+ colLast: s.intAttr(e, "colLast")
1679
+ };
1680
+ return t.name && !t.name.startsWith("_") && this.bookmarks.set(t.name, t), t;
1681
+ }
1682
+ /**
1683
+ * 解析书签结束
1684
+ * <w:bookmarkEnd w:id="0"/>
1685
+ */
1686
+ parseBookmarkEnd(e) {
1687
+ return {
1688
+ type: m.BookmarkEnd,
1689
+ id: s.attr(e, "id") || ""
1690
+ };
1691
+ }
1692
+ }
1693
+ class ke {
1694
+ // 尾注编号计数器
1695
+ constructor(e) {
1696
+ g(this, "document", null);
1697
+ g(this, "container");
1698
+ g(this, "options");
1699
+ g(this, "classPrefix");
1700
+ // 评论相关状态
1701
+ g(this, "commentRanges", /* @__PURE__ */ new Map());
1702
+ g(this, "activeCommentId", null);
1703
+ g(this, "svgLayer", null);
1704
+ g(this, "currentCommentIds", /* @__PURE__ */ new Set());
1705
+ // 当前正在渲染的评论范围
1706
+ g(this, "commentStartInParagraph", /* @__PURE__ */ new Set());
1707
+ // 在当前段落开始的评论
1708
+ // 页码相关状态
1709
+ g(this, "currentPageNumber", 1);
1710
+ g(this, "totalPages", 1);
1711
+ g(this, "inComplexField", !1);
1712
+ // 是否在复杂域中
1713
+ g(this, "currentFieldInstruction", "");
1714
+ // 当前域指令
1715
+ g(this, "skipFieldContent", !1);
1716
+ // 是否跳过域的静态内容(separate 后)
1717
+ // 编号/列表相关状态
1718
+ // 编号计数器:key 格式为 "numId-level",value 为当前计数
1719
+ g(this, "numberingCounters", /* @__PURE__ */ new Map());
1720
+ // 脚注/尾注相关状态
1721
+ g(this, "currentFootnoteIds", []);
1722
+ // 当前页面引用的脚注 ID
1723
+ g(this, "currentEndnoteIds", []);
1724
+ // 文档中引用的尾注 ID
1725
+ g(this, "footnoteCounter", 0);
1726
+ // 脚注编号计数器
1727
+ g(this, "endnoteCounter", 0);
1728
+ // 表格垂直合并状态
1729
+ g(this, "tableVerticalMerges", []);
1730
+ g(this, "currentVerticalMerge", /* @__PURE__ */ new Map());
1731
+ g(this, "currentCellCol", 0);
1732
+ // 表格边框状态(用于 insideH/insideV 内部边框)
1733
+ g(this, "currentTableBorders");
1734
+ g(this, "tableBordersStack", []);
1735
+ g(this, "currentTableRowIndex", 0);
1736
+ g(this, "currentTableRowCount", 0);
1737
+ g(this, "currentTableColCount", 0);
1738
+ const t = typeof e.container == "string" ? document.querySelector(e.container) : e.container;
1739
+ if (!t)
1740
+ throw new Error("容器元素不存在");
1741
+ this.container = t, this.classPrefix = e.classNamePrefix || "docx", this.options = {
1742
+ container: this.container,
1743
+ renderComments: e.renderComments ?? !0,
1744
+ enableCommentEdit: e.enableCommentEdit ?? !0,
1745
+ showCommentLines: e.showCommentLines ?? !0,
1746
+ breakPages: e.breakPages ?? !0,
1747
+ classNamePrefix: this.classPrefix,
1748
+ onCommentClick: e.onCommentClick || (() => {
1749
+ }),
1750
+ onCommentChange: e.onCommentChange || (() => {
1751
+ })
1752
+ };
1753
+ }
1754
+ /**
1755
+ * 渲染文档
1756
+ */
1757
+ render(e) {
1758
+ this.document = e, this.commentRanges.clear(), this.currentCommentIds.clear(), this.numberingCounters.clear(), this.currentFootnoteIds = [], this.currentEndnoteIds = [], this.footnoteCounter = 0, this.endnoteCounter = 0;
1759
+ for (const i of e.comments)
1760
+ this.commentRanges.set(i.id, {
1761
+ id: i.id,
1762
+ startElement: null,
1763
+ endElement: null,
1764
+ highlightElements: [],
1765
+ panelElement: null
1766
+ });
1767
+ this.container.innerHTML = "", this.container.className = `${this.classPrefix}-container`;
1768
+ const t = this.createElement("div", `${this.classPrefix}-wrapper`);
1769
+ this.options.breakPages ? this.renderWithPages(t, e) : this.renderSinglePage(t, e), this.container.appendChild(t), this.options.showCommentLines && (this.svgLayer = this.createSvgLayer(), this.container.appendChild(this.svgLayer)), this.options.renderComments && this.renderAllCommentBubbles();
1770
+ let n = !1;
1771
+ const r = () => {
1772
+ n || (requestAnimationFrame(() => {
1773
+ this.positionCommentBubbles(), this.updateLines(), n = !1;
1774
+ }), n = !0);
1775
+ };
1776
+ t.addEventListener("scroll", () => {
1777
+ this.positionCommentBubbles(), this.updateLines();
1778
+ }, { passive: !0 }), window.addEventListener("resize", r), requestAnimationFrame(() => {
1779
+ this.positionCommentBubbles(), this.updateLines();
1780
+ });
1781
+ }
1782
+ /**
1783
+ * 单页渲染模式
1784
+ */
1785
+ renderSinglePage(e, t) {
1786
+ const n = this.createElement("div", `${this.classPrefix}-document`), r = this.createElement("div", `${this.classPrefix}-page`), i = this.renderElement(t.body);
1787
+ i && r.appendChild(i), this.renderPageFootnotes(this.currentFootnoteIds, r), n.appendChild(r), e.appendChild(n), this.renderDocumentEndnotes(e);
1788
+ }
1789
+ /**
1790
+ * 分页渲染模式
1791
+ */
1792
+ renderWithPages(e, t) {
1793
+ const n = t.body, r = n.sectionProps, i = this.splitBySection(n.children || [], r), a = this.groupByPageBreaks(i);
1794
+ this.totalPages = a.length;
1795
+ let c;
1796
+ for (let l = 0; l < a.length; l++) {
1797
+ this.currentPageNumber = l + 1;
1798
+ const d = this.currentFootnoteIds.length, h = a[l];
1799
+ if (h.length === 0) continue;
1800
+ let u = h[0].sectProps || r;
1801
+ const f = this.createPageElement(u);
1802
+ u != null && u.headerRefs && this.renderHeaderFooter(
1803
+ u.headerRefs,
1804
+ u,
1805
+ l,
1806
+ c !== u,
1807
+ f,
1808
+ "header"
1809
+ );
1810
+ for (const y of h) {
1811
+ const v = this.createSectionContent(y.sectProps);
1812
+ for (const k of y.elements) {
1813
+ const E = this.renderElement(k);
1814
+ E && v.appendChild(E);
1815
+ }
1816
+ f.appendChild(v), u = y.sectProps || u;
1817
+ }
1818
+ const b = this.currentFootnoteIds.slice(d);
1819
+ this.renderPageFootnotes(b, f), u != null && u.footerRefs && this.renderHeaderFooter(
1820
+ u.footerRefs,
1821
+ u,
1822
+ l,
1823
+ c !== u,
1824
+ f,
1825
+ "footer"
1826
+ ), e.appendChild(f), c = u;
1827
+ }
1828
+ this.renderDocumentEndnotes(e);
1829
+ }
1830
+ /**
1831
+ * 按 Section 分割内容
1832
+ */
1833
+ splitBySection(e, t) {
1834
+ var a, c;
1835
+ const n = [];
1836
+ let r = { sectProps: null, elements: [], pageBreak: !1 };
1837
+ n.push(r);
1838
+ for (const l of e)
1839
+ if (l.type === m.Paragraph && (a = l.props) != null && a.pageBreakBefore && (r.pageBreak = !0, r = { sectProps: null, elements: [], pageBreak: !1 }, n.push(r)), r.elements.push(l), l.type === m.Paragraph) {
1840
+ const d = l, h = (c = d.props) == null ? void 0 : c.sectionProps;
1841
+ let p = !1;
1842
+ const u = (f) => {
1843
+ for (const b of f) {
1844
+ if (b.type === m.Break) {
1845
+ const y = b;
1846
+ if (y.breakType === "page" || y.breakType === "lastRenderedPageBreak") {
1847
+ p = !0;
1848
+ return;
1849
+ }
1850
+ }
1851
+ b.type === m.Run && b.children && u(b.children);
1852
+ }
1853
+ };
1854
+ this.options.breakPages && d.children && u(d.children), (h || p) && (r.sectProps = h || null, r.pageBreak = p, r = { sectProps: null, elements: [], pageBreak: !1 }, n.push(r));
1855
+ }
1856
+ let i = null;
1857
+ for (let l = n.length - 1; l >= 0; l--)
1858
+ n[l].sectProps === null ? n[l].sectProps = i || t || null : i = n[l].sectProps;
1859
+ return n;
1860
+ }
1861
+ /**
1862
+ * 按分页符分组
1863
+ */
1864
+ groupByPageBreaks(e) {
1865
+ const t = [];
1866
+ let n = [];
1867
+ t.push(n);
1868
+ let r = null;
1869
+ for (const i of e)
1870
+ n.push(i), (i.pageBreak || this.isPageBreakSection(r, i.sectProps)) && (n = [], t.push(n)), r = i.sectProps;
1871
+ return t.filter((i) => i.length > 0);
1872
+ }
1873
+ /**
1874
+ * 检查是否因为 Section 属性变化需要分页
1875
+ */
1876
+ isPageBreakSection(e, t) {
1877
+ if (!e || !t) return !1;
1878
+ const n = e.pageSize, r = t.pageSize;
1879
+ return !n || !r ? !1 : n.orientation !== r.orientation || n.width !== r.width || n.height !== r.height;
1880
+ }
1881
+ /**
1882
+ * 创建页面元素
1883
+ */
1884
+ createPageElement(e) {
1885
+ const t = this.createElement("section", `${this.classPrefix}-page`);
1886
+ if (e && (e.pageSize && (e.pageSize.width && (t.style.width = e.pageSize.width), e.pageSize.height && (t.style.minHeight = e.pageSize.height)), e.pageMargins)) {
1887
+ const n = e.pageMargins;
1888
+ n.top && (t.style.paddingTop = n.top), n.right && (t.style.paddingRight = n.right), n.bottom && (t.style.paddingBottom = n.bottom), n.left && (t.style.paddingLeft = n.left);
1889
+ }
1890
+ return t;
1891
+ }
1892
+ /**
1893
+ * 创建 Section 内容区域
1894
+ */
1895
+ createSectionContent(e) {
1896
+ const t = this.createElement("article", `${this.classPrefix}-section-content`);
1897
+ if (e != null && e.columns) {
1898
+ const n = e.columns;
1899
+ n.numberOfColumns && n.numberOfColumns > 1 && (t.style.columnCount = String(n.numberOfColumns), n.space && (t.style.columnGap = n.space), n.separator && (t.style.columnRule = "1px solid #ccc"));
1900
+ }
1901
+ return t;
1902
+ }
1903
+ /**
1904
+ * 渲染页眉或页脚
1905
+ */
1906
+ renderHeaderFooter(e, t, n, r, i, a) {
1907
+ var p, u;
1908
+ if (!e || e.length === 0) return;
1909
+ let c = null;
1910
+ if (t.titlePage && r && (c = e.find((f) => f.type === "first")), c || n % 2 === 1 && (c = e.find((f) => f.type === "even")), c || (c = e.find((f) => f.type === "default")), !c) return;
1911
+ const l = a === "header" ? (p = this.document) == null ? void 0 : p.headers : (u = this.document) == null ? void 0 : u.footers, d = l == null ? void 0 : l.get(c.id);
1912
+ if (!d) return;
1913
+ const h = this.createElement("div", `${this.classPrefix}-${a}`);
1914
+ for (const f of d.children || []) {
1915
+ const b = this.renderElement(f);
1916
+ b && h.appendChild(b);
1917
+ }
1918
+ if (t.pageMargins) {
1919
+ const f = t.pageMargins;
1920
+ a === "header" && f.header && f.top ? (h.style.marginTop = `calc(${f.header} - ${f.top})`, h.style.minHeight = `calc(${f.top} - ${f.header})`) : a === "footer" && f.footer && f.bottom && (h.style.marginBottom = `calc(${f.footer} - ${f.bottom})`, h.style.minHeight = `calc(${f.bottom} - ${f.footer})`);
1921
+ }
1922
+ a === "header" ? i.insertBefore(h, i.firstChild) : i.appendChild(h);
1923
+ }
1924
+ /**
1925
+ * 渲染所有评论气泡(右侧固定面板)
1926
+ */
1927
+ renderAllCommentBubbles() {
1928
+ var n;
1929
+ const e = this.createElement("div", `${this.classPrefix}-comments-layer`);
1930
+ this.container.appendChild(e);
1931
+ const t = ((n = this.document) == null ? void 0 : n.comments) || [];
1932
+ console.log("[DEBUG] renderAllCommentBubbles - Total comments:", t.length), t.forEach((r) => {
1933
+ var i;
1934
+ console.log("[DEBUG] Comment:", {
1935
+ id: r.id,
1936
+ author: r.author,
1937
+ date: r.date,
1938
+ childrenCount: ((i = r.children) == null ? void 0 : i.length) || 0,
1939
+ text: this.getCommentText(r)
1940
+ });
1941
+ }), console.log("[DEBUG] Comment ranges count:", this.commentRanges.size);
1942
+ for (const r of t) {
1943
+ const i = this.commentRanges.get(r.id);
1944
+ if (i && i.highlightElements.length > 0) {
1945
+ const a = this.createCommentBubble(r);
1946
+ i.panelElement = a, e.appendChild(a);
1947
+ }
1948
+ }
1949
+ }
1950
+ /**
1951
+ * 定位评论气泡到对应的高亮文字旁边
1952
+ * 原文不可见时隐藏评论
1953
+ */
1954
+ positionCommentBubbles() {
1955
+ const e = [], n = window.innerHeight - 40;
1956
+ for (const [, i] of this.commentRanges) {
1957
+ if (!i.panelElement || i.highlightElements.length === 0) continue;
1958
+ const c = i.highlightElements[0].getBoundingClientRect(), l = c.top + c.height / 2;
1959
+ l > 60 && l < n ? (e.push({ range: i, top: c.top }), i.panelElement.style.display = "block") : i.panelElement.style.display = "none";
1960
+ }
1961
+ e.sort((i, a) => i.top - a.top);
1962
+ let r = 60;
1963
+ for (const { range: i, top: a } of e) {
1964
+ let c = Math.max(a, r + 8);
1965
+ c = Math.min(c, n - 100), i.panelElement.style.top = `${c}px`, r = c + i.panelElement.offsetHeight;
1966
+ }
1967
+ }
1968
+ /**
1969
+ * 创建 SVG 连线层
1970
+ */
1971
+ createSvgLayer() {
1972
+ const e = document.createElementNS("http://www.w3.org/2000/svg", "svg");
1973
+ return e.classList.add(`${this.classPrefix}-lines`), e;
1974
+ }
1975
+ /**
1976
+ * 更新所有连线
1977
+ */
1978
+ updateLines() {
1979
+ if (this.svgLayer) {
1980
+ this.svgLayer.innerHTML = "";
1981
+ for (const [e] of this.commentRanges) {
1982
+ const t = e === this.activeCommentId;
1983
+ this.drawCommentLine(e, t);
1984
+ }
1985
+ }
1986
+ }
1987
+ /**
1988
+ * 绘制单个评论的连线
1989
+ */
1990
+ drawCommentLine(e, t) {
1991
+ const n = this.commentRanges.get(e);
1992
+ if (!n || !n.highlightElements.length || !n.panelElement || !this.svgLayer || n.panelElement.style.display === "none") return;
1993
+ const r = n.highlightElements[0].getBoundingClientRect(), i = n.panelElement.getBoundingClientRect(), a = r.right, c = r.top + r.height / 2, l = i.left, d = i.top + 16, h = document.createElementNS("http://www.w3.org/2000/svg", "line");
1994
+ h.setAttribute("x1", String(a)), h.setAttribute("y1", String(c)), h.setAttribute("x2", String(l)), h.setAttribute("y2", String(d)), h.setAttribute("stroke", "#ef4444"), h.setAttribute("stroke-width", t ? "2" : "1"), this.svgLayer.appendChild(h);
1995
+ }
1996
+ /**
1997
+ * 渲染元素
1998
+ */
1999
+ renderElement(e) {
2000
+ switch (e.type) {
2001
+ case m.Document:
2002
+ return this.renderDocument(e);
2003
+ case m.Paragraph:
2004
+ return this.renderParagraph(e);
2005
+ case m.Run:
2006
+ return this.renderRun(e);
2007
+ case m.Text:
2008
+ return this.renderText(e);
2009
+ case m.Break:
2010
+ return this.renderBreak(e);
2011
+ case m.Tab:
2012
+ return this.renderTab();
2013
+ case m.Symbol:
2014
+ return this.renderSymbol(e);
2015
+ case m.SimpleField:
2016
+ return this.renderSimpleField(e);
2017
+ case m.ComplexField:
2018
+ return this.renderComplexField(e);
2019
+ case m.FieldInstruction:
2020
+ return this.renderFieldInstruction(e);
2021
+ case m.Table:
2022
+ return this.renderTable(e);
2023
+ case m.TableRow:
2024
+ return this.renderTableRow(e);
2025
+ case m.TableCell:
2026
+ return this.renderTableCell(e);
2027
+ case m.Hyperlink:
2028
+ return this.renderHyperlink(e);
2029
+ case m.Drawing:
2030
+ return this.renderDrawing(e);
2031
+ case m.Image:
2032
+ return this.renderImage(e);
2033
+ case m.CommentRangeStart:
2034
+ return this.renderCommentRangeStart(e);
2035
+ case m.CommentRangeEnd:
2036
+ return this.renderCommentRangeEnd(e);
2037
+ case m.CommentReference:
2038
+ return this.renderCommentReference(e);
2039
+ case m.FootnoteReference:
2040
+ return this.renderFootnoteReference(e);
2041
+ case m.EndnoteReference:
2042
+ return this.renderEndnoteReference(e);
2043
+ case m.Footnote:
2044
+ return this.renderFootnote(e);
2045
+ case m.Endnote:
2046
+ return this.renderEndnote(e);
2047
+ case m.BookmarkStart:
2048
+ return this.renderBookmarkStart(e);
2049
+ case m.BookmarkEnd:
2050
+ return this.renderBookmarkEnd(e);
2051
+ default:
2052
+ return null;
2053
+ }
2054
+ }
2055
+ /**
2056
+ * 渲染文档
2057
+ */
2058
+ renderDocument(e) {
2059
+ const t = this.createElement("article", `${this.classPrefix}-body`);
2060
+ return this.renderChildren(e.children || [], t), t;
2061
+ }
2062
+ /**
2063
+ * 渲染段落
2064
+ */
2065
+ renderParagraph(e) {
2066
+ const t = this.createElement("p", `${this.classPrefix}-p`);
2067
+ this.commentStartInParagraph.clear(), e.props && this.applyParagraphStyles(t, e.props);
2068
+ const n = this.renderNumbering(e.props);
2069
+ return n && (t.insertBefore(n, t.firstChild), t.classList.add(`${this.classPrefix}-list-item`)), this.renderChildren(e.children || [], t), (t.childNodes.length === 0 || t.childNodes.length === 1 && n) && t.appendChild(document.createElement("br")), this.commentStartInParagraph.size > 0 && this.options.renderComments && (t.dataset.commentIds = Array.from(this.commentStartInParagraph).join(",")), t;
2070
+ }
2071
+ /**
2072
+ * 渲染编号
2073
+ */
2074
+ renderNumbering(e) {
2075
+ var h, p;
2076
+ if (!(e != null && e.numbering) || !((h = this.document) != null && h.numberingMap))
2077
+ return null;
2078
+ const { id: t, level: n } = e.numbering, r = this.document.numberingMap.get(t);
2079
+ if (!r)
2080
+ return null;
2081
+ const i = r.levels.find((u) => u.level === n);
2082
+ if (!i)
2083
+ return null;
2084
+ const a = this.getNumberingContent(r, i, t, n), c = this.createElement("span", `${this.classPrefix}-numbering`);
2085
+ c.textContent = a, i.runProps && this.applyRunStyles(c, i.runProps);
2086
+ const l = this.createElement("span", `${this.classPrefix}-numbering-suffix`);
2087
+ switch (i.suffix) {
2088
+ case "tab":
2089
+ l.innerHTML = "&emsp;";
2090
+ break;
2091
+ case "space":
2092
+ l.innerHTML = "&nbsp;";
2093
+ break;
2094
+ }
2095
+ const d = this.createElement("span", `${this.classPrefix}-numbering-wrapper`);
2096
+ if (d.appendChild(c), d.appendChild(l), (p = i.paragraphProps) != null && p.indentation) {
2097
+ const u = i.paragraphProps.indentation;
2098
+ u.left && (d.style.marginLeft = u.left), u.hanging && (d.style.textIndent = `-${u.hanging}`, d.style.paddingLeft = u.hanging);
2099
+ }
2100
+ return d;
2101
+ }
2102
+ /**
2103
+ * 获取编号内容
2104
+ */
2105
+ getNumberingContent(e, t, n, r) {
2106
+ const i = t.format, a = t.text;
2107
+ if (i === "bullet")
2108
+ return a || "•";
2109
+ const c = `${n}-${r}`;
2110
+ let l = this.numberingCounters.get(c) ?? t.start - 1;
2111
+ l++, this.numberingCounters.set(c, l);
2112
+ for (let h = r + 1; h <= 8; h++)
2113
+ this.numberingCounters.delete(`${n}-${h}`);
2114
+ let d = a;
2115
+ for (let h = 0; h <= r; h++) {
2116
+ const p = this.numberingCounters.get(`${n}-${h}`) ?? 1, u = e.levels.find((y) => y.level === h), f = (u == null ? void 0 : u.format) || "decimal", b = this.formatNumber(p, f);
2117
+ d = d.replace(`%${h + 1}`, b);
2118
+ }
2119
+ return d;
2120
+ }
2121
+ /**
2122
+ * 格式化编号
2123
+ */
2124
+ formatNumber(e, t) {
2125
+ switch (t) {
2126
+ case "decimal":
2127
+ return String(e);
2128
+ case "decimalZero":
2129
+ return e < 10 ? `0${e}` : String(e);
2130
+ case "lowerLetter":
2131
+ return this.toLetters(e, !1);
2132
+ case "upperLetter":
2133
+ return this.toLetters(e, !0);
2134
+ case "lowerRoman":
2135
+ return this.toRoman(e).toLowerCase();
2136
+ case "upperRoman":
2137
+ return this.toRoman(e);
2138
+ case "chineseCountingThousand":
2139
+ case "chineseCounting":
2140
+ return this.toChinese(e);
2141
+ case "ideographTraditional":
2142
+ return this.toChineseTraditional(e);
2143
+ case "bullet":
2144
+ return "•";
2145
+ default:
2146
+ return String(e);
2147
+ }
2148
+ }
2149
+ /**
2150
+ * 数字转字母
2151
+ */
2152
+ toLetters(e, t) {
2153
+ const n = t ? 65 : 97;
2154
+ let r = "";
2155
+ for (; e > 0; )
2156
+ e--, r = String.fromCharCode(n + e % 26) + r, e = Math.floor(e / 26);
2157
+ return r;
2158
+ }
2159
+ /**
2160
+ * 数字转罗马数字
2161
+ */
2162
+ toRoman(e) {
2163
+ const t = [
2164
+ [1e3, "M"],
2165
+ [900, "CM"],
2166
+ [500, "D"],
2167
+ [400, "CD"],
2168
+ [100, "C"],
2169
+ [90, "XC"],
2170
+ [50, "L"],
2171
+ [40, "XL"],
2172
+ [10, "X"],
2173
+ [9, "IX"],
2174
+ [5, "V"],
2175
+ [4, "IV"],
2176
+ [1, "I"]
2177
+ ];
2178
+ let n = "";
2179
+ for (const [r, i] of t)
2180
+ for (; e >= r; )
2181
+ n += i, e -= r;
2182
+ return n;
2183
+ }
2184
+ /**
2185
+ * 数字转中文数字
2186
+ */
2187
+ toChinese(e) {
2188
+ const t = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"], n = ["", "十", "百", "千", "万"];
2189
+ if (e <= 10)
2190
+ return e === 10 ? "十" : t[e];
2191
+ let r = "", i = 0;
2192
+ for (; e > 0; ) {
2193
+ const a = e % 10;
2194
+ a !== 0 ? r = t[a] + n[i] + r : r && !r.startsWith("零") && (r = "零" + r), e = Math.floor(e / 10), i++;
2195
+ }
2196
+ return r.startsWith("一十") && (r = r.substring(1)), r;
2197
+ }
2198
+ /**
2199
+ * 数字转中文传统数字(甲乙丙丁...)
2200
+ */
2201
+ toChineseTraditional(e) {
2202
+ const t = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"];
2203
+ return e >= 1 && e <= 10 ? t[e - 1] : String(e);
2204
+ }
2205
+ /**
2206
+ * 创建评论气泡
2207
+ */
2208
+ createCommentBubble(e) {
2209
+ const t = this.createElement("div", `${this.classPrefix}-comment-bubble`);
2210
+ t.dataset.commentId = e.id;
2211
+ const n = e.initials || e.author.charAt(0).toUpperCase(), r = this.formatDate(e.date), i = this.getCommentText(e);
2212
+ t.innerHTML = `
2213
+ <div class="${this.classPrefix}-comment-header">
2214
+ <div class="${this.classPrefix}-comment-avatar">${this.escapeHtml(n)}</div>
2215
+ <div class="${this.classPrefix}-comment-meta">
2216
+ <span class="${this.classPrefix}-comment-author">${this.escapeHtml(e.author)}</span>
2217
+ <span class="${this.classPrefix}-comment-date">${r}</span>
2218
+ </div>
2219
+ </div>
2220
+ <div class="${this.classPrefix}-comment-content">${this.escapeHtml(i)}</div>
2221
+ ${this.options.enableCommentEdit ? `
2222
+ <div class="${this.classPrefix}-comment-actions">
2223
+ <button class="${this.classPrefix}-comment-btn edit" title="编辑">
2224
+ <svg viewBox="0 0 24 24" width="14" height="14"><path fill="currentColor" d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>
2225
+ </button>
2226
+ <button class="${this.classPrefix}-comment-btn delete" title="删除">
2227
+ <svg viewBox="0 0 24 24" width="14" height="14"><path fill="currentColor" d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>
2228
+ </button>
2229
+ </div>
2230
+ ` : ""}
2231
+ `, t.addEventListener("mouseenter", () => this.highlightComment(e.id)), t.addEventListener("mouseleave", () => this.unhighlightComment(e.id)), t.addEventListener("click", () => {
2232
+ this.selectComment(e.id), this.options.onCommentClick(e);
2233
+ });
2234
+ const a = t.querySelector(".edit");
2235
+ a == null || a.addEventListener("click", (l) => {
2236
+ l.stopPropagation(), this.editComment(e);
2237
+ });
2238
+ const c = t.querySelector(".delete");
2239
+ return c == null || c.addEventListener("click", (l) => {
2240
+ l.stopPropagation(), this.deleteComment(e.id);
2241
+ }), t;
2242
+ }
2243
+ /**
2244
+ * 获取评论文本内容
2245
+ */
2246
+ getCommentText(e) {
2247
+ const t = [], n = (i) => {
2248
+ for (const a of i)
2249
+ a.type === m.Text && t.push(a.text), a.children && n(a.children);
2250
+ };
2251
+ n(e.children || []);
2252
+ const r = t.join("");
2253
+ return !r && e.rawText ? (console.log("[DEBUG] Comment", e.id, "using rawText:", e.rawText), e.rawText) : (console.log("[DEBUG] Comment", e.id, "text result:", r), r || "");
2254
+ }
2255
+ /**
2256
+ * 高亮评论
2257
+ */
2258
+ highlightComment(e) {
2259
+ var n;
2260
+ this.activeCommentId = e;
2261
+ const t = this.commentRanges.get(e);
2262
+ t && (t.highlightElements.forEach((r) => {
2263
+ r.classList.add(`${this.classPrefix}-highlight--active`);
2264
+ }), (n = t.panelElement) == null || n.classList.add(`${this.classPrefix}-comment-bubble--active`)), this.updateLines();
2265
+ }
2266
+ /**
2267
+ * 取消高亮评论
2268
+ */
2269
+ unhighlightComment(e) {
2270
+ var n;
2271
+ this.activeCommentId === e && (this.activeCommentId = null);
2272
+ const t = this.commentRanges.get(e);
2273
+ t && (t.highlightElements.forEach((r) => {
2274
+ r.classList.remove(`${this.classPrefix}-highlight--active`);
2275
+ }), (n = t.panelElement) == null || n.classList.remove(`${this.classPrefix}-comment-bubble--active`)), this.updateLines();
2276
+ }
2277
+ /**
2278
+ * 选中评论
2279
+ */
2280
+ selectComment(e) {
2281
+ this.activeCommentId = e, this.updateLines();
2282
+ }
2283
+ /**
2284
+ * 编辑评论
2285
+ */
2286
+ editComment(e) {
2287
+ const t = this.getCommentText(e), n = prompt("编辑评论:", t);
2288
+ if (n !== null && n !== t) {
2289
+ const r = { type: m.Text, text: n }, i = { type: m.Run, children: [r] }, a = { type: m.Paragraph, children: [i] };
2290
+ e.children = [a];
2291
+ const c = this.commentRanges.get(e.id);
2292
+ if (c != null && c.panelElement) {
2293
+ const l = c.panelElement.querySelector(`.${this.classPrefix}-comment-content`);
2294
+ l && (l.textContent = n);
2295
+ }
2296
+ this.options.onCommentChange(e, "update");
2297
+ }
2298
+ }
2299
+ /**
2300
+ * 删除评论
2301
+ */
2302
+ deleteComment(e) {
2303
+ var r, i;
2304
+ if (!confirm("确定要删除这条评论吗?")) return;
2305
+ const t = (r = this.document) == null ? void 0 : r.commentMap.get(e);
2306
+ if (!t) return;
2307
+ const n = this.commentRanges.get(e);
2308
+ if (n && (n.highlightElements.forEach((a) => {
2309
+ a.classList.remove(`${this.classPrefix}-highlight`), a.classList.remove(`${this.classPrefix}-highlight--active`);
2310
+ }), (i = n.panelElement) == null || i.remove()), this.document) {
2311
+ const a = this.document.comments.indexOf(t);
2312
+ a > -1 && this.document.comments.splice(a, 1), this.document.commentMap.delete(e);
2313
+ }
2314
+ this.commentRanges.delete(e), this.options.onCommentChange(t, "delete"), this.updateLines();
2315
+ }
2316
+ /**
2317
+ * 应用段落样式
2318
+ */
2319
+ applyParagraphStyles(e, t) {
2320
+ const n = [];
2321
+ if (t.justification) {
2322
+ const r = {
2323
+ left: "left",
2324
+ center: "center",
2325
+ right: "right",
2326
+ both: "justify"
2327
+ };
2328
+ n.push(`text-align: ${r[t.justification] || "left"}`);
2329
+ }
2330
+ if (t.indentation && (t.indentation.left && n.push(`padding-left: ${t.indentation.left}`), t.indentation.right && n.push(`padding-right: ${t.indentation.right}`), t.indentation.firstLine && n.push(`text-indent: ${t.indentation.firstLine}`)), t.spacing && (t.spacing.before && n.push(`margin-top: ${t.spacing.before}`), t.spacing.after && n.push(`margin-bottom: ${t.spacing.after}`), t.spacing.line !== void 0)) {
2331
+ const r = t.spacing.line;
2332
+ switch (t.spacing.lineRule) {
2333
+ case "auto":
2334
+ n.push(`line-height: ${(r / 240).toFixed(2)}`);
2335
+ break;
2336
+ case "atLeast":
2337
+ n.push(`line-height: calc(100% + ${r / 20}pt)`);
2338
+ break;
2339
+ case "exact":
2340
+ default:
2341
+ n.push(`line-height: ${r / 20}pt`);
2342
+ break;
2343
+ }
2344
+ }
2345
+ n.length > 0 && (e.style.cssText = n.join("; "));
2346
+ }
2347
+ /**
2348
+ * 渲染 Run
2349
+ */
2350
+ renderRun(e) {
2351
+ if (this.skipFieldContent && !(e.children || []).some(
2352
+ (r) => r.type === m.ComplexField && r.charType === "end"
2353
+ ))
2354
+ return null;
2355
+ const t = this.createElement("span", `${this.classPrefix}-run`);
2356
+ if (this.currentCommentIds.size > 0) {
2357
+ t.classList.add(`${this.classPrefix}-highlight`);
2358
+ for (const n of this.currentCommentIds) {
2359
+ t.classList.add(`${this.classPrefix}-highlight-${n}`), t.dataset.commentId = n;
2360
+ const r = this.commentRanges.get(n);
2361
+ r && r.highlightElements.push(t);
2362
+ }
2363
+ t.addEventListener("click", () => {
2364
+ const n = t.dataset.commentId;
2365
+ n && this.highlightComment(n);
2366
+ });
2367
+ }
2368
+ return e.props && this.applyRunStyles(t, e.props), this.renderChildren(e.children || [], t), t.childNodes.length === 0 ? null : t;
2369
+ }
2370
+ /**
2371
+ * 应用 Run 样式
2372
+ */
2373
+ applyRunStyles(e, t) {
2374
+ const n = [];
2375
+ t.bold && n.push("font-weight: bold"), t.italic && n.push("font-style: italic");
2376
+ const r = [];
2377
+ if (t.underline && t.underline !== "none" && (e.classList.add(`${this.classPrefix}-underline-${t.underline}`), this.isComplexUnderline(t.underline) || r.push("underline")), t.strike && r.push("line-through"), t.dstrike && e.classList.add(`${this.classPrefix}-dstrike`), r.length > 0 && n.push(`text-decoration: ${r.join(" ")}`), t.vertAlign && e.classList.add(`${this.classPrefix}-${t.vertAlign}`), t.color && n.push(`color: ${t.color}`), t.fontSize && n.push(`font-size: ${t.fontSize}`), t.fontFamily && n.push(`font-family: "${t.fontFamily}"`), t.highlight) {
2378
+ const i = {
2379
+ yellow: "#ffff00",
2380
+ green: "#00ff00",
2381
+ cyan: "#00ffff",
2382
+ magenta: "#ff00ff",
2383
+ blue: "#0000ff",
2384
+ red: "#ff0000",
2385
+ darkBlue: "#000080",
2386
+ darkCyan: "#008080",
2387
+ darkGreen: "#008000",
2388
+ darkMagenta: "#800080",
2389
+ darkRed: "#800000",
2390
+ darkYellow: "#808000",
2391
+ darkGray: "#808080",
2392
+ lightGray: "#c0c0c0",
2393
+ black: "#000000"
2394
+ };
2395
+ n.push(`background-color: ${i[t.highlight] || t.highlight}`);
2396
+ }
2397
+ n.length > 0 && (e.style.cssText = n.join("; "));
2398
+ }
2399
+ /**
2400
+ * 检查是否是复杂下划线样式(需要特殊 CSS 处理)
2401
+ */
2402
+ isComplexUnderline(e) {
2403
+ return [
2404
+ "double",
2405
+ "thick",
2406
+ "dotted",
2407
+ "dottedHeavy",
2408
+ "dash",
2409
+ "dashedHeavy",
2410
+ "dashLong",
2411
+ "dashLongHeavy",
2412
+ "dotDash",
2413
+ "dashDotHeavy",
2414
+ "dotDotDash",
2415
+ "dashDotDotHeavy",
2416
+ "wave",
2417
+ "wavyHeavy",
2418
+ "wavyDouble"
2419
+ ].includes(e);
2420
+ }
2421
+ /**
2422
+ * 渲染文本
2423
+ */
2424
+ renderText(e) {
2425
+ if (this.skipFieldContent)
2426
+ return null;
2427
+ const t = document.createElement("span");
2428
+ return t.textContent = e.text, t;
2429
+ }
2430
+ /**
2431
+ * 渲染换行
2432
+ */
2433
+ renderBreak(e) {
2434
+ switch (e.breakType) {
2435
+ case "page":
2436
+ case "lastRenderedPageBreak":
2437
+ const t = this.createElement("div", `${this.classPrefix}-page-break`);
2438
+ return t.style.pageBreakAfter = "always", t;
2439
+ case "column":
2440
+ const n = this.createElement("span", `${this.classPrefix}-column-break`);
2441
+ return n.style.breakAfter = "column", n;
2442
+ default:
2443
+ return document.createElement("br");
2444
+ }
2445
+ }
2446
+ /**
2447
+ * 渲染 Tab
2448
+ */
2449
+ renderTab() {
2450
+ const e = this.createElement("span", `${this.classPrefix}-tab`);
2451
+ return e.innerHTML = "&emsp;", e;
2452
+ }
2453
+ /**
2454
+ * 渲染 Symbol 字符
2455
+ * 处理 Word 中的特殊符号字符(如 Wingdings、Symbol 字体中的符号)
2456
+ */
2457
+ renderSymbol(e) {
2458
+ const t = this.createElement("span", `${this.classPrefix}-symbol`);
2459
+ return e.font && (t.style.fontFamily = `"${e.font}", "Segoe UI Symbol", "Apple Symbols", sans-serif`), e.char ? t.textContent = e.char : t.textContent = "□", t;
2460
+ }
2461
+ /**
2462
+ * 渲染简单域 - 如 PAGE, NUMPAGES 等
2463
+ */
2464
+ renderSimpleField(e) {
2465
+ const t = e.instruction.trim().toUpperCase(), n = this.evaluateFieldInstruction(t);
2466
+ if (n !== null) {
2467
+ const i = this.createElement("span", `${this.classPrefix}-field`);
2468
+ return i.textContent = n, i;
2469
+ }
2470
+ const r = this.createElement("span", `${this.classPrefix}-field`);
2471
+ return this.renderChildren(e.children || [], r), r;
2472
+ }
2473
+ /**
2474
+ * 渲染复杂域字符
2475
+ */
2476
+ renderComplexField(e) {
2477
+ switch (e.charType) {
2478
+ case "begin":
2479
+ return this.inComplexField = !0, this.skipFieldContent = !1, this.currentFieldInstruction = "", null;
2480
+ case "separate":
2481
+ const t = this.evaluateFieldInstruction(this.currentFieldInstruction.trim().toUpperCase());
2482
+ if (t !== null) {
2483
+ this.skipFieldContent = !0;
2484
+ const n = this.createElement("span", `${this.classPrefix}-field`);
2485
+ return n.textContent = t, n;
2486
+ }
2487
+ return null;
2488
+ case "end":
2489
+ return this.inComplexField = !1, this.skipFieldContent = !1, this.currentFieldInstruction = "", null;
2490
+ default:
2491
+ return null;
2492
+ }
2493
+ }
2494
+ /**
2495
+ * 渲染域指令
2496
+ */
2497
+ renderFieldInstruction(e) {
2498
+ return this.inComplexField && (this.currentFieldInstruction += e.text), null;
2499
+ }
2500
+ /**
2501
+ * 计算域值
2502
+ */
2503
+ evaluateFieldInstruction(e) {
2504
+ switch (e.split(/\s+/)[0]) {
2505
+ case "PAGE":
2506
+ return String(this.currentPageNumber);
2507
+ case "NUMPAGES":
2508
+ return String(this.totalPages);
2509
+ case "DATE":
2510
+ return (/* @__PURE__ */ new Date()).toLocaleDateString("zh-CN");
2511
+ case "TIME":
2512
+ return (/* @__PURE__ */ new Date()).toLocaleTimeString("zh-CN");
2513
+ default:
2514
+ return null;
2515
+ }
2516
+ }
2517
+ /**
2518
+ * 渲染表格
2519
+ */
2520
+ renderTable(e) {
2521
+ var r, i, a;
2522
+ const t = this.createElement("table", `${this.classPrefix}-table`);
2523
+ if (this.tableVerticalMerges.push(this.currentVerticalMerge), this.currentVerticalMerge = /* @__PURE__ */ new Map(), this.tableBordersStack.push(this.currentTableBorders), this.currentTableBorders = (r = e.props) == null ? void 0 : r.borders, this.currentTableRowCount = ((i = e.children) == null ? void 0 : i.length) || 0, this.currentTableColCount = ((a = e.columns) == null ? void 0 : a.length) || 0, this.currentTableRowIndex = 0, e.columns && e.columns.length > 0) {
2524
+ const c = document.createElement("colgroup");
2525
+ for (const l of e.columns) {
2526
+ const d = document.createElement("col");
2527
+ l.width && (d.style.width = l.width), c.appendChild(d);
2528
+ }
2529
+ t.appendChild(c);
2530
+ }
2531
+ e.props && this.applyTableStyles(t, e.props);
2532
+ const n = document.createElement("tbody");
2533
+ for (const c of e.children || []) {
2534
+ this.currentCellCol = 0;
2535
+ const l = this.renderTableRow(c);
2536
+ n.appendChild(l), this.currentTableRowIndex++;
2537
+ }
2538
+ return t.appendChild(n), this.currentVerticalMerge = this.tableVerticalMerges.pop() || /* @__PURE__ */ new Map(), this.currentTableBorders = this.tableBordersStack.pop(), t;
2539
+ }
2540
+ /**
2541
+ * 应用表格样式
2542
+ */
2543
+ applyTableStyles(e, t) {
2544
+ t.width && (t.widthType, e.style.width = t.width), t.justification === "center" && (e.style.marginLeft = "auto", e.style.marginRight = "auto"), t.cellSpacing && (e.style.borderSpacing = t.cellSpacing, e.style.borderCollapse = "separate");
2545
+ }
2546
+ /**
2547
+ * 将边框属性转换为 CSS 字符串
2548
+ */
2549
+ borderToCss(e) {
2550
+ if (!e || !e.style)
2551
+ return "none";
2552
+ const t = this.parseBorderType(e.style);
2553
+ if (t === "none")
2554
+ return "none";
2555
+ const n = e.width || "1px", r = e.color || "black";
2556
+ return `${n} ${t} ${r}`;
2557
+ }
2558
+ /**
2559
+ * 将 Word 边框类型转换为 CSS 边框样式
2560
+ */
2561
+ parseBorderType(e) {
2562
+ switch (e) {
2563
+ case "single":
2564
+ return "solid";
2565
+ case "dashDotStroked":
2566
+ return "solid";
2567
+ case "dashed":
2568
+ return "dashed";
2569
+ case "dashSmallGap":
2570
+ return "dashed";
2571
+ case "dotDash":
2572
+ return "dotted";
2573
+ case "dotDotDash":
2574
+ return "dotted";
2575
+ case "dotted":
2576
+ return "dotted";
2577
+ case "double":
2578
+ return "double";
2579
+ case "doubleWave":
2580
+ return "double";
2581
+ case "inset":
2582
+ return "inset";
2583
+ case "nil":
2584
+ return "none";
2585
+ case "none":
2586
+ return "none";
2587
+ case "outset":
2588
+ return "outset";
2589
+ case "thick":
2590
+ return "solid";
2591
+ case "thickThinLargeGap":
2592
+ return "solid";
2593
+ case "thickThinMediumGap":
2594
+ return "solid";
2595
+ case "thickThinSmallGap":
2596
+ return "solid";
2597
+ case "thinThickLargeGap":
2598
+ return "solid";
2599
+ case "thinThickMediumGap":
2600
+ return "solid";
2601
+ case "thinThickSmallGap":
2602
+ return "solid";
2603
+ case "thinThickThinLargeGap":
2604
+ return "solid";
2605
+ case "thinThickThinMediumGap":
2606
+ return "solid";
2607
+ case "thinThickThinSmallGap":
2608
+ return "solid";
2609
+ case "threeDEmboss":
2610
+ return "solid";
2611
+ case "threeDEngrave":
2612
+ return "solid";
2613
+ case "triple":
2614
+ return "double";
2615
+ case "wave":
2616
+ return "solid";
2617
+ default:
2618
+ return "solid";
2619
+ }
2620
+ }
2621
+ /**
2622
+ * 应用单元格边框样式
2623
+ */
2624
+ applyCellBorders(e, t, n, r, i) {
2625
+ const a = this.currentTableBorders, c = n === 0, l = n === this.currentTableRowCount - 1, d = r === 0, h = r + i >= this.currentTableColCount;
2626
+ let p = t == null ? void 0 : t.top;
2627
+ p || (c ? p = a == null ? void 0 : a.top : p = a == null ? void 0 : a.insideH), p && (e.style.borderTop = this.borderToCss(p));
2628
+ let u = t == null ? void 0 : t.bottom;
2629
+ u || (l ? u = a == null ? void 0 : a.bottom : u = a == null ? void 0 : a.insideH), u && (e.style.borderBottom = this.borderToCss(u));
2630
+ let f = t == null ? void 0 : t.left;
2631
+ f || (d ? f = a == null ? void 0 : a.left : f = a == null ? void 0 : a.insideV), f && (e.style.borderLeft = this.borderToCss(f));
2632
+ let b = t == null ? void 0 : t.right;
2633
+ b || (h ? b = a == null ? void 0 : a.right : b = a == null ? void 0 : a.insideV), b && (e.style.borderRight = this.borderToCss(b));
2634
+ }
2635
+ /**
2636
+ * 渲染表格行
2637
+ */
2638
+ renderTableRow(e) {
2639
+ const t = this.createElement("tr", `${this.classPrefix}-tr`);
2640
+ this.currentCellCol = 0;
2641
+ for (const n of e.children || []) {
2642
+ const r = this.renderTableCell(n);
2643
+ r && t.appendChild(r);
2644
+ }
2645
+ return t;
2646
+ }
2647
+ /**
2648
+ * 渲染表格单元格
2649
+ */
2650
+ renderTableCell(e) {
2651
+ const t = this.createElement("td", `${this.classPrefix}-td`), n = e.props, r = this.currentCellCol, i = (n == null ? void 0 : n.gridSpan) || 1;
2652
+ if (n != null && n.verticalMerge)
2653
+ if (n.verticalMerge === "restart")
2654
+ this.currentVerticalMerge.set(r, t), t.rowSpan = 1;
2655
+ else {
2656
+ const a = this.currentVerticalMerge.get(r);
2657
+ if (a)
2658
+ return a.rowSpan += 1, this.currentCellCol += i, null;
2659
+ }
2660
+ else
2661
+ this.currentVerticalMerge.delete(r);
2662
+ return n && (n.width && (t.style.width = n.width), n.verticalAlign && (t.style.verticalAlign = n.verticalAlign), n.shading && (t.style.backgroundColor = n.shading), i > 1 && (t.colSpan = i)), this.applyCellBorders(
2663
+ t,
2664
+ n == null ? void 0 : n.borders,
2665
+ this.currentTableRowIndex,
2666
+ r,
2667
+ i
2668
+ ), this.renderChildren(e.children || [], t), this.currentCellCol += i, t;
2669
+ }
2670
+ /**
2671
+ * 渲染超链接
2672
+ */
2673
+ renderHyperlink(e) {
2674
+ const t = document.createElement("a");
2675
+ return t.className = `${this.classPrefix}-link`, e.href ? (t.href = e.href, t.target = "_blank", t.rel = "noopener noreferrer") : e.anchor && (t.href = `#${e.anchor}`), this.renderChildren(e.children || [], t), t;
2676
+ }
2677
+ /**
2678
+ * 渲染绘图
2679
+ */
2680
+ renderDrawing(e) {
2681
+ const t = this.createElement("span", `${this.classPrefix}-drawing`);
2682
+ return this.renderChildren(e.children || [], t), t;
2683
+ }
2684
+ /**
2685
+ * 渲染图片
2686
+ */
2687
+ renderImage(e) {
2688
+ const t = document.createElement("img");
2689
+ return t.className = `${this.classPrefix}-image`, t.src = e.src, e.width && (t.style.width = e.width), e.height && (t.style.height = e.height), e.alt && (t.alt = e.alt), t;
2690
+ }
2691
+ /**
2692
+ * 渲染评论范围开始
2693
+ */
2694
+ renderCommentRangeStart(e) {
2695
+ this.currentCommentIds.add(e.id), this.commentStartInParagraph.add(e.id);
2696
+ const t = this.createElement("span", `${this.classPrefix}-comment-start`);
2697
+ t.dataset.commentId = e.id;
2698
+ const n = this.commentRanges.get(e.id);
2699
+ return n && (n.startElement = t), t;
2700
+ }
2701
+ /**
2702
+ * 渲染评论范围结束
2703
+ */
2704
+ renderCommentRangeEnd(e) {
2705
+ this.currentCommentIds.delete(e.id);
2706
+ const t = this.createElement("span", `${this.classPrefix}-comment-end`);
2707
+ t.dataset.commentId = e.id;
2708
+ const n = this.commentRanges.get(e.id);
2709
+ return n && (n.endElement = t), t;
2710
+ }
2711
+ /**
2712
+ * 渲染评论引用
2713
+ */
2714
+ renderCommentReference(e) {
2715
+ const t = this.createElement("span", `${this.classPrefix}-comment-ref`);
2716
+ return t.dataset.commentId = e.id, t.textContent = "📝", t.title = "查看评论", t.addEventListener("click", () => {
2717
+ this.highlightComment(e.id);
2718
+ }), t;
2719
+ }
2720
+ /**
2721
+ * 渲染书签开始标记
2722
+ * 创建一个锚点元素,供超链接跳转使用
2723
+ */
2724
+ renderBookmarkStart(e) {
2725
+ if (e.name.startsWith("_"))
2726
+ return this.createElement("span");
2727
+ const t = this.createElement("span", `${this.classPrefix}-bookmark`);
2728
+ return t.id = e.name, t.dataset.bookmarkId = e.id, t.dataset.bookmarkName = e.name, t;
2729
+ }
2730
+ /**
2731
+ * 渲染书签结束标记
2732
+ * 书签结束标记不需要渲染任何可见内容
2733
+ */
2734
+ renderBookmarkEnd(e) {
2735
+ return this.createElement("span");
2736
+ }
2737
+ /**
2738
+ * 渲染脚注引用(文档正文中的上标数字)
2739
+ */
2740
+ renderFootnoteReference(e) {
2741
+ this.footnoteCounter++, this.currentFootnoteIds.push(e.id);
2742
+ const t = this.createElement("sup", `${this.classPrefix}-footnote-ref`);
2743
+ return t.dataset.footnoteId = e.id, t.textContent = String(this.footnoteCounter), t.title = "脚注", t.addEventListener("click", () => {
2744
+ const n = document.getElementById(`${this.classPrefix}-footnote-${e.id}`);
2745
+ n == null || n.scrollIntoView({ behavior: "smooth", block: "center" });
2746
+ }), t;
2747
+ }
2748
+ /**
2749
+ * 渲染尾注引用(文档正文中的上标数字)
2750
+ */
2751
+ renderEndnoteReference(e) {
2752
+ this.endnoteCounter++, this.currentEndnoteIds.push(e.id);
2753
+ const t = this.createElement("sup", `${this.classPrefix}-endnote-ref`);
2754
+ return t.dataset.endnoteId = e.id, t.textContent = String(this.endnoteCounter), t.title = "尾注", t.addEventListener("click", () => {
2755
+ const n = document.getElementById(`${this.classPrefix}-endnote-${e.id}`);
2756
+ n == null || n.scrollIntoView({ behavior: "smooth", block: "center" });
2757
+ }), t;
2758
+ }
2759
+ /**
2760
+ * 渲染脚注内容
2761
+ */
2762
+ renderFootnote(e) {
2763
+ const t = this.createElement("li", `${this.classPrefix}-footnote`);
2764
+ return t.id = `${this.classPrefix}-footnote-${e.id}`, t.dataset.footnoteId = e.id, this.renderChildren(e.children || [], t), t;
2765
+ }
2766
+ /**
2767
+ * 渲染尾注内容
2768
+ */
2769
+ renderEndnote(e) {
2770
+ const t = this.createElement("li", `${this.classPrefix}-endnote`);
2771
+ return t.id = `${this.classPrefix}-endnote-${e.id}`, t.dataset.endnoteId = e.id, this.renderChildren(e.children || [], t), t;
2772
+ }
2773
+ /**
2774
+ * 渲染页面脚注区域
2775
+ */
2776
+ renderPageFootnotes(e, t) {
2777
+ var a;
2778
+ if (e.length === 0 || !((a = this.document) != null && a.footnotes)) return;
2779
+ const n = this.createElement("div", `${this.classPrefix}-footnotes-section`), r = this.createElement("hr", `${this.classPrefix}-footnotes-separator`);
2780
+ n.appendChild(r);
2781
+ const i = this.createElement("ol", `${this.classPrefix}-footnotes-list`);
2782
+ for (const c of e) {
2783
+ const l = this.document.footnotes.get(c);
2784
+ if (l) {
2785
+ const d = this.renderFootnote(l);
2786
+ i.appendChild(d);
2787
+ }
2788
+ }
2789
+ n.appendChild(i), t.appendChild(n);
2790
+ }
2791
+ /**
2792
+ * 渲染文档尾注区域
2793
+ */
2794
+ renderDocumentEndnotes(e) {
2795
+ var i;
2796
+ if (this.currentEndnoteIds.length === 0 || !((i = this.document) != null && i.endnotes)) return;
2797
+ const t = this.createElement("div", `${this.classPrefix}-endnotes-section`), n = this.createElement("h3", `${this.classPrefix}-endnotes-title`);
2798
+ n.textContent = "尾注", t.appendChild(n);
2799
+ const r = this.createElement("ol", `${this.classPrefix}-endnotes-list`);
2800
+ for (const a of this.currentEndnoteIds) {
2801
+ const c = this.document.endnotes.get(a);
2802
+ if (c) {
2803
+ const l = this.renderEndnote(c);
2804
+ r.appendChild(l);
2805
+ }
2806
+ }
2807
+ t.appendChild(r), e.appendChild(t);
2808
+ }
2809
+ /**
2810
+ * 渲染子元素
2811
+ */
2812
+ renderChildren(e, t) {
2813
+ for (const n of e) {
2814
+ const r = this.renderElement(n);
2815
+ r && t.appendChild(r);
2816
+ }
2817
+ }
2818
+ /**
2819
+ * 创建元素
2820
+ */
2821
+ createElement(e, t) {
2822
+ const n = document.createElement(e);
2823
+ return t && (n.className = t), n;
2824
+ }
2825
+ /**
2826
+ * 格式化日期
2827
+ */
2828
+ formatDate(e) {
2829
+ try {
2830
+ return new Date(e).toLocaleDateString("zh-CN", {
2831
+ year: "numeric",
2832
+ month: "2-digit",
2833
+ day: "2-digit"
2834
+ });
2835
+ } catch {
2836
+ return e;
2837
+ }
2838
+ }
2839
+ /**
2840
+ * 转义 HTML
2841
+ */
2842
+ escapeHtml(e) {
2843
+ const t = document.createElement("div");
2844
+ return t.textContent = e, t.innerHTML;
2845
+ }
2846
+ /**
2847
+ * 获取文档对象
2848
+ */
2849
+ getDocument() {
2850
+ return this.document;
2851
+ }
2852
+ }
2853
+ class xe {
2854
+ constructor(e) {
2855
+ g(this, "parser");
2856
+ g(this, "renderer");
2857
+ g(this, "document", null);
2858
+ this.parser = new we(), this.renderer = new ke(e);
2859
+ }
2860
+ /**
2861
+ * 渲染 DOCX 文件
2862
+ */
2863
+ async render(e) {
2864
+ this.document = await this.parser.parse(e), this.renderer.render(this.document);
2865
+ }
2866
+ /**
2867
+ * 获取文档对象
2868
+ */
2869
+ getDocument() {
2870
+ return this.document;
2871
+ }
2872
+ /**
2873
+ * 获取所有评论
2874
+ */
2875
+ getComments() {
2876
+ var e;
2877
+ return ((e = this.document) == null ? void 0 : e.comments) || [];
2878
+ }
2879
+ /**
2880
+ * 获取解析器(用于保存修改)
2881
+ */
2882
+ getParser() {
2883
+ return this.parser;
2884
+ }
2885
+ }
2886
+ async function Me(o, e, t) {
2887
+ const n = new xe({
2888
+ container: e,
2889
+ ...t
2890
+ });
2891
+ return await n.render(o), n;
2892
+ }
2893
+ export {
2894
+ C as DOCX_PARTS,
2895
+ we as DocumentParser,
2896
+ ke as DocumentRenderer,
2897
+ xe as DocxRender,
2898
+ m as DomType,
2899
+ U as XML_NS,
2900
+ K as applyTintShade,
2901
+ Ee as buildCommentTree,
2902
+ $e as buildFontFamily,
2903
+ Ae as cleanupFontStyles,
2904
+ Ne as getEmbedFontRefs,
2905
+ Fe as getFontDeclaration,
2906
+ Pe as getSubstituteFontName,
2907
+ Re as hasEmbeddedFont,
2908
+ oe as loadEmbeddedFonts,
2909
+ ye as parseCommentsExtended,
2910
+ J as parseFontTable,
2911
+ j as parseTheme,
2912
+ Me as renderDocx,
2913
+ Y as resolveThemeColor,
2914
+ Te as resolveThemeFont
2915
+ };