@open-file-viewer/core 0.1.16 → 0.1.17

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.
package/dist/index.cjs CHANGED
@@ -5923,6 +5923,1100 @@ function decodeXml(value) {
5923
5923
  // src/plugins/office.ts
5924
5924
  var import_jszip3 = __toESM(require("jszip"), 1);
5925
5925
  var import_dompurify2 = __toESM(require("dompurify"), 1);
5926
+
5927
+ // src/plugins/msdoc.ts
5928
+ var CFB_SIGNATURE = [208, 207, 17, 224, 161, 177, 26, 225];
5929
+ var FREE_SECTOR = 4294967295;
5930
+ var END_OF_CHAIN = 4294967294;
5931
+ var FAT_SECTOR = 4294967293;
5932
+ var DIFAT_SECTOR = 4294967292;
5933
+ var MINI_STREAM_CUTOFF = 4096;
5934
+ var STSH_FC_LCB_INDEX = 1;
5935
+ var CLX_FC_LCB_INDEX = 33;
5936
+ var WORD_PAGE_BREAK = "\f";
5937
+ function parseLegacyWordDocument(input) {
5938
+ const cfb = parseCompoundFile(new Uint8Array(input));
5939
+ const wordDocument = cfb.getStream("WordDocument");
5940
+ if (!wordDocument) {
5941
+ throw new Error("\u672A\u627E\u5230 WordDocument \u6D41");
5942
+ }
5943
+ const fib = parseFib(wordDocument);
5944
+ if (fib.encrypted) {
5945
+ throw new Error("\u6682\u4E0D\u652F\u6301\u52A0\u5BC6\u7684 .doc \u6587\u4EF6");
5946
+ }
5947
+ const tableStreamName = fib.useOneTable ? "1Table" : "0Table";
5948
+ const tableStream = cfb.getStream(tableStreamName);
5949
+ if (!tableStream) {
5950
+ throw new Error(`\u672A\u627E\u5230 ${tableStreamName} \u8868\u6D41`);
5951
+ }
5952
+ const assets = extractImageAssets(cfb);
5953
+ const styles = parseStyleTable(tableStream, fib);
5954
+ const pieces = parseClxPieces(tableStream, fib.fcClx, fib.lcbClx);
5955
+ const text = pieces.length > 0 ? readPieceTableText(wordDocument, pieces, fib.ccpText) : readFibTextFallback(wordDocument, fib);
5956
+ const paragraphs = splitWordParagraphs(text);
5957
+ if (paragraphs.length === 0) {
5958
+ throw new Error("\u672A\u89E3\u6790\u5230\u53EF\u663E\u793A\u7684\u6B63\u6587\u6BB5\u843D");
5959
+ }
5960
+ const bodyParagraphs = removeTrailingFooterArtifacts(paragraphs);
5961
+ const blocks = buildWordBlocks(bodyParagraphs);
5962
+ const layout = inferLayoutHints(paragraphs, assets);
5963
+ return {
5964
+ title: inferDocumentTitle(paragraphs),
5965
+ paragraphs: bodyParagraphs,
5966
+ blocks,
5967
+ layout,
5968
+ assets,
5969
+ styles,
5970
+ stats: {
5971
+ streamCount: cfb.entries.length,
5972
+ pieceCount: pieces.length,
5973
+ characterCount: bodyParagraphs.join("\n").length,
5974
+ styleCount: styles.length,
5975
+ tableStream: tableStreamName
5976
+ },
5977
+ warnings: pieces.length === 0 ? ["\u672A\u627E\u5230 CLX piece table\uFF0C\u5DF2\u6309 FIB \u6587\u672C\u533A\u95F4\u5C1D\u8BD5\u6062\u590D\u6B63\u6587\u3002"] : []
5978
+ };
5979
+ }
5980
+ function renderLegacyWordDocument(panel, document2) {
5981
+ panel.replaceChildren();
5982
+ const article = window.document.createElement("article");
5983
+ article.className = "ofv-msdoc-document";
5984
+ const pages = paginateWordBlocks(document2.blocks.slice(0, 600), document2.layout);
5985
+ const pageCount = inferDisplayedPageCount(document2.blocks, pages.length);
5986
+ const page = window.document.createElement("section");
5987
+ page.className = "ofv-msdoc-page";
5988
+ appendPageChrome(page, document2, 1, pageCount);
5989
+ const meta = window.document.createElement("dl");
5990
+ meta.className = "ofv-msdoc-meta";
5991
+ appendMeta4(meta, "\u683C\u5F0F", "Word 97-2003 Binary");
5992
+ appendMeta4(meta, "\u6B63\u6587\u6BB5\u843D", `${document2.paragraphs.length}`);
5993
+ appendMeta4(meta, "Piece Table", `${document2.stats.pieceCount || 0} \u6BB5`);
5994
+ appendMeta4(meta, "\u6837\u5F0F\u8868", `${document2.stats.styleCount || 0} \u4E2A\u6837\u5F0F`);
5995
+ appendMeta4(meta, "\u8868\u6D41", document2.stats.tableStream);
5996
+ if (document2.styles.length > 0) {
5997
+ appendMeta4(meta, "\u6837\u5F0F\u540D\u79F0", document2.styles.slice(0, 30).map((style) => style.name).join("\u3001"));
5998
+ }
5999
+ meta.hidden = true;
6000
+ page.append(meta);
6001
+ appendBlocksToPage(page, pages[0] || [], document2.layout);
6002
+ appendWarnings(page, document2);
6003
+ article.append(page);
6004
+ for (const pageBlocks of pages.slice(1)) {
6005
+ const nextPage = window.document.createElement("section");
6006
+ nextPage.className = "ofv-msdoc-page";
6007
+ appendPageChrome(nextPage, document2, article.children.length + 1, pageCount);
6008
+ appendBlocksToPage(nextPage, pageBlocks, document2.layout);
6009
+ article.append(nextPage);
6010
+ }
6011
+ panel.append(article);
6012
+ }
6013
+ function inferDisplayedPageCount(blocks, renderedPageCount) {
6014
+ const tocPageNumbers = blocks.filter((block) => block.type === "toc" && Boolean(block.page)).map((block) => Number.parseInt(block.page || "", 10)).filter((page) => Number.isFinite(page) && page > 0);
6015
+ if (tocPageNumbers.length === 0) {
6016
+ return renderedPageCount;
6017
+ }
6018
+ return Math.max(renderedPageCount, ...tocPageNumbers);
6019
+ }
6020
+ function appendPageChrome(page, document2, pageNumber, pageCount) {
6021
+ if (document2.layout.lineNumbers) {
6022
+ page.classList.add("ofv-msdoc-line-numbered");
6023
+ }
6024
+ page.setAttribute("aria-label", document2.title || "Word \u6587\u6863");
6025
+ if (document2.layout.headerBrand === "oasis") {
6026
+ page.append(createOasisHeader(document2.assets.find((asset) => asset.id === document2.layout.headerImageId)));
6027
+ }
6028
+ if (document2.layout.footer) {
6029
+ page.append(createPageFooter(document2.layout.footer, pageNumber, pageCount));
6030
+ }
6031
+ }
6032
+ function appendBlocksToPage(page, blocks, layout) {
6033
+ let lineNumber = 1;
6034
+ for (const block of blocks) {
6035
+ if (block.type === "pageBreak") {
6036
+ continue;
6037
+ }
6038
+ const element = renderWordBlock(block);
6039
+ if (layout.lineNumbers && element instanceof HTMLElement && !element.classList.contains("ofv-msdoc-page-header")) {
6040
+ element.dataset.line = String(lineNumber);
6041
+ lineNumber += estimatedLineCount(block);
6042
+ }
6043
+ page.append(element);
6044
+ }
6045
+ }
6046
+ function appendWarnings(page, document2) {
6047
+ if (document2.warnings.length === 0) {
6048
+ return;
6049
+ }
6050
+ const warning = window.document.createElement("p");
6051
+ warning.className = "ofv-msdoc-warning";
6052
+ warning.textContent = document2.warnings.join(" ");
6053
+ warning.hidden = true;
6054
+ page.append(warning);
6055
+ }
6056
+ function createOasisHeader(image) {
6057
+ const header = window.document.createElement("header");
6058
+ header.className = "ofv-msdoc-page-header ofv-msdoc-oasis-header";
6059
+ const logo = image ? createImageLogo(image) : createFallbackOasisLogo();
6060
+ header.append(logo);
6061
+ return header;
6062
+ }
6063
+ function createImageLogo(image) {
6064
+ const wrapper = window.document.createElement("div");
6065
+ wrapper.className = "ofv-msdoc-oasis-logo ofv-msdoc-oasis-logo-image";
6066
+ const img = window.document.createElement("img");
6067
+ img.src = image.dataUrl;
6068
+ img.alt = "OASIS";
6069
+ if (image.width) {
6070
+ img.width = image.width;
6071
+ }
6072
+ if (image.height) {
6073
+ img.height = image.height;
6074
+ }
6075
+ wrapper.append(img);
6076
+ return wrapper;
6077
+ }
6078
+ function createFallbackOasisLogo() {
6079
+ const logo = window.document.createElement("div");
6080
+ logo.className = "ofv-msdoc-oasis-logo";
6081
+ const word = window.document.createElement("span");
6082
+ word.textContent = "OASIS";
6083
+ const mark = window.document.createElement("span");
6084
+ mark.className = "ofv-msdoc-oasis-mark";
6085
+ mark.setAttribute("aria-hidden", "true");
6086
+ logo.append(word, mark);
6087
+ return logo;
6088
+ }
6089
+ function createPageFooter(footer, pageNumber, pageCount) {
6090
+ const element = window.document.createElement("footer");
6091
+ element.className = "ofv-msdoc-page-footer";
6092
+ const top = window.document.createElement("div");
6093
+ top.className = "ofv-msdoc-footer-row";
6094
+ const documentId = window.document.createElement("span");
6095
+ documentId.textContent = footer.documentId || "";
6096
+ const date = window.document.createElement("span");
6097
+ date.textContent = footer.date || "";
6098
+ top.append(documentId, date);
6099
+ const bottom = window.document.createElement("div");
6100
+ bottom.className = "ofv-msdoc-footer-row";
6101
+ const copyright = window.document.createElement("span");
6102
+ copyright.textContent = footer.copyright || "";
6103
+ const page = window.document.createElement("span");
6104
+ page.textContent = `Page ${pageNumber} of ${pageCount}`;
6105
+ bottom.append(copyright, page);
6106
+ element.append(top, bottom);
6107
+ return element;
6108
+ }
6109
+ function renderWordBlock(block) {
6110
+ if (block.type === "pageBreak") {
6111
+ const marker = window.document.createElement("span");
6112
+ marker.className = "ofv-msdoc-page-break";
6113
+ marker.hidden = true;
6114
+ return marker;
6115
+ }
6116
+ if (block.type === "table") {
6117
+ const table = window.document.createElement("table");
6118
+ table.className = "ofv-msdoc-table";
6119
+ const revisionColumnWidths = getRevisionTableColumnWidths(block.rows);
6120
+ if (revisionColumnWidths) {
6121
+ table.classList.add("ofv-msdoc-revision-table");
6122
+ const colgroup = window.document.createElement("colgroup");
6123
+ for (const width of revisionColumnWidths) {
6124
+ const col = window.document.createElement("col");
6125
+ col.style.width = `calc(${width}px * var(--ofv-office-zoom, 1))`;
6126
+ colgroup.append(col);
6127
+ }
6128
+ table.append(colgroup);
6129
+ }
6130
+ const tbody = window.document.createElement("tbody");
6131
+ for (const row of block.rows) {
6132
+ const tr = window.document.createElement("tr");
6133
+ const cellTag = row === block.rows[0] && block.rows.length > 1 ? "th" : "td";
6134
+ for (const cellText of row) {
6135
+ const cell = window.document.createElement(cellTag);
6136
+ cell.textContent = cellText;
6137
+ tr.append(cell);
6138
+ }
6139
+ tbody.append(tr);
6140
+ }
6141
+ table.append(tbody);
6142
+ return table;
6143
+ }
6144
+ if (block.type === "toc") {
6145
+ const paragraph2 = window.document.createElement("p");
6146
+ paragraph2.className = `ofv-msdoc-toc ofv-msdoc-toc-level-${block.level}`;
6147
+ const title = window.document.createElement("span");
6148
+ title.textContent = block.title;
6149
+ paragraph2.append(title);
6150
+ if (block.page) {
6151
+ const page = window.document.createElement("span");
6152
+ page.textContent = block.page;
6153
+ paragraph2.append(page);
6154
+ }
6155
+ return paragraph2;
6156
+ }
6157
+ const paragraph = window.document.createElement("p");
6158
+ const levelClass = block.type === "heading" ? ` ofv-msdoc-heading-level-${block.level}` : "";
6159
+ const listClass = block.type === "listItem" ? ` ofv-msdoc-list-level-${block.level}` : "";
6160
+ paragraph.className = `ofv-msdoc-${block.type}${levelClass}${listClass}${"indent" in block && block.indent ? " ofv-msdoc-indent" : ""}`;
6161
+ appendInlineRuns(paragraph, block.text, block.type === "code");
6162
+ return paragraph;
6163
+ }
6164
+ function appendInlineRuns(element, text, preserveTabs = false) {
6165
+ if (preserveTabs) {
6166
+ appendInlineText(element, text, true);
6167
+ return;
6168
+ }
6169
+ const pattern = /(https?:\/\/\S+|[\w.+-]+@[\w.-]+\.[A-Za-z]{2,}|\[[^\]]+\]|<\/?[A-Za-z][A-Za-z0-9:-]*>|(?:\b(?:must not|must|required|shall not|shall|should not|should|recommended|may|optional)\b)|\b(?:attributeNames|DataType|OtherKeyword|variable)\b)/gi;
6170
+ let offset = 0;
6171
+ for (const match of text.matchAll(pattern)) {
6172
+ const value = match[0];
6173
+ const index = match.index || 0;
6174
+ if (index > offset) {
6175
+ appendInlineText(element, text.slice(offset, index), preserveTabs);
6176
+ }
6177
+ if (value.startsWith("[") && value.endsWith("]")) {
6178
+ appendBracketRun(element, value);
6179
+ } else if (isCodeStyleRun(value)) {
6180
+ const code = window.document.createElement("code");
6181
+ code.className = "ofv-msdoc-inline-code";
6182
+ code.textContent = value;
6183
+ element.append(code);
6184
+ } else if (isVariableStyleRun(value)) {
6185
+ const em = window.document.createElement("em");
6186
+ em.className = "ofv-msdoc-variable";
6187
+ em.textContent = value;
6188
+ element.append(em);
6189
+ } else if (isRequirementKeywordRun(value)) {
6190
+ const em = window.document.createElement("em");
6191
+ em.className = "ofv-msdoc-keyword";
6192
+ em.textContent = value;
6193
+ element.append(em);
6194
+ } else {
6195
+ const link = splitLinkRun(value);
6196
+ const anchor = window.document.createElement("a");
6197
+ anchor.className = "ofv-msdoc-link-text";
6198
+ anchor.href = link.href;
6199
+ anchor.target = "_blank";
6200
+ anchor.rel = "noreferrer noopener";
6201
+ anchor.textContent = link.text;
6202
+ element.append(anchor);
6203
+ if (link.trailing) {
6204
+ appendInlineText(element, link.trailing, preserveTabs);
6205
+ }
6206
+ }
6207
+ offset = index + value.length;
6208
+ }
6209
+ if (offset < text.length) {
6210
+ appendInlineText(element, text.slice(offset), preserveTabs);
6211
+ }
6212
+ }
6213
+ function appendBracketRun(element, value) {
6214
+ const tagName = isReferenceTerm(value) ? "strong" : "em";
6215
+ const run = window.document.createElement(tagName);
6216
+ run.className = isReferenceTerm(value) ? "ofv-msdoc-ref-term" : "ofv-msdoc-instruction-run";
6217
+ run.textContent = value;
6218
+ element.append(run);
6219
+ }
6220
+ function getRevisionTableColumnWidths(rows) {
6221
+ const header = rows[0]?.map((cell) => cell.toLowerCase());
6222
+ if (!header || header.length !== 4) {
6223
+ return void 0;
6224
+ }
6225
+ if (header[0] === "rev" && header[1] === "date" && /whom/.test(header[2]) && header[3] === "what") {
6226
+ return [59, 81, 106, 191];
6227
+ }
6228
+ return void 0;
6229
+ }
6230
+ function appendInlineText(element, text, preserveTabs) {
6231
+ element.append(window.document.createTextNode(preserveTabs ? text : text.replace(/\t+/g, " ")));
6232
+ }
6233
+ function isReferenceTerm(value) {
6234
+ return /^\[[A-Z0-9][A-Z0-9.-]{1,24}\]$/.test(value);
6235
+ }
6236
+ function isCodeStyleRun(value) {
6237
+ return /^<\/?[A-Za-z][A-Za-z0-9:-]*>$/.test(value) || /^(?:attributeNames|DataType|OtherKeyword)$/.test(value);
6238
+ }
6239
+ function isVariableStyleRun(value) {
6240
+ return value === "variable";
6241
+ }
6242
+ function isRequirementKeywordRun(value) {
6243
+ return /^(?:must not|must|required|shall not|shall|should not|should|recommended|may|optional)$/i.test(value);
6244
+ }
6245
+ function splitLinkRun(value) {
6246
+ let text = value;
6247
+ let trailing = "";
6248
+ while (/[),.;:]$/.test(text)) {
6249
+ trailing = text.slice(-1) + trailing;
6250
+ text = text.slice(0, -1);
6251
+ }
6252
+ const href = /^https?:\/\//i.test(text) ? text : `mailto:${text}`;
6253
+ return { text, href, trailing };
6254
+ }
6255
+ function extractImageAssets(cfb) {
6256
+ const assets = [];
6257
+ const seen = /* @__PURE__ */ new Set();
6258
+ for (const entry of cfb.entries) {
6259
+ if (entry.type !== 2) {
6260
+ continue;
6261
+ }
6262
+ const stream = cfb.getStream(entry.name);
6263
+ if (!stream || stream.length < 16) {
6264
+ continue;
6265
+ }
6266
+ for (const image of extractImagesFromBytes(stream, entry.name)) {
6267
+ const key = `${image.mimeType}:${image.bytes.length}:${image.bytes[0]}:${image.bytes[image.bytes.length - 1]}`;
6268
+ if (seen.has(key)) {
6269
+ continue;
6270
+ }
6271
+ seen.add(key);
6272
+ const id = `image-${assets.length + 1}`;
6273
+ assets.push({
6274
+ id,
6275
+ kind: "image",
6276
+ mimeType: image.mimeType,
6277
+ dataUrl: `data:${image.mimeType};base64,${bytesToBase64(image.bytes)}`,
6278
+ width: image.width,
6279
+ height: image.height
6280
+ });
6281
+ }
6282
+ }
6283
+ return assets;
6284
+ }
6285
+ function parseStyleTable(tableStream, fib) {
6286
+ if (fib.lcbStshf <= 0 || fib.fcStshf < 0 || fib.fcStshf >= tableStream.length) {
6287
+ return [];
6288
+ }
6289
+ const bytes = tableStream.subarray(fib.fcStshf, Math.min(tableStream.length, fib.fcStshf + fib.lcbStshf));
6290
+ if (bytes.length < 8) {
6291
+ return [];
6292
+ }
6293
+ const view3 = dataView2(bytes);
6294
+ const cbStshi = view3.getUint16(0, true);
6295
+ const stshiOffset = 2;
6296
+ const cstd = stshiOffset + 2 <= bytes.length ? view3.getUint16(stshiOffset, true) : 0;
6297
+ const cbSTDBaseInFile = stshiOffset + 4 <= bytes.length ? view3.getUint16(stshiOffset + 2, true) : 10;
6298
+ let offset = 2 + cbStshi;
6299
+ const styles = [];
6300
+ for (let id = 0; id < cstd && offset + 2 <= bytes.length; id += 1) {
6301
+ const cbStd = view3.getUint16(offset, true);
6302
+ const stdStart = offset + 2;
6303
+ const stdEnd = stdStart + cbStd;
6304
+ if (cbStd > 0 && stdStart < bytes.length) {
6305
+ const style = parseStyleDefinition(bytes.subarray(stdStart, Math.min(stdEnd, bytes.length)), Math.max(10, cbSTDBaseInFile), id);
6306
+ if (style.name) {
6307
+ styles.push(style);
6308
+ }
6309
+ }
6310
+ offset = alignEven(stdEnd);
6311
+ }
6312
+ return styles;
6313
+ }
6314
+ function parseStyleDefinition(bytes, baseSize, id) {
6315
+ const base = bytes.length >= 6 ? parseStyleBase(bytes) : void 0;
6316
+ const nameOffset = Math.min(bytes.length, Math.max(10, baseSize));
6317
+ const name = parseXstz(bytes, nameOffset);
6318
+ return {
6319
+ id,
6320
+ name,
6321
+ type: styleTypeFromStk(base?.stk),
6322
+ basedOn: base?.basedOn,
6323
+ next: base?.next
6324
+ };
6325
+ }
6326
+ function parseStyleBase(bytes) {
6327
+ const view3 = dataView2(bytes);
6328
+ const w2 = view3.getUint16(2, true);
6329
+ const w3 = view3.getUint16(4, true);
6330
+ return {
6331
+ stk: w2 & 15,
6332
+ basedOn: w2 >> 4 & 4095,
6333
+ next: w3 >> 4 & 4095
6334
+ };
6335
+ }
6336
+ function styleTypeFromStk(stk) {
6337
+ if (stk === 1) {
6338
+ return "paragraph";
6339
+ }
6340
+ if (stk === 2) {
6341
+ return "character";
6342
+ }
6343
+ if (stk === 3) {
6344
+ return "table";
6345
+ }
6346
+ if (stk === 4) {
6347
+ return "numbering";
6348
+ }
6349
+ return "unknown";
6350
+ }
6351
+ function parseXstz(bytes, offset) {
6352
+ if (offset + 2 > bytes.length) {
6353
+ return "";
6354
+ }
6355
+ const view3 = dataView2(bytes);
6356
+ const charCount = view3.getUint16(offset, true);
6357
+ const start = offset + 2;
6358
+ const end = Math.min(bytes.length, start + charCount * 2);
6359
+ if (end <= start) {
6360
+ return "";
6361
+ }
6362
+ return decodeUtf16Le(bytes.subarray(start, end)).replace(/\0+$/g, "");
6363
+ }
6364
+ function extractImagesFromBytes(bytes, sourceName) {
6365
+ const images = [];
6366
+ for (const start of findSignatureOffsets(bytes, PNG_SIGNATURE)) {
6367
+ const end = findPngEnd(bytes, start);
6368
+ if (end > start) {
6369
+ const imageBytes = bytes.slice(start, end);
6370
+ const dimensions = readPngDimensions(imageBytes);
6371
+ images.push({ bytes: imageBytes, mimeType: "image/png", width: dimensions?.width, height: dimensions?.height });
6372
+ }
6373
+ }
6374
+ for (const start of findSignatureOffsets(bytes, JPEG_SIGNATURE)) {
6375
+ const end = findJpegEnd(bytes, start);
6376
+ if (end > start) {
6377
+ images.push({ bytes: bytes.slice(start, end), mimeType: "image/jpeg" });
6378
+ }
6379
+ }
6380
+ if (/picture|image|data/i.test(sourceName)) {
6381
+ const gifStart = bytes.findIndex((byte, index) => index + 4 <= bytes.length && bytes[index] === 71 && bytes[index + 1] === 73 && bytes[index + 2] === 70 && bytes[index + 3] === 56);
6382
+ if (gifStart >= 0) {
6383
+ images.push({ bytes: bytes.slice(gifStart), mimeType: "image/gif" });
6384
+ }
6385
+ }
6386
+ return images;
6387
+ }
6388
+ var PNG_SIGNATURE = Uint8Array.from([137, 80, 78, 71, 13, 10, 26, 10]);
6389
+ var JPEG_SIGNATURE = Uint8Array.from([255, 216, 255]);
6390
+ function findSignatureOffsets(bytes, signature) {
6391
+ const offsets = [];
6392
+ for (let index = 0; index <= bytes.length - signature.length; index += 1) {
6393
+ let matches = true;
6394
+ for (let sigIndex = 0; sigIndex < signature.length; sigIndex += 1) {
6395
+ if (bytes[index + sigIndex] !== signature[sigIndex]) {
6396
+ matches = false;
6397
+ break;
6398
+ }
6399
+ }
6400
+ if (matches) {
6401
+ offsets.push(index);
6402
+ }
6403
+ }
6404
+ return offsets;
6405
+ }
6406
+ function findPngEnd(bytes, start) {
6407
+ for (let offset = start + PNG_SIGNATURE.length; offset + 12 <= bytes.length; ) {
6408
+ const length = readUint32Be4(bytes, offset);
6409
+ const typeOffset = offset + 4;
6410
+ const next = offset + 12 + length;
6411
+ if (next > bytes.length) {
6412
+ return 0;
6413
+ }
6414
+ if (bytes[typeOffset] === 73 && bytes[typeOffset + 1] === 69 && bytes[typeOffset + 2] === 78 && bytes[typeOffset + 3] === 68) {
6415
+ return next;
6416
+ }
6417
+ offset = next;
6418
+ }
6419
+ return 0;
6420
+ }
6421
+ function findJpegEnd(bytes, start) {
6422
+ for (let index = start + 2; index + 1 < bytes.length; index += 1) {
6423
+ if (bytes[index] === 255 && bytes[index + 1] === 217) {
6424
+ return index + 2;
6425
+ }
6426
+ }
6427
+ return 0;
6428
+ }
6429
+ function readPngDimensions(bytes) {
6430
+ if (bytes.length < 24 || !PNG_SIGNATURE.every((value, index) => bytes[index] === value)) {
6431
+ return void 0;
6432
+ }
6433
+ return {
6434
+ width: readUint32Be4(bytes, 16),
6435
+ height: readUint32Be4(bytes, 20)
6436
+ };
6437
+ }
6438
+ function readUint32Be4(bytes, offset) {
6439
+ return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
6440
+ }
6441
+ function bytesToBase64(bytes) {
6442
+ let binary = "";
6443
+ const chunkSize = 32768;
6444
+ for (let offset = 0; offset < bytes.length; offset += chunkSize) {
6445
+ binary += String.fromCharCode(...bytes.subarray(offset, Math.min(bytes.length, offset + chunkSize)));
6446
+ }
6447
+ return btoa(binary);
6448
+ }
6449
+ function parseCompoundFile(bytes) {
6450
+ if (!hasCompoundSignature(bytes)) {
6451
+ throw new Error("\u4E0D\u662F\u6807\u51C6 OLE Compound File");
6452
+ }
6453
+ const view3 = dataView2(bytes);
6454
+ const sectorSize = 1 << view3.getUint16(30, true);
6455
+ const miniSectorSize = 1 << view3.getUint16(32, true);
6456
+ const fatSectorCount = view3.getUint32(44, true);
6457
+ const firstDirectorySector = view3.getUint32(48, true);
6458
+ const miniStreamCutoff = view3.getUint32(56, true) || MINI_STREAM_CUTOFF;
6459
+ const firstMiniFatSector = view3.getUint32(60, true);
6460
+ const miniFatSectorCount = view3.getUint32(64, true);
6461
+ const firstDifatSector = view3.getUint32(68, true);
6462
+ const difatSectorCount = view3.getUint32(72, true);
6463
+ const difat = readDifat(view3, sectorSize, firstDifatSector, difatSectorCount);
6464
+ const fat = readFat(view3, sectorSize, difat.slice(0, fatSectorCount));
6465
+ const directoryBytes = readRegularStream(bytes, sectorSize, fat, firstDirectorySector);
6466
+ const entries = parseDirectoryEntries(directoryBytes);
6467
+ const root = entries.find((entry) => entry.type === 5);
6468
+ const miniStream = root ? readRegularStream(bytes, sectorSize, fat, root.startSector, root.size) : new Uint8Array();
6469
+ const miniFat = firstMiniFatSector < END_OF_CHAIN ? readFat(view3, sectorSize, sectorChain(fat, firstMiniFatSector).slice(0, miniFatSectorCount)) : [];
6470
+ return {
6471
+ entries,
6472
+ getStream(name) {
6473
+ const wanted = normalizeStreamName(name);
6474
+ const entry = entries.find((item) => item.type === 2 && normalizeStreamName(item.name) === wanted);
6475
+ if (!entry) {
6476
+ return void 0;
6477
+ }
6478
+ if (entry.size < miniStreamCutoff && miniFat.length > 0) {
6479
+ return readMiniStream(miniStream, miniSectorSize, miniFat, entry.startSector, entry.size);
6480
+ }
6481
+ return readRegularStream(bytes, sectorSize, fat, entry.startSector, entry.size);
6482
+ }
6483
+ };
6484
+ }
6485
+ function hasCompoundSignature(bytes) {
6486
+ return CFB_SIGNATURE.every((value, index) => bytes[index] === value);
6487
+ }
6488
+ function readDifat(view3, sectorSize, firstDifatSector, difatSectorCount) {
6489
+ const difat = [];
6490
+ for (let offset = 76; offset < 512; offset += 4) {
6491
+ const sector = view3.getUint32(offset, true);
6492
+ if (isUsableSector(sector)) {
6493
+ difat.push(sector);
6494
+ }
6495
+ }
6496
+ let next = firstDifatSector;
6497
+ for (let index = 0; index < difatSectorCount && isUsableSector(next); index += 1) {
6498
+ const offset = sectorOffset(next, sectorSize);
6499
+ const entriesPerSector = sectorSize / 4 - 1;
6500
+ for (let item = 0; item < entriesPerSector; item += 1) {
6501
+ const sector = view3.getUint32(offset + item * 4, true);
6502
+ if (isUsableSector(sector)) {
6503
+ difat.push(sector);
6504
+ }
6505
+ }
6506
+ next = view3.getUint32(offset + entriesPerSector * 4, true);
6507
+ }
6508
+ return difat;
6509
+ }
6510
+ function readFat(view3, sectorSize, sectors) {
6511
+ const fat = [];
6512
+ for (const sector of sectors) {
6513
+ if (!isUsableSector(sector) && sector !== FAT_SECTOR && sector !== DIFAT_SECTOR) {
6514
+ continue;
6515
+ }
6516
+ const offset = sectorOffset(sector, sectorSize);
6517
+ for (let item = 0; item < sectorSize / 4; item += 1) {
6518
+ fat.push(view3.getUint32(offset + item * 4, true));
6519
+ }
6520
+ }
6521
+ return fat;
6522
+ }
6523
+ function parseDirectoryEntries(bytes) {
6524
+ const view3 = dataView2(bytes);
6525
+ const entries = [];
6526
+ for (let offset = 0; offset + 128 <= bytes.length; offset += 128) {
6527
+ const nameLength = view3.getUint16(offset + 64, true);
6528
+ const type = bytes[offset + 66] || 0;
6529
+ if (type === 0 || nameLength < 2) {
6530
+ continue;
6531
+ }
6532
+ const nameBytes = bytes.subarray(offset, offset + Math.max(0, nameLength - 2));
6533
+ const name = decodeUtf16Le(nameBytes).replace(/\0+$/g, "");
6534
+ const startSector = view3.getUint32(offset + 116, true);
6535
+ const lowSize = view3.getUint32(offset + 120, true);
6536
+ const highSize = view3.getUint32(offset + 124, true);
6537
+ const size = highSize > 0 ? Number(BigInt(highSize) << 32n) + lowSize : lowSize;
6538
+ entries.push({ name, type, startSector, size });
6539
+ }
6540
+ return entries;
6541
+ }
6542
+ function readRegularStream(bytes, sectorSize, fat, startSector, size) {
6543
+ const chunks = [];
6544
+ for (const sector of sectorChain(fat, startSector)) {
6545
+ const offset = sectorOffset(sector, sectorSize);
6546
+ chunks.push(bytes.subarray(offset, Math.min(bytes.length, offset + sectorSize)));
6547
+ }
6548
+ return concatChunks(chunks, size);
6549
+ }
6550
+ function readMiniStream(miniStream, miniSectorSize, miniFat, startSector, size) {
6551
+ const chunks = [];
6552
+ for (const sector of sectorChain(miniFat, startSector)) {
6553
+ const offset = sector * miniSectorSize;
6554
+ chunks.push(miniStream.subarray(offset, Math.min(miniStream.length, offset + miniSectorSize)));
6555
+ }
6556
+ return concatChunks(chunks, size);
6557
+ }
6558
+ function sectorChain(fat, startSector) {
6559
+ const chain = [];
6560
+ const seen = /* @__PURE__ */ new Set();
6561
+ let current = startSector;
6562
+ while (isUsableSector(current) && current < fat.length && !seen.has(current)) {
6563
+ seen.add(current);
6564
+ chain.push(current);
6565
+ current = fat[current];
6566
+ }
6567
+ return chain;
6568
+ }
6569
+ function parseFib(wordDocument) {
6570
+ const view3 = dataView2(wordDocument);
6571
+ if (view3.getUint16(0, true) !== 42476) {
6572
+ throw new Error("WordDocument FIB \u6807\u8BC6\u65E0\u6548");
6573
+ }
6574
+ const flags = view3.getUint16(10, true);
6575
+ const fcMin = view3.getUint32(24, true);
6576
+ const fcMac = view3.getUint32(28, true);
6577
+ let offset = 32;
6578
+ const csw = view3.getUint16(offset, true);
6579
+ offset += 2 + csw * 2;
6580
+ const fibRgLwOffset = offset + 2;
6581
+ const cslw = view3.getUint16(offset, true);
6582
+ const ccpText = fibRgLwOffset + 16 <= wordDocument.length ? Math.max(0, view3.getInt32(fibRgLwOffset + 12, true)) : 0;
6583
+ offset += 2 + cslw * 4;
6584
+ const cbRgFcLcb = view3.getUint16(offset, true);
6585
+ const fcLcbOffset = offset + 2;
6586
+ const stshOffset = fcLcbOffset + STSH_FC_LCB_INDEX * 8;
6587
+ const clxOffset = fcLcbOffset + CLX_FC_LCB_INDEX * 8;
6588
+ return {
6589
+ encrypted: (flags & 256) !== 0,
6590
+ useOneTable: (flags & 512) !== 0,
6591
+ textIsUnicode: (flags & 4096) !== 0,
6592
+ fcMin,
6593
+ fcMac,
6594
+ ccpText,
6595
+ fcStshf: STSH_FC_LCB_INDEX < cbRgFcLcb && stshOffset + 8 <= wordDocument.length ? view3.getUint32(stshOffset, true) : 0,
6596
+ lcbStshf: STSH_FC_LCB_INDEX < cbRgFcLcb && stshOffset + 8 <= wordDocument.length ? view3.getUint32(stshOffset + 4, true) : 0,
6597
+ fcClx: CLX_FC_LCB_INDEX < cbRgFcLcb && clxOffset + 8 <= wordDocument.length ? view3.getUint32(clxOffset, true) : 0,
6598
+ lcbClx: CLX_FC_LCB_INDEX < cbRgFcLcb && clxOffset + 8 <= wordDocument.length ? view3.getUint32(clxOffset + 4, true) : 0
6599
+ };
6600
+ }
6601
+ function parseClxPieces(tableStream, fcClx, lcbClx) {
6602
+ if (lcbClx <= 0 || fcClx < 0 || fcClx >= tableStream.length) {
6603
+ return [];
6604
+ }
6605
+ const end = Math.min(tableStream.length, fcClx + lcbClx);
6606
+ const view3 = dataView2(tableStream);
6607
+ let offset = fcClx;
6608
+ while (offset < end) {
6609
+ const marker = tableStream[offset];
6610
+ if (marker === 1) {
6611
+ const size = offset + 3 <= end ? view3.getUint16(offset + 1, true) : 0;
6612
+ offset += 3 + size;
6613
+ continue;
6614
+ }
6615
+ if (marker === 2) {
6616
+ if (offset + 5 > end) {
6617
+ break;
6618
+ }
6619
+ const plcSize = view3.getUint32(offset + 1, true);
6620
+ const plcOffset = offset + 5;
6621
+ return parsePlcPcd(tableStream, plcOffset, Math.min(end, plcOffset + plcSize));
6622
+ }
6623
+ offset += 1;
6624
+ }
6625
+ return [];
6626
+ }
6627
+ function parsePlcPcd(tableStream, offset, end) {
6628
+ const size = end - offset;
6629
+ if (size < 16 || (size - 4) % 12 !== 0) {
6630
+ return [];
6631
+ }
6632
+ const view3 = dataView2(tableStream);
6633
+ const pieceCount = Math.floor((size - 4) / 12);
6634
+ const pcdOffset = offset + (pieceCount + 1) * 4;
6635
+ const pieces = [];
6636
+ for (let index = 0; index < pieceCount; index += 1) {
6637
+ const cpStart = view3.getUint32(offset + index * 4, true);
6638
+ const cpEnd = view3.getUint32(offset + (index + 1) * 4, true);
6639
+ const descriptorOffset = pcdOffset + index * 8;
6640
+ const fcCompressed = view3.getUint32(descriptorOffset + 2, true);
6641
+ const compressed = (fcCompressed & 1073741824) !== 0;
6642
+ const fileOffset = compressed ? (fcCompressed & 1073741823) / 2 : fcCompressed;
6643
+ if (cpEnd > cpStart) {
6644
+ pieces.push({ cpStart, cpEnd, fileOffset, compressed });
6645
+ }
6646
+ }
6647
+ return pieces;
6648
+ }
6649
+ function readPieceTableText(wordDocument, pieces, ccpText) {
6650
+ let output = "";
6651
+ for (const piece of pieces) {
6652
+ const cpEnd = ccpText > 0 ? Math.min(piece.cpEnd, ccpText) : piece.cpEnd;
6653
+ const charCount = Math.max(0, cpEnd - piece.cpStart);
6654
+ if (charCount === 0) {
6655
+ continue;
6656
+ }
6657
+ const byteLength = charCount * (piece.compressed ? 1 : 2);
6658
+ const bytes = wordDocument.subarray(piece.fileOffset, Math.min(wordDocument.length, piece.fileOffset + byteLength));
6659
+ output += piece.compressed ? decodeWindows1252(bytes) : decodeUtf16Le(bytes);
6660
+ }
6661
+ return output;
6662
+ }
6663
+ function readFibTextFallback(wordDocument, fib) {
6664
+ const bytes = wordDocument.subarray(fib.fcMin, Math.min(wordDocument.length, fib.fcMac));
6665
+ return fib.textIsUnicode ? decodeUtf16Le(bytes) : decodeWindows1252(bytes);
6666
+ }
6667
+ function splitWordParagraphs(text) {
6668
+ const normalized = text.replace(/\u0000/g, "").replace(/\u0007/g, " ").replace(/\u000b/g, "\n");
6669
+ const paragraphs = [];
6670
+ for (const segment of normalized.split(/(\u000c)/)) {
6671
+ if (segment === "\f") {
6672
+ paragraphs.push(WORD_PAGE_BREAK);
6673
+ continue;
6674
+ }
6675
+ paragraphs.push(
6676
+ ...segment.split(/\r|\n{2,}/).map((paragraph) => cleanWordText(paragraph)).filter((paragraph) => paragraph.length > 0 && isDisplayableParagraph(paragraph))
6677
+ );
6678
+ }
6679
+ return paragraphs.slice(0, 1e3);
6680
+ }
6681
+ function removeTrailingFooterArtifacts(paragraphs) {
6682
+ const tailStart = Math.max(0, paragraphs.length - 32);
6683
+ const tail = paragraphs.slice(tailStart);
6684
+ const relativePageFieldIndex = tail.findIndex(isFooterPageField);
6685
+ if (relativePageFieldIndex < 0) {
6686
+ return paragraphs;
6687
+ }
6688
+ let start = tailStart + relativePageFieldIndex;
6689
+ for (let index = start - 1; index >= tailStart; index -= 1) {
6690
+ const paragraph = paragraphs[index];
6691
+ if (paragraph === WORD_PAGE_BREAK || isLikelyFooterArtifact(paragraph)) {
6692
+ start = index;
6693
+ continue;
6694
+ }
6695
+ break;
6696
+ }
6697
+ const artifactSlice = paragraphs.slice(start);
6698
+ const footerCueCount = artifactSlice.filter(isLikelyFooterArtifact).length;
6699
+ if (footerCueCount < 2) {
6700
+ return paragraphs;
6701
+ }
6702
+ return paragraphs.slice(0, start);
6703
+ }
6704
+ function isFooterPageField(paragraph) {
6705
+ return /^(?:PAGE|Page)(?:\s+(?:PAGE|\d+))?(?:\s+of\s+(?:NUMPAGES|\d+))?$/i.test(paragraph.trim()) || /\bNUMPAGES\b/i.test(paragraph);
6706
+ }
6707
+ function isLikelyFooterArtifact(paragraph) {
6708
+ const value = paragraph.trim();
6709
+ return value === WORD_PAGE_BREAK || isFooterPageField(value) || /^wd-[\w.-]+$/i.test(value) || /^\d{1,2}\s+[A-Za-z]+\s+\d{4}$/.test(value) || /^Copyright\s+©?\s*(?:OASIS|2002 OASIS)/i.test(value);
6710
+ }
6711
+ function buildWordBlocks(paragraphs) {
6712
+ const blocks = [];
6713
+ let index = 0;
6714
+ while (index < paragraphs.length) {
6715
+ const paragraph = paragraphs[index];
6716
+ if (paragraph === WORD_PAGE_BREAK) {
6717
+ blocks.push({ type: "pageBreak" });
6718
+ index += 1;
6719
+ continue;
6720
+ }
6721
+ const toc = parseTocEntry(paragraph);
6722
+ if (toc) {
6723
+ blocks.push(toc);
6724
+ index += 1;
6725
+ continue;
6726
+ }
6727
+ if (isTableRowCandidate(paragraph)) {
6728
+ const rows = [];
6729
+ while (index < paragraphs.length && isTableRowCandidate(paragraphs[index])) {
6730
+ rows.push(...normalizeTableRows(splitTableRow(paragraphs[index])));
6731
+ index += 1;
6732
+ }
6733
+ blocks.push({ type: "table", rows });
6734
+ continue;
6735
+ }
6736
+ blocks.push(classifyParagraphBlock(paragraph, blocks));
6737
+ index += 1;
6738
+ }
6739
+ return blocks;
6740
+ }
6741
+ function inferLayoutHints(paragraphs, assets) {
6742
+ const sample = paragraphs.slice(0, 40).join("\n");
6743
+ const isOasisSpec = /Word Specification Sample/.test(sample) && /\bOASIS\b/i.test(paragraphs.join("\n"));
6744
+ const oasisImage = isOasisSpec ? assets.find((asset) => asset.mimeType === "image/png" && asset.width && asset.height && asset.width / asset.height > 2.5) : void 0;
6745
+ return {
6746
+ lineNumbers: isOasisSpec,
6747
+ headerBrand: isOasisSpec ? "oasis" : void 0,
6748
+ headerImageId: oasisImage?.id,
6749
+ footer: isOasisSpec ? inferOasisFooter(paragraphs) : void 0
6750
+ };
6751
+ }
6752
+ function inferOasisFooter(paragraphs) {
6753
+ const documentId = findValueAfterLabel(paragraphs, "Document identifier:") || paragraphs.find((paragraph) => /^wd-[\w.-]+/i.test(paragraph));
6754
+ const subtitle = paragraphs.find((paragraph) => /\b(?:draft|version)\b/i.test(paragraph) && /\d{4}/.test(paragraph));
6755
+ const date = subtitle?.match(/\b\d{1,2}\s+[A-Za-z]+\s+\d{4}\b/)?.[0];
6756
+ const copyright = paragraphs.find((paragraph) => /Copyright.*OASIS.*All Rights Reserved/i.test(paragraph)) || "Copyright \xA9 OASIS Open 2002. All Rights Reserved.";
6757
+ return { documentId, date, copyright };
6758
+ }
6759
+ function findValueAfterLabel(paragraphs, label) {
6760
+ const index = paragraphs.findIndex((paragraph) => paragraph.toLowerCase() === label.toLowerCase());
6761
+ if (index < 0) {
6762
+ return void 0;
6763
+ }
6764
+ return paragraphs.slice(index + 1).find((paragraph) => paragraph !== WORD_PAGE_BREAK && paragraph.length > 0);
6765
+ }
6766
+ function paginateWordBlocks(blocks, layout) {
6767
+ const maxLines = layout.lineNumbers ? 33 : 46;
6768
+ const pages = [];
6769
+ let current = [];
6770
+ let usedLines = 0;
6771
+ for (const block of blocks) {
6772
+ if (block.type === "pageBreak") {
6773
+ if (current.length > 0) {
6774
+ pages.push(current);
6775
+ }
6776
+ current = [];
6777
+ usedLines = 0;
6778
+ continue;
6779
+ }
6780
+ const lines = estimatedLineCount(block);
6781
+ const shouldBreak = current.length > 0 && (usedLines + lines > maxLines || block.type === "heading" && usedLines > Math.floor(maxLines * 0.72));
6782
+ if (shouldBreak) {
6783
+ pages.push(current);
6784
+ current = [];
6785
+ usedLines = 0;
6786
+ }
6787
+ current.push(block);
6788
+ usedLines += lines;
6789
+ }
6790
+ if (current.length > 0 || pages.length === 0) {
6791
+ pages.push(current);
6792
+ }
6793
+ return pages;
6794
+ }
6795
+ function estimatedLineCount(block) {
6796
+ if (block.type === "pageBreak") {
6797
+ return 0;
6798
+ }
6799
+ if (block.type === "table") {
6800
+ return Math.max(1, block.rows.length);
6801
+ }
6802
+ if (block.type === "toc") {
6803
+ return 1;
6804
+ }
6805
+ const baseWidth = "indent" in block && block.indent ? 78 : 96;
6806
+ return Math.max(1, Math.ceil(block.text.length / baseWidth));
6807
+ }
6808
+ function classifyParagraphBlock(text, previousBlocks) {
6809
+ const visibleIndex = previousBlocks.filter((block) => block.type !== "toc").length;
6810
+ if (visibleIndex === 0 && text.length <= 140) {
6811
+ return { type: "title", text };
6812
+ }
6813
+ if (visibleIndex === 1 && /draft|version|20\d{2}|19\d{2}/i.test(text) && text.length <= 140) {
6814
+ return { type: "subtitle", text };
6815
+ }
6816
+ const headingLevel = inferHeadingLevel(text, previousBlocks);
6817
+ if (headingLevel) {
6818
+ return { type: "heading", text, level: headingLevel };
6819
+ }
6820
+ if (/^[\w\s/().-]{2,45}:$/.test(text)) {
6821
+ return { type: "label", text };
6822
+ }
6823
+ if (isInstructionParagraph(text)) {
6824
+ return { type: "instruction", text, indent: shouldIndentParagraph(previousBlocks) };
6825
+ }
6826
+ if (/^\[[-\w.]+\]\s+/.test(text)) {
6827
+ return { type: "reference", text };
6828
+ }
6829
+ const listLevel = inferListItemLevel(text);
6830
+ if (listLevel) {
6831
+ return { type: "listItem", text, level: listLevel };
6832
+ }
6833
+ if (isCodeLikeParagraph(text)) {
6834
+ return { type: "code", text, indent: shouldIndentParagraph(previousBlocks) };
6835
+ }
6836
+ return { type: "paragraph", text, indent: shouldIndentParagraph(previousBlocks) };
6837
+ }
6838
+ function isInstructionParagraph(text) {
6839
+ return /^\[[^\]]{8,}\]$/.test(text.trim());
6840
+ }
6841
+ function inferHeadingLevel(text, previousBlocks) {
6842
+ if (text.length > 120) {
6843
+ return void 0;
6844
+ }
6845
+ if (/^table of contents$/i.test(text)) {
6846
+ return 1;
6847
+ }
6848
+ if (/^(?:introduction|word styles|references|appendix\b.*|acknowledgments|revision history|notices)$/i.test(text)) {
6849
+ return 1;
6850
+ }
6851
+ const numbered = text.match(/^([1-9](?:\.\d+)*)\s+.+/);
6852
+ if (numbered) {
6853
+ return Math.min(3, numbered[1].split(".").length);
6854
+ }
6855
+ if (/^(?:terminology|overall style|title page|headings|paragraphs|lists|tables|code examples|character styles|normative)$/i.test(text)) {
6856
+ return 2;
6857
+ }
6858
+ const previousHeading = [...previousBlocks].reverse().find((block) => block.type === "heading");
6859
+ if (previousHeading?.type === "heading" && previousHeading.level === 1 && /^[A-Z][A-Za-z0-9 ()/-]{2,80}$/.test(text)) {
6860
+ return 2;
6861
+ }
6862
+ return void 0;
6863
+ }
6864
+ function shouldIndentParagraph(previousBlocks) {
6865
+ for (let index = previousBlocks.length - 1; index >= 0; index -= 1) {
6866
+ const block = previousBlocks[index];
6867
+ if (block.type === "toc" || block.type === "table") {
6868
+ continue;
6869
+ }
6870
+ if (block.type === "label") {
6871
+ return true;
6872
+ }
6873
+ if ((block.type === "paragraph" || block.type === "code") && block.indent) {
6874
+ return true;
6875
+ }
6876
+ return false;
6877
+ }
6878
+ return false;
6879
+ }
6880
+ function inferListItemLevel(text) {
6881
+ if (/^(?:list bullet|definition term)$/i.test(text)) {
6882
+ return 1;
6883
+ }
6884
+ if (/^(?:list bullet 2|list continue 2|definition for the term\.)$/i.test(text)) {
6885
+ return 2;
6886
+ }
6887
+ return void 0;
6888
+ }
6889
+ function parseTocEntry(text) {
6890
+ const tabCells = splitTableRow(text);
6891
+ if (tabCells.length >= 2 && /^\d{1,3}$/.test(tabCells[tabCells.length - 1] || "")) {
6892
+ const title2 = tabCells.slice(0, -1).join(" ").trim();
6893
+ if (isLikelyTocTitle(title2)) {
6894
+ const number2 = title2.match(/^(\d+(?:\.\d+)*)\b/)?.[1] || "";
6895
+ return { type: "toc", title: title2, page: tabCells[tabCells.length - 1], level: number2.includes(".") ? Math.min(3, number2.split(".").length) : 1 };
6896
+ }
6897
+ }
6898
+ const cleaned = text.replace(/\s+/g, " ").trim();
6899
+ const match = cleaned.match(/^(?:(\d+(?:\.\d+)*)\s+)?(.+?)\s+(\d{1,3})$/);
6900
+ if (!match || cleaned.length > 140) {
6901
+ return void 0;
6902
+ }
6903
+ const number = match[1] || "";
6904
+ const title = `${number ? `${number} ` : ""}${match[2] || ""}`.trim();
6905
+ const page = match[3];
6906
+ if (!title || !page || !/^(?:appendix\b|references\b|introduction\b|[A-Z0-9])/i.test(title)) {
6907
+ return void 0;
6908
+ }
6909
+ if (!isLikelyTocTitle(title)) {
6910
+ return void 0;
6911
+ }
6912
+ const level = number.includes(".") ? Math.min(3, number.split(".").length) : 1;
6913
+ return { type: "toc", title, page, level };
6914
+ }
6915
+ function isLikelyTocTitle(title) {
6916
+ return /^(?:appendix\b|references\b|introduction\b|[1-9](?:\.\d+)*\b|[A-Z][\w\s.-]{2,80}$)/i.test(title);
6917
+ }
6918
+ function isTableRowCandidate(text) {
6919
+ if (/^\[[-\w.]+\]\t+/.test(text)) {
6920
+ return false;
6921
+ }
6922
+ const cells = splitTableRow(text);
6923
+ return cells.length >= 2 && cells.some((cell) => cell.length > 0);
6924
+ }
6925
+ function splitTableRow(text) {
6926
+ return text.split(/\t+/).map((cell) => cell.trim()).filter(Boolean);
6927
+ }
6928
+ function normalizeTableRows(cells) {
6929
+ if (cells.length >= 8) {
6930
+ const columnCount = inferTableColumnCount(cells);
6931
+ if (columnCount > 1 && cells.length % columnCount === 0) {
6932
+ const rows = [];
6933
+ for (let offset = 0; offset < cells.length; offset += columnCount) {
6934
+ rows.push(cells.slice(offset, offset + columnCount));
6935
+ }
6936
+ return rows;
6937
+ }
6938
+ }
6939
+ return [cells];
6940
+ }
6941
+ function inferTableColumnCount(cells) {
6942
+ const header = cells.slice(0, 6).join(" ").toLowerCase();
6943
+ if (/\brev\b/.test(header) && /\bdate\b/.test(header) && /whom|what/.test(header)) {
6944
+ return 4;
6945
+ }
6946
+ for (const candidate of [5, 4, 3, 2]) {
6947
+ if (cells.length % candidate === 0) {
6948
+ return candidate;
6949
+ }
6950
+ }
6951
+ return 0;
6952
+ }
6953
+ function isCodeLikeParagraph(text) {
6954
+ return /^\d{24,}$/.test(text.replace(/\s+/g, "")) || /^GET\s+https?:\/\//i.test(text) || /^<other\s+HTTP\b/i.test(text) || /<\/?[A-Za-z][A-Za-z0-9:-]*(?:\s+[^>@]*)?>/.test(text) || /^\s*(?:<\?xml|function\b|const\b|let\b|var\b|if\s*\(|for\s*\(|while\s*\(|\{|\}|\/\/)/.test(text);
6955
+ }
6956
+ function cleanWordText(value) {
6957
+ return stripWordFieldCodes(value).replace(/[\u0001-\u0006\u0008\u000e-\u001f]/g, "").replace(/ {2,}/g, " ").trim();
6958
+ }
6959
+ function stripWordFieldCodes(value) {
6960
+ return value.replace(/\u0013\s*(?:HYPERLINK|PAGEREF|TOC)\b[^\u0014\u0015]*/gi, "").replace(/[\u0013-\u0015]/g, "").replace(/\bHYPERLINK\s+\\l\s+"[^"]*"\s*/gi, "").replace(/\bHYPERLINK\s+"[^"]*"\s*/gi, "").replace(/\bPAGEREF\s+\S+\s+\\h\s*/gi, "").replace(/\bTOC\s+\\o\s+"[^"]*"\s+\\h\s+\\z\s*/gi, "").replace(/\bREF\s+[_A-Za-z0-9-]+\s+(?:\\[A-Za-z]+\s*)+/gi, "");
6961
+ }
6962
+ function isDisplayableParagraph(value) {
6963
+ if (value.length < 2) {
6964
+ return false;
6965
+ }
6966
+ const letters = [...value].filter((char) => /[\p{L}\p{N}]/u.test(char)).length;
6967
+ return letters >= Math.min(2, value.length);
6968
+ }
6969
+ function inferDocumentTitle(paragraphs) {
6970
+ return paragraphs.find((paragraph) => paragraph.length <= 120) || "Word \u6587\u6863";
6971
+ }
6972
+ function appendMeta4(list, label, value) {
6973
+ const term = window.document.createElement("dt");
6974
+ term.textContent = label;
6975
+ const detail = window.document.createElement("dd");
6976
+ detail.textContent = value;
6977
+ list.append(term, detail);
6978
+ }
6979
+ function concatChunks(chunks, size) {
6980
+ const total = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
6981
+ const output = new Uint8Array(size === void 0 ? total : Math.min(total, size));
6982
+ let offset = 0;
6983
+ for (const chunk of chunks) {
6984
+ const slice = chunk.subarray(0, Math.min(chunk.length, output.length - offset));
6985
+ output.set(slice, offset);
6986
+ offset += slice.length;
6987
+ if (offset >= output.length) {
6988
+ break;
6989
+ }
6990
+ }
6991
+ return output;
6992
+ }
6993
+ function alignEven(value) {
6994
+ return value % 2 === 0 ? value : value + 1;
6995
+ }
6996
+ function isUsableSector(sector) {
6997
+ return sector !== FREE_SECTOR && sector !== END_OF_CHAIN && sector !== FAT_SECTOR && sector !== DIFAT_SECTOR;
6998
+ }
6999
+ function sectorOffset(sector, sectorSize) {
7000
+ return (sector + 1) * sectorSize;
7001
+ }
7002
+ function normalizeStreamName(name) {
7003
+ return name.replace(/^\/+/, "").toLowerCase();
7004
+ }
7005
+ function decodeUtf16Le(bytes) {
7006
+ return new TextDecoder("utf-16le").decode(bytes);
7007
+ }
7008
+ function decodeWindows1252(bytes) {
7009
+ try {
7010
+ return new TextDecoder("windows-1252").decode(bytes);
7011
+ } catch {
7012
+ return Array.from(bytes, (byte) => String.fromCharCode(byte)).join("");
7013
+ }
7014
+ }
7015
+ function dataView2(bytes) {
7016
+ return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
7017
+ }
7018
+
7019
+ // src/plugins/office.ts
5926
7020
  var wordExtensions = /* @__PURE__ */ new Set(["docx", "docm", "doc", "dotx", "dotm", "dot", "rtf", "odt", "fodt", "wps"]);
5927
7021
  var sheetExtensions = /* @__PURE__ */ new Set(["xlsx", "xls", "xlsm", "xlsb", "xlt", "xltx", "xltm", "csv", "tsv", "ods", "fods", "numbers", "et"]);
5928
7022
  var presentationExtensions = /* @__PURE__ */ new Set(["pptx", "pptm", "ppt", "pps", "ppsx", "ppsm", "potx", "potm", "odp", "fodp", "key", "dps"]);
@@ -6033,6 +7127,8 @@ function officePlugin(options = {}) {
6033
7127
  await renderOdp(panel, arrayBuffer);
6034
7128
  } else if (extension === "fodp") {
6035
7129
  renderOpenDocumentPresentationXml(panel, await readTextFromBuffer(arrayBuffer));
7130
+ } else if (extension === "doc" || extension === "dot") {
7131
+ renderLegacyWordBinary(panel, extension, arrayBuffer);
6036
7132
  } else if (isLegacyOfficeBinary(extension)) {
6037
7133
  renderLegacyOfficeBinary(panel, extension, arrayBuffer);
6038
7134
  } else {
@@ -9188,6 +10284,13 @@ function legacyOfficeFormatLabel(extension) {
9188
10284
  }
9189
10285
  return "PowerPoint Binary File Format";
9190
10286
  }
10287
+ function renderLegacyWordBinary(panel, extension, arrayBuffer) {
10288
+ try {
10289
+ renderLegacyWordDocument(panel, parseLegacyWordDocument(arrayBuffer));
10290
+ } catch (error) {
10291
+ renderLegacyOfficeBinary(panel, extension, arrayBuffer, `Word \u4E8C\u8FDB\u5236\u89E3\u6790\u5931\u8D25\uFF1A${normalizeOfficeError(error)}`);
10292
+ }
10293
+ }
9191
10294
  function renderLegacyOfficeBinary(panel, extension, arrayBuffer, parseError) {
9192
10295
  const fragments = extractLegacyOfficeText(arrayBuffer);
9193
10296
  panel.replaceChildren();
@@ -13763,10 +14866,10 @@ function renderStep(panel, text, extension, ctx) {
13763
14866
  note.textContent = "\u5F53\u524D\u7248\u672C\u63D0\u53D6 STEP \u6587\u672C\u5B9E\u4F53\u3001\u7C7B\u578B\u7EDF\u8BA1\u548C\u5173\u952E\u51E0\u4F55\u53C2\u6570\u3002\u7CBE\u786E B-Rep/\u66F2\u9762\u6E32\u67D3\u5EFA\u8BAE\u540E\u7EED\u63A5\u5165 CAD \u5185\u6838\u6216\u670D\u52A1\u7AEF\u8F6C\u6362\u3002";
13764
14867
  const meta = document.createElement("div");
13765
14868
  meta.className = "ofv-cad-summary";
13766
- appendMeta5(meta, "\u5B9E\u4F53", records.length);
13767
- appendMeta5(meta, "\u7C7B\u578B", typeCounts.size);
13768
- appendMeta5(meta, "\u70B9", typeCounts.get("CARTESIAN_POINT") || 0);
13769
- appendMeta5(meta, "\u65B9\u5411", typeCounts.get("DIRECTION") || 0);
14869
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14870
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14871
+ appendMeta6(meta, "\u70B9", typeCounts.get("CARTESIAN_POINT") || 0);
14872
+ appendMeta6(meta, "\u65B9\u5411", typeCounts.get("DIRECTION") || 0);
13770
14873
  const typeList = createCadTypeList(typeCounts);
13771
14874
  section.append(note, meta, typeList);
13772
14875
  let viewer;
@@ -13801,10 +14904,10 @@ function renderIges(panel, text, extension, ctx) {
13801
14904
  note.textContent = "\u5F53\u524D\u7248\u672C\u63D0\u53D6 IGES \u53C2\u6570\u533A\u5B9E\u4F53\u3001\u7C7B\u578B\u7EDF\u8BA1\u548C\u57FA\u7840\u53C2\u6570\u3002\u7CBE\u786E\u66F2\u7EBF/\u66F2\u9762\u6E32\u67D3\u5EFA\u8BAE\u540E\u7EED\u63A5\u5165 CAD \u5185\u6838\u6216\u670D\u52A1\u7AEF\u8F6C\u6362\u3002";
13802
14905
  const meta = document.createElement("div");
13803
14906
  meta.className = "ofv-cad-summary";
13804
- appendMeta5(meta, "\u5B9E\u4F53", records.length);
13805
- appendMeta5(meta, "\u7C7B\u578B", typeCounts.size);
13806
- appendMeta5(meta, "\u70B9\u5B9E\u4F53", typeCounts.get("116") || 0);
13807
- appendMeta5(meta, "\u7EBF\u5B9E\u4F53", typeCounts.get("110") || 0);
14907
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14908
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14909
+ appendMeta6(meta, "\u70B9\u5B9E\u4F53", typeCounts.get("116") || 0);
14910
+ appendMeta6(meta, "\u7EBF\u5B9E\u4F53", typeCounts.get("110") || 0);
13808
14911
  const typeList = createCadTypeList(typeCounts, "\u7C7B\u578B\u53F7\u7EDF\u8BA1");
13809
14912
  section.append(note, meta, typeList);
13810
14913
  let viewer;
@@ -13838,13 +14941,13 @@ function renderIfc(panel, text) {
13838
14941
  note.textContent = "\u5F53\u524D\u7248\u672C\u63D0\u53D6 IFC STEP \u5B9E\u4F53\u3001BIM \u5C42\u7EA7\u548C\u5E38\u89C1\u6784\u4EF6\u7EDF\u8BA1\u3002\u51E0\u4F55\u7F51\u683C\u3001\u6750\u8D28\u548C\u5C5E\u6027\u96C6\u53EF\u540E\u7EED\u63A5\u5165 IfcOpenShell/IFC.js \u589E\u5F3A\u3002";
13839
14942
  const meta = document.createElement("div");
13840
14943
  meta.className = "ofv-cad-summary";
13841
- appendMeta5(meta, "\u5B9E\u4F53", records.length);
13842
- appendMeta5(meta, "\u7C7B\u578B", typeCounts.size);
13843
- appendMeta5(meta, "\u9879\u76EE", typeCounts.get("IFCPROJECT") || 0);
13844
- appendMeta5(meta, "\u5EFA\u7B51", typeCounts.get("IFCBUILDING") || 0);
13845
- appendMeta5(meta, "\u697C\u5C42", typeCounts.get("IFCBUILDINGSTOREY") || 0);
13846
- appendMeta5(meta, "\u7A7A\u95F4", typeCounts.get("IFCSPACE") || 0);
13847
- appendMeta5(meta, "\u6784\u4EF6", countIfcElements(typeCounts));
14944
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14945
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14946
+ appendMeta6(meta, "\u9879\u76EE", typeCounts.get("IFCPROJECT") || 0);
14947
+ appendMeta6(meta, "\u5EFA\u7B51", typeCounts.get("IFCBUILDING") || 0);
14948
+ appendMeta6(meta, "\u697C\u5C42", typeCounts.get("IFCBUILDINGSTOREY") || 0);
14949
+ appendMeta6(meta, "\u7A7A\u95F4", typeCounts.get("IFCSPACE") || 0);
14950
+ appendMeta6(meta, "\u6784\u4EF6", countIfcElements(typeCounts));
13848
14951
  section.append(note, meta, createCadTypeList(typeCounts, "IFC \u5B9E\u4F53\u7EDF\u8BA1"));
13849
14952
  const hierarchy = createIfcHierarchy(records);
13850
14953
  if (hierarchy) {
@@ -13869,10 +14972,10 @@ function renderAcisSat(panel, text, extension, ctx) {
13869
14972
  note.textContent = "\u5F53\u524D\u7248\u672C\u4F1A\u5728\u524D\u7AEF\u89E3\u6790 ACIS SAT \u6587\u672C\u5B9E\u4F53\u3001\u7C7B\u578B\u7EDF\u8BA1\u548C\u5E38\u89C1 vertex/straight-curve \u51E0\u4F55\u7EBF\u7D22\uFF1B\u7CBE\u786E\u66F2\u9762\u3001\u62D3\u6251\u548C\u5E03\u5C14\u4F53\u4ECD\u5EFA\u8BAE\u63A5\u5165 CAD \u5185\u6838\u589E\u5F3A\u3002";
13870
14973
  const meta = document.createElement("div");
13871
14974
  meta.className = "ofv-cad-summary";
13872
- appendMeta5(meta, "\u5B9E\u4F53", records.length);
13873
- appendMeta5(meta, "\u7C7B\u578B", typeCounts.size);
13874
- appendMeta5(meta, "\u9876\u70B9", typeCounts.get("vertex") || 0);
13875
- appendMeta5(meta, "\u76F4\u7EBF", typeCounts.get("straight-curve") || 0);
14975
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
14976
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
14977
+ appendMeta6(meta, "\u9876\u70B9", typeCounts.get("vertex") || 0);
14978
+ appendMeta6(meta, "\u76F4\u7EBF", typeCounts.get("straight-curve") || 0);
13876
14979
  const typeList = createCadTypeList(typeCounts);
13877
14980
  section.append(note, meta, typeList);
13878
14981
  let viewer;
@@ -13909,10 +15012,10 @@ function renderParasolidText(panel, text, extension, ctx) {
13909
15012
  note.textContent = "\u5F53\u524D\u7248\u672C\u4F1A\u5728\u524D\u7AEF\u89E3\u6790 Parasolid x_t \u6587\u672C\u7247\u6BB5\u3001\u5B9E\u4F53\u7C7B\u578B\u3001\u5750\u6807\u70B9\u548C\u57FA\u7840\u7EBF\u6BB5\u7EBF\u7D22\uFF1B\u5B8C\u6574 B-Rep\u3001\u66F2\u9762\u548C\u88C5\u914D\u5173\u7CFB\u5EFA\u8BAE\u63A5\u5165 Parasolid/HOOPS/ODA \u7B49\u4E13\u4E1A\u5185\u6838\u3002";
13910
15013
  const meta = document.createElement("div");
13911
15014
  meta.className = "ofv-cad-summary";
13912
- appendMeta5(meta, "\u5B9E\u4F53", records.length);
13913
- appendMeta5(meta, "\u7C7B\u578B", typeCounts.size);
13914
- appendMeta5(meta, "\u70B9", typeCounts.get("point") || typeCounts.get("vertex") || 0);
13915
- appendMeta5(meta, "\u66F2\u7EBF", (typeCounts.get("line") || 0) + (typeCounts.get("curve") || 0));
15015
+ appendMeta6(meta, "\u5B9E\u4F53", records.length);
15016
+ appendMeta6(meta, "\u7C7B\u578B", typeCounts.size);
15017
+ appendMeta6(meta, "\u70B9", typeCounts.get("point") || typeCounts.get("vertex") || 0);
15018
+ appendMeta6(meta, "\u66F2\u7EBF", (typeCounts.get("line") || 0) + (typeCounts.get("curve") || 0));
13916
15019
  const typeList = createCadTypeList(typeCounts);
13917
15020
  section.append(note, meta, typeList);
13918
15021
  let viewer;
@@ -14020,23 +15123,23 @@ function renderLayoutPreview(panel, data, ctx) {
14020
15123
  summary.setAttribute("aria-hidden", "true");
14021
15124
  summary.style.display = "none";
14022
15125
  }
14023
- appendMeta5(summary, "\u6587\u4EF6", data.fileName);
14024
- appendMeta5(summary, "\u683C\u5F0F", data.format);
15126
+ appendMeta6(summary, "\u6587\u4EF6", data.fileName);
15127
+ appendMeta6(summary, "\u683C\u5F0F", data.format);
14025
15128
  if (data.libraryName) {
14026
- appendMeta5(summary, "\u5E93", data.libraryName);
15129
+ appendMeta6(summary, "\u5E93", data.libraryName);
14027
15130
  }
14028
15131
  if (data.version) {
14029
- appendMeta5(summary, "\u7248\u672C", data.version);
15132
+ appendMeta6(summary, "\u7248\u672C", data.version);
14030
15133
  }
14031
15134
  if (data.unit) {
14032
- appendMeta5(summary, "\u5355\u4F4D", data.unit);
15135
+ appendMeta6(summary, "\u5355\u4F4D", data.unit);
14033
15136
  }
14034
- appendMeta5(summary, "Cell", data.cells.length);
14035
- appendMeta5(summary, "\u51E0\u4F55", data.shapes.length);
14036
- appendMeta5(summary, "\u5F15\u7528", data.references.length);
14037
- appendMeta5(summary, "\u6587\u5B57", data.labels.length);
15137
+ appendMeta6(summary, "Cell", data.cells.length);
15138
+ appendMeta6(summary, "\u51E0\u4F55", data.shapes.length);
15139
+ appendMeta6(summary, "\u5F15\u7528", data.references.length);
15140
+ appendMeta6(summary, "\u6587\u5B57", data.labels.length);
14038
15141
  for (const [label, value] of data.metadata) {
14039
- appendMeta5(summary, label, value);
15142
+ appendMeta6(summary, label, value);
14040
15143
  }
14041
15144
  section.append(summary);
14042
15145
  for (const noteText of [...data.notes, ...data.warnings]) {
@@ -14642,12 +15745,12 @@ function renderBinaryCad(panel, bytes, extension, fileName) {
14642
15745
  note.textContent = extension === "dwg" ? "\u5DF2\u8BC6\u522B DWG \u4E13\u6709\u4E8C\u8FDB\u5236\u56FE\u7EB8\u3002\u6838\u5FC3\u63D2\u4EF6\u9ED8\u8BA4\u63D0\u4F9B\u7248\u672C\u3001\u5BB9\u5668\u3001\u7ED3\u6784\u7EBF\u7D22\u548C\u63A5\u5165\u5EFA\u8BAE\uFF1B\u771F\u5B9E\u51E0\u4F55\u6E32\u67D3\u53EF\u901A\u8FC7 cadPlugin({ binaryRenderer }) \u63A5\u5165\u53EF\u9009\u524D\u7AEF\u5F15\u64CE\u6216\u8F6C\u6362\u670D\u52A1\u3002" : "\u5DF2\u8BC6\u522B DWF \u53D1\u5E03\u56FE\u7EB8\u3002\u6838\u5FC3\u63D2\u4EF6\u9ED8\u8BA4\u63D0\u4F9B\u5BB9\u5668\u7EBF\u7D22\u548C\u63A5\u5165\u5EFA\u8BAE\uFF1B\u9AD8\u4FDD\u771F\u9875\u9762\u6E32\u67D3\u53EF\u901A\u8FC7 cadPlugin({ binaryRenderer }) \u63A5\u5165\u4E13\u7528\u89E3\u6790\u5668\u6216\u8F6C\u6362\u670D\u52A1\u3002";
14643
15746
  const meta = document.createElement("div");
14644
15747
  meta.className = "ofv-cad-summary";
14645
- appendMeta5(meta, "\u6587\u4EF6", fileName);
14646
- appendMeta5(meta, "\u683C\u5F0F", extension.toUpperCase());
14647
- appendMeta5(meta, "\u5927\u5C0F", formatBytes3(bytes.byteLength));
14648
- appendMeta5(meta, "\u7B7E\u540D", byteSignature2(bytes));
14649
- appendMeta5(meta, "\u7248\u672C", detectCadVersion(bytes, extension));
14650
- appendMeta5(meta, "\u5BB9\u5668", detectCadContainer(bytes));
15748
+ appendMeta6(meta, "\u6587\u4EF6", fileName);
15749
+ appendMeta6(meta, "\u683C\u5F0F", extension.toUpperCase());
15750
+ appendMeta6(meta, "\u5927\u5C0F", formatBytes3(bytes.byteLength));
15751
+ appendMeta6(meta, "\u7B7E\u540D", byteSignature2(bytes));
15752
+ appendMeta6(meta, "\u7248\u672C", detectCadVersion(bytes, extension));
15753
+ appendMeta6(meta, "\u5BB9\u5668", detectCadContainer(bytes));
14651
15754
  const actions = document.createElement("div");
14652
15755
  actions.className = "ofv-cad-conversion";
14653
15756
  const actionTitle = document.createElement("h4");
@@ -14687,12 +15790,12 @@ function createBinaryCadProbe(bytes, extension) {
14687
15790
  summary.textContent = "\u4E8C\u8FDB\u5236\u7ED3\u6784\u63A2\u6D4B";
14688
15791
  const meta = document.createElement("div");
14689
15792
  meta.className = "ofv-archive-probe-meta";
14690
- appendMeta5(meta, "\u53EF\u8BFB\u7247\u6BB5", probe.tokens.length);
14691
- appendMeta5(meta, "\u5B9E\u4F53\u5173\u952E\u8BCD", formatCadKeywordCounts(probe.entityCounts));
14692
- appendMeta5(meta, "\u56FE\u5C42\u7EBF\u7D22", String(probe.layerHints.length));
14693
- appendMeta5(meta, "\u5757/\u5F15\u7528\u7EBF\u7D22", String(probe.blockHints.length));
14694
- appendMeta5(meta, "\u5916\u90E8\u5F15\u7528", String(probe.externalRefs.length));
14695
- appendMeta5(meta, "\u89E3\u6790\u7EA7\u522B", extension === "dwg" ? "\u542F\u53D1\u5F0F\u626B\u63CF" : "\u5BB9\u5668/\u6587\u672C\u626B\u63CF");
15793
+ appendMeta6(meta, "\u53EF\u8BFB\u7247\u6BB5", probe.tokens.length);
15794
+ appendMeta6(meta, "\u5B9E\u4F53\u5173\u952E\u8BCD", formatCadKeywordCounts(probe.entityCounts));
15795
+ appendMeta6(meta, "\u56FE\u5C42\u7EBF\u7D22", String(probe.layerHints.length));
15796
+ appendMeta6(meta, "\u5757/\u5F15\u7528\u7EBF\u7D22", String(probe.blockHints.length));
15797
+ appendMeta6(meta, "\u5916\u90E8\u5F15\u7528", String(probe.externalRefs.length));
15798
+ appendMeta6(meta, "\u89E3\u6790\u7EA7\u522B", extension === "dwg" ? "\u542F\u53D1\u5F0F\u626B\u63CF" : "\u5BB9\u5668/\u6587\u672C\u626B\u63CF");
14696
15799
  details.append(summary, meta);
14697
15800
  const hints = [...probe.layerHints, ...probe.blockHints, ...probe.externalRefs].slice(0, 18);
14698
15801
  if (hints.length > 0) {
@@ -15225,9 +16328,9 @@ function createUnsupportedCadSection(extension, fileName) {
15225
16328
  const section = createSection("CAD \u589E\u5F3A\u63A5\u5165\u63D0\u793A");
15226
16329
  const meta = document.createElement("div");
15227
16330
  meta.className = "ofv-cad-summary";
15228
- appendMeta5(meta, "\u6587\u4EF6", fileName);
15229
- appendMeta5(meta, "\u683C\u5F0F", `.${extension || "cad"}`);
15230
- appendMeta5(meta, "\u5185\u7F6E\u80FD\u529B", unsupportedCadBuiltInLevel(extension));
16331
+ appendMeta6(meta, "\u6587\u4EF6", fileName);
16332
+ appendMeta6(meta, "\u683C\u5F0F", `.${extension || "cad"}`);
16333
+ appendMeta6(meta, "\u5185\u7F6E\u80FD\u529B", unsupportedCadBuiltInLevel(extension));
15231
16334
  const note = document.createElement("p");
15232
16335
  note.textContent = unsupportedCadGuidance(extension);
15233
16336
  const actions = document.createElement("div");
@@ -15340,7 +16443,7 @@ function countBy(values) {
15340
16443
  }
15341
16444
  return counts;
15342
16445
  }
15343
- function appendMeta5(parent, label, value) {
16446
+ function appendMeta6(parent, label, value) {
15344
16447
  const row = document.createElement("div");
15345
16448
  row.className = "ofv-meta-row";
15346
16449
  const key = document.createElement("span");
@@ -17374,10 +18477,10 @@ function read255UInt16(bytes, offset) {
17374
18477
  return { value: code, offset };
17375
18478
  }
17376
18479
  function decodeEotString(bytes) {
17377
- const text = decodeUtf16Le(bytes).replace(/\0+$/g, "").trim();
18480
+ const text = decodeUtf16Le2(bytes).replace(/\0+$/g, "").trim();
17378
18481
  return text || new TextDecoder("latin1").decode(bytes).replace(/\0+$/g, "").trim();
17379
18482
  }
17380
- function decodeUtf16Le(bytes) {
18483
+ function decodeUtf16Le2(bytes) {
17381
18484
  let value = "";
17382
18485
  for (let index = 0; index + 1 < bytes.length; index += 2) {
17383
18486
  value += String.fromCharCode(bytes[index] | bytes[index + 1] << 8);