@gilav21/shadcn-angular-rte 0.1.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,1528 @@
1
+ import { i as inflate } from './gilav21-shadcn-angular-rte-inflate-laXxypva.mjs';
2
+ import { i as isValidImageMagicBytes } from './gilav21-shadcn-angular-rte-gilav21-shadcn-angular-rte-DWSBW7Gw.mjs';
3
+
4
+ const DEFAULT_MAX_UNCOMPRESSED = 1024 * 1024 * 1024;
5
+ const DEFAULT_MAX_FILE_SIZE = 200 * 1024 * 1024;
6
+ const ZIP_LOCAL_HEADER = 0x04034b50;
7
+ const ZIP_CENTRAL_DIR = 0x02014b50;
8
+ const ZIP_END_OF_CENTRAL = 0x06054b50;
9
+ const ZIP64_END_OF_CENTRAL = 0x06064b50;
10
+ const ZIP64_END_LOCATOR = 0x07064b50;
11
+ const CRC32_TABLE = buildCrc32Table();
12
+ function buildCrc32Table() {
13
+ const table = new Uint32Array(256);
14
+ for (let i = 0; i < 256; i++) {
15
+ let c = i;
16
+ for (let j = 0; j < 8; j++) {
17
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
18
+ }
19
+ table[i] = c;
20
+ }
21
+ return table;
22
+ }
23
+ function crc32(data) {
24
+ let crc = 0xffffffff;
25
+ for (const byte of data) {
26
+ crc = CRC32_TABLE[(crc ^ byte) & 0xff] ^ (crc >>> 8);
27
+ }
28
+ return (crc ^ 0xffffffff) >>> 0;
29
+ }
30
+ function readU16LE(data, offset) {
31
+ return data[offset] | (data[offset + 1] << 8);
32
+ }
33
+ function readU32LE(data, offset) {
34
+ return (data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24)) >>> 0;
35
+ }
36
+ function readU64LE(data, offset) {
37
+ const low = readU32LE(data, offset);
38
+ const high = readU32LE(data, offset + 4);
39
+ return high * 0x100000000 + low;
40
+ }
41
+ function validateZipMagic(data) {
42
+ if (data.length < 22) {
43
+ throw new Error('Data too small to be a ZIP file');
44
+ }
45
+ if (readU32LE(data, 0) !== ZIP_LOCAL_HEADER) {
46
+ throw new Error('Invalid ZIP file: missing PK signature');
47
+ }
48
+ }
49
+ function validatePath(path) {
50
+ if (path.startsWith('/') || path.startsWith('\\')) {
51
+ throw new Error(`Absolute path rejected: ${path}`);
52
+ }
53
+ const segments = path.split(/[/\\]/);
54
+ for (const seg of segments) {
55
+ if (seg === '..') {
56
+ throw new Error(`Path traversal rejected: ${path}`);
57
+ }
58
+ }
59
+ }
60
+ function findEndOfCentralDir(data) {
61
+ const searchStart = Math.max(0, data.length - 65557);
62
+ for (let i = data.length - 22; i >= searchStart; i--) {
63
+ if (readU32LE(data, i) === ZIP_END_OF_CENTRAL) {
64
+ return i;
65
+ }
66
+ }
67
+ throw new Error('Cannot find end of central directory');
68
+ }
69
+ function tryReadZip64Eocd(data, eocdOffset) {
70
+ if (eocdOffset < 20)
71
+ return null;
72
+ const locatorOffset = eocdOffset - 20;
73
+ if (readU32LE(data, locatorOffset) !== ZIP64_END_LOCATOR)
74
+ return null;
75
+ const zip64EocdOffset = readU64LE(data, locatorOffset + 8);
76
+ if (zip64EocdOffset + 56 > data.length)
77
+ return null;
78
+ if (readU32LE(data, zip64EocdOffset) !== ZIP64_END_OF_CENTRAL)
79
+ return null;
80
+ const entryCount = readU64LE(data, zip64EocdOffset + 32);
81
+ const centralDirOffset = readU64LE(data, zip64EocdOffset + 48);
82
+ return { entryCount, centralDirOffset };
83
+ }
84
+ function applyZip64Extra(zip64Extra, current) {
85
+ if (!zip64Extra)
86
+ return;
87
+ if (zip64Extra.uncompressedSize !== undefined)
88
+ current.uncompressedSize = zip64Extra.uncompressedSize;
89
+ if (zip64Extra.compressedSize !== undefined)
90
+ current.compressedSize = zip64Extra.compressedSize;
91
+ if (zip64Extra.localHeaderOffset !== undefined)
92
+ current.localHeaderOffset = zip64Extra.localHeaderOffset;
93
+ }
94
+ function parseCentralDirectory(data) {
95
+ const eocdOffset = findEndOfCentralDir(data);
96
+ const zip64 = tryReadZip64Eocd(data, eocdOffset);
97
+ let entryCount;
98
+ let centralDirOffset;
99
+ if (zip64) {
100
+ entryCount = zip64.entryCount;
101
+ centralDirOffset = zip64.centralDirOffset;
102
+ }
103
+ else {
104
+ entryCount = readU16LE(data, eocdOffset + 10);
105
+ centralDirOffset = readU32LE(data, eocdOffset + 16);
106
+ }
107
+ const entries = [];
108
+ let pos = centralDirOffset;
109
+ for (let i = 0; i < entryCount; i++) {
110
+ if (pos + 46 > data.length)
111
+ break;
112
+ if (readU32LE(data, pos) !== ZIP_CENTRAL_DIR)
113
+ break;
114
+ const flags = readU16LE(data, pos + 8);
115
+ const compressionMethod = readU16LE(data, pos + 10);
116
+ const entryCrc32 = readU32LE(data, pos + 16);
117
+ const nameLen = readU16LE(data, pos + 28);
118
+ const extraLen = readU16LE(data, pos + 30);
119
+ const commentLen = readU16LE(data, pos + 32);
120
+ const sizes = {
121
+ compressedSize: readU32LE(data, pos + 20),
122
+ uncompressedSize: readU32LE(data, pos + 24),
123
+ localHeaderOffset: readU32LE(data, pos + 42),
124
+ };
125
+ const pathBytes = data.subarray(pos + 46, pos + 46 + nameLen);
126
+ const path = new TextDecoder().decode(pathBytes);
127
+ if (sizes.compressedSize === 0xFFFFFFFF || sizes.uncompressedSize === 0xFFFFFFFF || sizes.localHeaderOffset === 0xFFFFFFFF) {
128
+ const zip64Extra = findZip64ExtraField(data, pos + 46 + nameLen, extraLen, sizes.uncompressedSize, sizes.compressedSize, sizes.localHeaderOffset);
129
+ applyZip64Extra(zip64Extra, sizes);
130
+ }
131
+ entries.push({
132
+ path,
133
+ compressedSize: sizes.compressedSize,
134
+ uncompressedSize: sizes.uncompressedSize,
135
+ compressionMethod,
136
+ crc32: entryCrc32,
137
+ offset: sizes.localHeaderOffset,
138
+ flags,
139
+ });
140
+ pos += 46 + nameLen + extraLen + commentLen;
141
+ }
142
+ return entries;
143
+ }
144
+ function findZip64ExtraField(data, extraStart, extraLen, origUncompressed, origCompressed, origOffset) {
145
+ let offset = extraStart;
146
+ const end = extraStart + extraLen;
147
+ while (offset + 4 <= end) {
148
+ const headerId = readU16LE(data, offset);
149
+ const dataSize = readU16LE(data, offset + 2);
150
+ if (headerId === 0x0001) {
151
+ const result = {};
152
+ let fieldOffset = offset + 4;
153
+ if (origUncompressed === 0xFFFFFFFF && fieldOffset + 8 <= end) {
154
+ result.uncompressedSize = readU64LE(data, fieldOffset);
155
+ fieldOffset += 8;
156
+ }
157
+ if (origCompressed === 0xFFFFFFFF && fieldOffset + 8 <= end) {
158
+ result.compressedSize = readU64LE(data, fieldOffset);
159
+ fieldOffset += 8;
160
+ }
161
+ if (origOffset === 0xFFFFFFFF && fieldOffset + 8 <= end) {
162
+ result.localHeaderOffset = readU64LE(data, fieldOffset);
163
+ }
164
+ return result;
165
+ }
166
+ offset += 4 + dataSize;
167
+ }
168
+ return null;
169
+ }
170
+ function checkEncrypted(entry) {
171
+ if (entry.flags & 0x01) {
172
+ throw new Error(`Encrypted ZIP entry not supported: ${entry.path}`);
173
+ }
174
+ }
175
+ function extractEntryData(data, entry, maxFileSize) {
176
+ checkEncrypted(entry);
177
+ if (entry.uncompressedSize > maxFileSize) {
178
+ throw new Error(`File too large: ${entry.path} (${entry.uncompressedSize} bytes)`);
179
+ }
180
+ const localOffset = entry.offset;
181
+ if (localOffset + 30 > data.length) {
182
+ throw new Error(`Invalid local header offset for ${entry.path}`);
183
+ }
184
+ if (readU32LE(data, localOffset) !== ZIP_LOCAL_HEADER) {
185
+ throw new Error(`Invalid local header for ${entry.path}`);
186
+ }
187
+ const localNameLen = readU16LE(data, localOffset + 26);
188
+ const localExtraLen = readU16LE(data, localOffset + 28);
189
+ const dataStart = localOffset + 30 + localNameLen + localExtraLen;
190
+ const compressedData = data.subarray(dataStart, dataStart + entry.compressedSize);
191
+ let result;
192
+ if (entry.compressionMethod === 0) {
193
+ result = compressedData.slice();
194
+ }
195
+ else if (entry.compressionMethod === 8) {
196
+ // Bound the ACTUAL output, not the size the archive claims: an entry's
197
+ // `uncompressedSize` is attacker-written metadata, so a crafted zip can
198
+ // under-declare a bomb and slip past the checks above. CRC only catches
199
+ // the lie after the stream has already inflated in memory.
200
+ result = inflate(compressedData, { maxOutputBytes: maxFileSize });
201
+ }
202
+ else {
203
+ throw new Error(`Unsupported compression method ${entry.compressionMethod} for ${entry.path}`);
204
+ }
205
+ const actualCrc = crc32(result);
206
+ if (actualCrc !== entry.crc32) {
207
+ throw new Error(`CRC32 mismatch for ${entry.path}: expected ${entry.crc32}, got ${actualCrc}`);
208
+ }
209
+ return result;
210
+ }
211
+ function listZipEntries(data) {
212
+ validateZipMagic(data);
213
+ return parseCentralDirectory(data);
214
+ }
215
+ function extractZipEntry(data, path, options) {
216
+ validateZipMagic(data);
217
+ const maxFileSize = options?.maxFileSize ?? DEFAULT_MAX_FILE_SIZE;
218
+ const entries = parseCentralDirectory(data);
219
+ const entry = entries.find(e => e.path === path);
220
+ if (!entry)
221
+ return null;
222
+ validatePath(entry.path);
223
+ return extractEntryData(data, entry, maxFileSize);
224
+ }
225
+ function readZip(data, options) {
226
+ validateZipMagic(data);
227
+ const maxUncompressed = options?.maxUncompressedSize ?? DEFAULT_MAX_UNCOMPRESSED;
228
+ const maxFileSize = options?.maxFileSize ?? DEFAULT_MAX_FILE_SIZE;
229
+ const entries = parseCentralDirectory(data);
230
+ let totalUncompressed = 0;
231
+ for (const entry of entries) {
232
+ totalUncompressed += entry.uncompressedSize;
233
+ }
234
+ if (totalUncompressed > maxUncompressed) {
235
+ throw new Error(`Total uncompressed size too large: ${totalUncompressed} bytes (max ${maxUncompressed})`);
236
+ }
237
+ const files = new Map();
238
+ for (const entry of entries) {
239
+ if (entry.path.endsWith('/'))
240
+ continue;
241
+ validatePath(entry.path);
242
+ files.set(entry.path, extractEntryData(data, entry, maxFileSize));
243
+ }
244
+ return files;
245
+ }
246
+
247
+ /**
248
+ * How deep nested tables may go before the parser stops descending.
249
+ * Far beyond any real document; it exists so a crafted file cannot overflow
250
+ * the stack.
251
+ */
252
+ const MAX_TABLE_NESTING = 20;
253
+ const NS_W = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
254
+ const NS_R = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
255
+ const NS_WP = 'http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing';
256
+ const NS_A = 'http://schemas.openxmlformats.org/drawingml/2006/main';
257
+ const NS_MC = 'http://schemas.openxmlformats.org/markup-compatibility/2006';
258
+ const SCHEME_COLOR_ALIASES = new Map([
259
+ ['tx1', 'dk1'], ['tx2', 'dk2'],
260
+ ['bg1', 'lt1'], ['bg2', 'lt2'],
261
+ ]);
262
+ const EMU_PER_PIXEL = 9525;
263
+ const TWIPS_PER_PT = 20;
264
+ const HIGHLIGHT_COLOR_MAP = {
265
+ yellow: '#FFFF00',
266
+ green: '#00FF00',
267
+ cyan: '#00FFFF',
268
+ magenta: '#FF00FF',
269
+ blue: '#0000FF',
270
+ red: '#FF0000',
271
+ darkBlue: '#00008B',
272
+ darkCyan: '#008B8B',
273
+ darkGreen: '#006400',
274
+ darkMagenta: '#8B008B',
275
+ darkRed: '#8B0000',
276
+ darkYellow: '#808000',
277
+ darkGray: '#A9A9A9',
278
+ lightGray: '#D3D3D3',
279
+ black: '#000000',
280
+ white: '#FFFFFF',
281
+ };
282
+ function parseXml(xmlString) {
283
+ const parser = new DOMParser();
284
+ return parser.parseFromString(xmlString, 'application/xml');
285
+ }
286
+ function getChildNS(parent, ns, localName) {
287
+ const children = parent.getElementsByTagNameNS(ns, localName);
288
+ return children.length > 0 ? children[0] : null;
289
+ }
290
+ function getAllChildrenNS(parent, ns, localName) {
291
+ return Array.from(parent.getElementsByTagNameNS(ns, localName));
292
+ }
293
+ function getAttrVal(element, ns, localName) {
294
+ const nsVal = element.getAttributeNS(ns, localName);
295
+ if (nsVal)
296
+ return nsVal;
297
+ return element.getAttribute(localName);
298
+ }
299
+ function parseRelationships(files) {
300
+ const relsFile = files.get('word/_rels/document.xml.rels');
301
+ if (!relsFile)
302
+ return new Map();
303
+ const doc = parseXml(new TextDecoder().decode(relsFile));
304
+ const rels = doc.getElementsByTagName('Relationship');
305
+ const map = new Map();
306
+ for (const rel of Array.from(rels)) {
307
+ const id = rel.getAttribute('Id') ?? '';
308
+ const target = rel.getAttribute('Target') ?? '';
309
+ map.set(id, target);
310
+ }
311
+ return map;
312
+ }
313
+ function parseNumberingDefinitions(files) {
314
+ const numFile = files.get('word/numbering.xml');
315
+ if (!numFile)
316
+ return new Map();
317
+ const doc = parseXml(new TextDecoder().decode(numFile));
318
+ const abstractNums = new Map();
319
+ const abstractNumEls = getAllChildrenNS(doc.documentElement, NS_W, 'abstractNum');
320
+ for (const abstractNum of abstractNumEls) {
321
+ const abstractId = getAttrVal(abstractNum, NS_W, 'abstractNumId') ?? '';
322
+ const levels = new Map();
323
+ const lvlEls = getAllChildrenNS(abstractNum, NS_W, 'lvl');
324
+ for (const lvl of lvlEls) {
325
+ const ilvl = Number.parseInt(getAttrVal(lvl, NS_W, 'ilvl') ?? '0', 10);
326
+ const numFmtEl = getChildNS(lvl, NS_W, 'numFmt');
327
+ const numFmt = numFmtEl ? (getAttrVal(numFmtEl, NS_W, 'val') ?? 'bullet') : 'bullet';
328
+ levels.set(ilvl, { numFmt });
329
+ }
330
+ abstractNums.set(abstractId, levels);
331
+ }
332
+ const numMap = new Map();
333
+ const numEls = getAllChildrenNS(doc.documentElement, NS_W, 'num');
334
+ for (const num of numEls) {
335
+ const numId = getAttrVal(num, NS_W, 'numId') ?? '';
336
+ const abstractNumIdEl = getChildNS(num, NS_W, 'abstractNumId');
337
+ const abstractId = abstractNumIdEl ? (getAttrVal(abstractNumIdEl, NS_W, 'val') ?? '') : '';
338
+ const levels = abstractNums.get(abstractId);
339
+ if (levels) {
340
+ numMap.set(numId, levels);
341
+ }
342
+ }
343
+ return numMap;
344
+ }
345
+ function parseRunStyle(rPr, themeColors) {
346
+ if (!rPr)
347
+ return {};
348
+ const result = {};
349
+ parseBoldItalic(rPr, result);
350
+ if (getChildNS(rPr, NS_W, 'u'))
351
+ result.underline = true;
352
+ if (getChildNS(rPr, NS_W, 'strike'))
353
+ result.strikethrough = true;
354
+ if (getChildNS(rPr, NS_W, 'dstrike'))
355
+ result.doubleStrikethrough = true;
356
+ if (getChildNS(rPr, NS_W, 'caps'))
357
+ result.caps = true;
358
+ if (getChildNS(rPr, NS_W, 'smallCaps'))
359
+ result.smallCaps = true;
360
+ if (getChildNS(rPr, NS_W, 'vanish'))
361
+ result.hidden = true;
362
+ parseFontSizeAndColor(rPr, result, themeColors);
363
+ parseFontFamily(rPr, result);
364
+ parseHighlightAndShading(rPr, result);
365
+ parseVertAlignAndRtl(rPr, result);
366
+ parseCharSpacing(rPr, result);
367
+ return result;
368
+ }
369
+ function parseBoldItalic(rPr, result) {
370
+ const bEl = getChildNS(rPr, NS_W, 'b');
371
+ if (bEl) {
372
+ const bVal = getAttrVal(bEl, NS_W, 'val');
373
+ result.bold = !bVal || bVal !== '0';
374
+ }
375
+ const iEl = getChildNS(rPr, NS_W, 'i');
376
+ if (iEl) {
377
+ const iVal = getAttrVal(iEl, NS_W, 'val');
378
+ result.italic = !iVal || iVal !== '0';
379
+ }
380
+ }
381
+ function parseFontSizeAndColor(rPr, result, themeColors) {
382
+ const sz = getChildNS(rPr, NS_W, 'sz');
383
+ if (sz) {
384
+ const val = getAttrVal(sz, NS_W, 'val');
385
+ if (val)
386
+ result.fontSize = Number.parseInt(val, 10) / 2;
387
+ }
388
+ const color = getChildNS(rPr, NS_W, 'color');
389
+ if (color) {
390
+ result.color = parseColorElement(color, themeColors);
391
+ }
392
+ }
393
+ function parseColorElement(color, themeColors) {
394
+ const val = getAttrVal(color, NS_W, 'val');
395
+ if (val && val !== 'auto')
396
+ return `#${val}`;
397
+ if (!themeColors)
398
+ return undefined;
399
+ const themeColor = getAttrVal(color, NS_W, 'themeColor');
400
+ if (!themeColor)
401
+ return undefined;
402
+ const resolved = resolveThemeColor(themeColor, themeColors);
403
+ if (!resolved)
404
+ return undefined;
405
+ const tint = getAttrVal(color, NS_W, 'themeTint');
406
+ const shade = getAttrVal(color, NS_W, 'themeShade');
407
+ return applyTintShade(resolved, tint, shade);
408
+ }
409
+ function resolveThemeColor(themeColor, themeColors) {
410
+ const mapped = SCHEME_COLOR_ALIASES.get(themeColor) ?? themeColor;
411
+ return themeColors.get(mapped);
412
+ }
413
+ function applyTintShade(hex, tint, shade) {
414
+ if (!tint && !shade)
415
+ return hex;
416
+ const r = Number.parseInt(hex.substring(1, 3), 16);
417
+ const g = Number.parseInt(hex.substring(3, 5), 16);
418
+ const b = Number.parseInt(hex.substring(5, 7), 16);
419
+ if (tint) {
420
+ const t = Number.parseInt(tint, 16) / 255;
421
+ return rgbToHex(Math.round(r + (255 - r) * t), Math.round(g + (255 - g) * t), Math.round(b + (255 - b) * t));
422
+ }
423
+ if (shade) {
424
+ const s = Number.parseInt(shade, 16) / 255;
425
+ return rgbToHex(Math.round(r * s), Math.round(g * s), Math.round(b * s));
426
+ }
427
+ return hex;
428
+ }
429
+ function rgbToHex(r, g, b) {
430
+ const toHex = (v) => Math.min(255, Math.max(0, v)).toString(16).padStart(2, '0');
431
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
432
+ }
433
+ function parseCharSpacing(rPr, result) {
434
+ const spacing = getChildNS(rPr, NS_W, 'spacing');
435
+ if (spacing) {
436
+ const val = getAttrVal(spacing, NS_W, 'val');
437
+ if (val)
438
+ result.charSpacing = Number.parseInt(val, 10) / TWIPS_PER_PT;
439
+ }
440
+ }
441
+ function parseFontFamily(rPr, result) {
442
+ const rFonts = getChildNS(rPr, NS_W, 'rFonts');
443
+ if (rFonts) {
444
+ const ascii = getAttrVal(rFonts, NS_W, 'ascii')
445
+ ?? getAttrVal(rFonts, NS_W, 'hAnsi')
446
+ ?? getAttrVal(rFonts, NS_W, 'cs');
447
+ if (ascii)
448
+ result.fontFamily = ascii;
449
+ }
450
+ }
451
+ function parseHighlightAndShading(rPr, result) {
452
+ const highlightEl = getChildNS(rPr, NS_W, 'highlight');
453
+ if (highlightEl) {
454
+ const val = getAttrVal(highlightEl, NS_W, 'val');
455
+ if (val && val !== 'none') {
456
+ result.highlight = HIGHLIGHT_COLOR_MAP[val] ?? `#${val}`;
457
+ }
458
+ }
459
+ const shd = getChildNS(rPr, NS_W, 'shd');
460
+ if (shd) {
461
+ const fill = getAttrVal(shd, NS_W, 'fill');
462
+ if (fill && fill !== 'auto')
463
+ result.backgroundColor = `#${fill}`;
464
+ }
465
+ }
466
+ function parseVertAlignAndRtl(rPr, result) {
467
+ const vertAlignEl = getChildNS(rPr, NS_W, 'vertAlign');
468
+ if (vertAlignEl) {
469
+ const val = getAttrVal(vertAlignEl, NS_W, 'val');
470
+ if (val === 'superscript' || val === 'subscript') {
471
+ result.vertAlign = val;
472
+ }
473
+ }
474
+ const rtlEl = getChildNS(rPr, NS_W, 'rtl');
475
+ if (rtlEl) {
476
+ const rtlVal = getAttrVal(rtlEl, NS_W, 'val');
477
+ result.rtl = !rtlVal || rtlVal !== '0';
478
+ }
479
+ }
480
+ function extractImageFromDrawing(drawing, relationships, files) {
481
+ const blipEl = getAllChildrenNS(drawing, NS_A, 'blip')[0];
482
+ if (!blipEl)
483
+ return null;
484
+ const rId = blipEl.getAttributeNS(NS_R, 'embed') ?? '';
485
+ if (!rId)
486
+ return null;
487
+ const target = relationships.get(rId);
488
+ if (!target)
489
+ return null;
490
+ const imagePath = target.startsWith('/') ? target.substring(1) : `word/${target}`;
491
+ const imageData = files.get(imagePath);
492
+ if (!imageData || !isValidImageMagicBytes(imageData))
493
+ return null;
494
+ let width = 200;
495
+ let height = 200;
496
+ const extent = getAllChildrenNS(drawing, NS_WP, 'extent')[0]
497
+ ?? getAllChildrenNS(drawing, NS_A, 'ext')[0];
498
+ if (extent) {
499
+ const cx = extent.getAttribute('cx');
500
+ const cy = extent.getAttribute('cy');
501
+ if (cx)
502
+ width = Math.round(Number.parseInt(cx, 10) / EMU_PER_PIXEL);
503
+ if (cy)
504
+ height = Math.round(Number.parseInt(cy, 10) / EMU_PER_PIXEL);
505
+ }
506
+ const mimeType = guessMimeType(imageData);
507
+ const base64 = uint8ArrayToBase64(imageData);
508
+ const dataUrl = `data:${mimeType};base64,${base64}`;
509
+ const altText = drawing.getAttribute('descr') ?? '';
510
+ return { type: 'image', dataUrl, width, height, altText };
511
+ }
512
+ function guessMimeType(data) {
513
+ if (data[0] === 0xFF && data[1] === 0xD8)
514
+ return 'image/jpeg';
515
+ if (data[0] === 0x89 && data[1] === 0x50)
516
+ return 'image/png';
517
+ if (data[0] === 0x47 && data[1] === 0x49)
518
+ return 'image/gif';
519
+ if (data.length >= 12 && data[0] === 0x52 && data[8] === 0x57)
520
+ return 'image/webp';
521
+ return 'image/png';
522
+ }
523
+ function uint8ArrayToBase64(data) {
524
+ let binary = '';
525
+ const chunkSize = 8192;
526
+ for (let i = 0; i < data.length; i += chunkSize) {
527
+ const slice = data.subarray(i, Math.min(i + chunkSize, data.length));
528
+ for (const byte of slice) {
529
+ binary += String.fromCodePoint(byte);
530
+ }
531
+ }
532
+ return btoa(binary);
533
+ }
534
+ function parseParagraphStyle(pPr, numberingMap) {
535
+ if (!pPr)
536
+ return { style: '' };
537
+ const pStyleEl = getChildNS(pPr, NS_W, 'pStyle');
538
+ const style = (pStyleEl ? getAttrVal(pStyleEl, NS_W, 'val') : null) ?? '';
539
+ return {
540
+ style,
541
+ ...parseListProperties(pPr, numberingMap),
542
+ ...parseBidiAndAlignment(pPr),
543
+ ...parseSpacingProperties(pPr),
544
+ ...parseIndentProperties(pPr),
545
+ ...parseParagraphBordersAndShading(pPr),
546
+ };
547
+ }
548
+ function parseParagraphBordersAndShading(pPr) {
549
+ const result = {};
550
+ const shd = getChildNS(pPr, NS_W, 'shd');
551
+ if (shd) {
552
+ const fill = getAttrVal(shd, NS_W, 'fill');
553
+ if (fill && fill !== 'auto')
554
+ result.shading = `#${fill}`;
555
+ }
556
+ const pBdr = getChildNS(pPr, NS_W, 'pBdr');
557
+ if (pBdr) {
558
+ result.borders = parseBorderSet(pBdr);
559
+ }
560
+ return result;
561
+ }
562
+ function parseBorderSet(borderParent) {
563
+ const borders = {};
564
+ const top = getChildNS(borderParent, NS_W, 'top');
565
+ if (top)
566
+ borders.top = parseSingleBorder(top);
567
+ const bottom = getChildNS(borderParent, NS_W, 'bottom');
568
+ if (bottom)
569
+ borders.bottom = parseSingleBorder(bottom);
570
+ const left = getChildNS(borderParent, NS_W, 'left');
571
+ if (left)
572
+ borders.left = parseSingleBorder(left);
573
+ const right = getChildNS(borderParent, NS_W, 'right');
574
+ if (right)
575
+ borders.right = parseSingleBorder(right);
576
+ return borders;
577
+ }
578
+ function parseSingleBorder(el) {
579
+ const style = getAttrVal(el, NS_W, 'val') ?? 'single';
580
+ const colorVal = getAttrVal(el, NS_W, 'color');
581
+ const color = colorVal && colorVal !== 'auto' ? `#${colorVal}` : '#000000';
582
+ const sizeVal = getAttrVal(el, NS_W, 'sz');
583
+ const size = sizeVal ? Number.parseInt(sizeVal, 10) / 8 : 1;
584
+ return { style, color, size };
585
+ }
586
+ function parseListProperties(pPr, numberingMap) {
587
+ const numPr = getChildNS(pPr, NS_W, 'numPr');
588
+ if (!numPr)
589
+ return {};
590
+ const ilvl = getChildNS(numPr, NS_W, 'ilvl');
591
+ const level = ilvl ? Number.parseInt(getAttrVal(ilvl, NS_W, 'val') ?? '0', 10) : 0;
592
+ const numId = getChildNS(numPr, NS_W, 'numId');
593
+ const numIdVal = numId ? (getAttrVal(numId, NS_W, 'val') ?? '0') : '0';
594
+ if (numIdVal === '0')
595
+ return {};
596
+ return { listLevel: level, listType: resolveListType(numberingMap, numIdVal, level) };
597
+ }
598
+ function resolveListType(numberingMap, numIdVal, level) {
599
+ const levels = numberingMap.get(numIdVal);
600
+ if (!levels)
601
+ return 'bullet';
602
+ const def = levels.get(level);
603
+ if (!def)
604
+ return 'bullet';
605
+ const fmt = def.numFmt;
606
+ if (fmt === 'bullet' || fmt === 'none')
607
+ return 'bullet';
608
+ return 'numbered';
609
+ }
610
+ function parseBidiAndAlignment(pPr) {
611
+ const result = {};
612
+ const bidi = getChildNS(pPr, NS_W, 'bidi');
613
+ if (bidi) {
614
+ const bidiVal = getAttrVal(bidi, NS_W, 'val');
615
+ result.rtl = !bidiVal || bidiVal !== '0';
616
+ }
617
+ const jcEl = getChildNS(pPr, NS_W, 'jc');
618
+ if (jcEl) {
619
+ const val = getAttrVal(jcEl, NS_W, 'val');
620
+ if (val)
621
+ result.alignment = val;
622
+ }
623
+ return result;
624
+ }
625
+ function parseSpacingProperties(pPr) {
626
+ const spacing = getChildNS(pPr, NS_W, 'spacing');
627
+ if (!spacing)
628
+ return {};
629
+ const result = {};
630
+ const before = getAttrVal(spacing, NS_W, 'before');
631
+ if (before)
632
+ result.spacingBefore = Number.parseInt(before, 10) / TWIPS_PER_PT;
633
+ const after = getAttrVal(spacing, NS_W, 'after');
634
+ if (after)
635
+ result.spacingAfter = Number.parseInt(after, 10) / TWIPS_PER_PT;
636
+ const line = getAttrVal(spacing, NS_W, 'line');
637
+ const lineRule = getAttrVal(spacing, NS_W, 'lineRule');
638
+ if (line) {
639
+ const lineVal = Number.parseInt(line, 10);
640
+ if (lineRule === 'exact' || lineRule === 'atLeast') {
641
+ result.lineSpacing = lineVal / TWIPS_PER_PT;
642
+ }
643
+ else {
644
+ result.lineSpacing = lineVal / 240;
645
+ }
646
+ }
647
+ return result;
648
+ }
649
+ function parseIndentProperties(pPr) {
650
+ const ind = getChildNS(pPr, NS_W, 'ind');
651
+ if (!ind)
652
+ return {};
653
+ const result = {};
654
+ const left = getAttrVal(ind, NS_W, 'left') ?? getAttrVal(ind, NS_W, 'start');
655
+ if (left)
656
+ result.indentLeft = Number.parseInt(left, 10) / TWIPS_PER_PT;
657
+ const right = getAttrVal(ind, NS_W, 'right') ?? getAttrVal(ind, NS_W, 'end');
658
+ if (right)
659
+ result.indentRight = Number.parseInt(right, 10) / TWIPS_PER_PT;
660
+ const hanging = getAttrVal(ind, NS_W, 'hanging');
661
+ if (hanging)
662
+ result.indentHanging = Number.parseInt(hanging, 10) / TWIPS_PER_PT;
663
+ const firstLine = getAttrVal(ind, NS_W, 'firstLine');
664
+ if (firstLine)
665
+ result.indentFirstLine = Number.parseInt(firstLine, 10) / TWIPS_PER_PT;
666
+ return result;
667
+ }
668
+ function parseRunChildren(run, style, relationships, files) {
669
+ const runs = [];
670
+ const images = [];
671
+ for (const child of Array.from(run.childNodes)) {
672
+ if (child instanceof Element) {
673
+ parseRunChildElement(child, style, runs, images, relationships, files);
674
+ }
675
+ }
676
+ return { runs, images };
677
+ }
678
+ const SIMPLE_RUN_CHARS = {
679
+ tab: '\t',
680
+ noBreakHyphen: '\u2011',
681
+ softHyphen: '\u00AD',
682
+ };
683
+ function parseRunChildElement(child, style, runs, images, relationships, files) {
684
+ const localName = child.localName;
685
+ if (localName === 't' || localName === 'delText') {
686
+ const text = child.textContent ?? '';
687
+ if (text)
688
+ runs.push({ text, style });
689
+ return;
690
+ }
691
+ if (localName === 'br') {
692
+ runs.push({ text: '\n', style, breakType: parseBreakType(child) });
693
+ return;
694
+ }
695
+ const simpleChar = SIMPLE_RUN_CHARS[localName];
696
+ if (simpleChar) {
697
+ runs.push({ text: simpleChar, style });
698
+ return;
699
+ }
700
+ if (localName === 'sym') {
701
+ const symRun = parseSymbol(child, style);
702
+ if (symRun)
703
+ runs.push(symRun);
704
+ return;
705
+ }
706
+ parseRunChildElementExtended(child, localName, style, runs, images, relationships, files);
707
+ }
708
+ function parseRunChildElementExtended(child, localName, style, runs, images, relationships, files) {
709
+ if (localName === 'drawing' || localName === 'pict') {
710
+ const img = extractImageFromDrawing(child, relationships, files);
711
+ if (img)
712
+ images.push(img);
713
+ return;
714
+ }
715
+ if (localName === 'footnoteReference' || localName === 'endnoteReference') {
716
+ parseNoteReference(child, localName, style, runs);
717
+ return;
718
+ }
719
+ if (localName === 'commentReference') {
720
+ const commentId = getAttrVal(child, NS_W, 'id');
721
+ if (commentId) {
722
+ runs.push({ text: `*${commentId}`, style: { ...style, vertAlign: 'superscript' } });
723
+ }
724
+ }
725
+ }
726
+ function parseNoteReference(child, localName, style, runs) {
727
+ const noteId = getAttrVal(child, NS_W, 'id');
728
+ if (noteId) {
729
+ const marker = localName === 'footnoteReference' ? `[${noteId}]` : `{${noteId}}`;
730
+ runs.push({ text: marker, style: { ...style, vertAlign: 'superscript' } });
731
+ }
732
+ }
733
+ function parseBreakType(br) {
734
+ const typeAttr = getAttrVal(br, NS_W, 'type');
735
+ if (typeAttr === 'page')
736
+ return 'page';
737
+ if (typeAttr === 'column')
738
+ return 'column';
739
+ return undefined;
740
+ }
741
+ function parseSymbol(sym, baseStyle) {
742
+ const charCode = getAttrVal(sym, NS_W, 'char');
743
+ if (!charCode)
744
+ return null;
745
+ const codePoint = Number.parseInt(charCode, 16);
746
+ const text = String.fromCodePoint(codePoint);
747
+ const font = getAttrVal(sym, NS_W, 'font');
748
+ const style = font ? { ...baseStyle, fontFamily: font } : baseStyle;
749
+ return { text, style };
750
+ }
751
+ function parseRun(run, relationships, files, themeColors) {
752
+ const rPr = getChildNS(run, NS_W, 'rPr');
753
+ const style = parseRunStyle(rPr, themeColors);
754
+ return parseRunChildren(run, style, relationships, files);
755
+ }
756
+ function parseHyperlinkRuns(hyperlink, relationships, files, themeColors) {
757
+ const allRuns = [];
758
+ const allImages = [];
759
+ const rId = hyperlink.getAttributeNS(NS_R, 'id') ?? hyperlink.getAttribute('r:id') ?? '';
760
+ const target = rId ? (relationships.get(rId) ?? '') : '';
761
+ const anchor = hyperlink.getAttributeNS(NS_W, 'anchor') ?? hyperlink.getAttribute('w:anchor') ?? '';
762
+ const href = target || (anchor ? `#bookmark-${anchor}` : '');
763
+ const runElements = getAllChildrenNS(hyperlink, NS_W, 'r');
764
+ for (const run of runElements) {
765
+ const { runs, images } = parseRun(run, relationships, files, themeColors);
766
+ for (const r of runs) {
767
+ if (href && r.text.trim()) {
768
+ allRuns.push({
769
+ text: r.text,
770
+ style: { ...r.style, underline: true, color: r.style.color ?? '#0563C1' },
771
+ href,
772
+ });
773
+ }
774
+ else {
775
+ allRuns.push(r);
776
+ }
777
+ }
778
+ allImages.push(...images);
779
+ }
780
+ return { runs: allRuns, images: allImages };
781
+ }
782
+ function collectDirectChildRuns(para, relationships, files, themeColors) {
783
+ const allRuns = [];
784
+ const allImages = [];
785
+ let fieldState = 'none';
786
+ for (const child of Array.from(para.childNodes)) {
787
+ if (!(child instanceof Element))
788
+ continue;
789
+ fieldState = processDirectChild(child, fieldState, allRuns, allImages, relationships, files, themeColors);
790
+ }
791
+ return { runs: allRuns, images: allImages };
792
+ }
793
+ function processDirectChild(child, fieldState, allRuns, allImages, relationships, files, themeColors) {
794
+ if (child.localName === 'r' && child.namespaceURI === NS_W) {
795
+ return processRunInField(child, fieldState, allRuns, allImages, relationships, files, themeColors);
796
+ }
797
+ if (fieldState !== 'begin') {
798
+ collectChildElement(child, allRuns, allImages, relationships, files, themeColors);
799
+ }
800
+ return fieldState;
801
+ }
802
+ function processRunInField(child, fieldState, allRuns, allImages, relationships, files, themeColors) {
803
+ const fldCharResult = checkFieldChar(child);
804
+ if (fldCharResult === 'begin')
805
+ return 'begin';
806
+ if (fldCharResult === 'separate')
807
+ return 'separate';
808
+ if (fldCharResult === 'end')
809
+ return 'none';
810
+ if (fieldState === 'begin')
811
+ return fieldState;
812
+ if (fieldState === 'separate') {
813
+ const { runs, images } = parseRun(child, relationships, files, themeColors);
814
+ allRuns.push(...runs);
815
+ allImages.push(...images);
816
+ return fieldState;
817
+ }
818
+ collectChildElement(child, allRuns, allImages, relationships, files, themeColors);
819
+ return fieldState;
820
+ }
821
+ function checkFieldChar(run) {
822
+ for (const child of Array.from(run.childNodes)) {
823
+ if (child instanceof Element && child.localName === 'fldChar') {
824
+ const fldCharType = getAttrVal(child, NS_W, 'fldCharType');
825
+ if (fldCharType === 'begin')
826
+ return 'begin';
827
+ if (fldCharType === 'separate')
828
+ return 'separate';
829
+ if (fldCharType === 'end')
830
+ return 'end';
831
+ }
832
+ }
833
+ return null;
834
+ }
835
+ function collectChildElement(child, allRuns, allImages, relationships, files, themeColors) {
836
+ const localName = child.localName;
837
+ if (localName === 'r') {
838
+ const { runs, images } = parseRun(child, relationships, files, themeColors);
839
+ allRuns.push(...runs);
840
+ allImages.push(...images);
841
+ }
842
+ else if (localName === 'hyperlink') {
843
+ const { runs, images } = parseHyperlinkRuns(child, relationships, files, themeColors);
844
+ allRuns.push(...runs);
845
+ allImages.push(...images);
846
+ }
847
+ else if (localName === 'drawing') {
848
+ const img = extractImageFromDrawing(child, relationships, files);
849
+ if (img)
850
+ allImages.push(img);
851
+ }
852
+ else if (localName === 'bookmarkStart') {
853
+ const name = getAttrVal(child, NS_W, 'name');
854
+ if (name && name !== '_GoBack') {
855
+ allRuns.push({ text: '', style: {}, anchorId: `bookmark-${name}` });
856
+ }
857
+ }
858
+ else if (localName === 'ins') {
859
+ collectTrackChangeRuns(child, allRuns, allImages, relationships, files, true, themeColors);
860
+ }
861
+ else if (localName === 'del') {
862
+ collectTrackChangeRuns(child, allRuns, allImages, relationships, files, false, themeColors);
863
+ }
864
+ else if (localName === 'fldSimple') {
865
+ collectFieldSimpleRuns(child, allRuns, allImages, relationships, files, themeColors);
866
+ }
867
+ else if (isUnwrappableElement(localName)) {
868
+ unwrapAndCollect(child, allRuns, allImages, relationships, files, themeColors);
869
+ }
870
+ else if (localName === 'AlternateContent' && child.namespaceURI === NS_MC) {
871
+ collectAlternateContent(child, allRuns, allImages, relationships, files, themeColors);
872
+ }
873
+ }
874
+ function isUnwrappableElement(localName) {
875
+ return localName === 'sdt' || localName === 'smartTag' || localName === 'customXml';
876
+ }
877
+ function unwrapAndCollect(wrapper, allRuns, allImages, relationships, files, themeColors) {
878
+ const content = wrapper.localName === 'sdt'
879
+ ? getChildNS(wrapper, NS_W, 'sdtContent')
880
+ : wrapper;
881
+ if (!content)
882
+ return;
883
+ const { runs, images } = collectDirectChildRuns(content, relationships, files, themeColors);
884
+ allRuns.push(...runs);
885
+ allImages.push(...images);
886
+ }
887
+ function collectTrackChangeRuns(element, allRuns, allImages, relationships, files, isInserted, themeColors) {
888
+ for (const child of Array.from(element.childNodes)) {
889
+ if (!(child instanceof Element))
890
+ continue;
891
+ if (child.localName === 'r') {
892
+ const { runs, images } = parseRun(child, relationships, files, themeColors);
893
+ for (const r of runs) {
894
+ allRuns.push(isInserted
895
+ ? { ...r, isInserted: true }
896
+ : { ...r, isDeleted: true });
897
+ }
898
+ allImages.push(...images);
899
+ }
900
+ else {
901
+ collectChildElement(child, allRuns, allImages, relationships, files, themeColors);
902
+ }
903
+ }
904
+ }
905
+ function collectFieldSimpleRuns(fldSimple, allRuns, allImages, relationships, files, themeColors) {
906
+ const { runs, images } = collectDirectChildRuns(fldSimple, relationships, files, themeColors);
907
+ allRuns.push(...runs);
908
+ allImages.push(...images);
909
+ }
910
+ function collectAlternateContent(mc, allRuns, allImages, relationships, files, themeColors) {
911
+ const choice = getChildNS(mc, NS_MC, 'Choice');
912
+ const target = choice ?? getChildNS(mc, NS_MC, 'Fallback');
913
+ if (!target)
914
+ return;
915
+ const { runs, images } = collectDirectChildRuns(target, relationships, files, themeColors);
916
+ allRuns.push(...runs);
917
+ allImages.push(...images);
918
+ }
919
+ function parseParagraph(para, relationships, files, numberingMap, themeColors) {
920
+ const pPr = getChildNS(para, NS_W, 'pPr');
921
+ const styleResult = parseParagraphStyle(pPr, numberingMap);
922
+ const { runs: allRuns, images: allImages } = collectDirectChildRuns(para, relationships, files, themeColors);
923
+ const paragraph = buildParagraphFromStyle(styleResult, allRuns);
924
+ return { paragraph, images: allImages };
925
+ }
926
+ function buildParagraphFromStyle(sr, runs) {
927
+ const paragraph = {
928
+ type: 'paragraph',
929
+ runs,
930
+ style: sr.style,
931
+ ...(sr.listLevel === undefined ? {} : { listLevel: sr.listLevel }),
932
+ ...(sr.listType === undefined ? {} : { listType: sr.listType }),
933
+ ...(sr.rtl === undefined ? {} : { rtl: sr.rtl }),
934
+ ...(sr.alignment === undefined ? {} : { alignment: sr.alignment }),
935
+ ...(sr.spacingBefore === undefined ? {} : { spacingBefore: sr.spacingBefore }),
936
+ ...(sr.spacingAfter === undefined ? {} : { spacingAfter: sr.spacingAfter }),
937
+ ...(sr.lineSpacing === undefined ? {} : { lineSpacing: sr.lineSpacing }),
938
+ ...(sr.indentLeft === undefined ? {} : { indentLeft: sr.indentLeft }),
939
+ ...(sr.indentRight === undefined ? {} : { indentRight: sr.indentRight }),
940
+ ...(sr.indentHanging === undefined ? {} : { indentHanging: sr.indentHanging }),
941
+ ...(sr.indentFirstLine === undefined ? {} : { indentFirstLine: sr.indentFirstLine }),
942
+ ...(sr.shading === undefined ? {} : { shading: sr.shading }),
943
+ ...(sr.borders === undefined ? {} : { borders: sr.borders }),
944
+ };
945
+ return paragraph;
946
+ }
947
+ function parseTableCellStyle(tcPr) {
948
+ if (!tcPr)
949
+ return { colSpan: 1, rowSpan: 1 };
950
+ let colSpan = 1;
951
+ let rowSpan = 1;
952
+ const gridSpan = getChildNS(tcPr, NS_W, 'gridSpan');
953
+ if (gridSpan) {
954
+ colSpan = Number.parseInt(getAttrVal(gridSpan, NS_W, 'val') ?? '1', 10);
955
+ }
956
+ const vMerge = getChildNS(tcPr, NS_W, 'vMerge');
957
+ if (vMerge) {
958
+ const mergeVal = getAttrVal(vMerge, NS_W, 'val');
959
+ if (!mergeVal || mergeVal === 'continue') {
960
+ rowSpan = 0;
961
+ }
962
+ }
963
+ const cellStyle = buildCellStyle(tcPr);
964
+ return { colSpan, rowSpan, cellStyle };
965
+ }
966
+ function buildCellStyle(tcPr) {
967
+ const style = {};
968
+ let hasStyle = false;
969
+ const shd = getChildNS(tcPr, NS_W, 'shd');
970
+ if (shd) {
971
+ const fill = getAttrVal(shd, NS_W, 'fill');
972
+ if (fill && fill !== 'auto') {
973
+ style.backgroundColor = `#${fill}`;
974
+ hasStyle = true;
975
+ }
976
+ }
977
+ const vAlign = getChildNS(tcPr, NS_W, 'vAlign');
978
+ if (vAlign) {
979
+ const val = getAttrVal(vAlign, NS_W, 'val');
980
+ if (val) {
981
+ style.verticalAlign = val;
982
+ hasStyle = true;
983
+ }
984
+ }
985
+ const tcW = getChildNS(tcPr, NS_W, 'tcW');
986
+ if (tcW) {
987
+ const w = getAttrVal(tcW, NS_W, 'w');
988
+ const wType = getAttrVal(tcW, NS_W, 'type') ?? 'dxa';
989
+ if (w) {
990
+ style.width = Number.parseInt(w, 10);
991
+ style.widthUnit = wType;
992
+ hasStyle = true;
993
+ }
994
+ }
995
+ const tcBorders = getChildNS(tcPr, NS_W, 'tcBorders');
996
+ if (tcBorders) {
997
+ style.borders = parseTableBorderSet(tcBorders);
998
+ hasStyle = true;
999
+ }
1000
+ const tcMar = getChildNS(tcPr, NS_W, 'tcMar');
1001
+ if (tcMar) {
1002
+ style.paddings = parseCellMargins(tcMar);
1003
+ hasStyle = true;
1004
+ }
1005
+ return hasStyle ? style : undefined;
1006
+ }
1007
+ function parseCellMargins(tcMar) {
1008
+ const paddings = {};
1009
+ const sideToNs = { left: 'start', right: 'end' };
1010
+ for (const side of ['top', 'bottom', 'left', 'right']) {
1011
+ const nsName = sideToNs[side] ?? side;
1012
+ const el = getChildNS(tcMar, NS_W, nsName) ?? getChildNS(tcMar, NS_W, side);
1013
+ if (el) {
1014
+ const w = getAttrVal(el, NS_W, 'w');
1015
+ if (w)
1016
+ paddings[side] = Number.parseInt(w, 10) / TWIPS_PER_PT;
1017
+ }
1018
+ }
1019
+ return paddings;
1020
+ }
1021
+ function parseTableBorderSet(borderParent) {
1022
+ const borders = {};
1023
+ for (const side of ['top', 'bottom', 'left', 'right']) {
1024
+ const el = getChildNS(borderParent, NS_W, side);
1025
+ if (el)
1026
+ borders[side] = parseTableBorderElement(el);
1027
+ }
1028
+ return borders;
1029
+ }
1030
+ function parseTableBorderElement(el) {
1031
+ return parseSingleBorder(el);
1032
+ }
1033
+ function getDirectChildElements(parent, ns, localName) {
1034
+ const result = [];
1035
+ for (const child of Array.from(parent.childNodes)) {
1036
+ if (child instanceof Element && child.namespaceURI === ns && child.localName === localName) {
1037
+ result.push(child);
1038
+ }
1039
+ }
1040
+ return result;
1041
+ }
1042
+ function parseTableCell(tc, relationships, files, numberingMap, themeColors, depth = 0) {
1043
+ const tcPr = getChildNS(tc, NS_W, 'tcPr');
1044
+ const { colSpan, rowSpan, cellStyle } = parseTableCellStyle(tcPr);
1045
+ const elements = [];
1046
+ for (const child of Array.from(tc.childNodes)) {
1047
+ if (!(child instanceof Element))
1048
+ continue;
1049
+ if (child.localName === 'p' && child.namespaceURI === NS_W) {
1050
+ const { paragraph } = parseParagraph(child, relationships, files, numberingMap, themeColors);
1051
+ elements.push(paragraph);
1052
+ }
1053
+ else if (child.localName === 'tbl' && child.namespaceURI === NS_W
1054
+ && depth < MAX_TABLE_NESTING) {
1055
+ elements.push(parseTable(child, relationships, files, numberingMap, themeColors, depth + 1));
1056
+ }
1057
+ }
1058
+ return { elements, colSpan, rowSpan, cellStyle };
1059
+ }
1060
+ function parseTableStyle(tblPr) {
1061
+ if (!tblPr)
1062
+ return undefined;
1063
+ const style = {};
1064
+ let hasStyle = false;
1065
+ const tblW = getChildNS(tblPr, NS_W, 'tblW');
1066
+ if (tblW) {
1067
+ const w = getAttrVal(tblW, NS_W, 'w');
1068
+ const wType = getAttrVal(tblW, NS_W, 'type') ?? 'dxa';
1069
+ if (w) {
1070
+ style.width = Number.parseInt(w, 10);
1071
+ style.widthUnit = wType;
1072
+ hasStyle = true;
1073
+ }
1074
+ }
1075
+ const tblBorders = getChildNS(tblPr, NS_W, 'tblBorders');
1076
+ if (tblBorders) {
1077
+ const borders = {};
1078
+ for (const side of ['top', 'bottom', 'left', 'right', 'insideH', 'insideV']) {
1079
+ const el = getChildNS(tblBorders, NS_W, side);
1080
+ if (el)
1081
+ borders[side] = parseTableBorderElement(el);
1082
+ }
1083
+ style.borders = borders;
1084
+ hasStyle = true;
1085
+ }
1086
+ return hasStyle ? style : undefined;
1087
+ }
1088
+ function parseRowStyle(tr) {
1089
+ const trPr = getChildNS(tr, NS_W, 'trPr');
1090
+ if (!trPr)
1091
+ return undefined;
1092
+ const style = {};
1093
+ let hasStyle = false;
1094
+ const trHeight = getChildNS(trPr, NS_W, 'trHeight');
1095
+ if (trHeight) {
1096
+ const val = getAttrVal(trHeight, NS_W, 'val');
1097
+ if (val) {
1098
+ style.height = Number.parseInt(val, 10) / TWIPS_PER_PT;
1099
+ hasStyle = true;
1100
+ }
1101
+ }
1102
+ const tblHeader = getChildNS(trPr, NS_W, 'tblHeader');
1103
+ if (tblHeader) {
1104
+ style.isHeader = true;
1105
+ hasStyle = true;
1106
+ }
1107
+ return hasStyle ? style : undefined;
1108
+ }
1109
+ /**
1110
+ * Tables nest, so this recurses through cells — bounded by
1111
+ * {@link MAX_TABLE_NESTING}. A document is data from wherever the user got it,
1112
+ * and XML nesting compresses to almost nothing, so an unbounded walk turns a
1113
+ * tiny file into a stack overflow. Content past the limit is dropped rather
1114
+ * than crashing the import.
1115
+ */
1116
+ function parseTable(tbl, relationships, files, numberingMap, themeColors, depth = 0) {
1117
+ const tblPr = getChildNS(tbl, NS_W, 'tblPr');
1118
+ const tableStyle = parseTableStyle(tblPr);
1119
+ const rows = [];
1120
+ const trElements = getDirectChildElements(tbl, NS_W, 'tr');
1121
+ for (const tr of trElements) {
1122
+ const cells = [];
1123
+ const tcElements = getDirectChildElements(tr, NS_W, 'tc');
1124
+ for (const tc of tcElements) {
1125
+ cells.push(parseTableCell(tc, relationships, files, numberingMap, themeColors, depth));
1126
+ }
1127
+ const rowStyle = parseRowStyle(tr);
1128
+ rows.push({ cells, rowStyle });
1129
+ }
1130
+ fixRowSpans(rows);
1131
+ return { type: 'table', rows, tableStyle };
1132
+ }
1133
+ function fixRowSpans(rows) {
1134
+ if (rows.length === 0)
1135
+ return;
1136
+ const maxCols = Math.max(...rows.map(r => r.cells.length));
1137
+ for (let col = 0; col < maxCols; col++) {
1138
+ let startRow = -1;
1139
+ for (let row = 0; row < rows.length; row++) {
1140
+ const cell = rows[row].cells[col];
1141
+ if (!cell)
1142
+ continue;
1143
+ if (cell.rowSpan === 0 && startRow >= 0) {
1144
+ const startCell = rows[startRow].cells[col];
1145
+ startCell.rowSpan++;
1146
+ }
1147
+ else if (cell.rowSpan !== 0) {
1148
+ startRow = row;
1149
+ }
1150
+ }
1151
+ }
1152
+ }
1153
+ function extractPlainText(elements) {
1154
+ const parts = [];
1155
+ for (const el of elements) {
1156
+ if (el.type === 'paragraph') {
1157
+ const text = el.runs.map(r => r.text).join('');
1158
+ if (text.trim())
1159
+ parts.push(text);
1160
+ }
1161
+ else if (el.type === 'table') {
1162
+ for (const row of el.rows) {
1163
+ const cellTexts = row.cells.map(cell => extractCellText(cell));
1164
+ parts.push(cellTexts.join('\t'));
1165
+ }
1166
+ }
1167
+ }
1168
+ return parts.join('\n');
1169
+ }
1170
+ function extractCellText(cell) {
1171
+ return cell.elements.map(el => {
1172
+ if (el.type === 'paragraph') {
1173
+ return el.runs.map(r => r.text).join('');
1174
+ }
1175
+ return '';
1176
+ }).join(' ');
1177
+ }
1178
+ function parseBodyElements(body, relationships, files, numberingMap, themeColors) {
1179
+ const elements = [];
1180
+ for (const child of Array.from(body.childNodes)) {
1181
+ if (!(child instanceof Element))
1182
+ continue;
1183
+ parseBodyChild(child, elements, relationships, files, numberingMap, themeColors);
1184
+ }
1185
+ return elements;
1186
+ }
1187
+ function parseBodyChild(child, elements, relationships, files, numberingMap, themeColors) {
1188
+ const localName = child.localName;
1189
+ if (localName === 'p') {
1190
+ const { paragraph, images } = parseParagraph(child, relationships, files, numberingMap, themeColors);
1191
+ elements.push(...images, paragraph);
1192
+ }
1193
+ else if (localName === 'tbl') {
1194
+ elements.push(parseTable(child, relationships, files, numberingMap, themeColors));
1195
+ }
1196
+ else if (localName === 'sdt' || localName === 'customXml' || localName === 'smartTag') {
1197
+ const content = localName === 'sdt'
1198
+ ? getChildNS(child, NS_W, 'sdtContent')
1199
+ : child;
1200
+ if (content) {
1201
+ elements.push(...parseBodyElements(content, relationships, files, numberingMap, themeColors));
1202
+ }
1203
+ }
1204
+ else if (localName === 'AlternateContent' && child.namespaceURI === NS_MC) {
1205
+ const choice = getChildNS(child, NS_MC, 'Choice');
1206
+ const target = choice ?? getChildNS(child, NS_MC, 'Fallback');
1207
+ if (target) {
1208
+ elements.push(...parseBodyElements(target, relationships, files, numberingMap, themeColors));
1209
+ }
1210
+ }
1211
+ }
1212
+ function parseThemeColors(files) {
1213
+ const themeFile = files.get('word/theme/theme1.xml');
1214
+ if (!themeFile)
1215
+ return new Map();
1216
+ const doc = parseXml(new TextDecoder().decode(themeFile));
1217
+ const map = new Map();
1218
+ const themeElements = getChildNS(doc.documentElement, NS_A, 'themeElements');
1219
+ const clrScheme = themeElements ? getChildNS(themeElements, NS_A, 'clrScheme') : null;
1220
+ if (!clrScheme)
1221
+ return map;
1222
+ const colorNames = ['dk1', 'lt1', 'dk2', 'lt2', 'accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6', 'hlink', 'folHlink'];
1223
+ for (const name of colorNames) {
1224
+ const el = getChildNS(clrScheme, NS_A, name);
1225
+ if (!el)
1226
+ continue;
1227
+ const srgb = getChildNS(el, NS_A, 'srgbClr');
1228
+ if (srgb) {
1229
+ map.set(name, `#${srgb.getAttribute('val') ?? '000000'}`);
1230
+ continue;
1231
+ }
1232
+ const sys = getChildNS(el, NS_A, 'sysClr');
1233
+ if (sys) {
1234
+ map.set(name, `#${sys.getAttribute('lastClr') ?? sys.getAttribute('val') ?? '000000'}`);
1235
+ }
1236
+ }
1237
+ return map;
1238
+ }
1239
+ function parseFootnotesOrEndnotes(files, fileName, relationships, numberingMap, themeColors) {
1240
+ const file = files.get(fileName);
1241
+ if (!file)
1242
+ return [];
1243
+ const doc = parseXml(new TextDecoder().decode(file));
1244
+ const tagName = fileName.includes('footnote') ? 'footnote' : 'endnote';
1245
+ const noteElements = getAllChildrenNS(doc.documentElement, NS_W, tagName);
1246
+ const notes = [];
1247
+ for (const note of noteElements) {
1248
+ const id = getAttrVal(note, NS_W, 'id') ?? '';
1249
+ const noteType = getAttrVal(note, NS_W, 'type');
1250
+ if (noteType === 'separator' || noteType === 'continuationSeparator')
1251
+ continue;
1252
+ const paragraphs = [];
1253
+ const paraElements = getAllChildrenNS(note, NS_W, 'p');
1254
+ for (const para of paraElements) {
1255
+ const { paragraph } = parseParagraph(para, relationships, files, numberingMap, themeColors);
1256
+ paragraphs.push(paragraph);
1257
+ }
1258
+ if (paragraphs.length > 0) {
1259
+ notes.push({ id, paragraphs });
1260
+ }
1261
+ }
1262
+ return notes;
1263
+ }
1264
+ function parseStyles(files, themeColors) {
1265
+ const stylesFile = files.get('word/styles.xml');
1266
+ if (!stylesFile)
1267
+ return new Map();
1268
+ const doc = parseXml(new TextDecoder().decode(stylesFile));
1269
+ const rawStyles = new Map();
1270
+ const defaultRunStyle = extractDocDefaults(doc, themeColors);
1271
+ const styleElements = getAllChildrenNS(doc.documentElement, NS_W, 'style');
1272
+ for (const styleEl of styleElements) {
1273
+ const styleId = getAttrVal(styleEl, NS_W, 'styleId') ?? '';
1274
+ if (!styleId)
1275
+ continue;
1276
+ const basedOnEl = getChildNS(styleEl, NS_W, 'basedOn');
1277
+ const basedOn = basedOnEl ? (getAttrVal(basedOnEl, NS_W, 'val') ?? undefined) : undefined;
1278
+ const rPr = getChildNS(styleEl, NS_W, 'rPr') ?? undefined;
1279
+ const pPr = getChildNS(styleEl, NS_W, 'pPr') ?? undefined;
1280
+ rawStyles.set(styleId, { basedOn, rPr, pPr });
1281
+ }
1282
+ return resolveAllStyles(rawStyles, defaultRunStyle, themeColors);
1283
+ }
1284
+ function extractDocDefaults(doc, themeColors) {
1285
+ const docDefaults = getChildNS(doc.documentElement, NS_W, 'docDefaults');
1286
+ if (!docDefaults)
1287
+ return {};
1288
+ const rPrDefault = getChildNS(docDefaults, NS_W, 'rPrDefault');
1289
+ if (!rPrDefault)
1290
+ return {};
1291
+ const rPr = getChildNS(rPrDefault, NS_W, 'rPr');
1292
+ return parseRunStyle(rPr, themeColors);
1293
+ }
1294
+ function resolveAllStyles(rawStyles, defaultRunStyle, themeColors) {
1295
+ const resolved = new Map();
1296
+ const resolving = new Set();
1297
+ for (const styleId of rawStyles.keys()) {
1298
+ resolveStyleChain(styleId, rawStyles, resolved, resolving, defaultRunStyle, themeColors);
1299
+ }
1300
+ return resolved;
1301
+ }
1302
+ function resolveStyleChain(styleId, rawStyles, resolved, resolving, defaultRunStyle, themeColors) {
1303
+ const cached = resolved.get(styleId);
1304
+ if (cached !== undefined)
1305
+ return cached;
1306
+ if (resolving.has(styleId))
1307
+ return {};
1308
+ resolving.add(styleId);
1309
+ const raw = rawStyles.get(styleId);
1310
+ if (!raw) {
1311
+ resolving.delete(styleId);
1312
+ return {};
1313
+ }
1314
+ let base = {};
1315
+ if (raw.basedOn) {
1316
+ base = resolveStyleChain(raw.basedOn, rawStyles, resolved, resolving, defaultRunStyle, themeColors);
1317
+ }
1318
+ const ownRun = raw.rPr ? parseRunStyle(raw.rPr, themeColors) : {};
1319
+ const mergedRun = mergeRunStyles(defaultRunStyle, base.runStyle ?? {}, ownRun);
1320
+ const ownPara = extractParagraphStyleProps(raw.pPr);
1321
+ const result = {
1322
+ runStyle: mergedRun,
1323
+ paragraphAlignment: ownPara.alignment ?? base.paragraphAlignment,
1324
+ paragraphSpacingBefore: ownPara.spacingBefore ?? base.paragraphSpacingBefore,
1325
+ paragraphSpacingAfter: ownPara.spacingAfter ?? base.paragraphSpacingAfter,
1326
+ paragraphIndentLeft: ownPara.indentLeft ?? base.paragraphIndentLeft,
1327
+ paragraphIndentRight: ownPara.indentRight ?? base.paragraphIndentRight,
1328
+ paragraphIndentFirstLine: ownPara.indentFirstLine ?? base.paragraphIndentFirstLine,
1329
+ };
1330
+ resolved.set(styleId, result);
1331
+ resolving.delete(styleId);
1332
+ return result;
1333
+ }
1334
+ function mergeRunStyles(defaults, base, own) {
1335
+ return {
1336
+ ...mergeRunStylesText(defaults, base, own),
1337
+ ...mergeRunStylesDecoration(defaults, base, own),
1338
+ };
1339
+ }
1340
+ function mergeField(own, base, def) {
1341
+ return own ?? base ?? def;
1342
+ }
1343
+ function mergeRunStylesText(defaults, base, own) {
1344
+ return {
1345
+ bold: mergeField(own.bold, base.bold, defaults.bold),
1346
+ italic: mergeField(own.italic, base.italic, defaults.italic),
1347
+ fontSize: mergeField(own.fontSize, base.fontSize, defaults.fontSize),
1348
+ color: mergeField(own.color, base.color, defaults.color),
1349
+ fontFamily: mergeField(own.fontFamily, base.fontFamily, defaults.fontFamily),
1350
+ rtl: mergeField(own.rtl, base.rtl, defaults.rtl),
1351
+ charSpacing: mergeField(own.charSpacing, base.charSpacing, defaults.charSpacing),
1352
+ hidden: mergeField(own.hidden, base.hidden, defaults.hidden),
1353
+ vertAlign: mergeField(own.vertAlign, base.vertAlign, defaults.vertAlign),
1354
+ };
1355
+ }
1356
+ function mergeRunStylesDecoration(defaults, base, own) {
1357
+ return {
1358
+ underline: mergeField(own.underline, base.underline, defaults.underline),
1359
+ strikethrough: mergeField(own.strikethrough, base.strikethrough, defaults.strikethrough),
1360
+ doubleStrikethrough: mergeField(own.doubleStrikethrough, base.doubleStrikethrough, defaults.doubleStrikethrough),
1361
+ caps: mergeField(own.caps, base.caps, defaults.caps),
1362
+ smallCaps: mergeField(own.smallCaps, base.smallCaps, defaults.smallCaps),
1363
+ highlight: mergeField(own.highlight, base.highlight, defaults.highlight),
1364
+ backgroundColor: mergeField(own.backgroundColor, base.backgroundColor, defaults.backgroundColor),
1365
+ };
1366
+ }
1367
+ function extractParagraphStyleProps(pPr) {
1368
+ if (!pPr)
1369
+ return {};
1370
+ const result = {};
1371
+ const jcEl = getChildNS(pPr, NS_W, 'jc');
1372
+ if (jcEl) {
1373
+ const val = getAttrVal(jcEl, NS_W, 'val');
1374
+ if (val)
1375
+ result.alignment = val;
1376
+ }
1377
+ extractSpacingProps(pPr, result);
1378
+ extractIndentProps(pPr, result);
1379
+ return result;
1380
+ }
1381
+ function extractSpacingProps(pPr, result) {
1382
+ const spacing = getChildNS(pPr, NS_W, 'spacing');
1383
+ if (!spacing)
1384
+ return;
1385
+ const before = getAttrVal(spacing, NS_W, 'before');
1386
+ if (before)
1387
+ result.spacingBefore = Number.parseInt(before, 10) / TWIPS_PER_PT;
1388
+ const after = getAttrVal(spacing, NS_W, 'after');
1389
+ if (after)
1390
+ result.spacingAfter = Number.parseInt(after, 10) / TWIPS_PER_PT;
1391
+ }
1392
+ function extractIndentProps(pPr, result) {
1393
+ const ind = getChildNS(pPr, NS_W, 'ind');
1394
+ if (!ind)
1395
+ return;
1396
+ const left = getAttrVal(ind, NS_W, 'left') ?? getAttrVal(ind, NS_W, 'start');
1397
+ if (left)
1398
+ result.indentLeft = Number.parseInt(left, 10) / TWIPS_PER_PT;
1399
+ const right = getAttrVal(ind, NS_W, 'right') ?? getAttrVal(ind, NS_W, 'end');
1400
+ if (right)
1401
+ result.indentRight = Number.parseInt(right, 10) / TWIPS_PER_PT;
1402
+ const firstLine = getAttrVal(ind, NS_W, 'firstLine');
1403
+ if (firstLine)
1404
+ result.indentFirstLine = Number.parseInt(firstLine, 10) / TWIPS_PER_PT;
1405
+ }
1406
+ function parseComments(files, relationships, numberingMap, themeColors) {
1407
+ const file = files.get('word/comments.xml');
1408
+ if (!file)
1409
+ return [];
1410
+ const doc = parseXml(new TextDecoder().decode(file));
1411
+ const commentElements = getAllChildrenNS(doc.documentElement, NS_W, 'comment');
1412
+ const comments = [];
1413
+ for (const comment of commentElements) {
1414
+ const id = getAttrVal(comment, NS_W, 'id') ?? '';
1415
+ const author = getAttrVal(comment, NS_W, 'author') ?? '';
1416
+ const date = getAttrVal(comment, NS_W, 'date') ?? '';
1417
+ const paragraphs = [];
1418
+ const paraElements = getAllChildrenNS(comment, NS_W, 'p');
1419
+ for (const para of paraElements) {
1420
+ const { paragraph } = parseParagraph(para, relationships, files, numberingMap, themeColors);
1421
+ paragraphs.push(paragraph);
1422
+ }
1423
+ if (paragraphs.length > 0) {
1424
+ comments.push({ id, author, date, paragraphs });
1425
+ }
1426
+ }
1427
+ return comments;
1428
+ }
1429
+ function parseHeadersFooters(files, relationships, numberingMap, themeColors) {
1430
+ const headers = [];
1431
+ const footers = [];
1432
+ for (const [, target] of relationships) {
1433
+ if (!target.startsWith('header') && !target.startsWith('footer'))
1434
+ continue;
1435
+ const filePath = target.startsWith('/') ? target.substring(1) : `word/${target}`;
1436
+ const file = files.get(filePath);
1437
+ if (!file)
1438
+ continue;
1439
+ const doc = parseXml(new TextDecoder().decode(file));
1440
+ const body = doc.documentElement;
1441
+ const elements = parseBodyElements(body, relationships, files, numberingMap, themeColors);
1442
+ if (target.startsWith('header')) {
1443
+ headers.push(elements);
1444
+ }
1445
+ else {
1446
+ footers.push(elements);
1447
+ }
1448
+ }
1449
+ return { headers, footers };
1450
+ }
1451
+ function applyStyleInheritance(elements, styleMap) {
1452
+ return elements.map(el => {
1453
+ if (el.type === 'paragraph')
1454
+ return applyStyleToParagraph(el, styleMap);
1455
+ if (el.type === 'table')
1456
+ return applyStyleToTable(el, styleMap);
1457
+ return el;
1458
+ });
1459
+ }
1460
+ function applyStyleToParagraph(para, styleMap) {
1461
+ if (!para.style)
1462
+ return para;
1463
+ const resolved = styleMap.get(para.style);
1464
+ if (!resolved)
1465
+ return para;
1466
+ const mergedRuns = para.runs.map(run => applyStyleToRun(run, resolved));
1467
+ return {
1468
+ ...para,
1469
+ runs: mergedRuns,
1470
+ alignment: para.alignment ?? resolved.paragraphAlignment,
1471
+ spacingBefore: para.spacingBefore ?? resolved.paragraphSpacingBefore,
1472
+ spacingAfter: para.spacingAfter ?? resolved.paragraphSpacingAfter,
1473
+ indentLeft: para.indentLeft ?? resolved.paragraphIndentLeft,
1474
+ indentRight: para.indentRight ?? resolved.paragraphIndentRight,
1475
+ indentFirstLine: para.indentFirstLine ?? resolved.paragraphIndentFirstLine,
1476
+ };
1477
+ }
1478
+ function applyStyleToRun(run, resolved) {
1479
+ if (!resolved.runStyle)
1480
+ return run;
1481
+ const rs = resolved.runStyle;
1482
+ return { ...run, style: mergeRunStyles(rs, {}, run.style) };
1483
+ }
1484
+ function applyStyleToTable(table, styleMap) {
1485
+ return {
1486
+ ...table,
1487
+ rows: table.rows.map(row => ({
1488
+ ...row,
1489
+ cells: row.cells.map(cell => ({
1490
+ ...cell,
1491
+ elements: cell.elements.map(el => {
1492
+ if (el.type === 'paragraph')
1493
+ return applyStyleToParagraph(el, styleMap);
1494
+ if (el.type === 'table')
1495
+ return applyStyleToTable(el, styleMap);
1496
+ return el;
1497
+ }),
1498
+ })),
1499
+ })),
1500
+ };
1501
+ }
1502
+ function parseDocx(data) {
1503
+ const files = readZip(data);
1504
+ const documentFile = files.get('word/document.xml');
1505
+ if (!documentFile) {
1506
+ throw new Error('Invalid DOCX: missing word/document.xml');
1507
+ }
1508
+ const relationships = parseRelationships(files);
1509
+ const numberingMap = parseNumberingDefinitions(files);
1510
+ const themeColors = parseThemeColors(files);
1511
+ const styleMap = parseStyles(files, themeColors);
1512
+ const doc = parseXml(new TextDecoder().decode(documentFile));
1513
+ const body = doc.getElementsByTagNameNS(NS_W, 'body')[0];
1514
+ if (!body) {
1515
+ throw new Error('Invalid DOCX: missing document body');
1516
+ }
1517
+ let elements = parseBodyElements(body, relationships, files, numberingMap, themeColors);
1518
+ elements = applyStyleInheritance(elements, styleMap);
1519
+ const { headers, footers } = parseHeadersFooters(files, relationships, numberingMap, themeColors);
1520
+ const footnotes = parseFootnotesOrEndnotes(files, 'word/footnotes.xml', relationships, numberingMap, themeColors);
1521
+ const endnotes = parseFootnotesOrEndnotes(files, 'word/endnotes.xml', relationships, numberingMap, themeColors);
1522
+ const comments = parseComments(files, relationships, numberingMap, themeColors);
1523
+ const plainText = extractPlainText(elements);
1524
+ return { elements, plainText, footnotes, endnotes, comments, headers, footers };
1525
+ }
1526
+
1527
+ export { parseDocx };
1528
+ //# sourceMappingURL=gilav21-shadcn-angular-rte-docx-parser-CFx_4GC5.mjs.map