kordoc 4.1.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/README.md +25 -5
  2. package/dist/{-AS4IABL2.js → -SXQIZHYA.js} +10 -9
  3. package/dist/{parser-PEOYBXBO.js → chunk-26AJJCFF.js} +1339 -2023
  4. package/dist/chunk-26AJJCFF.js.map +1 -0
  5. package/dist/{parser-XX4QTDFQ.js → chunk-4JPPLIIV.js} +1337 -2019
  6. package/dist/chunk-4JPPLIIV.js.map +1 -0
  7. package/dist/chunk-4VNLZ2GZ.js +13 -0
  8. package/dist/chunk-4VNLZ2GZ.js.map +1 -0
  9. package/dist/{chunk-37HJHCPA.js → chunk-6SHO3BNV.js} +3 -3
  10. package/dist/{chunk-UOO7LSDG.js → chunk-7FCNOKOR.js} +1 -9
  11. package/dist/chunk-7FCNOKOR.js.map +1 -0
  12. package/dist/{chunk-SSTK6IKK.js → chunk-CMN3SYZ3.js} +14 -5
  13. package/dist/chunk-CMN3SYZ3.js.map +1 -0
  14. package/dist/{chunk-F2ZU3IZG.js → chunk-ELOV2GIJ.js} +2 -2
  15. package/dist/chunk-F2HYH62H.cjs +130 -0
  16. package/dist/chunk-F2HYH62H.cjs.map +1 -0
  17. package/dist/{chunk-O5VS7RIR.js → chunk-FSXLSHCW.js} +3 -3
  18. package/dist/{chunk-O5VS7RIR.js.map → chunk-FSXLSHCW.js.map} +1 -1
  19. package/dist/chunk-GEPINOL6.js +83 -0
  20. package/dist/chunk-GEPINOL6.js.map +1 -0
  21. package/dist/chunk-H7OWEYH2.cjs +243 -0
  22. package/dist/chunk-H7OWEYH2.cjs.map +1 -0
  23. package/dist/{chunk-L2XQQTOY.js → chunk-IGGRLWT5.js} +126 -46
  24. package/dist/chunk-IGGRLWT5.js.map +1 -0
  25. package/dist/chunk-J2RZ444H.js +243 -0
  26. package/dist/chunk-J2RZ444H.js.map +1 -0
  27. package/dist/chunk-JP5YH3Z4.js +130 -0
  28. package/dist/chunk-JP5YH3Z4.js.map +1 -0
  29. package/dist/{parser-N4A7UGDK.cjs → chunk-LHROM2BO.cjs} +1300 -1985
  30. package/dist/chunk-LHROM2BO.cjs.map +1 -0
  31. package/dist/chunk-NNDVFNMJ.js +246 -0
  32. package/dist/chunk-NNDVFNMJ.js.map +1 -0
  33. package/dist/{chunk-WO52HVQJ.js → chunk-PLIY23LY.js} +2 -2
  34. package/dist/{chunk-GQVSHGG4.js → chunk-V6U6YS5B.js} +2 -2
  35. package/dist/{chunk-4KI23VHA.js → chunk-WF2E5P2G.js} +16 -130
  36. package/dist/chunk-WF2E5P2G.js.map +1 -0
  37. package/dist/{chunk-AX2R5Q2N.js → chunk-WQLHPOMJ.js} +3 -3
  38. package/dist/{chunk-37VKMUST.cjs → chunk-XTCT6KQ5.cjs} +34 -148
  39. package/dist/chunk-XTCT6KQ5.cjs.map +1 -0
  40. package/dist/chunks-ZQEFAZNC.js +10 -0
  41. package/dist/cli.js +76 -19
  42. package/dist/cli.js.map +1 -1
  43. package/dist/{formula-RXVSQPXI.js → formula-KSNAEBZ2.js} +23 -232
  44. package/dist/formula-KSNAEBZ2.js.map +1 -0
  45. package/dist/{formula-5NKVS2LR.cjs → formula-SB3NHDUM.cjs} +30 -240
  46. package/dist/formula-SB3NHDUM.cjs.map +1 -0
  47. package/dist/{formula-JCNF43NE.js → formula-SXC6LRRC.js} +23 -233
  48. package/dist/formula-SXC6LRRC.js.map +1 -0
  49. package/dist/index.cjs +527 -447
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.d.cts +7 -3
  52. package/dist/index.d.ts +7 -3
  53. package/dist/index.js +129 -49
  54. package/dist/index.js.map +1 -1
  55. package/dist/mcp.js +21 -19
  56. package/dist/mcp.js.map +1 -1
  57. package/dist/models-KA4GLQK5.js +25 -0
  58. package/dist/parser-ND2YGQZR.js +800 -0
  59. package/dist/parser-ND2YGQZR.js.map +1 -0
  60. package/dist/parser-RBZHA6SY.js +804 -0
  61. package/dist/parser-RBZHA6SY.js.map +1 -0
  62. package/dist/parser-WDZOMDG4.cjs +803 -0
  63. package/dist/parser-WDZOMDG4.cjs.map +1 -0
  64. package/dist/pdf-ocr-2Z7VZIFI.cjs +439 -0
  65. package/dist/pdf-ocr-2Z7VZIFI.cjs.map +1 -0
  66. package/dist/pdf-ocr-FJFXFADQ.js +438 -0
  67. package/dist/pdf-ocr-FJFXFADQ.js.map +1 -0
  68. package/dist/pdf-ocr-VYE4DHD4.js +386 -0
  69. package/dist/pdf-ocr-VYE4DHD4.js.map +1 -0
  70. package/dist/{profile-io-PLDQFPJA.js → profile-io-TWHDIVPL.js} +3 -3
  71. package/dist/{rasterize-WWNQLKYW.js → rasterize-W2NEZUSW.js} +2 -2
  72. package/dist/render-4MG5QUDG.js +10 -0
  73. package/dist/seal-D2QNXJVO.js +10 -0
  74. package/dist/seal-D2QNXJVO.js.map +1 -0
  75. package/dist/{watch-SFHXZALC.js → watch-VWXJZT2R.js} +11 -10
  76. package/dist/watch-VWXJZT2R.js.map +1 -0
  77. package/package.json +2 -1
  78. package/dist/chunk-37VKMUST.cjs.map +0 -1
  79. package/dist/chunk-4KI23VHA.js.map +0 -1
  80. package/dist/chunk-L2XQQTOY.js.map +0 -1
  81. package/dist/chunk-SSTK6IKK.js.map +0 -1
  82. package/dist/chunk-UOO7LSDG.js.map +0 -1
  83. package/dist/chunks-WVMGF7JL.js +0 -10
  84. package/dist/formula-5NKVS2LR.cjs.map +0 -1
  85. package/dist/formula-JCNF43NE.js.map +0 -1
  86. package/dist/formula-RXVSQPXI.js.map +0 -1
  87. package/dist/parser-N4A7UGDK.cjs.map +0 -1
  88. package/dist/parser-PEOYBXBO.js.map +0 -1
  89. package/dist/parser-XX4QTDFQ.js.map +0 -1
  90. package/dist/provider-4FAYHJ6N.cjs +0 -39
  91. package/dist/provider-4FAYHJ6N.cjs.map +0 -1
  92. package/dist/provider-C6IOGIS5.js +0 -37
  93. package/dist/provider-C6IOGIS5.js.map +0 -1
  94. package/dist/provider-UIBW2MIH.js +0 -39
  95. package/dist/provider-UIBW2MIH.js.map +0 -1
  96. package/dist/render-T7S6H6AN.js +0 -10
  97. package/dist/seal-7PTL6MXH.js +0 -10
  98. package/dist/watch-SFHXZALC.js.map +0 -1
  99. /package/dist/{-AS4IABL2.js.map → -SXQIZHYA.js.map} +0 -0
  100. /package/dist/{chunk-37HJHCPA.js.map → chunk-6SHO3BNV.js.map} +0 -0
  101. /package/dist/{chunk-F2ZU3IZG.js.map → chunk-ELOV2GIJ.js.map} +0 -0
  102. /package/dist/{chunk-WO52HVQJ.js.map → chunk-PLIY23LY.js.map} +0 -0
  103. /package/dist/{chunk-GQVSHGG4.js.map → chunk-V6U6YS5B.js.map} +0 -0
  104. /package/dist/{chunk-AX2R5Q2N.js.map → chunk-WQLHPOMJ.js.map} +0 -0
  105. /package/dist/{chunks-WVMGF7JL.js.map → chunks-ZQEFAZNC.js.map} +0 -0
  106. /package/dist/{profile-io-PLDQFPJA.js.map → models-KA4GLQK5.js.map} +0 -0
  107. /package/dist/{render-T7S6H6AN.js.map → profile-io-TWHDIVPL.js.map} +0 -0
  108. /package/dist/{rasterize-WWNQLKYW.js.map → rasterize-W2NEZUSW.js.map} +0 -0
  109. /package/dist/{seal-7PTL6MXH.js.map → render-4MG5QUDG.js.map} +0 -0
package/dist/index.d.cts CHANGED
@@ -134,8 +134,12 @@ interface ParseOptions {
134
134
  * PDF: 정확한 페이지 단위. HWP/HWPX: 섹션 단위 근사치.
135
135
  */
136
136
  pages?: number[] | string;
137
- /** 이미지 기반 PDF OCR 프로바이더 (선택) */
138
- ocr?: OcrProvider;
137
+ /** 이미지 기반 PDF OCR (선택).
138
+ * - `true`: 내장 엔진(PP-OCRv5 korean, ~18MB 자동 다운로드)으로 OCR 필요 판정
139
+ * 페이지만 인식 (스캔 페이지·글꼴 매핑 깨진 페이지). 정상 페이지는 파싱 결과 유지.
140
+ * - `"force"`: 전 페이지를 내장 엔진으로 강제 OCR.
141
+ * - 함수: 사용자 제공 OcrProvider (Claude Vision·Tesseract 등) — 판정은 `true`와 동일. */
142
+ ocr?: boolean | "force" | OcrProvider;
139
143
  /** 진행률 콜백 — current: 현재 페이지/섹션, total: 전체 수 */
140
144
  onProgress?: (current: number, total: number) => void;
141
145
  /** PDF 머리글/바닥글 자동 제거 */
@@ -190,7 +194,7 @@ interface ParseWarning {
190
194
  /** 구조화된 경고 코드 */
191
195
  code: WarningCode;
192
196
  }
193
- type WarningCode = "SKIPPED_IMAGE" | "SKIPPED_OLE" | "TRUNCATED_TABLE" | "OCR_FALLBACK" | "UNSUPPORTED_ELEMENT" | "BROKEN_ZIP_RECOVERY" | "HIDDEN_TEXT_FILTERED" | "MALFORMED_XML" | "PARTIAL_PARSE" | "LENIENT_CFB_RECOVERY" | "NEEDS_OCR" | "COM_EMPTY" | "DRM_COM_FALLBACK";
197
+ type WarningCode = "SKIPPED_IMAGE" | "SKIPPED_OLE" | "TRUNCATED_TABLE" | "OCR_FALLBACK" | "UNSUPPORTED_ELEMENT" | "BROKEN_ZIP_RECOVERY" | "HIDDEN_TEXT_FILTERED" | "MALFORMED_XML" | "PARTIAL_PARSE" | "LENIENT_CFB_RECOVERY" | "NEEDS_OCR" | "OCR_FAILED" | "OCR_APPLIED" | "COM_EMPTY" | "DRM_COM_FALLBACK";
194
198
  /** 문서 구조 (헤딩 트리) */
195
199
  interface OutlineItem {
196
200
  level: number;
package/dist/index.d.ts CHANGED
@@ -134,8 +134,12 @@ interface ParseOptions {
134
134
  * PDF: 정확한 페이지 단위. HWP/HWPX: 섹션 단위 근사치.
135
135
  */
136
136
  pages?: number[] | string;
137
- /** 이미지 기반 PDF OCR 프로바이더 (선택) */
138
- ocr?: OcrProvider;
137
+ /** 이미지 기반 PDF OCR (선택).
138
+ * - `true`: 내장 엔진(PP-OCRv5 korean, ~18MB 자동 다운로드)으로 OCR 필요 판정
139
+ * 페이지만 인식 (스캔 페이지·글꼴 매핑 깨진 페이지). 정상 페이지는 파싱 결과 유지.
140
+ * - `"force"`: 전 페이지를 내장 엔진으로 강제 OCR.
141
+ * - 함수: 사용자 제공 OcrProvider (Claude Vision·Tesseract 등) — 판정은 `true`와 동일. */
142
+ ocr?: boolean | "force" | OcrProvider;
139
143
  /** 진행률 콜백 — current: 현재 페이지/섹션, total: 전체 수 */
140
144
  onProgress?: (current: number, total: number) => void;
141
145
  /** PDF 머리글/바닥글 자동 제거 */
@@ -190,7 +194,7 @@ interface ParseWarning {
190
194
  /** 구조화된 경고 코드 */
191
195
  code: WarningCode;
192
196
  }
193
- type WarningCode = "SKIPPED_IMAGE" | "SKIPPED_OLE" | "TRUNCATED_TABLE" | "OCR_FALLBACK" | "UNSUPPORTED_ELEMENT" | "BROKEN_ZIP_RECOVERY" | "HIDDEN_TEXT_FILTERED" | "MALFORMED_XML" | "PARTIAL_PARSE" | "LENIENT_CFB_RECOVERY" | "NEEDS_OCR" | "COM_EMPTY" | "DRM_COM_FALLBACK";
197
+ type WarningCode = "SKIPPED_IMAGE" | "SKIPPED_OLE" | "TRUNCATED_TABLE" | "OCR_FALLBACK" | "UNSUPPORTED_ELEMENT" | "BROKEN_ZIP_RECOVERY" | "HIDDEN_TEXT_FILTERED" | "MALFORMED_XML" | "PARTIAL_PARSE" | "LENIENT_CFB_RECOVERY" | "NEEDS_OCR" | "OCR_FAILED" | "OCR_APPLIED" | "COM_EMPTY" | "DRM_COM_FALLBACK";
194
198
  /** 문서 구조 (헤딩 트리) */
195
199
  interface OutlineItem {
196
200
  level: number;
package/dist/index.js CHANGED
@@ -1,31 +1,33 @@
1
1
  import {
2
- HEADING_RATIO_H1,
3
- HEADING_RATIO_H2,
4
- HEADING_RATIO_H3,
5
- KordocError,
6
2
  MAX_COLS,
7
3
  MAX_ROWS,
8
- VERSION,
9
4
  blocksToMarkdown,
10
5
  buildTable,
11
- classifyError,
12
- compareSectionPaths,
13
6
  convertTableToText,
14
7
  dedupeRunningHeaders,
15
8
  flattenLayoutTables,
16
9
  inlineImagesIntoMarkdown,
10
+ mapPuaText
11
+ } from "./chunk-WF2E5P2G.js";
12
+ import {
13
+ parsePageRange
14
+ } from "./chunk-GE43BE46.js";
15
+ import {
16
+ HEADING_RATIO_H1,
17
+ HEADING_RATIO_H2,
18
+ HEADING_RATIO_H3,
19
+ KordocError,
20
+ VERSION,
21
+ classifyError,
22
+ compareSectionPaths,
17
23
  isPathTraversal,
18
- mapPuaText,
19
24
  normalizeSectionHref,
20
25
  precheckZipSize,
21
26
  sanitizeError,
22
27
  sanitizeHref,
23
28
  stripDtd,
24
29
  toArrayBuffer
25
- } from "./chunk-4KI23VHA.js";
26
- import {
27
- parsePageRange
28
- } from "./chunk-GE43BE46.js";
30
+ } from "./chunk-JP5YH3Z4.js";
29
31
 
30
32
  // src/index.ts
31
33
  import { readFile } from "fs/promises";
@@ -2232,6 +2234,19 @@ function findKordocMarkedCell(el, depth) {
2232
2234
  }
2233
2235
  return null;
2234
2236
  }
2237
+ function hasPageAutoNum(el, depth = 0) {
2238
+ if (depth > 10) return false;
2239
+ const children = el.childNodes;
2240
+ if (!children) return false;
2241
+ for (let i = 0; i < children.length; i++) {
2242
+ const ch = children[i];
2243
+ if (ch.nodeType !== 1) continue;
2244
+ const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
2245
+ if (tag === "autoNum" && ch.getAttribute?.("numType") === "PAGE") return true;
2246
+ if (hasPageAutoNum(ch, depth + 1)) return true;
2247
+ }
2248
+ return false;
2249
+ }
2235
2250
  function collectSubListText(el, ctx, depth = 0) {
2236
2251
  if (depth > 10) return "";
2237
2252
  const parts = [];
@@ -2410,6 +2425,22 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2410
2425
  let href;
2411
2426
  let footnote;
2412
2427
  let charPrId;
2428
+ const linkRanges = [];
2429
+ const openFields = [];
2430
+ const onFieldBegin = (el) => {
2431
+ const url = extractHyperlinkHref(el);
2432
+ if (url) {
2433
+ linkRanges.push({ url, start: text.length });
2434
+ openFields.push({ rangeIdx: linkRanges.length - 1 });
2435
+ if (!href) href = url;
2436
+ } else {
2437
+ openFields.push({});
2438
+ }
2439
+ };
2440
+ const onFieldEnd = () => {
2441
+ const open = openFields.pop();
2442
+ if (open?.rangeIdx !== void 0) linkRanges[open.rangeIdx].end = text.length;
2443
+ };
2413
2444
  const handleCtrl = (ctrlEl) => {
2414
2445
  const kids2 = ctrlEl.childNodes;
2415
2446
  if (!kids2) return;
@@ -2419,10 +2450,13 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2419
2450
  const ktag = (k.tagName || k.localName || "").replace(/^[^:]+:/, "");
2420
2451
  switch (ktag) {
2421
2452
  // 머리말/꼬리말 — 문서당 1회 수집, 본문 앞/뒤 배치
2453
+ // 페이지 번호 크롬(autoNum PAGE + 문자 없는 잔여 텍스트, 예: "- 1 -")은 본문 정보가
2454
+ // 아니므로 방출하지 않는다
2422
2455
  case "header":
2423
2456
  case "footer": {
2424
2457
  if (!ctx) break;
2425
2458
  const t = collectSubListText(k, ctx);
2459
+ if (t && hasPageAutoNum(k) && !/\p{L}/u.test(t)) break;
2426
2460
  if (t) {
2427
2461
  const bucket = ktag === "header" ? ctx.shared.pageText.headers : ctx.shared.pageText.footers;
2428
2462
  if (!bucket.includes(t)) bucket.push(t);
@@ -2436,13 +2470,12 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2436
2470
  if (noteText) footnote = (footnote ? footnote + "; " : "") + noteText;
2437
2471
  break;
2438
2472
  }
2439
- // 하이퍼링크 — fieldBegin type=HYPERLINK의 Path 파라미터
2440
- case "fieldBegin": {
2441
- const url = extractHyperlinkHref(k);
2442
- if (url && !href) href = url;
2473
+ // 하이퍼링크 — fieldBegin type=HYPERLINK의 Path 파라미터 (extent 오프셋 추적)
2474
+ case "fieldBegin":
2475
+ onFieldBegin(k);
2443
2476
  break;
2444
- }
2445
2477
  case "fieldEnd":
2478
+ onFieldEnd();
2446
2479
  break;
2447
2480
  // 변경추적 — 삭제 구간(deleteBegin~End)의 텍스트는 출력 제외 (최종본 상태 재현)
2448
2481
  case "deleteBegin":
@@ -2555,12 +2588,10 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2555
2588
  case "ctrl":
2556
2589
  handleCtrl(child);
2557
2590
  break;
2558
- // run 직계 fieldBegin (비표준 경로) — 하이퍼링크 URL 추출
2559
- case "fieldBegin": {
2560
- const url = extractHyperlinkHref(child);
2561
- if (url && !href) href = url;
2591
+ // run 직계 fieldBegin (비표준 경로) — 하이퍼링크 URL·extent 추적
2592
+ case "fieldBegin":
2593
+ onFieldBegin(child);
2562
2594
  break;
2563
- }
2564
2595
  // run 직계 변경추적 마커 (비표준 경로)
2565
2596
  case "deleteBegin":
2566
2597
  if (ctx) ctx.shared.track.deleteDepth++;
@@ -2572,6 +2603,8 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2572
2603
  case "insertEnd":
2573
2604
  break;
2574
2605
  case "fieldEnd":
2606
+ onFieldEnd();
2607
+ break;
2575
2608
  case "parameters":
2576
2609
  case "stringParam":
2577
2610
  case "integerParam":
@@ -2620,6 +2653,18 @@ function extractParagraphInfo(para2, styleMap, ctx) {
2620
2653
  }
2621
2654
  };
2622
2655
  walk(para2);
2656
+ {
2657
+ const applied = [];
2658
+ const closed = linkRanges.filter((r) => r.end !== void 0 && r.end > r.start).sort((a, b) => b.start - a.start);
2659
+ for (const r of closed) {
2660
+ if (applied.some(([s, e]) => r.start < e && r.end > s)) continue;
2661
+ const anchor = text.slice(r.start, r.end);
2662
+ if (!anchor.trim() || /[\n\x1F\[\]]/.test(anchor)) continue;
2663
+ text = text.slice(0, r.start) + `[${anchor}](${r.url})` + text.slice(r.end);
2664
+ applied.push([r.start, r.end]);
2665
+ }
2666
+ if (applied.length) href = void 0;
2667
+ }
2623
2668
  const leaderIdx = text.indexOf("");
2624
2669
  if (leaderIdx >= 0) text = text.substring(0, leaderIdx);
2625
2670
  let cleanText = text.replace(/[ \t]+/g, " ").trim();
@@ -17413,8 +17458,50 @@ function decodeJohab(ch) {
17413
17458
  }
17414
17459
  const hit = lookupSymbol(ch);
17415
17460
  if (hit !== null) return hit;
17461
+ return JOHAB_UNMAPPED;
17462
+ }
17463
+ return decodeHwp3Extra(ch);
17464
+ }
17465
+ function decodeHwp3Extra(ch) {
17466
+ if (ch >= 13712 && ch <= 13721) return 8544 + (ch - 13712);
17467
+ if (ch >= 14055 && ch <= 14064) return 9312 + (ch - 14055);
17468
+ switch (ch) {
17469
+ case 129:
17470
+ return 8220;
17471
+ // 왼쪽 큰따옴표
17472
+ case 130:
17473
+ return 8221;
17474
+ // 오른쪽 큰따옴표
17475
+ case 12316:
17476
+ return 9473;
17477
+ // ━ 굵은 가로선 (rhwp: U+F080F, 표시값 직행)
17478
+ case 12349:
17479
+ return 9632;
17480
+ // ■ (rhwp: U+F0827, 표시값 직행)
17481
+ case 13158:
17482
+ return 9633;
17483
+ // □ 글머리 (rhwp: U+F03C5, 한컴 표시값 직행)
17484
+ case 13316:
17485
+ return 8228;
17486
+ // 한 점 리더
17487
+ case 13377:
17488
+ return 9632;
17489
+ // ■
17490
+ case 13382:
17491
+ return 8594;
17492
+ // → 오른쪽 화살표
17493
+ case 13793:
17494
+ return 9472;
17495
+ // ─ 상자 그리기 가로선
17496
+ case 13433:
17497
+ return 9655;
17498
+ // ▷
17499
+ case 13434:
17500
+ return 9654;
17501
+ // ▶
17502
+ default:
17503
+ return JOHAB_UNMAPPED;
17416
17504
  }
17417
- return JOHAB_UNMAPPED;
17418
17505
  }
17419
17506
  function decodeHcharString(bytes) {
17420
17507
  let out = "";
@@ -17534,7 +17621,7 @@ var PARA_SHAPE_SIZE = 187;
17534
17621
  var LINE_INFO_SIZE = 14;
17535
17622
  var INLINE_CHAR_SHAPE_SIZE = 31;
17536
17623
  var SIMPLE_CTRL = /* @__PURE__ */ new Map([
17537
- [9, { extraBytes: 0, extraHchar: 0, emit: " " }],
17624
+ [9, { extraBytes: 6, extraHchar: 3, emit: " " }],
17538
17625
  [7, { extraBytes: 6, extraHchar: 3, emit: "\uFFFC" }],
17539
17626
  [8, { extraBytes: 6, extraHchar: 3, emit: "\uFFFC" }],
17540
17627
  [18, { extraBytes: 6, extraHchar: 3, emit: " " }],
@@ -17710,6 +17797,12 @@ function parseCharStream(reader, charCount, ctx) {
17710
17797
  parseParagraphList2(reader, ctx);
17711
17798
  break;
17712
17799
  }
17800
+ case 5:
17801
+ if (headerVal1 > 0 && headerVal1 < 1e6) reader.skip(headerVal1);
17802
+ break;
17803
+ case 6:
17804
+ reader.skip(34);
17805
+ break;
17713
17806
  case 29:
17714
17807
  if (headerVal1 < 1e6) reader.skip(headerVal1);
17715
17808
  break;
@@ -17987,7 +18080,7 @@ function parseWorksheet(xml, sharedStrings, dateXfs, date1904) {
17987
18080
  }
17988
18081
  return { grid, merges, maxRow, maxCol };
17989
18082
  }
17990
- function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex) {
18083
+ function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex, keepAnchoredEmptyCols) {
17991
18084
  const blocks = [];
17992
18085
  if (sheetName) {
17993
18086
  blocks.push({
@@ -18039,7 +18132,7 @@ function sheetToBlocks(sheetName, grid, merges, maxRow, maxCol, sheetIndex) {
18039
18132
  cellRows.push(row);
18040
18133
  }
18041
18134
  if (cellRows.length > 0) {
18042
- const table2 = buildTable(cellRows);
18135
+ const table2 = buildTable(cellRows, { keepAnchoredEmptyCols });
18043
18136
  if (table2.rows > 0) {
18044
18137
  blocks.push({ type: "table", table: table2, pageNumber: sheetIndex + 1 });
18045
18138
  }
@@ -18109,7 +18202,7 @@ async function parseXlsxDocument(buffer, options) {
18109
18202
  try {
18110
18203
  const sheetXml = await sheetFile.async("text");
18111
18204
  const { grid, merges, maxRow, maxCol } = parseWorksheet(sheetXml, sharedStrings, dateXfs, date1904);
18112
- const sheetBlocks = sheetToBlocks(sheet.name, grid, merges, maxRow, maxCol, i);
18205
+ const sheetBlocks = sheetToBlocks(sheet.name, grid, merges, maxRow, maxCol, i, options?.keepTrailingEmptyCols);
18113
18206
  blocks.push(...sheetBlocks);
18114
18207
  } catch (err) {
18115
18208
  warnings.push({
@@ -18658,7 +18751,7 @@ function cellValueToText(v) {
18658
18751
  if (typeof v === "boolean") return v ? "TRUE" : "FALSE";
18659
18752
  return v;
18660
18753
  }
18661
- function sheetToBlocks2(sheetName, sheet, sheetIndex) {
18754
+ function sheetToBlocks2(sheetName, sheet, sheetIndex, keepAnchoredEmptyCols) {
18662
18755
  const blocks = [];
18663
18756
  if (sheetName) {
18664
18757
  blocks.push({
@@ -18731,7 +18824,7 @@ function sheetToBlocks2(sheetName, sheet, sheetIndex) {
18731
18824
  cellRows.push(row);
18732
18825
  }
18733
18826
  if (cellRows.length > 0) {
18734
- const table2 = buildTable(cellRows);
18827
+ const table2 = buildTable(cellRows, { keepAnchoredEmptyCols });
18735
18828
  if (table2.rows > 0) {
18736
18829
  blocks.push({ type: "table", table: table2, pageNumber: sheetIndex + 1 });
18737
18830
  }
@@ -18812,7 +18905,7 @@ async function parseXlsDocument(buffer, options) {
18812
18905
  }
18813
18906
  try {
18814
18907
  const { sheet } = extractSheetCells(records, bofIdx, globals.sst, convertNum);
18815
- const blocks = sheetToBlocks2(meta.name, sheet, i);
18908
+ const blocks = sheetToBlocks2(meta.name, sheet, i, options?.keepTrailingEmptyCols);
18816
18909
  allBlocks.push(...blocks);
18817
18910
  } catch (e) {
18818
18911
  warnings.push({
@@ -20033,8 +20126,8 @@ function parseTable2(el, blocks, paraShapeMap, sectionNum, warnings, keep) {
20033
20126
  for (let j = 0; j < rowCells.length; j++) {
20034
20127
  const cellEl = rowCells[j];
20035
20128
  if (cellEl.nodeType !== 1 || localName(cellEl) !== "CELL") continue;
20036
- const colAddr = parseInt(cellEl.getAttribute("ColAddr") ?? "0", 10);
20037
- const rowAddr = parseInt(cellEl.getAttribute("RowAddr") ?? "0", 10);
20129
+ const colAddr = parseInt(cellEl.getAttribute("ColAddr") ?? "0", 10) || 0;
20130
+ const rowAddr = parseInt(cellEl.getAttribute("RowAddr") ?? "0", 10) || 0;
20038
20131
  const colSpan = Math.min(Math.max(1, parseInt(cellEl.getAttribute("ColSpan") ?? "1", 10) || 1), MAX_TABLE_COLS);
20039
20132
  const rowSpan = Math.min(Math.max(1, parseInt(cellEl.getAttribute("RowSpan") ?? "1", 10) || 1), MAX_TABLE_ROWS);
20040
20133
  const cellText = extractCellText(cellEl);
@@ -20042,24 +20135,11 @@ function parseTable2(el, blocks, paraShapeMap, sectionNum, warnings, keep) {
20042
20135
  }
20043
20136
  }
20044
20137
  if (cells.length === 0) return;
20045
- const grid = Array.from({ length: rowCount }, () => Array(colCount).fill(null));
20138
+ const cellRows = Array.from({ length: rowCount }, () => []);
20046
20139
  for (const cell2 of cells) {
20047
- const r = cell2.rowAddr ?? 0;
20048
- const c = cell2.colAddr ?? 0;
20049
- if (isNaN(r) || isNaN(c) || r >= rowCount || c >= colCount) continue;
20050
- grid[r][c] = cell2;
20051
- for (let dr = 0; dr < cell2.rowSpan; dr++) {
20052
- for (let dc = 0; dc < cell2.colSpan; dc++) {
20053
- if (dr === 0 && dc === 0) continue;
20054
- if (r + dr < rowCount && c + dc < colCount) {
20055
- grid[r + dr][c + dc] = { text: "", colSpan: 1, rowSpan: 1 };
20056
- }
20057
- }
20058
- }
20140
+ const r = Math.min(Math.max(cell2.rowAddr ?? 0, 0), rowCount - 1);
20141
+ cellRows[r].push(cell2);
20059
20142
  }
20060
- const cellRows = grid.map(
20061
- (row) => row.map((cell2) => cell2 ?? { text: "", colSpan: 1, rowSpan: 1 })
20062
- );
20063
20143
  const table2 = buildTable(cellRows, { keepAnchoredEmptyCols: keep });
20064
20144
  const caption = extractShapeCaption(el);
20065
20145
  if (caption.text && caption.before) {
@@ -30414,7 +30494,7 @@ async function parseHwp(buffer, options) {
30414
30494
  async function parsePdf(buffer, options) {
30415
30495
  let parsePdfDocument;
30416
30496
  try {
30417
- const mod = await import("./parser-XX4QTDFQ.js");
30497
+ const mod = await import("./parser-ND2YGQZR.js");
30418
30498
  parsePdfDocument = mod.parsePdfDocument;
30419
30499
  } catch {
30420
30500
  return {