kordoc 4.16.2 → 4.17.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 (150) hide show
  1. package/README.md +14 -13
  2. package/dist/{-4G6MA4X6.js → -PRAKO6M4.js} +11 -11
  3. package/dist/{chunk-AUWGDP4G.js → chunk-2KF5WZCR.js} +2 -2
  4. package/dist/{chunk-UTP2WCHS.js → chunk-4GSF2R7T.js} +4 -4
  5. package/dist/{chunk-TXUKTOG2.js → chunk-4XVNQAK5.js} +219 -23
  6. package/dist/chunk-4XVNQAK5.js.map +1 -0
  7. package/dist/chunk-5CDUL6PH.js +250 -0
  8. package/dist/chunk-5CDUL6PH.js.map +1 -0
  9. package/dist/{chunk-4VODJKFL.js → chunk-6RGGYQQC.js} +3 -3
  10. package/dist/{chunk-DES2LGFZ.js → chunk-A55JGNKD.js} +2 -2
  11. package/dist/chunk-AKB72TEH.cjs +248 -0
  12. package/dist/chunk-AKB72TEH.cjs.map +1 -0
  13. package/dist/{chunk-LEIAEWZ7.js → chunk-BFT5IM2R.js} +2 -2
  14. package/dist/{chunk-KIOQ4N37.js → chunk-BLPR4HRF.js} +2 -2
  15. package/dist/{chunk-JELRWAZC.js → chunk-BZG7K44Z.js} +2 -2
  16. package/dist/{chunk-F4NRLLY4.js → chunk-EFO6JZY6.js} +2 -2
  17. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  18. package/dist/{chunk-JFLAM3MM.js → chunk-I5DJOP62.js} +2 -2
  19. package/dist/chunk-I5DJOP62.js.map +1 -0
  20. package/dist/chunk-J55UQC5H.cjs.map +1 -1
  21. package/dist/{chunk-QOCS7W7R.js → chunk-K2VYABZ3.js} +86 -43
  22. package/dist/chunk-K2VYABZ3.js.map +1 -0
  23. package/dist/chunk-MJBCXW5R.js +248 -0
  24. package/dist/chunk-MJBCXW5R.js.map +1 -0
  25. package/dist/{chunk-MLIS253L.js → chunk-ML4NHUR7.js} +2 -2
  26. package/dist/{chunk-GO5IFOUF.js → chunk-N6V7LQBL.js} +2 -2
  27. package/dist/{chunk-FKUDAIJI.cjs → chunk-O7OUX6NU.cjs} +12 -12
  28. package/dist/chunk-O7OUX6NU.cjs.map +1 -0
  29. package/dist/{chunk-S2PL227Q.js → chunk-PHID6WNG.js} +2 -2
  30. package/dist/{chunk-IQGIT2VX.js → chunk-QJWVMPB6.js} +34 -17
  31. package/dist/chunk-QJWVMPB6.js.map +1 -0
  32. package/dist/{chunk-STM3ORY7.cjs → chunk-QNJLLF4J.cjs} +2 -2
  33. package/dist/chunk-QNJLLF4J.cjs.map +1 -0
  34. package/dist/{chunk-FSDJLAOW.js → chunk-QPJXYJIK.js} +55 -1
  35. package/dist/chunk-QPJXYJIK.js.map +1 -0
  36. package/dist/{chunk-XTFN5WKS.cjs → chunk-R2BUANHQ.cjs} +6 -6
  37. package/dist/chunk-R2BUANHQ.cjs.map +1 -0
  38. package/dist/{chunk-OXLPVQYK.js → chunk-TDQ6XDB3.js} +3 -3
  39. package/dist/{chunk-SFEQYKYJ.js → chunk-WN6OD2CQ.js} +218 -22
  40. package/dist/chunk-WN6OD2CQ.js.map +1 -0
  41. package/dist/{chunk-5KS5PWJR.js → chunk-WY5JAR4O.js} +2 -2
  42. package/dist/{chunk-CEIATRDW.cjs → chunk-WYON5ANU.cjs} +3 -3
  43. package/dist/chunk-WYON5ANU.cjs.map +1 -0
  44. package/dist/{chunk-WDQTFAXY.cjs → chunk-XEPKOC2O.cjs} +240 -44
  45. package/dist/chunk-XEPKOC2O.cjs.map +1 -0
  46. package/dist/{chunk-7KNGSQU7.js → chunk-YZ5HHS6A.js} +2 -2
  47. package/dist/{chunk-P6ZDXTV6.js → chunk-ZF6KHPB7.js} +2 -2
  48. package/dist/chunks-YBFBLJ4G.js +10 -0
  49. package/dist/cli.js +36 -54
  50. package/dist/cli.js.map +1 -1
  51. package/dist/{formula-NARUOXRX.js → formula-7MMFBRGJ.js} +4 -4
  52. package/dist/{formula-WIMV5TUX.cjs → formula-ECNOZT36.cjs} +9 -9
  53. package/dist/formula-ECNOZT36.cjs.map +1 -0
  54. package/dist/{formula-EPKLPDU7.js → formula-SHBXRXOJ.js} +3 -3
  55. package/dist/{image-ocr-3WJ4QH3T.js → image-ocr-P6ECJCT2.js} +8 -8
  56. package/dist/{image-ocr-5BUJQ4TK.js → image-ocr-QCT3A7X5.js} +6 -6
  57. package/dist/{image-ocr-AXWXR6JV.cjs → image-ocr-VUDSP2B4.cjs} +15 -15
  58. package/dist/image-ocr-VUDSP2B4.cjs.map +1 -0
  59. package/dist/index.cjs +768 -710
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.d.cts +4 -0
  62. package/dist/index.d.ts +4 -0
  63. package/dist/index.js +106 -48
  64. package/dist/index.js.map +1 -1
  65. package/dist/mcp.js +38 -43
  66. package/dist/mcp.js.map +1 -1
  67. package/dist/{model-bundle-IMBW7D2Z.js → model-bundle-OUHGCEZY.js} +5 -5
  68. package/dist/{models-SY75IBOE.js → models-6D6LMOTH.js} +5 -5
  69. package/dist/page-range-QHHFTL7X.cjs.map +1 -1
  70. package/dist/{parser-ZQM3664Z.js → parser-CTRB7PKD.js} +257 -46
  71. package/dist/parser-CTRB7PKD.js.map +1 -0
  72. package/dist/{parser-2LU4EVU3.cjs → parser-RQ4PJRTJ.cjs} +411 -200
  73. package/dist/parser-RQ4PJRTJ.cjs.map +1 -0
  74. package/dist/{parser-N6476XAC.js → parser-ZPRQ3SSU.js} +260 -49
  75. package/dist/parser-ZPRQ3SSU.js.map +1 -0
  76. package/dist/pdf-ocr-462ZFSHX.js +15 -0
  77. package/dist/pdf-ocr-L35FQYGP.js +18 -0
  78. package/dist/pdf-ocr-STK5EQFF.cjs +16 -0
  79. package/dist/pdf-ocr-STK5EQFF.cjs.map +1 -0
  80. package/dist/{profile-io-GJPKCYPT.js → profile-io-YZUW6MAN.js} +3 -3
  81. package/dist/{rasterize-UOALJQDS.js → rasterize-OUR2QJXX.js} +3 -3
  82. package/dist/{redact-doc-22SYW3KH.js → redact-doc-4OQKG4SM.js} +11 -11
  83. package/dist/{render-MJ4H3R23.js → render-XNO6PZJO.js} +7 -7
  84. package/dist/seal-CJ7C44JN.js +10 -0
  85. package/dist/{setup-2URYVUEO.js → setup-UU3EIHNI.js} +3 -3
  86. package/dist/visual-QRMRFPUK.js +20 -0
  87. package/dist/{watch-ALXZGTOB.js → watch-SR6Q5SQN.js} +12 -12
  88. package/package.json +2 -2
  89. package/dist/chunk-3IB7LBHC.js +0 -57
  90. package/dist/chunk-3IB7LBHC.js.map +0 -1
  91. package/dist/chunk-62W7QCEX.cjs +0 -57
  92. package/dist/chunk-62W7QCEX.cjs.map +0 -1
  93. package/dist/chunk-CEIATRDW.cjs.map +0 -1
  94. package/dist/chunk-FKUDAIJI.cjs.map +0 -1
  95. package/dist/chunk-FSDJLAOW.js.map +0 -1
  96. package/dist/chunk-IQGIT2VX.js.map +0 -1
  97. package/dist/chunk-J3IF6KGW.js +0 -59
  98. package/dist/chunk-J3IF6KGW.js.map +0 -1
  99. package/dist/chunk-JFLAM3MM.js.map +0 -1
  100. package/dist/chunk-QOCS7W7R.js.map +0 -1
  101. package/dist/chunk-SFEQYKYJ.js.map +0 -1
  102. package/dist/chunk-STM3ORY7.cjs.map +0 -1
  103. package/dist/chunk-TXUKTOG2.js.map +0 -1
  104. package/dist/chunk-WDQTFAXY.cjs.map +0 -1
  105. package/dist/chunk-XTFN5WKS.cjs.map +0 -1
  106. package/dist/chunks-NUNIKS2J.js +0 -10
  107. package/dist/formula-WIMV5TUX.cjs.map +0 -1
  108. package/dist/image-ocr-AXWXR6JV.cjs.map +0 -1
  109. package/dist/parser-2LU4EVU3.cjs.map +0 -1
  110. package/dist/parser-N6476XAC.js.map +0 -1
  111. package/dist/parser-ZQM3664Z.js.map +0 -1
  112. package/dist/pdf-ocr-6DEE23IP.js +0 -15
  113. package/dist/pdf-ocr-GHEJVPX2.cjs +0 -16
  114. package/dist/pdf-ocr-GHEJVPX2.cjs.map +0 -1
  115. package/dist/pdf-ocr-MQTWODVU.js +0 -18
  116. package/dist/seal-XWMRUTI4.js +0 -10
  117. package/dist/visual-USPS4QRC.js +0 -20
  118. /package/dist/{-4G6MA4X6.js.map → -PRAKO6M4.js.map} +0 -0
  119. /package/dist/{chunk-AUWGDP4G.js.map → chunk-2KF5WZCR.js.map} +0 -0
  120. /package/dist/{chunk-UTP2WCHS.js.map → chunk-4GSF2R7T.js.map} +0 -0
  121. /package/dist/{chunk-4VODJKFL.js.map → chunk-6RGGYQQC.js.map} +0 -0
  122. /package/dist/{chunk-DES2LGFZ.js.map → chunk-A55JGNKD.js.map} +0 -0
  123. /package/dist/{chunk-LEIAEWZ7.js.map → chunk-BFT5IM2R.js.map} +0 -0
  124. /package/dist/{chunk-KIOQ4N37.js.map → chunk-BLPR4HRF.js.map} +0 -0
  125. /package/dist/{chunk-JELRWAZC.js.map → chunk-BZG7K44Z.js.map} +0 -0
  126. /package/dist/{chunk-F4NRLLY4.js.map → chunk-EFO6JZY6.js.map} +0 -0
  127. /package/dist/{chunk-MLIS253L.js.map → chunk-ML4NHUR7.js.map} +0 -0
  128. /package/dist/{chunk-GO5IFOUF.js.map → chunk-N6V7LQBL.js.map} +0 -0
  129. /package/dist/{chunk-S2PL227Q.js.map → chunk-PHID6WNG.js.map} +0 -0
  130. /package/dist/{chunk-OXLPVQYK.js.map → chunk-TDQ6XDB3.js.map} +0 -0
  131. /package/dist/{chunk-5KS5PWJR.js.map → chunk-WY5JAR4O.js.map} +0 -0
  132. /package/dist/{chunk-7KNGSQU7.js.map → chunk-YZ5HHS6A.js.map} +0 -0
  133. /package/dist/{chunk-P6ZDXTV6.js.map → chunk-ZF6KHPB7.js.map} +0 -0
  134. /package/dist/{chunks-NUNIKS2J.js.map → chunks-YBFBLJ4G.js.map} +0 -0
  135. /package/dist/{formula-NARUOXRX.js.map → formula-7MMFBRGJ.js.map} +0 -0
  136. /package/dist/{formula-EPKLPDU7.js.map → formula-SHBXRXOJ.js.map} +0 -0
  137. /package/dist/{image-ocr-3WJ4QH3T.js.map → image-ocr-P6ECJCT2.js.map} +0 -0
  138. /package/dist/{image-ocr-5BUJQ4TK.js.map → image-ocr-QCT3A7X5.js.map} +0 -0
  139. /package/dist/{model-bundle-IMBW7D2Z.js.map → model-bundle-OUHGCEZY.js.map} +0 -0
  140. /package/dist/{models-SY75IBOE.js.map → models-6D6LMOTH.js.map} +0 -0
  141. /package/dist/{pdf-ocr-6DEE23IP.js.map → pdf-ocr-462ZFSHX.js.map} +0 -0
  142. /package/dist/{pdf-ocr-MQTWODVU.js.map → pdf-ocr-L35FQYGP.js.map} +0 -0
  143. /package/dist/{profile-io-GJPKCYPT.js.map → profile-io-YZUW6MAN.js.map} +0 -0
  144. /package/dist/{rasterize-UOALJQDS.js.map → rasterize-OUR2QJXX.js.map} +0 -0
  145. /package/dist/{redact-doc-22SYW3KH.js.map → redact-doc-4OQKG4SM.js.map} +0 -0
  146. /package/dist/{render-MJ4H3R23.js.map → render-XNO6PZJO.js.map} +0 -0
  147. /package/dist/{seal-XWMRUTI4.js.map → seal-CJ7C44JN.js.map} +0 -0
  148. /package/dist/{setup-2URYVUEO.js.map → setup-UU3EIHNI.js.map} +0 -0
  149. /package/dist/{visual-USPS4QRC.js.map → visual-QRMRFPUK.js.map} +0 -0
  150. /package/dist/{watch-ALXZGTOB.js.map → watch-SR6Q5SQN.js.map} +0 -0
@@ -6,7 +6,12 @@ import {
6
6
  EMPTY_PARTS,
7
7
  FILLER_CELLS,
8
8
  IMAGE_CELLS,
9
+ NO_EDGES,
10
+ PART_COLXS,
11
+ ROW_RULES,
9
12
  TABLE_COLXS,
13
+ TABLE_ROWYS,
14
+ TABLE_TAIL,
10
15
  TOC_BLOCKS,
11
16
  WrapLexicon,
12
17
  collapseEvenSpacing,
@@ -24,6 +29,7 @@ import {
24
29
  extractLines,
25
30
  extractPageBlocksWithLines,
26
31
  filterHiddenText,
32
+ joinCellEdges,
27
33
  joinPageBreakWraps,
28
34
  latinSoftWrap,
29
35
  mergeStackedHeadingLines,
@@ -33,21 +39,24 @@ import {
33
39
  startsNewItem,
34
40
  trimTrailingEmptyTableCols,
35
41
  wrapJoiner
36
- } from "./chunk-SFEQYKYJ.js";
42
+ } from "./chunk-WN6OD2CQ.js";
37
43
  import {
38
44
  ocrModelsCached
39
- } from "./chunk-DES2LGFZ.js";
40
- import "./chunk-KIOQ4N37.js";
41
- import "./chunk-JELRWAZC.js";
45
+ } from "./chunk-A55JGNKD.js";
46
+ import "./chunk-BLPR4HRF.js";
47
+ import "./chunk-BZG7K44Z.js";
42
48
  import {
43
49
  blocksToPages
44
- } from "./chunk-AUWGDP4G.js";
50
+ } from "./chunk-2KF5WZCR.js";
45
51
  import {
46
52
  encodePng
47
53
  } from "./chunk-7FCNOKOR.js";
48
54
  import {
49
- stripScriptTags
50
- } from "./chunk-J3IF6KGW.js";
55
+ CELL_EDGES,
56
+ CONTENT_CELLS,
57
+ stripScriptTags,
58
+ unframeLayoutTables
59
+ } from "./chunk-5CDUL6PH.js";
51
60
  import {
52
61
  hasRequestedPagesAfter,
53
62
  parsePageRange
@@ -56,11 +65,11 @@ import {
56
65
  WINGDINGS,
57
66
  blocksToMarkdown,
58
67
  escapeLiteralDollar
59
- } from "./chunk-LEIAEWZ7.js";
68
+ } from "./chunk-BFT5IM2R.js";
60
69
  import {
61
70
  KordocError,
62
71
  sanitizeHref
63
- } from "./chunk-P6ZDXTV6.js";
72
+ } from "./chunk-ZF6KHPB7.js";
64
73
 
65
74
  // src/pdf/ocr-region-merge.ts
66
75
  function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
@@ -681,6 +690,7 @@ function splitContactTables(blocks) {
681
690
 
682
691
  // src/pdf/table-parts.ts
683
692
  var PART_COL_TOL = 1;
693
+ var PART_COL_SNAP = 0.3;
684
694
  function anchorsOf(table) {
685
695
  const out = [];
686
696
  const covered = /* @__PURE__ */ new Set();
@@ -698,9 +708,22 @@ function anchorsOf(table) {
698
708
  return out;
699
709
  }
700
710
  function unionCoords(a, b) {
711
+ const drift = a.length === b.length && a.every((x, i) => Math.abs(x - b[i]) <= PART_COL_TOL);
712
+ const tol = drift ? PART_COL_TOL : PART_COL_SNAP;
713
+ const pairs = [];
714
+ for (const v of b) for (const x of a) if (Math.abs(x - v) <= tol) pairs.push([Math.abs(x - v), v, x]);
715
+ pairs.sort((p, q) => p[0] - q[0]);
716
+ const map = /* @__PURE__ */ new Map(), taken = /* @__PURE__ */ new Set();
717
+ for (const [, v, x] of pairs) if (!map.has(v) && !taken.has(x)) {
718
+ map.set(v, x);
719
+ taken.add(x);
720
+ }
701
721
  const out = [...a];
702
- for (const v of b) if (!a.some((x) => Math.abs(x - v) <= PART_COL_TOL)) out.push(v);
703
- return out.sort((x, y) => x - y);
722
+ for (const v of b) if (!map.has(v)) {
723
+ map.set(v, v);
724
+ out.push(v);
725
+ }
726
+ return { U: out.sort((x, y) => x - y), map };
704
727
  }
705
728
  var indexOf = (coords, x) => {
706
729
  let best = -1, bestD = Infinity;
@@ -717,18 +740,31 @@ var rowText = (anchors, r) => anchors.filter((a) => a.r === r).map((a) => a.cell
717
740
  var hasText = (t) => t.replace(/\|/g, "") !== "";
718
741
  function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom, lex) {
719
742
  if (pcx.length !== prev.cols + 1 || ccx.length !== curr.cols + 1) return null;
720
- const U = unionCoords(pcx, ccx);
743
+ const { U, map } = unionCoords(pcx, ccx);
744
+ const cxU = ccx.map((v) => map.get(v) ?? v);
721
745
  const cols = U.length - 1;
722
746
  if (cols < 1) return null;
723
747
  const pa = anchorsOf(prev), ca = anchorsOf(curr);
724
- let skip = 0;
748
+ let skip = 0, head = 0;
725
749
  while (skip < Math.min(3, curr.rows - 1, prev.rows) && rowText(ca, skip) !== "" && rowText(ca, skip) === rowText(pa, skip)) skip++;
726
750
  for (let h = 1; h <= 2 && !skip; h++) {
751
+ head = h;
727
752
  while (skip < Math.min(3, curr.rows - 1, prev.rows - h) && hasText(rowText(ca, skip)) && rowText(ca, skip) === rowText(pa, h + skip)) skip++;
728
753
  }
754
+ const sameSpans = (u, d) => {
755
+ if (u.length !== d.length || !u.length) return false;
756
+ const shift = pcx[u[u.length - 1].c + u[u.length - 1].cs] - ccx[d[d.length - 1].c + d[d.length - 1].cs];
757
+ return u.every((a, n) => Math.abs(pcx[a.c] - ccx[d[n].c] - shift) <= CONTINUATION_COL_TOL && Math.abs(pcx[a.c + a.cs] - ccx[d[n].c + d[n].cs] - shift) <= CONTINUATION_COL_TOL);
758
+ };
759
+ for (let k = 0; k < skip; k++) {
760
+ if (sameSpans(pa.filter((a) => a.r === head + k), ca.filter((a) => a.r === k))) continue;
761
+ if (hasText(rowText(ca, k))) return null;
762
+ skip = k;
763
+ }
729
764
  const rows = prev.rows + curr.rows - skip;
730
765
  const grid = Array.from({ length: rows }, () => Array.from({ length: cols }, () => ({ text: "", colSpan: 1, rowSpan: 1 })));
731
766
  const owner = Array.from({ length: rows }, () => new Array(cols).fill(null));
767
+ let edged = false;
732
768
  const place = (a, x, rowOff, shift = 0) => {
733
769
  const c1 = indexOf(U, x[a.c]), c2 = indexOf(U, x[a.c + a.cs]);
734
770
  if (c1 < 0 || c2 <= c1) return false;
@@ -741,12 +777,17 @@ function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom, lex) {
741
777
  const lines = CELL_LINES.get(a.cell);
742
778
  if (lines) CELL_LINES.set(grid[r][c1], shift ? lines.map((l) => ({ ...l, l: l.l + shift, r: l.r + shift })) : lines);
743
779
  if (IMAGE_CELLS.has(a.cell)) IMAGE_CELLS.add(grid[r][c1]);
780
+ const edges = CELL_EDGES.get(a.cell);
781
+ if (edges) {
782
+ CELL_EDGES.set(grid[r][c1], edges);
783
+ edged = true;
784
+ }
744
785
  return true;
745
786
  };
746
787
  for (const a of pa) if (!FILLER_CELLS.has(a.cell) && !place(a, pcx, 0)) return null;
747
788
  for (const a of ca) {
748
789
  if (a.r < skip || FILLER_CELLS.has(a.cell)) continue;
749
- if (!place(a, ccx, prev.rows - skip, dx)) return null;
790
+ if (!place(a, cxU, prev.rows - skip, dx)) return null;
750
791
  }
751
792
  const first = prev.rows;
752
793
  for (let c = 0; c < cols; c++) {
@@ -770,12 +811,32 @@ function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom, lex) {
770
811
  for (let rr = above.r; rr < above.r + newRs; rr++) for (let dc = above.c; dc < above.c + above.cs; dc++) owner[rr][dc] = grown;
771
812
  }
772
813
  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]);
814
+ if (edged) {
815
+ for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) if (owner[r][c] === null) CELL_EDGES.set(grid[r][c], NO_EDGES);
816
+ }
817
+ for (let c = 0; c < cols && U[c + 1] <= pcx[0] + PART_COL_TOL; c++) {
818
+ let r = prev.rows;
819
+ while (r < rows && owner[r][c] === null) r++;
820
+ const through = { r: 0, c, rs: r, cs: 1, cell: grid[0][c] };
821
+ for (let rr = 0; rr < r; rr++) owner[rr][c] = through;
822
+ }
773
823
  const table = { rows, cols, cells: grid, hasHeader: prev.hasHeader, ...prev.caption ? { caption: prev.caption } : {} };
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);
824
+ const pr = ROW_RULES.get(prev), cr = ROW_RULES.get(curr);
825
+ const shifted = dx !== 0;
826
+ const cut = {
827
+ open: !!pr && !!cr && !pr.bottom && !cr.top && pr.innerOpen + cr.innerOpen === 0 && pr.innerRuled + cr.innerRuled > 0,
828
+ ruled: !!pr && !!cr && pr.bottom && cr.top,
829
+ list: !shifted ? "any" : skip > 0 && ca.filter((a) => a.r < skip && a.cell.text.trim()).length < 2 ? "none" : "multi"
830
+ };
831
+ let split = rows > prev.rows && mergeSplitRow(table, owner, prev.rows, U, false, cut);
832
+ if (rows > prev.rows && !split && prevBottom !== void 0 && mergeStraddlingCells(table, owner, prev.rows, prevBottom, lex, U)) split = mergeSplitRow(table, owner, prev.rows, U, true, { ...cut, open: false });
833
+ if (pr && cr) {
834
+ const cutRuled = pr.bottom || cr.top;
835
+ ROW_RULES.set(table, { top: pr.top, bottom: cr.bottom, innerRuled: pr.innerRuled + cr.innerRuled + (!split && cutRuled ? 1 : 0), innerOpen: pr.innerOpen + cr.innerOpen + (!split && !cutRuled ? 1 : 0) });
836
+ }
776
837
  return { table, colXs: U, split, header: ca.filter((a) => a.r < skip && a.cell.text.trim()).length >= 2 };
777
838
  }
778
- function mergeStraddlingCells(table, owner, first, prevBottom, lex) {
839
+ function mergeStraddlingCells(table, owner, first, prevBottom, lex, colXs) {
779
840
  const last = first - 1;
780
841
  const straddles = owner[first].some((o, c) => o !== null && o === owner[last][c]);
781
842
  let firstNew = table.cols;
@@ -799,6 +860,19 @@ function mergeStraddlingCells(table, owner, first, prevBottom, lex) {
799
860
  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
861
  if (/^[가-힣]{2,}$/.test(tail) && /^[가-힣]{2,}/.test(head) && lex.evidence2(tail, head) === "") midWord = true;
801
862
  }
863
+ const crossed = /* @__PURE__ */ new Set();
864
+ const shape = (u, d) => `${u.r}:${u.rs}:${d.rs}`;
865
+ if (straddles && colXs) for (let c = 0; c < table.cols; ) {
866
+ const u = owner[last][c], d = owner[first][c];
867
+ if (!u) {
868
+ c++;
869
+ continue;
870
+ }
871
+ c = u.c + u.cs;
872
+ if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs || u.rs < 2) continue;
873
+ const a = table.cells[u.r][u.c], b = table.cells[first][d.c];
874
+ if (hasContent(a) && hasContent(b) && continuesAcross(a, b, colXs[u.c], colXs[u.c + u.cs])) crossed.add(shape(u, d));
875
+ }
802
876
  let merged = false;
803
877
  for (let c = 0; c < table.cols; ) {
804
878
  const u = owner[last][c], d = owner[first][c];
@@ -809,13 +883,16 @@ function mergeStraddlingCells(table, owner, first, prevBottom, lex) {
809
883
  c = u.c + u.cs;
810
884
  if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
811
885
  const a = table.cells[u.r][u.c], b = table.cells[first][d.c];
812
- if (!(u.rs >= 2 && u.c + u.cs <= firstNew && hasContent(a) && !hasContent(b))) {
886
+ if (!crossed.has(shape(u, d)) && !(u.rs >= 2 && u.c + u.cs <= firstNew && hasContent(a) && !hasContent(b))) {
813
887
  if (!straddles && !midWord) continue;
814
888
  if (u.r >= last && d.rs < 2) continue;
815
889
  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;
890
+ if (!U?.length || !hasContent(b)) continue;
891
+ if (!(straddles && filledToBottom(U, prevBottom) && clauseContinues(a, b))) {
892
+ if (U.length > STRADDLE_MAX_LINES) continue;
893
+ const lu = U[U.length - 1];
894
+ if (!midWord && lu.y - prevBottom > (u.r >= last ? STRADDLE_BOTTOM_ONE_ROW : STRADDLE_BOTTOM) * (lu.h || 10)) continue;
895
+ }
819
896
  }
820
897
  appendCell(a, b);
821
898
  a.rowSpan = first + d.rs - u.r;
@@ -826,6 +903,11 @@ function mergeStraddlingCells(table, owner, first, prevBottom, lex) {
826
903
  }
827
904
  return merged;
828
905
  }
906
+ function filledToBottom(U, bottom) {
907
+ if (U.length < 2) return false;
908
+ const lu = U[U.length - 1];
909
+ return lu.y - bottom < (U[0].y - lu.y) / (U.length - 1) + FILL_SLACK * (lu.h || 10);
910
+ }
829
911
  var FULL_LINE_TOL = 1;
830
912
  var FULL_LINE_MIN_FRAC = 0.5;
831
913
  var FULL_LINE_EDGE_MIN = 12;
@@ -834,6 +916,7 @@ var SHORT_LINE_GAP = 1.5;
834
916
  var STRADDLE_MAX_LINES = 3;
835
917
  var STRADDLE_BOTTOM = 1.2;
836
918
  var STRADDLE_BOTTOM_ONE_ROW = 0.55;
919
+ var FILL_SLACK = 0.5;
837
920
  var CARRIED_MIN_COL_W = 4;
838
921
  var LABEL_ROOM = 1.5;
839
922
  var HANGING_MIN = 0.5;
@@ -855,10 +938,16 @@ function continuesAcross(u, d, x1, x2) {
855
938
  maxR = Math.max(maxR, x2 - (minL - x1));
856
939
  if (maxR - last.r > FULL_LINE_TOL * fs) return false;
857
940
  if (U.length === 1 && x2 - last.r > Math.max(FULL_LINE_EDGE_MIN, SINGLE_LINE_WORD_GAP * fs)) return false;
858
- if (last.r - last.l < FULL_LINE_MIN_FRAC * (x2 - x1)) return false;
859
- const leftAligned = (l) => l.l - minL <= fs && maxR - l.r > SHORT_LINE_GAP * fs;
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;
861
- return U.some(leftAligned) || D.some(leftAligned) || hanging;
941
+ const indented = last.l - minL >= HANGING_MIN * fs;
942
+ if (last.r - last.l < FULL_LINE_MIN_FRAC * (indented ? x2 - last.l : x2 - x1)) return false;
943
+ const newItem = startsNewItem(u.text, d.text);
944
+ const all = D.length ? U.concat(D) : U;
945
+ const leftAligned = (l) => maxR - l.r > SHORT_LINE_GAP * fs && (l.l - minL <= fs || !newItem && all.some((o) => o !== l && Math.abs(o.l - l.l) <= HANGING_TOL && Math.abs(o.r - l.r) >= HANGING_MIN * fs));
946
+ const hanging = U.length >= 2 && U.every((l) => maxR - l.r <= FULL_LINE_TOL * fs) && indented && Math.abs(D[0].l - last.l) <= HANGING_TOL;
947
+ const hangingHead = !indented && D.length >= 2 && D[0].l - last.l >= HANGING_MIN * fs && maxR - D[0].r <= FULL_LINE_TOL * fs && D.every((l) => Math.abs(l.l - D[0].l) <= HANGING_TOL);
948
+ const d0 = D[0];
949
+ const hangStart = U.length === 1 && !newItem && d0.l - last.l >= HANGING_MIN * fs && D.every((l) => l.l >= d0.l - HANGING_TOL) && (Math.abs(d0.r - last.r) <= HANGING_TOL && d0.r - d0.l >= FULL_LINE_MIN_FRAC * (x2 - x1) || last.r - d0.r > SHORT_LINE_GAP * fs && Math.abs(d0.l + d0.r - last.l - last.r) / 2 >= HANGING_MIN * fs);
950
+ return U.some(leftAligned) || D.some(leftAligned) || hanging || hangingHead || hangStart;
862
951
  }
863
952
  var OUTLINE_HEAD = /^[□■]\s*\S/;
864
953
  var OUTLINE_ITEM = /^[ㅇ○◦\-‐–·․‧※*]\s*\S/;
@@ -867,14 +956,19 @@ function outlineContinues(u, d) {
867
956
  const D = d.text.split("\n").map((l) => l.trim()).filter(Boolean);
868
957
  return U.length >= 2 && D.length >= 1 && U.some((l) => OUTLINE_HEAD.test(l)) && OUTLINE_ITEM.test(D[0]);
869
958
  }
870
- function lineEnded(c, x1, x2, next = "") {
959
+ function lineEnded(c, x1, x2, next) {
871
960
  const L = CELL_LINES.get(c);
872
961
  if (!L || L.length !== 1) return false;
873
962
  const l = L[0], h = l.h || 10;
874
- const word = next.trim().split(/\s+/)[0] ?? "";
963
+ const d0 = next ? CELL_LINES.get(next)?.[0] : void 0;
964
+ if (d0 && d0.l - l.l >= HANGING_MIN * h) return false;
965
+ return x2 - l.r - (l.l - x1) >= Math.max(LABEL_ROOM, firstWordUnits(next?.text ?? "")) * h;
966
+ }
967
+ function firstWordUnits(text) {
968
+ const word = text.trim().replace(/^([(\[「『<〈])\s+/, "$1").split(/\s+/)[0] ?? "";
875
969
  let units = 0;
876
970
  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;
971
+ return units;
878
972
  }
879
973
  function appendCell(a, b) {
880
974
  if (a.blocks?.length || b.blocks?.length) {
@@ -882,6 +976,7 @@ function appendCell(a, b) {
882
976
  a.blocks = [...asBlocks(a), ...asBlocks(b)];
883
977
  }
884
978
  if (b.text.trim()) a.text = a.text.trim() ? a.text + "\n" + b.text : b.text;
979
+ joinCellEdges(a, b);
885
980
  }
886
981
  var hasContent = (cell) => !!cell.text.trim() || !!cell.blocks?.length || IMAGE_CELLS.has(cell);
887
982
  var CLAUSE_OPEN_ENDING = /(?:하는|되는|하고|하며|하여|되어|되고|되며|이며|으며|어야|아야|여야)$/;
@@ -895,11 +990,42 @@ function clauseContinues(u, d) {
895
990
  const last = tail[tail.length - 1], before = tail[tail.length - 2];
896
991
  return last === "\uC744" && batchim(before) || last === "\uB97C" && !batchim(before) || CLAUSE_OPEN_ENDING.test(tail);
897
992
  }
993
+ function wordOverflows(u, d, x1, x2) {
994
+ const U = CELL_LINES.get(u);
995
+ if (!U?.length || startsNewItem(u.text, d.text)) return false;
996
+ const last = U[U.length - 1], units = firstWordUnits(d.text);
997
+ return units > 0 && last.r - last.l + units * (last.h || 10) > x2 - x1;
998
+ }
999
+ var KO_ORDER = "\uAC00\uB098\uB2E4\uB77C\uB9C8\uBC14\uC0AC\uC544\uC790\uCC28\uCE74\uD0C0\uD30C\uD558";
1000
+ function itemMark(line) {
1001
+ let m = /^(\d{1,2})([.)])(?!\d)/.exec(line);
1002
+ if (m) return { style: "1" + m[2], n: +m[1] };
1003
+ if (m = /^\((\d{1,2})\)/.exec(line)) return { style: "(1)", n: +m[1] };
1004
+ if ((m = /^([가-하])([.)])/.exec(line)) && KO_ORDER.includes(m[1])) return { style: "\uAC00" + m[2], n: KO_ORDER.indexOf(m[1]) };
1005
+ if ((m = /^\(([가-하])\)/.exec(line)) && KO_ORDER.includes(m[1])) return { style: "(\uAC00)", n: KO_ORDER.indexOf(m[1]) };
1006
+ if (m = /^[①-⑳]/.exec(line)) return { style: "\u2460", n: m[0].charCodeAt(0) };
1007
+ if (m = /^([A-Z])\.\s/.exec(line)) return { style: "A.", n: m[1].charCodeAt(0) };
1008
+ return null;
1009
+ }
1010
+ function listContinues(u, d, multi = false) {
1011
+ const head = itemMark(d.text.trim());
1012
+ if (!head) return false;
1013
+ const marks = u.text.split("\n").map((l) => itemMark(l.trim()));
1014
+ let last = -1, count = 0;
1015
+ marks.forEach((m, i) => {
1016
+ if (m?.style === head.style) {
1017
+ last = i;
1018
+ count++;
1019
+ }
1020
+ });
1021
+ return last >= 0 && marks[last].n + 1 === head.n && (count >= 2 || !multi && last > 0);
1022
+ }
898
1023
  function outlineOnly(pairs, cell) {
899
1024
  const filled = pairs.filter(([, d]) => hasContent(d.cell));
900
1025
  return filled.length === 1 && outlineContinues(cell(filled[0][0]), cell(filled[0][1]));
901
1026
  }
902
- function mergeSplitRow(table, owner, first, colXs, textOnly = false) {
1027
+ var NO_CUT = { open: false, ruled: false, list: "any" };
1028
+ function mergeSplitRow(table, owner, first, colXs, textOnly = false, cut = NO_CUT) {
903
1029
  const last = first - 1;
904
1030
  const pairs = [];
905
1031
  let carried = false;
@@ -912,19 +1038,30 @@ function mergeSplitRow(table, owner, first, colXs, textOnly = false) {
912
1038
  }
913
1039
  if (!a || !b) return false;
914
1040
  if (a !== b) {
915
- if (a.c !== b.c || a.cs !== b.cs || a.r + a.rs - 1 !== last || b.r !== first || b.rs !== 1) return false;
1041
+ if (a.c !== b.c || a.cs !== b.cs || a.r + a.rs - 1 !== last || b.r !== first) return false;
1042
+ if (b.rs > 1 && (a.rs > 1 || !hasContent(a.cell))) return false;
916
1043
  pairs.push([a, b]);
917
1044
  } else if (a.r === last && a.rs === 2) carried = true;
918
1045
  c = a.c + a.cs;
919
1046
  }
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));
1047
+ const newCell = pairs.some(([u, d]) => !hasContent(u.cell) && hasContent(d.cell));
921
1048
  const cell = (a) => table.cells[a.r][a.c];
1049
+ const contentPairs = pairs.filter(([u, d]) => hasContent(u.cell) && hasContent(d.cell));
1050
+ const carriedSplit = !textOnly && carried && !newCell && (contentPairs.length <= 1 || contentPairs.every(([, d]) => d.rs > 1) || !cut.ruled && contentPairs.some(([u, d]) => wordOverflows(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs])));
922
1051
  if (!carriedSplit) {
923
1052
  const norm = (c) => c.text.replace(/\s+/g, "");
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;
1053
+ 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)))) return false;
1054
+ const flows = ([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs]) || clauseContinues(cell(u), cell(d));
1055
+ if (!(cut.open && !newCell)) {
1056
+ if (pairs.some((p) => p[1].rs > 1 && !flows(p))) return false;
1057
+ const one = pairs.filter(([, d]) => d.rs === 1);
1058
+ if (!outlineOnly(pairs, cell) && !one.some(flows) && (cut.list === "none" || !one.some(([u, d]) => listContinues(cell(u), cell(d), cut.list === "multi")))) return false;
1059
+ }
1060
+ }
1061
+ for (const [u, d] of pairs) {
1062
+ appendCell(table.cells[u.r][u.c], table.cells[d.r][d.c]);
1063
+ if (d.rs > 1) table.cells[u.r][u.c].rowSpan = u.rs + d.rs;
926
1064
  }
927
- for (const [u, d] of pairs) appendCell(table.cells[u.r][u.c], table.cells[d.r][d.c]);
928
1065
  for (let r = 0; r < first; r++) for (let c = 0; c < table.cols; c++) {
929
1066
  const o = owner[r][c];
930
1067
  if (o && o.r === r && o.c === c && r + table.cells[r][c].rowSpan > first) table.cells[r][c].rowSpan--;
@@ -972,11 +1109,14 @@ function sameHeadShape(a, b) {
972
1109
  function mergeCrossPageTables(blocks, pageHeights, lex) {
973
1110
  mergeColumnFlow(blocks, pageHeights, lex);
974
1111
  for (let i = blocks.length - 2; i >= 0; i--) {
975
- const prev = blocks[i];
976
- if (prev.type !== "table" || !prev.table || !prev.bbox || !prev.pageNumber) continue;
1112
+ const tail = tailOf(blocks[i]);
1113
+ if (tail.type !== "table" || !tail.table || !tail.bbox || !tail.pageNumber) continue;
977
1114
  let j = i + 1;
978
- while (j < blocks.length && (blocks[j].type !== "table" || insideTable(blocks[j], prev) || leftColumnOf(blocks[j], prev)) && (blocks[j].pageNumber ?? 0) <= prev.pageNumber + 1) j++;
1115
+ const skip = (b) => b.type !== "table" || [blocks[i], tail].some((t) => insideTable(b, t) || leftColumnOf(b, t));
1116
+ while (j < blocks.length && skip(blocks[j]) && (blocks[j].pageNumber ?? 0) <= tail.pageNumber + 1) j++;
979
1117
  const curr = blocks[j];
1118
+ const prev = tail !== blocks[i] && curr?.pageNumber === tail.pageNumber ? blocks[i] : tail;
1119
+ if (!prev.table || !prev.bbox || !prev.pageNumber) continue;
980
1120
  if (!curr || curr.type !== "table" || !curr.table || !curr.bbox || curr.pageNumber !== prev.pageNumber + 1) continue;
981
1121
  if (startsWithUnitRow(prev.table) && startsWithUnitRow(curr.table)) continue;
982
1122
  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;
@@ -1059,24 +1199,36 @@ function joinClipParts(prev, curr, pageHeights, lex) {
1059
1199
  if (!CLIP_TABLES.has(pt) || !CLIP_TABLES.has(ct)) return null;
1060
1200
  const px = TABLE_COLXS.get(pt), cx = TABLE_COLXS.get(ct);
1061
1201
  if (!px || !cx) return null;
1062
- let xs = cx, shifted = false, dx = 0, foreign = false;
1202
+ let xs = cx, shifted = false, dx = 0, foreign = false, within = false;
1063
1203
  if (!shiftedSame(px, cx, false)) {
1064
1204
  if (!pageHeights?.get(prev.pageNumber) || !pageHeights?.get(curr.pageNumber)) return null;
1065
1205
  dx = px[px.length - 1] - cx[cx.length - 1];
1066
- if (Math.abs(dx) > CONTINUATION_COL_TOL) {
1206
+ within = Math.abs(dx) > CONTINUATION_COL_TOL && cx.length >= 3 && cx.every((x) => px.some((p) => Math.abs(p - x) <= CONTINUATION_COL_TOL));
1207
+ if (Math.abs(dx) > CONTINUATION_COL_TOL && !within) {
1067
1208
  xs = cx.map((x) => x + dx);
1068
1209
  shifted = true;
1069
1210
  } else dx = 0;
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] ?? []);
1211
+ if (!px.some((x) => Math.abs(x - xs[0]) <= CONTINUATION_COL_TOL) && !prevLacksLeftCols(prev, px, xs, pageHeights)) return null;
1212
+ const unrelated = (b) => {
1213
+ const inner = b.slice(1, -1).map((x) => x + dx);
1214
+ return inner.length > 0 && !inner.some((x) => px.some((p) => Math.abs(p - x) <= CONTINUATION_COL_TOL));
1215
+ };
1216
+ foreign = unrelated(cx) && unrelated(PART_COLXS.get(ct) ?? cx) && (headingRow(ct.cells[0] ?? []) || px.length > FOREIGN_FIRST_ROW_CELLS && anchorsOf(ct).filter((a) => a.r === 0).length >= FOREIGN_FIRST_ROW_CELLS);
1073
1217
  }
1074
1218
  const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y, lex);
1075
- if (!res || (shifted || foreign) && !res.split && !res.header) return null;
1219
+ if (!res || (shifted || foreign || within) && !res.split && !res.header) return null;
1076
1220
  TABLE_COLXS.set(res.table, res.colXs);
1221
+ const ys = TABLE_ROWYS.get(pt);
1222
+ if (ys) TABLE_ROWYS.set(res.table, ys);
1223
+ PART_COLXS.set(res.table, PART_COLXS.get(pt) ?? px);
1077
1224
  CLIP_TABLES.add(res.table);
1078
1225
  return res.table;
1079
1226
  }
1227
+ function prevLacksLeftCols(prev, px, xs, pageHeights) {
1228
+ const ph = pageHeights?.get(prev.pageNumber);
1229
+ if (!ph || prev.bbox.y + prev.bbox.height < ph * (1 - PAGE_EDGE_BAND)) return false;
1230
+ return xs[0] < px[0] && xs.slice(1, -1).some((x) => Math.abs(x - px[0]) <= CONTINUATION_COL_TOL);
1231
+ }
1080
1232
  function headingRow(row) {
1081
1233
  const heads = row.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
1082
1234
  if (heads.length === 1) return heads[0].length <= 8 || /^[①-⑳❶-❿]/.test(heads[0]);
@@ -1085,13 +1237,36 @@ function headingRow(row) {
1085
1237
  var ANNEX_HEAD_RE = /^\s*[<\[(【]?\s*(?:붙\s*임|참\s*고|별\s*첨|별\s*지|별\s*표|첨\s*부|부\s*록)(?:\s*\d|\s*$|\s*[>\])】])|^\s*■/;
1086
1238
  function looksContinued(prev, curr, pageHeights) {
1087
1239
  const ph = pageHeights?.get(prev.pageNumber), ch = pageHeights?.get(curr.pageNumber);
1088
- if (ph && ch && (prev.bbox.y > ph * PAGE_EDGE_BAND || curr.bbox.y + curr.bbox.height < ch * (1 - PAGE_EDGE_BAND))) return false;
1240
+ if (ph && ch && (prev.bbox.y > ph * PAGE_EDGE_BAND && !pushedLead(prev, curr) || curr.bbox.y + curr.bbox.height < ch * (1 - PAGE_EDGE_BAND))) return false;
1089
1241
  const firstRow = curr.table.cells[0] ?? [];
1090
1242
  const firstText = firstRow.find((c) => c.text.trim())?.text ?? "";
1091
1243
  if (!ANNEX_HEAD_RE.test(firstText)) return true;
1092
1244
  const filled = firstRow.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
1093
1245
  return filled.length >= 2 && filled.every((t) => t === filled[0]);
1094
1246
  }
1247
+ function pushedLead(prev, curr) {
1248
+ if (!CLIP_TABLES.has(prev.table) || !CLIP_TABLES.has(curr.table)) return false;
1249
+ const lead = leadRows(curr.table);
1250
+ return lead.image && lead.height > prev.bbox.y;
1251
+ }
1252
+ function leadRows(t) {
1253
+ const ys = TABLE_ROWYS.get(t);
1254
+ if (!ys || ys.length < 2) return { height: 0, image: false };
1255
+ const anchors = anchorsOf(t);
1256
+ let end = 1, image = false;
1257
+ for (let r = 0; r < end; r++) {
1258
+ for (const a of anchors) {
1259
+ if (a.r !== r) continue;
1260
+ end = Math.max(end, r + a.rs);
1261
+ if (IMAGE_CELLS.has(a.cell)) image = true;
1262
+ }
1263
+ }
1264
+ return { height: ys[0] - ys[Math.min(end, ys.length - 1)], image };
1265
+ }
1266
+ function tailOf(b) {
1267
+ const t = b.table && TABLE_TAIL.get(b.table);
1268
+ return t && b.bbox ? { ...b, pageNumber: t.page, bbox: { ...b.bbox, page: t.page, y: t.y, height: t.height } } : b;
1269
+ }
1095
1270
  function firstRowSig(t) {
1096
1271
  const x = TABLE_COLXS.get(t);
1097
1272
  if (!x || x.length !== t.cols + 1) return null;
@@ -1142,14 +1317,14 @@ function chainHead(blocks, i, pageHeights) {
1142
1317
  break;
1143
1318
  }
1144
1319
  }
1145
- const pb = blocks[p];
1320
+ const pb = tailOf(blocks[p]);
1146
1321
  if (pb.pageNumber !== (cur.pageNumber ?? 0) - 1) break;
1147
1322
  if (!blocks.slice(p + 1, k).every((b) => besideOwn(b, pb, cur) || insideTable(b, pb))) break;
1148
1323
  if (!looksContinued(pb, cur, pageHeights)) break;
1149
1324
  const px = TABLE_COLXS.get(pb.table), cx = TABLE_COLXS.get(cur.table);
1150
1325
  if (!px || !cx) break;
1151
1326
  const dx = px[px.length - 1] - cx[cx.length - 1];
1152
- if (!shiftedSame(px, cx) && !px.some((x) => Math.abs(x - (cx[0] + dx)) <= CONTINUATION_COL_TOL)) break;
1327
+ if (!shiftedSame(px, cx) && !px.some((x) => Math.abs(x - (cx[0] + dx)) <= CONTINUATION_COL_TOL) && !prevLacksLeftCols(pb, px, cx, pageHeights)) break;
1153
1328
  k = p;
1154
1329
  }
1155
1330
  return k;
@@ -1163,6 +1338,7 @@ function rowTextsEqual(a, b) {
1163
1338
  return a.some((c) => c.text.trim() !== "");
1164
1339
  }
1165
1340
  var CONTINUATION_COL_TOL = 2;
1341
+ var FOREIGN_FIRST_ROW_CELLS = 3;
1166
1342
  function shiftedSame(px, cx, allowShift = true) {
1167
1343
  if (px.length !== cx.length) return false;
1168
1344
  const dx = allowShift ? px[px.length - 1] - cx[cx.length - 1] : 0;
@@ -1207,6 +1383,10 @@ function mergeContinuedCells(blocks, pageHeights) {
1207
1383
  const at = cell.blocks || add.blocks ? cellBlocks(cell, prev.pageNumber).length : -1;
1208
1384
  if (cell.blocks || add.blocks) cell.blocks = [...cellBlocks(cell, prev.pageNumber), ...cellBlocks(add, part.pageNumber)];
1209
1385
  cell.text = [cell.text, add.text].filter((s) => s.trim()).join("\n");
1386
+ joinCellEdges(cell, add);
1387
+ const lines = CELL_LINES.get(add);
1388
+ if (lines?.length) CELL_LINES.set(cell, [...CELL_LINES.get(cell) ?? [], ...lines]);
1389
+ if (part.pageNumber && part.bbox) TABLE_TAIL.set(prev.table, TABLE_TAIL.get(part.table) ?? { page: part.pageNumber, y: part.bbox.y, height: part.bbox.height });
1210
1390
  if (cell.text.trim() || cell.blocks?.length) EMPTY_PARTS.delete(prev.table);
1211
1391
  blocks.splice(j, 1);
1212
1392
  if (cell.blocks && at > 0) {
@@ -1239,6 +1419,7 @@ function fillNestedContinuation(blocks, at) {
1239
1419
  if (!cell || !add || cell.text.trim() || cell.blocks?.length) return;
1240
1420
  cell.text = add.text;
1241
1421
  if (add.blocks) cell.blocks = add.blocks;
1422
+ joinCellEdges(cell, add);
1242
1423
  blocks.splice(at, 1);
1243
1424
  }
1244
1425
 
@@ -2515,7 +2696,7 @@ function mergeLinkRuns(markdown) {
2515
2696
 
2516
2697
  // src/pdf/formula-ocr.ts
2517
2698
  async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
2518
- const formulaMod = await import("./formula-NARUOXRX.js");
2699
+ const formulaMod = await import("./formula-7MMFBRGJ.js");
2519
2700
  const { FormulaPipeline, ensureFormulaModels } = formulaMod;
2520
2701
  await ensureFormulaModels((p) => {
2521
2702
  if (p.phase === "download" && p.total) {
@@ -2898,7 +3079,7 @@ async function parsePdfDocument(buffer, options) {
2898
3079
  }
2899
3080
  if (targets.size > 0) {
2900
3081
  try {
2901
- const { runPdfOcr } = await import("./pdf-ocr-MQTWODVU.js");
3082
+ const { runPdfOcr } = await import("./pdf-ocr-L35FQYGP.js");
2902
3083
  const mode = typeof options?.ocr === "function" ? options.ocr : "builtin";
2903
3084
  const regionPages = new Map([...ocrRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
2904
3085
  const ocrPageBlocks = await runPdfOcr(ocrBuffer, targets, mode, warnings, options?.onProgress, options?.tables !== false, vectorPageOps, regionPages);
@@ -3023,6 +3204,28 @@ async function parsePdfDocument(buffer, options) {
3023
3204
  return b.bbox.y > h * 0.1 && b.bbox.y + b.bbox.height < h * 0.9;
3024
3205
  });
3025
3206
  joinLatinCellWraps(outBlocks);
3207
+ if (options?.layoutTables !== "keep" && await isHancomPdf(doc)) {
3208
+ const shown = /* @__PURE__ */ new Map();
3209
+ const markContent = (bs) => {
3210
+ for (const b of bs ?? []) if (b.table) for (const row of b.table.cells) for (const c of row) {
3211
+ if (IMAGE_CELLS.has(c)) CONTENT_CELLS.add(c);
3212
+ markContent(c.blocks);
3213
+ }
3214
+ };
3215
+ const visual = (bs) => bs.flatMap((b) => {
3216
+ if (b.type !== "table") return [b];
3217
+ let v = shown.get(b);
3218
+ if (!v) {
3219
+ markContent([b]);
3220
+ shown.set(b, v = unframeLayoutTables([b], !!options?.keepTrailingEmptyCols));
3221
+ }
3222
+ return v;
3223
+ });
3224
+ outBlocks = visual(outBlocks);
3225
+ const kept = visual(blocks);
3226
+ blocks.length = 0;
3227
+ for (const b of kept) blocks.push(b);
3228
+ }
3026
3229
  const finishMarkdown = (bs) => mergeLinkRuns(cleanPdfText(blocksToMarkdown(bs), { keepLoneNumbers: true }));
3027
3230
  let markdown = finishMarkdown(outBlocks);
3028
3231
  return {
@@ -3059,6 +3262,14 @@ async function extractPdfMetadata(doc, metadata) {
3059
3262
  } catch {
3060
3263
  }
3061
3264
  }
3265
+ async function isHancomPdf(doc) {
3266
+ try {
3267
+ const info = (await doc.getMetadata())?.info;
3268
+ return [info?.Producer, info?.Creator].some((v) => typeof v === "string" && /^\s*(?:hancom\b|hwp\b)/i.test(v));
3269
+ } catch {
3270
+ return false;
3271
+ }
3272
+ }
3062
3273
  function parsePdfDate(dateStr) {
3063
3274
  const m = dateStr.match(/D:(\d{4})(\d{2})?(\d{2})?(\d{2})?(\d{2})?(\d{2})?/);
3064
3275
  if (!m) return void 0;
@@ -3098,4 +3309,4 @@ export {
3098
3309
  parsePdfDocument,
3099
3310
  removeHeaderFooterBlocks
3100
3311
  };
3101
- //# sourceMappingURL=parser-N6476XAC.js.map
3312
+ //# sourceMappingURL=parser-ZPRQ3SSU.js.map