kordoc 4.16.0 → 4.16.2

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 (145) hide show
  1. package/README.md +344 -1135
  2. package/dist/{-VQNLLLPE.js → -4G6MA4X6.js} +11 -11
  3. package/dist/chunk-3IB7LBHC.js +57 -0
  4. package/dist/chunk-3IB7LBHC.js.map +1 -0
  5. package/dist/{chunk-6LMKQM7I.js → chunk-4VODJKFL.js} +3 -3
  6. package/dist/{chunk-UDX7TSOC.js → chunk-5KS5PWJR.js} +2 -2
  7. package/dist/chunk-62W7QCEX.cjs +57 -0
  8. package/dist/chunk-62W7QCEX.cjs.map +1 -0
  9. package/dist/{chunk-NNYF2AGC.js → chunk-7KNGSQU7.js} +4 -4
  10. package/dist/chunk-7KNGSQU7.js.map +1 -0
  11. package/dist/{chunk-DYENR3PX.js → chunk-AUWGDP4G.js} +2 -2
  12. package/dist/{chunk-H6KMTYYZ.cjs → chunk-CEIATRDW.cjs} +3 -3
  13. package/dist/{chunk-H6KMTYYZ.cjs.map → chunk-CEIATRDW.cjs.map} +1 -1
  14. package/dist/{chunk-N6TPODYL.js → chunk-DES2LGFZ.js} +2 -2
  15. package/dist/{chunk-PQRP4NSF.js → chunk-F4NRLLY4.js} +2 -2
  16. package/dist/{chunk-B5NEGP65.cjs → chunk-FKUDAIJI.cjs} +692 -33
  17. package/dist/chunk-FKUDAIJI.cjs.map +1 -0
  18. package/dist/{chunk-XWA625AN.js → chunk-FSDJLAOW.js} +3 -1
  19. package/dist/chunk-FSDJLAOW.js.map +1 -0
  20. package/dist/{chunk-PIMB2YNO.js → chunk-GO5IFOUF.js} +2 -2
  21. package/dist/{chunk-476OYHGZ.js → chunk-IQGIT2VX.js} +37 -7
  22. package/dist/chunk-IQGIT2VX.js.map +1 -0
  23. package/dist/chunk-J3IF6KGW.js +59 -0
  24. package/dist/chunk-J3IF6KGW.js.map +1 -0
  25. package/dist/{chunk-C75WE52C.js → chunk-JELRWAZC.js} +2 -2
  26. package/dist/{chunk-46DZF3RK.js → chunk-JFLAM3MM.js} +2 -2
  27. package/dist/{chunk-A3QDRMVD.js → chunk-KIOQ4N37.js} +2 -2
  28. package/dist/{chunk-TGD7UFHD.js → chunk-LEIAEWZ7.js} +4 -4
  29. package/dist/chunk-LEIAEWZ7.js.map +1 -0
  30. package/dist/{chunk-GOQBON77.js → chunk-MLIS253L.js} +2 -2
  31. package/dist/{chunk-JB5X5NNL.js → chunk-OXLPVQYK.js} +680 -21
  32. package/dist/chunk-OXLPVQYK.js.map +1 -0
  33. package/dist/{chunk-RC4C7Q33.js → chunk-P6ZDXTV6.js} +2 -2
  34. package/dist/{chunk-CB5XDCSL.js → chunk-QOCS7W7R.js} +5034 -4569
  35. package/dist/chunk-QOCS7W7R.js.map +1 -0
  36. package/dist/{chunk-3JWMDL3S.js → chunk-S2PL227Q.js} +2 -2
  37. package/dist/{chunk-HIVK5V27.js → chunk-SFEQYKYJ.js} +133 -110
  38. package/dist/chunk-SFEQYKYJ.js.map +1 -0
  39. package/dist/{chunk-NWODPYBD.cjs → chunk-STM3ORY7.cjs} +2 -2
  40. package/dist/{chunk-NWODPYBD.cjs.map → chunk-STM3ORY7.cjs.map} +1 -1
  41. package/dist/{chunk-43FKGDDO.js → chunk-TXUKTOG2.js} +213 -30
  42. package/dist/chunk-TXUKTOG2.js.map +1 -0
  43. package/dist/{chunk-XHOZB2WP.js → chunk-UTP2WCHS.js} +681 -22
  44. package/dist/chunk-UTP2WCHS.js.map +1 -0
  45. package/dist/{chunk-MH6MAL64.cjs → chunk-WDQTFAXY.cjs} +217 -114
  46. package/dist/chunk-WDQTFAXY.cjs.map +1 -0
  47. package/dist/{chunk-DRY3L5KQ.cjs → chunk-XTFN5WKS.cjs} +7 -7
  48. package/dist/chunk-XTFN5WKS.cjs.map +1 -0
  49. package/dist/chunks-NUNIKS2J.js +10 -0
  50. package/dist/cli.js +33 -30
  51. package/dist/cli.js.map +1 -1
  52. package/dist/{formula-FNQYHMIY.js → formula-EPKLPDU7.js} +3 -3
  53. package/dist/{formula-5775PTP2.js → formula-NARUOXRX.js} +4 -4
  54. package/dist/{formula-VEFKYXPB.cjs → formula-WIMV5TUX.cjs} +9 -9
  55. package/dist/{formula-VEFKYXPB.cjs.map → formula-WIMV5TUX.cjs.map} +1 -1
  56. package/dist/{image-ocr-PYZU4TO7.js → image-ocr-3WJ4QH3T.js} +8 -8
  57. package/dist/{image-ocr-YA2MQBRP.js → image-ocr-5BUJQ4TK.js} +6 -6
  58. package/dist/{image-ocr-6JZR734G.cjs → image-ocr-AXWXR6JV.cjs} +15 -15
  59. package/dist/{image-ocr-6JZR734G.cjs.map → image-ocr-AXWXR6JV.cjs.map} +1 -1
  60. package/dist/index.cjs +1900 -1406
  61. package/dist/index.cjs.map +1 -1
  62. package/dist/index.d.cts +24 -6
  63. package/dist/index.d.ts +24 -6
  64. package/dist/index.js +1282 -788
  65. package/dist/index.js.map +1 -1
  66. package/dist/mcp.js +34 -28
  67. package/dist/mcp.js.map +1 -1
  68. package/dist/{model-bundle-O6J7ORVC.js → model-bundle-IMBW7D2Z.js} +5 -5
  69. package/dist/{models-YMOKZGCI.js → models-SY75IBOE.js} +5 -5
  70. package/dist/{parser-YAQV7FBO.cjs → parser-2LU4EVU3.cjs} +360 -219
  71. package/dist/parser-2LU4EVU3.cjs.map +1 -0
  72. package/dist/{parser-3B6I2XL7.js → parser-N6476XAC.js} +225 -84
  73. package/dist/parser-N6476XAC.js.map +1 -0
  74. package/dist/{parser-PXATL5DM.js → parser-ZQM3664Z.js} +222 -81
  75. package/dist/parser-ZQM3664Z.js.map +1 -0
  76. package/dist/pdf-ocr-6DEE23IP.js +15 -0
  77. package/dist/pdf-ocr-GHEJVPX2.cjs +16 -0
  78. package/dist/{pdf-ocr-T2JXQATA.cjs.map → pdf-ocr-GHEJVPX2.cjs.map} +1 -1
  79. package/dist/pdf-ocr-MQTWODVU.js +18 -0
  80. package/dist/{profile-io-ZTV2MKRT.js → profile-io-GJPKCYPT.js} +3 -3
  81. package/dist/{rasterize-MMUZ537K.js → rasterize-UOALJQDS.js} +3 -3
  82. package/dist/{redact-doc-S42XGV5D.js → redact-doc-22SYW3KH.js} +11 -11
  83. package/dist/{render-WCWPZKJ7.js → render-MJ4H3R23.js} +7 -7
  84. package/dist/seal-XWMRUTI4.js +10 -0
  85. package/dist/{setup-D35LKZCH.js → setup-2URYVUEO.js} +3 -3
  86. package/dist/visual-USPS4QRC.js +20 -0
  87. package/dist/{watch-AX64CIMN.js → watch-ALXZGTOB.js} +12 -12
  88. package/package.json +1 -1
  89. package/dist/chunk-43FKGDDO.js.map +0 -1
  90. package/dist/chunk-476OYHGZ.js.map +0 -1
  91. package/dist/chunk-B5NEGP65.cjs.map +0 -1
  92. package/dist/chunk-CB5XDCSL.js.map +0 -1
  93. package/dist/chunk-DRY3L5KQ.cjs.map +0 -1
  94. package/dist/chunk-HIVK5V27.js.map +0 -1
  95. package/dist/chunk-JB5X5NNL.js.map +0 -1
  96. package/dist/chunk-MH6MAL64.cjs.map +0 -1
  97. package/dist/chunk-NNYF2AGC.js.map +0 -1
  98. package/dist/chunk-QJERJZJ6.js +0 -11
  99. package/dist/chunk-QJERJZJ6.js.map +0 -1
  100. package/dist/chunk-TGD7UFHD.js.map +0 -1
  101. package/dist/chunk-UQ6TZDW6.js +0 -13
  102. package/dist/chunk-UQ6TZDW6.js.map +0 -1
  103. package/dist/chunk-XHOZB2WP.js.map +0 -1
  104. package/dist/chunk-XWA625AN.js.map +0 -1
  105. package/dist/chunk-ZY5K3LPM.cjs +0 -11
  106. package/dist/chunk-ZY5K3LPM.cjs.map +0 -1
  107. package/dist/chunks-JD25E5PM.js +0 -10
  108. package/dist/parser-3B6I2XL7.js.map +0 -1
  109. package/dist/parser-PXATL5DM.js.map +0 -1
  110. package/dist/parser-YAQV7FBO.cjs.map +0 -1
  111. package/dist/pdf-ocr-2TTO5PX2.js +0 -15
  112. package/dist/pdf-ocr-T2JXQATA.cjs +0 -16
  113. package/dist/pdf-ocr-WF2NQA6X.js +0 -18
  114. package/dist/seal-WHK4GOHR.js +0 -10
  115. package/dist/visual-WL4TDE5B.js +0 -20
  116. /package/dist/{-VQNLLLPE.js.map → -4G6MA4X6.js.map} +0 -0
  117. /package/dist/{chunk-6LMKQM7I.js.map → chunk-4VODJKFL.js.map} +0 -0
  118. /package/dist/{chunk-UDX7TSOC.js.map → chunk-5KS5PWJR.js.map} +0 -0
  119. /package/dist/{chunk-DYENR3PX.js.map → chunk-AUWGDP4G.js.map} +0 -0
  120. /package/dist/{chunk-N6TPODYL.js.map → chunk-DES2LGFZ.js.map} +0 -0
  121. /package/dist/{chunk-PQRP4NSF.js.map → chunk-F4NRLLY4.js.map} +0 -0
  122. /package/dist/{chunk-PIMB2YNO.js.map → chunk-GO5IFOUF.js.map} +0 -0
  123. /package/dist/{chunk-C75WE52C.js.map → chunk-JELRWAZC.js.map} +0 -0
  124. /package/dist/{chunk-46DZF3RK.js.map → chunk-JFLAM3MM.js.map} +0 -0
  125. /package/dist/{chunk-A3QDRMVD.js.map → chunk-KIOQ4N37.js.map} +0 -0
  126. /package/dist/{chunk-GOQBON77.js.map → chunk-MLIS253L.js.map} +0 -0
  127. /package/dist/{chunk-RC4C7Q33.js.map → chunk-P6ZDXTV6.js.map} +0 -0
  128. /package/dist/{chunk-3JWMDL3S.js.map → chunk-S2PL227Q.js.map} +0 -0
  129. /package/dist/{chunks-JD25E5PM.js.map → chunks-NUNIKS2J.js.map} +0 -0
  130. /package/dist/{formula-FNQYHMIY.js.map → formula-EPKLPDU7.js.map} +0 -0
  131. /package/dist/{formula-5775PTP2.js.map → formula-NARUOXRX.js.map} +0 -0
  132. /package/dist/{image-ocr-PYZU4TO7.js.map → image-ocr-3WJ4QH3T.js.map} +0 -0
  133. /package/dist/{image-ocr-YA2MQBRP.js.map → image-ocr-5BUJQ4TK.js.map} +0 -0
  134. /package/dist/{model-bundle-O6J7ORVC.js.map → model-bundle-IMBW7D2Z.js.map} +0 -0
  135. /package/dist/{models-YMOKZGCI.js.map → models-SY75IBOE.js.map} +0 -0
  136. /package/dist/{pdf-ocr-2TTO5PX2.js.map → pdf-ocr-6DEE23IP.js.map} +0 -0
  137. /package/dist/{pdf-ocr-WF2NQA6X.js.map → pdf-ocr-MQTWODVU.js.map} +0 -0
  138. /package/dist/{profile-io-ZTV2MKRT.js.map → profile-io-GJPKCYPT.js.map} +0 -0
  139. /package/dist/{rasterize-MMUZ537K.js.map → rasterize-UOALJQDS.js.map} +0 -0
  140. /package/dist/{redact-doc-S42XGV5D.js.map → redact-doc-22SYW3KH.js.map} +0 -0
  141. /package/dist/{render-WCWPZKJ7.js.map → render-MJ4H3R23.js.map} +0 -0
  142. /package/dist/{seal-WHK4GOHR.js.map → seal-XWMRUTI4.js.map} +0 -0
  143. /package/dist/{setup-D35LKZCH.js.map → setup-2URYVUEO.js.map} +0 -0
  144. /package/dist/{visual-WL4TDE5B.js.map → visual-USPS4QRC.js.map} +0 -0
  145. /package/dist/{watch-AX64CIMN.js.map → watch-ALXZGTOB.js.map} +0 -0
@@ -30,21 +30,24 @@ import {
30
30
  normalizeItems,
31
31
  refineDocumentStyleHeadings,
32
32
  removeHeaderFooterBlocks,
33
+ startsNewItem,
33
34
  trimTrailingEmptyTableCols,
34
35
  wrapJoiner
35
- } from "./chunk-43FKGDDO.js";
36
+ } from "./chunk-SFEQYKYJ.js";
36
37
  import {
37
38
  ocrModelsCached
38
- } from "./chunk-N6TPODYL.js";
39
- import "./chunk-A3QDRMVD.js";
40
- import "./chunk-C75WE52C.js";
39
+ } from "./chunk-DES2LGFZ.js";
40
+ import "./chunk-KIOQ4N37.js";
41
+ import "./chunk-JELRWAZC.js";
41
42
  import {
42
43
  blocksToPages
43
- } from "./chunk-DYENR3PX.js";
44
+ } from "./chunk-AUWGDP4G.js";
44
45
  import {
45
46
  encodePng
46
47
  } from "./chunk-7FCNOKOR.js";
47
- import "./chunk-UQ6TZDW6.js";
48
+ import {
49
+ stripScriptTags
50
+ } from "./chunk-J3IF6KGW.js";
48
51
  import {
49
52
  hasRequestedPagesAfter,
50
53
  parsePageRange
@@ -53,11 +56,11 @@ import {
53
56
  WINGDINGS,
54
57
  blocksToMarkdown,
55
58
  escapeLiteralDollar
56
- } from "./chunk-TGD7UFHD.js";
59
+ } from "./chunk-LEIAEWZ7.js";
57
60
  import {
58
61
  KordocError,
59
62
  sanitizeHref
60
- } from "./chunk-RC4C7Q33.js";
63
+ } from "./chunk-P6ZDXTV6.js";
61
64
 
62
65
  // src/pdf/ocr-region-merge.ts
63
66
  function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
@@ -642,6 +645,40 @@ function ocrVectorOps(opList, paths) {
642
645
  return { fnArray, argsArray };
643
646
  }
644
647
 
648
+ // src/pdf/contact-table.ts
649
+ var CONTACT_HEAD = /^(?:담당\s*부서|<[^<>]+>)$/;
650
+ var CONTACT_ROLE = /^(?:책임자|담당자)$/;
651
+ var PERSON = /^(.+?)\s+([가-힣]{2,4})\s+(\([^()]*\d[^()]*\)|\S+@\S+)$/;
652
+ function splitContactTables(blocks) {
653
+ for (const b of blocks) {
654
+ const t = b.type === "table" ? b.table : void 0;
655
+ if (!t || t.cols !== 4 || t.rows < 2) continue;
656
+ const rows = t.cells;
657
+ if (!CONTACT_HEAD.test(rows[0][0].text.replace(/\s+/g, " ").trim())) continue;
658
+ const people = rows.map((r) => PERSON.exec(r[3].text.replace(/\s+/g, " ").trim()));
659
+ if (people.some((p) => !p) || rows.some((r) => !CONTACT_ROLE.test(r[2].text.replace(/\s+/g, "")) || r[2].rowSpan !== 1 || r[3].rowSpan !== 1)) continue;
660
+ const lead = [];
661
+ let ok = true;
662
+ for (const c of [0, 1]) {
663
+ const top = rows[0][c];
664
+ if (top.rowSpan === 1) {
665
+ lead.push(rows.map((r) => r[c].text));
666
+ continue;
667
+ }
668
+ const lines = top.text.split("\n").map((s) => s.trim()).filter(Boolean);
669
+ if (top.rowSpan !== t.rows || lines.length > t.rows) {
670
+ ok = false;
671
+ break;
672
+ }
673
+ lead.push(rows.map((_, r) => lines[r] ?? ""));
674
+ }
675
+ if (!ok) continue;
676
+ const one = (text) => ({ text, colSpan: 1, rowSpan: 1 });
677
+ t.cells = rows.map((r, i) => [one(lead[0][i]), one(lead[1][i]), one(r[2].text), one(people[i][1]), one(people[i][2]), one(people[i][3])]);
678
+ t.cols = 6;
679
+ }
680
+ }
681
+
645
682
  // src/pdf/table-parts.ts
646
683
  var PART_COL_TOL = 1;
647
684
  function anchorsOf(table) {
@@ -678,7 +715,7 @@ var indexOf = (coords, x) => {
678
715
  };
679
716
  var rowText = (anchors, r) => anchors.filter((a) => a.r === r).map((a) => a.cell.text.replace(/\s+/g, "")).join("|");
680
717
  var hasText = (t) => t.replace(/\|/g, "") !== "";
681
- function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
718
+ function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom, lex) {
682
719
  if (pcx.length !== prev.cols + 1 || ccx.length !== curr.cols + 1) return null;
683
720
  const U = unionCoords(pcx, ccx);
684
721
  const cols = U.length - 1;
@@ -734,13 +771,35 @@ function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
734
771
  }
735
772
  for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) if (owner[r][c] === null) FILLER_CELLS.add(grid[r][c]);
736
773
  const table = { rows, cols, cells: grid, hasHeader: prev.hasHeader, ...prev.caption ? { caption: prev.caption } : {} };
737
- const split = rows > prev.rows && mergeSplitRow(table, owner, prev.rows, U);
738
- if (rows > prev.rows && !split && prevBottom !== void 0) mergeStraddlingCells(table, owner, prev.rows, prevBottom);
774
+ let split = rows > prev.rows && mergeSplitRow(table, owner, prev.rows, U);
775
+ if (rows > prev.rows && !split && prevBottom !== void 0 && mergeStraddlingCells(table, owner, prev.rows, prevBottom, lex)) split = mergeSplitRow(table, owner, prev.rows, U, true);
739
776
  return { table, colXs: U, split, header: ca.filter((a) => a.r < skip && a.cell.text.trim()).length >= 2 };
740
777
  }
741
- function mergeStraddlingCells(table, owner, first, prevBottom) {
778
+ function mergeStraddlingCells(table, owner, first, prevBottom, lex) {
742
779
  const last = first - 1;
743
- if (!owner[first].some((o, c) => o !== null && o === owner[last][c])) return;
780
+ const straddles = owner[first].some((o, c) => o !== null && o === owner[last][c]);
781
+ let firstNew = table.cols;
782
+ for (let c = 0; c < table.cols; c++) {
783
+ const d = owner[first][c];
784
+ if (d && d.r === first && d !== owner[last][c] && hasContent(table.cells[d.r][d.c])) {
785
+ firstNew = c;
786
+ break;
787
+ }
788
+ }
789
+ let midWord = false;
790
+ if (lex) for (let c = 0; c < table.cols && !midWord; ) {
791
+ const u = owner[last][c], d = owner[first][c];
792
+ if (!u) {
793
+ c++;
794
+ continue;
795
+ }
796
+ c = u.c + u.cs;
797
+ if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
798
+ if (u.r !== last || d.rs < 2) continue;
799
+ const tail = table.cells[u.r][u.c].text.trim().split(/\s+/).pop() ?? "", head = table.cells[first][d.c].text.trim().split(/\s+/)[0] ?? "";
800
+ if (/^[가-힣]{2,}$/.test(tail) && /^[가-힣]{2,}/.test(head) && lex.evidence2(tail, head) === "") midWord = true;
801
+ }
802
+ let merged = false;
744
803
  for (let c = 0; c < table.cols; ) {
745
804
  const u = owner[last][c], d = owner[first][c];
746
805
  if (!u) {
@@ -748,18 +807,24 @@ function mergeStraddlingCells(table, owner, first, prevBottom) {
748
807
  continue;
749
808
  }
750
809
  c = u.c + u.cs;
751
- if (!d || d === u || u.r >= last && d.rs < 2 || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
810
+ if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
752
811
  const a = table.cells[u.r][u.c], b = table.cells[first][d.c];
753
- const U = CELL_LINES.get(a);
754
- if (!U?.length || U.length > STRADDLE_MAX_LINES || !hasContent(b)) continue;
755
- const lu = U[U.length - 1];
756
- if (lu.y - prevBottom > (u.r >= last ? STRADDLE_BOTTOM_ONE_ROW : STRADDLE_BOTTOM) * (lu.h || 10)) continue;
812
+ if (!(u.rs >= 2 && u.c + u.cs <= firstNew && hasContent(a) && !hasContent(b))) {
813
+ if (!straddles && !midWord) continue;
814
+ if (u.r >= last && d.rs < 2) continue;
815
+ const U = CELL_LINES.get(a);
816
+ if (!U?.length || U.length > STRADDLE_MAX_LINES || !hasContent(b)) continue;
817
+ const lu = U[U.length - 1];
818
+ if (!midWord && lu.y - prevBottom > (u.r >= last ? STRADDLE_BOTTOM_ONE_ROW : STRADDLE_BOTTOM) * (lu.h || 10)) continue;
819
+ }
757
820
  appendCell(a, b);
758
821
  a.rowSpan = first + d.rs - u.r;
759
822
  table.cells[first][d.c] = { text: "", colSpan: 1, rowSpan: 1 };
760
823
  const grown = { ...u, rs: a.rowSpan };
761
824
  for (let rr = u.r; rr < u.r + grown.rs; rr++) for (let dc = u.c; dc < u.c + u.cs; dc++) owner[rr][dc] = grown;
825
+ merged = true;
762
826
  }
827
+ return merged;
763
828
  }
764
829
  var FULL_LINE_TOL = 1;
765
830
  var FULL_LINE_MIN_FRAC = 0.5;
@@ -795,11 +860,21 @@ function continuesAcross(u, d, x1, x2) {
795
860
  const hanging = U.length >= 2 && U.every((l) => maxR - l.r <= FULL_LINE_TOL * fs) && last.l - minL >= HANGING_MIN * fs && Math.abs(D[0].l - last.l) <= HANGING_TOL;
796
861
  return U.some(leftAligned) || D.some(leftAligned) || hanging;
797
862
  }
798
- function lineEnded(c, x1, x2) {
863
+ var OUTLINE_HEAD = /^[□■]\s*\S/;
864
+ var OUTLINE_ITEM = /^[ㅇ○◦\-‐–·․‧※*]\s*\S/;
865
+ function outlineContinues(u, d) {
866
+ const U = u.text.split("\n").map((l) => l.trim()).filter(Boolean);
867
+ const D = d.text.split("\n").map((l) => l.trim()).filter(Boolean);
868
+ return U.length >= 2 && D.length >= 1 && U.some((l) => OUTLINE_HEAD.test(l)) && OUTLINE_ITEM.test(D[0]);
869
+ }
870
+ function lineEnded(c, x1, x2, next = "") {
799
871
  const L = CELL_LINES.get(c);
800
872
  if (!L || L.length !== 1) return false;
801
- const l = L[0];
802
- return x2 - l.r - (l.l - x1) >= LABEL_ROOM * (l.h || 10);
873
+ const l = L[0], h = l.h || 10;
874
+ const word = next.trim().split(/\s+/)[0] ?? "";
875
+ let units = 0;
876
+ for (const ch of word) units += /[가-힣\u3400-\u9fff]/.test(ch) ? 1 : 0.55;
877
+ return x2 - l.r - (l.l - x1) >= Math.max(LABEL_ROOM, units) * h;
803
878
  }
804
879
  function appendCell(a, b) {
805
880
  if (a.blocks?.length || b.blocks?.length) {
@@ -809,7 +884,22 @@ function appendCell(a, b) {
809
884
  if (b.text.trim()) a.text = a.text.trim() ? a.text + "\n" + b.text : b.text;
810
885
  }
811
886
  var hasContent = (cell) => !!cell.text.trim() || !!cell.blocks?.length || IMAGE_CELLS.has(cell);
812
- function mergeSplitRow(table, owner, first, colXs) {
887
+ var CLAUSE_OPEN_ENDING = /(?:하는|되는|하고|하며|하여|되어|되고|되며|이며|으며|어야|아야|여야)$/;
888
+ var batchim = (ch) => {
889
+ const k = ch.charCodeAt(0) - 44032;
890
+ return k >= 0 && k < 11172 && k % 28 !== 0;
891
+ };
892
+ function clauseContinues(u, d) {
893
+ const tail = u.text.trim().split(/\s+/).pop() ?? "", head = d.text.trim();
894
+ if (!/^[가-힣]{2,}$/.test(tail) || !/^[가-힣]/.test(head) || startsNewItem(u.text, head)) return false;
895
+ const last = tail[tail.length - 1], before = tail[tail.length - 2];
896
+ return last === "\uC744" && batchim(before) || last === "\uB97C" && !batchim(before) || CLAUSE_OPEN_ENDING.test(tail);
897
+ }
898
+ function outlineOnly(pairs, cell) {
899
+ const filled = pairs.filter(([, d]) => hasContent(d.cell));
900
+ return filled.length === 1 && outlineContinues(cell(filled[0][0]), cell(filled[0][1]));
901
+ }
902
+ function mergeSplitRow(table, owner, first, colXs, textOnly = false) {
813
903
  const last = first - 1;
814
904
  const pairs = [];
815
905
  let carried = false;
@@ -827,12 +917,12 @@ function mergeSplitRow(table, owner, first, colXs) {
827
917
  } else if (a.r === last && a.rs === 2) carried = true;
828
918
  c = a.c + a.cs;
829
919
  }
830
- const carriedSplit = carried && pairs.filter(([u, d]) => hasContent(u.cell) && hasContent(d.cell)).length <= 1 && !pairs.some(([u, d]) => !hasContent(u.cell) && hasContent(d.cell));
920
+ const carriedSplit = !textOnly && carried && pairs.filter(([u, d]) => hasContent(u.cell) && hasContent(d.cell)).length <= 1 && !pairs.some(([u, d]) => !hasContent(u.cell) && hasContent(d.cell));
831
921
  const cell = (a) => table.cells[a.r][a.c];
832
922
  if (!carriedSplit) {
833
923
  const norm = (c) => c.text.replace(/\s+/g, "");
834
- if (pairs.some(([u, d]) => hasContent(d.cell) && norm(cell(d)) !== norm(cell(u)) && lineEnded(cell(u), colXs[u.c], colXs[u.c + u.cs]))) return false;
835
- if (!pairs.some(([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs]))) return false;
924
+ if (pairs.some(([u, d]) => hasContent(d.cell) && norm(cell(d)) !== norm(cell(u)) && lineEnded(cell(u), colXs[u.c], colXs[u.c + u.cs], cell(d).text))) return false;
925
+ if (!outlineOnly(pairs, cell) && !pairs.some(([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs])) && !pairs.some(([u, d]) => clauseContinues(cell(u), cell(d)))) return false;
836
926
  }
837
927
  for (const [u, d] of pairs) appendCell(table.cells[u.r][u.c], table.cells[d.r][d.c]);
838
928
  for (let r = 0; r < first; r++) for (let c = 0; c < table.cols; c++) {
@@ -879,8 +969,8 @@ function sameHeadShape(a, b) {
879
969
  }
880
970
  return tall;
881
971
  }
882
- function mergeCrossPageTables(blocks, pageHeights) {
883
- mergeColumnFlow(blocks, pageHeights);
972
+ function mergeCrossPageTables(blocks, pageHeights, lex) {
973
+ mergeColumnFlow(blocks, pageHeights, lex);
884
974
  for (let i = blocks.length - 2; i >= 0; i--) {
885
975
  const prev = blocks[i];
886
976
  if (prev.type !== "table" || !prev.table || !prev.bbox || !prev.pageNumber) continue;
@@ -889,7 +979,7 @@ function mergeCrossPageTables(blocks, pageHeights) {
889
979
  const curr = blocks[j];
890
980
  if (!curr || curr.type !== "table" || !curr.table || !curr.bbox || curr.pageNumber !== prev.pageNumber + 1) continue;
891
981
  if (startsWithUnitRow(prev.table) && startsWithUnitRow(curr.table)) continue;
892
- const joined = j === i + 1 || blocks.slice(i + 1, j).every((b) => besideOwn(b, prev, curr) || insideTable(b, prev)) ? looksContinued(prev, curr, pageHeights) && !restartsTable(blocks, i, curr.table, pageHeights) ? joinClipParts(prev, curr, pageHeights) ?? false : null : null;
982
+ const joined = j === i + 1 || blocks.slice(i + 1, j).every((b) => besideOwn(b, prev, curr) || insideTable(b, prev)) ? looksContinued(prev, curr, pageHeights) && !restartsTable(blocks, i, curr.table, pageHeights) ? joinClipParts(prev, curr, pageHeights, lex) ?? false : null : null;
893
983
  if (joined) {
894
984
  placeJoined(blocks, i, j, joined);
895
985
  continue;
@@ -933,7 +1023,7 @@ function mergeCrossPageTables(blocks, pageHeights) {
933
1023
  if (blocks[i].type === "table" && t && EMPTY_PARTS.has(t)) blocks.splice(i, 1);
934
1024
  }
935
1025
  }
936
- function mergeColumnFlow(blocks, pageHeights) {
1026
+ function mergeColumnFlow(blocks, pageHeights, lex) {
937
1027
  if (!pageHeights) return;
938
1028
  for (let i = 0; i < blocks.length; i++) {
939
1029
  const L = blocks[i];
@@ -955,7 +1045,7 @@ function mergeColumnFlow(blocks, pageHeights) {
955
1045
  const R = blocks[k];
956
1046
  if (Math.abs(R.bbox.width - L.bbox.width) > Math.max(R.bbox.width, L.bbox.width) * NEIGHBOR_TABLE_EPSILON) continue;
957
1047
  if (!looksContinued(L, R) || restartsTable(blocks, i, R.table, pageHeights)) continue;
958
- const joined = joinClipParts(L, R, pageHeights);
1048
+ const joined = joinClipParts(L, R, pageHeights, lex);
959
1049
  if (!joined) continue;
960
1050
  const top = L.bbox.y + L.bbox.height;
961
1051
  const at = Math.min(i, k);
@@ -964,12 +1054,12 @@ function mergeColumnFlow(blocks, pageHeights) {
964
1054
  i = at - 1;
965
1055
  }
966
1056
  }
967
- function joinClipParts(prev, curr, pageHeights) {
1057
+ function joinClipParts(prev, curr, pageHeights, lex) {
968
1058
  const pt = prev.table, ct = curr.table;
969
1059
  if (!CLIP_TABLES.has(pt) || !CLIP_TABLES.has(ct)) return null;
970
1060
  const px = TABLE_COLXS.get(pt), cx = TABLE_COLXS.get(ct);
971
1061
  if (!px || !cx) return null;
972
- let xs = cx, shifted = false, dx = 0;
1062
+ let xs = cx, shifted = false, dx = 0, foreign = false;
973
1063
  if (!shiftedSame(px, cx, false)) {
974
1064
  if (!pageHeights?.get(prev.pageNumber) || !pageHeights?.get(curr.pageNumber)) return null;
975
1065
  dx = px[px.length - 1] - cx[cx.length - 1];
@@ -978,19 +1068,29 @@ function joinClipParts(prev, curr, pageHeights) {
978
1068
  shifted = true;
979
1069
  } else dx = 0;
980
1070
  if (!px.some((x) => Math.abs(x - xs[0]) <= CONTINUATION_COL_TOL)) return null;
1071
+ const inner = xs.slice(1, -1);
1072
+ foreign = inner.length > 0 && !inner.some((x) => px.some((p) => Math.abs(p - x) <= CONTINUATION_COL_TOL)) && headingRow(ct.cells[0] ?? []);
981
1073
  }
982
- const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y);
983
- if (!res || shifted && !res.split && !res.header) return null;
1074
+ const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y, lex);
1075
+ if (!res || (shifted || foreign) && !res.split && !res.header) return null;
984
1076
  TABLE_COLXS.set(res.table, res.colXs);
985
1077
  CLIP_TABLES.add(res.table);
986
1078
  return res.table;
987
1079
  }
1080
+ function headingRow(row) {
1081
+ const heads = row.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
1082
+ if (heads.length === 1) return heads[0].length <= 8 || /^[①-⑳❶-❿]/.test(heads[0]);
1083
+ return heads.length === 2 && /^(?:\d{1,2}|[ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ]+|[①-⑳❶-❿])$/.test(heads[0]);
1084
+ }
988
1085
  var ANNEX_HEAD_RE = /^\s*[<\[(【]?\s*(?:붙\s*임|참\s*고|별\s*첨|별\s*지|별\s*표|첨\s*부|부\s*록)(?:\s*\d|\s*$|\s*[>\])】])|^\s*■/;
989
1086
  function looksContinued(prev, curr, pageHeights) {
990
1087
  const ph = pageHeights?.get(prev.pageNumber), ch = pageHeights?.get(curr.pageNumber);
991
1088
  if (ph && ch && (prev.bbox.y > ph * PAGE_EDGE_BAND || curr.bbox.y + curr.bbox.height < ch * (1 - PAGE_EDGE_BAND))) return false;
992
- const firstText = curr.table.cells[0]?.find((c) => c.text.trim())?.text ?? "";
993
- return !ANNEX_HEAD_RE.test(firstText);
1089
+ const firstRow = curr.table.cells[0] ?? [];
1090
+ const firstText = firstRow.find((c) => c.text.trim())?.text ?? "";
1091
+ if (!ANNEX_HEAD_RE.test(firstText)) return true;
1092
+ const filled = firstRow.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
1093
+ return filled.length >= 2 && filled.every((t) => t === filled[0]);
994
1094
  }
995
1095
  function firstRowSig(t) {
996
1096
  const x = TABLE_COLXS.get(t);
@@ -1003,6 +1103,7 @@ function restartsTable(blocks, i, curr, pageHeights) {
1003
1103
  const head = blocks[chainHead(blocks, i, pageHeights)].table;
1004
1104
  if (cs.length === 1 && restartsTitledForm(head, curr)) return true;
1005
1105
  if (cs.length < RESTART_MIN_ANCHORS) return false;
1106
+ if (CONTACT_HEAD.test(cs[0].t) && cs.some((c) => CONTACT_ROLE.test(c.t))) return false;
1006
1107
  const hs = firstRowSig(head);
1007
1108
  if (!hs || hs.length !== cs.length) return false;
1008
1109
  const dx = hs[hs.length - 1].x2 - cs[cs.length - 1].x2;
@@ -1849,6 +1950,52 @@ function restoreTrackedSpacing(items, fnArray, argsArray) {
1849
1950
  }
1850
1951
  return changed;
1851
1952
  }
1953
+ function markSyntheticSpaces(items, fnArray, argsArray) {
1954
+ if (!items.some((it) => typeof it.str === "string" && it.str.length > 0 && !it.str.trim())) return;
1955
+ const streams = /* @__PURE__ */ new Map();
1956
+ const saved = [];
1957
+ let font = "";
1958
+ for (let i = 0; i < fnArray.length; i++) {
1959
+ const fn = fnArray[i];
1960
+ const args = argsArray[i];
1961
+ if (fn === OPS5.setFont) font = String(args[0]);
1962
+ else if (fn === OPS5.save || fn === OPS5.paintFormXObjectBegin) saved.push(font);
1963
+ else if (fn === OPS5.restore || fn === OPS5.paintFormXObjectEnd) font = saved.pop() ?? font;
1964
+ else if (fn === OPS5.showText) {
1965
+ let list = streams.get(font);
1966
+ if (!list) streams.set(font, list = []);
1967
+ for (const g2 of args[0]) {
1968
+ if (g2 && typeof g2 === "object" && typeof g2.unicode === "string") list.push(normalizeUnicode3(g2.unicode));
1969
+ }
1970
+ }
1971
+ }
1972
+ const cursor = /* @__PURE__ */ new Map();
1973
+ const failed = /* @__PURE__ */ new Set();
1974
+ const marks = [];
1975
+ for (const it of items) {
1976
+ const f = it.fontName ?? "";
1977
+ const glyphs = streams.get(f);
1978
+ if (!glyphs || failed.has(f) || typeof it.str !== "string" || !it.str) continue;
1979
+ let gi = cursor.get(f) ?? 0;
1980
+ if (!it.str.trim()) {
1981
+ if (gi < glyphs.length && /^\s+$/.test(glyphs[gi])) {
1982
+ while (gi < glyphs.length && /^\s+$/.test(glyphs[gi])) gi++;
1983
+ cursor.set(f, gi);
1984
+ } else marks.push(it);
1985
+ continue;
1986
+ }
1987
+ const want = it.str.replace(/\s+/g, "");
1988
+ while (gi < glyphs.length && /^\s*$/.test(glyphs[gi])) gi++;
1989
+ let got = "";
1990
+ while (gi < glyphs.length && got.length < want.length) got += glyphs[gi++].replace(/\s+/g, "");
1991
+ if (got !== want) {
1992
+ failed.add(f);
1993
+ continue;
1994
+ }
1995
+ cursor.set(f, gi);
1996
+ }
1997
+ for (const it of marks) if (!failed.has(it.fontName ?? "")) it.synthetic = true;
1998
+ }
1852
1999
 
1853
2000
  // src/pdf/endnotes.ts
1854
2001
  var NOTE_MARK = /^\s*(문\d{1,5}[))]|\d{1,5}\)|\(\d{1,5}\))/;
@@ -1986,6 +2133,7 @@ function orderTwoUpPage(blocks, pageWidth, pageHeight) {
1986
2133
  var BAND = 0.12;
1987
2134
  var MAX_CHARS = 10;
1988
2135
  var MIN_REPEAT = 3;
2136
+ var RUN_GAP = 5;
1989
2137
  function removeSideTabs(blocks, pageWidths) {
1990
2138
  const edges = /* @__PURE__ */ new Map();
1991
2139
  for (const b of blocks) {
@@ -2018,13 +2166,21 @@ function removeSideTabs(blocks, pageWidths) {
2018
2166
  }
2019
2167
  const running = /* @__PURE__ */ new Set();
2020
2168
  for (const [k, ps] of pages) {
2021
- const list = [...ps];
2022
- const span = Math.max(...list) - Math.min(...list) + 1;
2023
- if (list.length >= MIN_REPEAT && list.length >= span * 0.4) running.add(k);
2169
+ const list = [...ps].sort((a, b) => a - b);
2170
+ let run = [];
2171
+ const flush = () => {
2172
+ if (run.length >= MIN_REPEAT && run.length >= (run[run.length - 1] - run[0] + 1) * 0.4) for (const p of run) running.add(`${p}\0${k}`);
2173
+ run = [];
2174
+ };
2175
+ for (const p of list) {
2176
+ if (run.length && p - run[run.length - 1] > RUN_GAP) flush();
2177
+ run.push(p);
2178
+ }
2179
+ flush();
2024
2180
  }
2025
2181
  return running.size ? blocks.filter((b) => {
2026
2182
  const k = key(b);
2027
- return !k || !running.has(k);
2183
+ return !k || !running.has(`${b.pageNumber}\0${k}`);
2028
2184
  }) : blocks;
2029
2185
  }
2030
2186
 
@@ -2192,7 +2348,9 @@ function normalizeAraea(text) {
2192
2348
  return text.replace(/(?<![\u1100-\u115F])\u119E/g, "\u318D");
2193
2349
  }
2194
2350
  var stripNoUnicodeGlyph = (text) => text.includes("\uF000") ? text.replace(/\uF000/g, "") : text;
2195
- var cleanChars = (text) => normalizeAraea(stripNoUnicodeGlyph(stripControlChars(text)));
2351
+ var CHOSEONG_COMPAT = "\u3131\u3132\u3134\u3137\u3138\u3139\u3141\u3142\u3143\u3145\u3146\u3147\u3148\u3149\u314A\u314B\u314C\u314D\u314E";
2352
+ var normalizeLoneChoseong = (text) => /[\u1100-\u1112]/.test(text) ? text.replace(/[\u1100-\u1112](?![\u1160-\u11A7\uD7B0-\uD7C6])/g, (c) => CHOSEONG_COMPAT[c.charCodeAt(0) - 4352]) : text;
2353
+ var cleanChars = (text) => normalizeLoneChoseong(normalizeAraea(stripNoUnicodeGlyph(stripControlChars(text))));
2196
2354
  function sanitizeBlockControlChars(blocks) {
2197
2355
  for (const b of blocks) {
2198
2356
  if (b.text) b.text = cleanChars(b.text);
@@ -2269,7 +2427,7 @@ function cleanPdfText(text, opts) {
2269
2427
  }
2270
2428
  const mark = /^(?:#{1,6}|-) /.exec(line)?.[0] ?? "";
2271
2429
  return mark + collapseEvenSpacing(line.slice(mark.length), false);
2272
- }).replace(/\\~\\~/g, "~~").replace(/~~~~/g, "").replace(/<u>\s*<\/u>/g, "").replace(/\n{3,}/g, "\n\n").trim();
2430
+ }).replace(/\\~\\~/g, "~~").replace(/~~~~/g, "").replace(/<u>\s*<\/u>/g, "").replace(/<(sup|sub)>\s*<\/\1>/g, "").replace(/\n{3,}/g, "\n\n").trim();
2273
2431
  }
2274
2432
  function startsWithMarker(line) {
2275
2433
  const t = line.trimStart();
@@ -2357,7 +2515,7 @@ function mergeLinkRuns(markdown) {
2357
2515
 
2358
2516
  // src/pdf/formula-ocr.ts
2359
2517
  async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
2360
- const formulaMod = await import("./formula-5775PTP2.js");
2518
+ const formulaMod = await import("./formula-NARUOXRX.js");
2361
2519
  const { FormulaPipeline, ensureFormulaModels } = formulaMod;
2362
2520
  await ensureFormulaModels((p) => {
2363
2521
  if (p.phase === "download" && p.total) {
@@ -2497,42 +2655,15 @@ g.pdfjsWorker = pdfjsWorker;
2497
2655
  import { getDocument, GlobalWorkerOptions, OPS as OPS6 } from "pdfjs-dist/legacy/build/pdf.mjs";
2498
2656
  import { createRequire } from "module";
2499
2657
  import { dirname, join } from "path";
2500
-
2501
- // src/pdf/contact-table.ts
2502
- var HEAD = /^(?:담당\s*부서|<[^<>]+>)$/;
2503
- var ROLE = /^(?:책임자|담당자)$/;
2504
- var PERSON = /^(.+?)\s+([가-힣]{2,4})\s+(\([^()]*\d[^()]*\)|\S+@\S+)$/;
2505
- function splitContactTables(blocks) {
2506
- for (const b of blocks) {
2507
- const t = b.type === "table" ? b.table : void 0;
2508
- if (!t || t.cols !== 4 || t.rows < 2) continue;
2509
- const rows = t.cells;
2510
- if (!HEAD.test(rows[0][0].text.replace(/\s+/g, " ").trim())) continue;
2511
- const people = rows.map((r) => PERSON.exec(r[3].text.replace(/\s+/g, " ").trim()));
2512
- if (people.some((p) => !p) || rows.some((r) => !ROLE.test(r[2].text.replace(/\s+/g, "")) || r[2].rowSpan !== 1 || r[3].rowSpan !== 1)) continue;
2513
- const lead = [];
2514
- let ok = true;
2515
- for (const c of [0, 1]) {
2516
- const top = rows[0][c];
2517
- if (top.rowSpan === 1) {
2518
- lead.push(rows.map((r) => r[c].text));
2519
- continue;
2520
- }
2521
- const lines = top.text.split("\n").map((s) => s.trim()).filter(Boolean);
2522
- if (top.rowSpan !== t.rows || lines.length > t.rows) {
2523
- ok = false;
2524
- break;
2525
- }
2526
- lead.push(rows.map((_, r) => lines[r] ?? ""));
2527
- }
2528
- if (!ok) continue;
2529
- const one = (text) => ({ text, colSpan: 1, rowSpan: 1 });
2530
- t.cells = rows.map((r, i) => [one(lead[0][i]), one(lead[1][i]), one(r[2].text), one(people[i][1]), one(people[i][2]), one(people[i][3])]);
2531
- t.cols = 6;
2658
+ function ocrImageRegions(regions, large, all) {
2659
+ if (all) return regions;
2660
+ const out = /* @__PURE__ */ new Map();
2661
+ for (const [p, rs] of regions) {
2662
+ const big = rs.filter((r) => large.has(r));
2663
+ if (big.length) out.set(p, big);
2532
2664
  }
2665
+ return out;
2533
2666
  }
2534
-
2535
- // src/pdf/parser.ts
2536
2667
  GlobalWorkerOptions.workerSrc = "";
2537
2668
  var MAX_PAGES = 5e3;
2538
2669
  var MAX_TOTAL_TEXT = 100 * 1024 * 1024;
@@ -2605,6 +2736,7 @@ async function parsePdfDocument(buffer, options) {
2605
2736
  const pagesWithLargeImage = /* @__PURE__ */ new Set();
2606
2737
  const skippedImagePages = /* @__PURE__ */ new Map();
2607
2738
  const uncoveredImageRegions = /* @__PURE__ */ new Map();
2739
+ const largeImageRegions = /* @__PURE__ */ new Set();
2608
2740
  const imageState = createPdfImageState();
2609
2741
  const extractedImages = [];
2610
2742
  const pageImageBlocks = /* @__PURE__ */ new Map();
@@ -2636,6 +2768,7 @@ async function parsePdfDocument(buffer, options) {
2636
2768
  const differencesOf = (loadedName) => fontObj(loadedName)?.differences;
2637
2769
  restoreNamedGlyphs(rawItems, rawOps.fnArray, rawOps.argsArray, differencesOf, (n) => fontObj(n)?.name);
2638
2770
  restoreTrackedSpacing(rawItems, rawOps.fnArray, rawOps.argsArray);
2771
+ markSyntheticSpaces(rawItems, rawOps.fnArray, rawOps.argsArray);
2639
2772
  const occluded = occludedTextItems(rawItems, rawOps.fnArray, rawOps.argsArray);
2640
2773
  const items = normalizeItems(occluded.size ? rawItems.filter((it) => !occluded.has(it)) : rawItems);
2641
2774
  const filtered = filterHiddenText(items, pageW, pageH, viewX1, viewY1);
@@ -2699,6 +2832,7 @@ async function parsePdfDocument(buffer, options) {
2699
2832
  const regions = uncoveredImageRegions.get(i) ?? [];
2700
2833
  regions.push(r);
2701
2834
  uncoveredImageRegions.set(i, regions);
2835
+ if (large) largeImageRegions.add(r);
2702
2836
  }
2703
2837
  }
2704
2838
  }
@@ -2747,6 +2881,7 @@ async function parsePdfDocument(buffer, options) {
2747
2881
  const parsedPageCount = parsedPages || (pageFilter ? pageFilter.size : effectivePageCount);
2748
2882
  const isImageBased = pageFilter?.size !== 0 && totalChars / Math.max(parsedPageCount, 1) < 10;
2749
2883
  const ocrDone = /* @__PURE__ */ new Set();
2884
+ const ocrRegions = options?.ocr === true || autoOcr ? ocrImageRegions(uncoveredImageRegions, largeImageRegions, options?.ocr === true) : /* @__PURE__ */ new Map();
2750
2885
  if (ocrBuffer) {
2751
2886
  const inScope = (p) => !pageFilter || pageFilter.has(p);
2752
2887
  const targets = /* @__PURE__ */ new Set();
@@ -2759,14 +2894,15 @@ async function parsePdfDocument(buffer, options) {
2759
2894
  if (autoOcr && pq.ocrReason !== "low_text" && pq.ocrReason !== "vector_text") continue;
2760
2895
  targets.add(pq.page);
2761
2896
  }
2762
- if (options?.ocr === true) for (const p of uncoveredImageRegions.keys()) targets.add(p);
2897
+ for (const p of ocrRegions.keys()) targets.add(p);
2763
2898
  }
2764
2899
  if (targets.size > 0) {
2765
2900
  try {
2766
- const { runPdfOcr } = await import("./pdf-ocr-WF2NQA6X.js");
2901
+ const { runPdfOcr } = await import("./pdf-ocr-MQTWODVU.js");
2767
2902
  const mode = typeof options?.ocr === "function" ? options.ocr : "builtin";
2768
- const regionPages = new Map([...uncoveredImageRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
2903
+ const regionPages = new Map([...ocrRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
2769
2904
  const ocrPageBlocks = await runPdfOcr(ocrBuffer, targets, mode, warnings, options?.onProgress, options?.tables !== false, vectorPageOps, regionPages);
2905
+ for (const obs of ocrPageBlocks.values()) stripScriptTags({ blocks: obs });
2770
2906
  if (ocrPageBlocks.size > 0) {
2771
2907
  const replacePages = /* @__PURE__ */ new Set();
2772
2908
  for (const [p, obs] of ocrPageBlocks) {
@@ -2776,7 +2912,7 @@ async function parsePdfDocument(buffer, options) {
2776
2912
  ocrDone.add(p);
2777
2913
  continue;
2778
2914
  }
2779
- const regions = uncoveredImageRegions.get(p);
2915
+ const regions = ocrRegions.get(p);
2780
2916
  if (!regions || mergeOcrImageRegions(blocks, p, regions, obs) === 0) continue;
2781
2917
  ocrDone.add(p);
2782
2918
  if (pageImageBlocks.get(p)?.length === 1) pageImageBlocks.delete(p);
@@ -2830,7 +2966,7 @@ async function parsePdfDocument(buffer, options) {
2830
2966
  }
2831
2967
  }
2832
2968
  if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
2833
- const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings);
2969
+ const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks);
2834
2970
  for (let ri = removed.length - 1; ri >= 0; ri--) {
2835
2971
  blocks.splice(removed[ri], 1);
2836
2972
  }
@@ -2841,7 +2977,11 @@ async function parsePdfDocument(buffer, options) {
2841
2977
  }
2842
2978
  }
2843
2979
  mergeContinuedCells(blocks, pageHeights);
2844
- mergeCrossPageTables(blocks, pageHeights);
2980
+ mergeCrossPageTables(blocks, pageHeights, wrapLexicon);
2981
+ if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
2982
+ const boxes = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks, true);
2983
+ for (let ri = boxes.length - 1; ri >= 0; ri--) blocks.splice(boxes[ri], 1);
2984
+ }
2845
2985
  splitContactTables(blocks);
2846
2986
  if (!options?.keepTrailingEmptyCols) trimTrailingEmptyTableCols(blocks);
2847
2987
  joinPageBreakWraps(blocks, wrapLexicon);
@@ -2954,7 +3094,8 @@ export {
2954
3094
  detectTableCaptions,
2955
3095
  extractPdfMetadataOnly,
2956
3096
  mergeCrossPageTables,
3097
+ ocrImageRegions,
2957
3098
  parsePdfDocument,
2958
3099
  removeHeaderFooterBlocks
2959
3100
  };
2960
- //# sourceMappingURL=parser-3B6I2XL7.js.map
3101
+ //# sourceMappingURL=parser-N6476XAC.js.map