kordoc 4.18.3 → 4.18.4

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/dist/{-WOKB25R2.js → -DDAVBMHD.js} +11 -11
  2. package/dist/{chunk-BGOR5GCF.js → chunk-274ZPMHK.js} +2 -2
  3. package/dist/{chunk-2ZBLQVAS.cjs → chunk-3WLZOJIE.cjs} +6 -6
  4. package/dist/chunk-3WLZOJIE.cjs.map +1 -0
  5. package/dist/{chunk-SHRRD2TD.cjs → chunk-3XSP7V5P.cjs} +2 -2
  6. package/dist/chunk-3XSP7V5P.cjs.map +1 -0
  7. package/dist/{chunk-6GLTGOP6.js → chunk-4IBY5LTJ.js} +2 -2
  8. package/dist/chunk-6H25SXDI.js +11 -0
  9. package/dist/chunk-6H25SXDI.js.map +1 -0
  10. package/dist/{chunk-CAN5P6N6.js → chunk-7GR2GCJF.js} +2 -2
  11. package/dist/{chunk-HZV52V2X.cjs → chunk-AVIZ55NQ.cjs} +3 -3
  12. package/dist/chunk-AVIZ55NQ.cjs.map +1 -0
  13. package/dist/chunk-DC6CTQTK.js +9 -0
  14. package/dist/chunk-DC6CTQTK.js.map +1 -0
  15. package/dist/{chunk-NES5U4JK.js → chunk-DUV7Y6IQ.js} +3 -3
  16. package/dist/{chunk-WN5YLP7H.cjs → chunk-E2644XCO.cjs} +693 -187
  17. package/dist/chunk-E2644XCO.cjs.map +1 -0
  18. package/dist/{chunk-3FZGL3IL.js → chunk-ELOPDQES.js} +2 -2
  19. package/dist/{chunk-2I2RTJJ5.js → chunk-F2GDLA45.js} +25 -35
  20. package/dist/chunk-F2GDLA45.js.map +1 -0
  21. package/dist/{chunk-VGDTONTB.js → chunk-F5YVCJVF.js} +2 -2
  22. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  23. package/dist/{chunk-RDBTOE5X.js → chunk-HRJJDNRD.js} +2 -2
  24. package/dist/{chunk-KSJ7GKNQ.js → chunk-IAXGGQGD.js} +2 -2
  25. package/dist/{chunk-IXX3WHIE.js → chunk-IBQCK4F3.js} +7 -3
  26. package/dist/chunk-IBQCK4F3.js.map +1 -0
  27. package/dist/chunk-J55UQC5H.cjs.map +1 -1
  28. package/dist/{chunk-J2A46VCA.js → chunk-KUUSP6OS.js} +576 -70
  29. package/dist/chunk-KUUSP6OS.js.map +1 -0
  30. package/dist/{chunk-RSDUH4XF.js → chunk-LGF2IO66.js} +2 -2
  31. package/dist/{chunk-BJ6RYYXV.js → chunk-MXA6YW2W.js} +577 -71
  32. package/dist/chunk-MXA6YW2W.js.map +1 -0
  33. package/dist/{chunk-ZD5WNQNC.cjs → chunk-OIUSF2VA.cjs} +16 -12
  34. package/dist/chunk-OIUSF2VA.cjs.map +1 -0
  35. package/dist/{chunk-AZQWESRH.js → chunk-QVCHFCT2.js} +2 -2
  36. package/dist/{chunk-W7P4GPOV.js → chunk-RCI7LY4N.js} +8 -4
  37. package/dist/chunk-RCI7LY4N.js.map +1 -0
  38. package/dist/{chunk-V4BKT65D.cjs → chunk-SVNBZEL6.cjs} +3 -3
  39. package/dist/chunk-SVNBZEL6.cjs.map +1 -0
  40. package/dist/{chunk-OOX2GZZ4.js → chunk-T2BJPT6D.js} +3 -3
  41. package/dist/{chunk-OOX2GZZ4.js.map → chunk-T2BJPT6D.js.map} +1 -1
  42. package/dist/chunk-TK3FDAEE.cjs +9 -0
  43. package/dist/chunk-TK3FDAEE.cjs.map +1 -0
  44. package/dist/{chunk-UVUKT3IQ.js → chunk-TMJVD6FW.js} +2 -2
  45. package/dist/{chunk-ZN3LHNJG.js → chunk-V5X4LLVM.js} +28 -27
  46. package/dist/chunk-V5X4LLVM.js.map +1 -0
  47. package/dist/{chunk-W3RADOLO.js → chunk-VTVK2JMI.js} +2 -2
  48. package/dist/{chunk-PSJLB3SZ.js → chunk-XG4SYOZL.js} +2 -2
  49. package/dist/{chunk-RRURZDEK.js → chunk-YCY2R4FM.js} +2 -2
  50. package/dist/{chunk-5X7XWYR2.js → chunk-Z2PPDQK2.js} +2 -2
  51. package/dist/chunks-5QTTAT5T.js +10 -0
  52. package/dist/cli.js +154 -115
  53. package/dist/cli.js.map +1 -1
  54. package/dist/{formula-QZAOKPBX.js → formula-7ZOZ5QJ6.js} +8 -4
  55. package/dist/{formula-QZAOKPBX.js.map → formula-7ZOZ5QJ6.js.map} +1 -1
  56. package/dist/{formula-GPCOJJXN.js → formula-HQFZEXFF.js} +7 -3
  57. package/dist/{formula-GPCOJJXN.js.map → formula-HQFZEXFF.js.map} +1 -1
  58. package/dist/{formula-BQ5RW5XD.cjs → formula-YYJQBKEN.cjs} +13 -9
  59. package/dist/formula-YYJQBKEN.cjs.map +1 -0
  60. package/dist/{image-ocr-POCME5I4.js → image-ocr-4BGX2EJJ.js} +7 -6
  61. package/dist/{image-ocr-POCME5I4.js.map → image-ocr-4BGX2EJJ.js.map} +1 -1
  62. package/dist/{image-ocr-VKIUBLBX.cjs → image-ocr-CC26Q5KG.cjs} +16 -15
  63. package/dist/image-ocr-CC26Q5KG.cjs.map +1 -0
  64. package/dist/{image-ocr-TWNNVTZS.js → image-ocr-RK3HJVCI.js} +10 -9
  65. package/dist/{image-ocr-TWNNVTZS.js.map → image-ocr-RK3HJVCI.js.map} +1 -1
  66. package/dist/index.cjs +338 -347
  67. package/dist/index.cjs.map +1 -1
  68. package/dist/index.js +42 -51
  69. package/dist/index.js.map +1 -1
  70. package/dist/mcp.js +22 -22
  71. package/dist/{model-bundle-THYUL7GG.js → model-bundle-VHRXG63R.js} +5 -5
  72. package/dist/{models-U22N4RXX.js → models-G3WA24SY.js} +5 -5
  73. package/dist/page-range-QHHFTL7X.cjs.map +1 -1
  74. package/dist/{parser-JOMFOZLH.cjs → parser-BGORCLIU.cjs} +449 -244
  75. package/dist/parser-BGORCLIU.cjs.map +1 -0
  76. package/dist/{parser-SCXRLOW7.js → parser-GFDGAVLV.js} +242 -37
  77. package/dist/parser-GFDGAVLV.js.map +1 -0
  78. package/dist/{parser-NKP2NCSV.js → parser-SOWTUOMK.js} +245 -40
  79. package/dist/parser-SOWTUOMK.js.map +1 -0
  80. package/dist/pdf-ocr-7IOOVR2I.js +20 -0
  81. package/dist/pdf-ocr-EJ2HNZN6.cjs +17 -0
  82. package/dist/pdf-ocr-EJ2HNZN6.cjs.map +1 -0
  83. package/dist/pdf-ocr-RACAZU3N.js +16 -0
  84. package/dist/{profile-io-UI3TZBYH.js → profile-io-Q2T47RVH.js} +3 -3
  85. package/dist/{rasterize-XMBV5H2I.js → rasterize-OAVMUTE6.js} +3 -3
  86. package/dist/{redact-doc-7ZZMHDBO.js → redact-doc-ECFOVR4X.js} +11 -11
  87. package/dist/{render-SWRTUDAV.js → render-NSKWZVTD.js} +7 -7
  88. package/dist/seal-A4MG7MPQ.js +10 -0
  89. package/dist/{setup-43JJEEU7.js → setup-REH2KZP2.js} +3 -3
  90. package/dist/visual-B56WQAGW.js +20 -0
  91. package/dist/{watch-NRATQ472.js → watch-JXDUZYBY.js} +12 -12
  92. package/package.json +1 -1
  93. package/dist/chunk-2I2RTJJ5.js.map +0 -1
  94. package/dist/chunk-2ZBLQVAS.cjs.map +0 -1
  95. package/dist/chunk-BJ6RYYXV.js.map +0 -1
  96. package/dist/chunk-HZV52V2X.cjs.map +0 -1
  97. package/dist/chunk-IXX3WHIE.js.map +0 -1
  98. package/dist/chunk-J2A46VCA.js.map +0 -1
  99. package/dist/chunk-SHRRD2TD.cjs.map +0 -1
  100. package/dist/chunk-V4BKT65D.cjs.map +0 -1
  101. package/dist/chunk-W7P4GPOV.js.map +0 -1
  102. package/dist/chunk-WN5YLP7H.cjs.map +0 -1
  103. package/dist/chunk-ZD5WNQNC.cjs.map +0 -1
  104. package/dist/chunk-ZN3LHNJG.js.map +0 -1
  105. package/dist/chunks-OQDRDICD.js +0 -10
  106. package/dist/formula-BQ5RW5XD.cjs.map +0 -1
  107. package/dist/image-ocr-VKIUBLBX.cjs.map +0 -1
  108. package/dist/parser-JOMFOZLH.cjs.map +0 -1
  109. package/dist/parser-NKP2NCSV.js.map +0 -1
  110. package/dist/parser-SCXRLOW7.js.map +0 -1
  111. package/dist/pdf-ocr-NF4AY5MI.cjs +0 -16
  112. package/dist/pdf-ocr-NF4AY5MI.cjs.map +0 -1
  113. package/dist/pdf-ocr-OLII3WAG.js +0 -15
  114. package/dist/pdf-ocr-VJL7ON2Q.js +0 -19
  115. package/dist/seal-UKKJZHKE.js +0 -10
  116. package/dist/visual-D2563HCJ.js +0 -20
  117. /package/dist/{-WOKB25R2.js.map → -DDAVBMHD.js.map} +0 -0
  118. /package/dist/{chunk-BGOR5GCF.js.map → chunk-274ZPMHK.js.map} +0 -0
  119. /package/dist/{chunk-6GLTGOP6.js.map → chunk-4IBY5LTJ.js.map} +0 -0
  120. /package/dist/{chunk-CAN5P6N6.js.map → chunk-7GR2GCJF.js.map} +0 -0
  121. /package/dist/{chunk-NES5U4JK.js.map → chunk-DUV7Y6IQ.js.map} +0 -0
  122. /package/dist/{chunk-3FZGL3IL.js.map → chunk-ELOPDQES.js.map} +0 -0
  123. /package/dist/{chunk-VGDTONTB.js.map → chunk-F5YVCJVF.js.map} +0 -0
  124. /package/dist/{chunk-RDBTOE5X.js.map → chunk-HRJJDNRD.js.map} +0 -0
  125. /package/dist/{chunk-KSJ7GKNQ.js.map → chunk-IAXGGQGD.js.map} +0 -0
  126. /package/dist/{chunk-RSDUH4XF.js.map → chunk-LGF2IO66.js.map} +0 -0
  127. /package/dist/{chunk-AZQWESRH.js.map → chunk-QVCHFCT2.js.map} +0 -0
  128. /package/dist/{chunk-UVUKT3IQ.js.map → chunk-TMJVD6FW.js.map} +0 -0
  129. /package/dist/{chunk-W3RADOLO.js.map → chunk-VTVK2JMI.js.map} +0 -0
  130. /package/dist/{chunk-PSJLB3SZ.js.map → chunk-XG4SYOZL.js.map} +0 -0
  131. /package/dist/{chunk-RRURZDEK.js.map → chunk-YCY2R4FM.js.map} +0 -0
  132. /package/dist/{chunk-5X7XWYR2.js.map → chunk-Z2PPDQK2.js.map} +0 -0
  133. /package/dist/{chunks-OQDRDICD.js.map → chunks-5QTTAT5T.js.map} +0 -0
  134. /package/dist/{model-bundle-THYUL7GG.js.map → model-bundle-VHRXG63R.js.map} +0 -0
  135. /package/dist/{models-U22N4RXX.js.map → models-G3WA24SY.js.map} +0 -0
  136. /package/dist/{pdf-ocr-OLII3WAG.js.map → pdf-ocr-7IOOVR2I.js.map} +0 -0
  137. /package/dist/{pdf-ocr-VJL7ON2Q.js.map → pdf-ocr-RACAZU3N.js.map} +0 -0
  138. /package/dist/{profile-io-UI3TZBYH.js.map → profile-io-Q2T47RVH.js.map} +0 -0
  139. /package/dist/{rasterize-XMBV5H2I.js.map → rasterize-OAVMUTE6.js.map} +0 -0
  140. /package/dist/{redact-doc-7ZZMHDBO.js.map → redact-doc-ECFOVR4X.js.map} +0 -0
  141. /package/dist/{render-SWRTUDAV.js.map → render-NSKWZVTD.js.map} +0 -0
  142. /package/dist/{seal-UKKJZHKE.js.map → seal-A4MG7MPQ.js.map} +0 -0
  143. /package/dist/{setup-43JJEEU7.js.map → setup-REH2KZP2.js.map} +0 -0
  144. /package/dist/{visual-D2563HCJ.js.map → visual-B56WQAGW.js.map} +0 -0
  145. /package/dist/{watch-NRATQ472.js.map → watch-JXDUZYBY.js.map} +0 -0
@@ -4,15 +4,15 @@
4
4
 
5
5
 
6
6
 
7
- var _chunk2ZBLQVAScjs = require('./chunk-2ZBLQVAS.cjs');
7
+ var _chunk3WLZOJIEcjs = require('./chunk-3WLZOJIE.cjs');
8
8
 
9
9
 
10
10
 
11
- var _chunkHZV52V2Xcjs = require('./chunk-HZV52V2X.cjs');
11
+ var _chunkAVIZ55NQcjs = require('./chunk-AVIZ55NQ.cjs');
12
12
 
13
13
 
14
14
 
15
- var _chunkSHRRD2TDcjs = require('./chunk-SHRRD2TD.cjs');
15
+ var _chunk3XSP7V5Pcjs = require('./chunk-3XSP7V5P.cjs');
16
16
 
17
17
  // src/ocr/models.ts
18
18
  var _path = require('path');
@@ -40,10 +40,10 @@ var OCR_REC_DICT = {
40
40
  };
41
41
  var ALL_OCR_MODELS = [OCR_DET_MODEL, OCR_REC_MODEL, OCR_REC_DICT];
42
42
  function getOcrModelsDir() {
43
- return _chunkHZV52V2Xcjs.getModelsDir.call(void 0, "ppocr");
43
+ return _chunkAVIZ55NQcjs.getModelsDir.call(void 0, "ppocr");
44
44
  }
45
45
  async function ensureOcrModels(onProgress) {
46
- return _chunkHZV52V2Xcjs.ensureModelsIn.call(void 0, getOcrModelsDir(), ALL_OCR_MODELS, onProgress);
46
+ return _chunkAVIZ55NQcjs.ensureModelsIn.call(void 0, getOcrModelsDir(), ALL_OCR_MODELS, onProgress);
47
47
  }
48
48
  async function ocrModelsCached() {
49
49
  const dir = getOcrModelsDir();
@@ -488,13 +488,13 @@ function classifyAndAdd(seg, lineWidth, horizontals, verticals, fromFill = false
488
488
  verticals.push({ x1: x, y1, x2: x, y2, lineWidth, fromFill });
489
489
  }
490
490
  }
491
- function preprocessLines(horizontals, verticals) {
491
+ function preprocessLines(horizontals, verticals, nonRules) {
492
492
  let h = horizontals.filter((l) => l.lineWidth <= MAX_LINE_WIDTH);
493
493
  let v = verticals.filter((l) => l.lineWidth <= MAX_LINE_WIDTH);
494
494
  h = dropShadingStacks(h, "h");
495
495
  v = dropShadingStacks(v, "v");
496
- h = mergeParallelLines(h, "h");
497
- v = mergeParallelLines(v, "v");
496
+ h = mergeParallelLines(h, "h", nonRules);
497
+ v = mergeParallelLines(v, "v", nonRules);
498
498
  return { horizontals: h, verticals: v };
499
499
  }
500
500
  var STACK_GAP = 2;
@@ -654,15 +654,15 @@ function closeOpenTableEdges(horizontals, verticals) {
654
654
  const hasInterior = verticals.some((v) => v.x1 > x1 + EDGE_INSET && v.x1 < x2 - EDGE_INSET && crossCount(v) >= 2);
655
655
  if (!hasInterior) continue;
656
656
  for (const edgeX of [x1, x2]) {
657
- const closed = verticals.some((v) => Math.abs(v.x1 - edgeX) <= EDGE_NEAR && v.y1 <= yMax + EDGE_CONNECT_TOL && v.y2 >= yMin - EDGE_CONNECT_TOL);
658
- if (!closed) {
657
+ const closed2 = verticals.some((v) => Math.abs(v.x1 - edgeX) <= EDGE_NEAR && v.y1 <= yMax + EDGE_CONNECT_TOL && v.y2 >= yMin - EDGE_CONNECT_TOL);
658
+ if (!closed2) {
659
659
  synthesized.push({ x1: edgeX, y1: yMin, x2: edgeX, y2: yMax, lineWidth: 0.5 });
660
660
  }
661
661
  }
662
662
  }
663
663
  return synthesized.length ? [...verticals, ...synthesized] : verticals;
664
664
  }
665
- function mergeParallelLines(lines, dir) {
665
+ function mergeParallelLines(lines, dir, nonRules) {
666
666
  if (lines.length <= 1) return lines;
667
667
  const sorted = [...lines].sort((a, b) => {
668
668
  const posA = dir === "h" ? a.y1 : a.x1;
@@ -685,6 +685,7 @@ function mergeParallelLines(lines, dir) {
685
685
  const overlap2 = Math.min(prevEnd, currEnd) - Math.max(prevStart, currStart);
686
686
  const minLen = Math.min(prevEnd - prevStart, currEnd - currStart);
687
687
  if (overlap2 > minLen * 0.3) {
688
+ if (_optionalChain([nonRules, 'optionalAccess', _4 => _4.has, 'call', _5 => _5(prev)]) && !nonRules.has(curr)) nonRules.delete(prev);
688
689
  if (dir === "h") {
689
690
  prev.x1 = Math.min(prev.x1, curr.x1);
690
691
  prev.x2 = Math.max(prev.x2, curr.x2);
@@ -752,8 +753,8 @@ function extractImageRegions(fnArray, argsArray, respectClip = false) {
752
753
  break;
753
754
  case _pdfmjs.OPS.restore: {
754
755
  const state = stack.pop();
755
- ctm = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _4 => _4.ctm]), () => ( [1, 0, 0, 1, 0, 0]));
756
- clip = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _5 => _5.clip]), () => ( null));
756
+ ctm = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _6 => _6.ctm]), () => ( [1, 0, 0, 1, 0, 0]));
757
+ clip = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _7 => _7.clip]), () => ( null));
757
758
  break;
758
759
  }
759
760
  case _pdfmjs.OPS.transform: {
@@ -764,19 +765,19 @@ function extractImageRegions(fnArray, argsArray, respectClip = false) {
764
765
  // Form XObject 는 /Matrix 공간에서 그린다 — pdfjs 인자 [matrix, bbox], End 에서 복원 (line-extract.ts 와 같음)
765
766
  case _pdfmjs.OPS.paintFormXObjectBegin: {
766
767
  stack.push({ ctm, clip });
767
- const m = _optionalChain([argsArray, 'access', _6 => _6[i], 'optionalAccess', _7 => _7[0]]);
768
+ const m = _optionalChain([argsArray, 'access', _8 => _8[i], 'optionalAccess', _9 => _9[0]]);
768
769
  if (Array.isArray(m) && m.length >= 6) ctm = multiplyTransform(ctm, m);
769
770
  break;
770
771
  }
771
772
  case _pdfmjs.OPS.paintFormXObjectEnd: {
772
773
  const state = stack.pop();
773
- ctm = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _8 => _8.ctm]), () => ( [1, 0, 0, 1, 0, 0]));
774
- clip = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _9 => _9.clip]), () => ( null));
774
+ ctm = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _10 => _10.ctm]), () => ( [1, 0, 0, 1, 0, 0]));
775
+ clip = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _11 => _11.clip]), () => ( null));
775
776
  break;
776
777
  }
777
778
  case _pdfmjs.OPS.constructPath: {
778
779
  const [ops, coords] = argsArray[i];
779
- pathRect = pathRect === void 0 && _optionalChain([ops, 'optionalAccess', _10 => _10.length]) === 1 && ops[0] === _pdfmjs.OPS.rectangle && _optionalChain([coords, 'optionalAccess', _11 => _11.length]) >= 4 ? transformedRect(ctm, coords[0], coords[1], coords[2], coords[3]) : null;
780
+ pathRect = pathRect === void 0 && _optionalChain([ops, 'optionalAccess', _12 => _12.length]) === 1 && ops[0] === _pdfmjs.OPS.rectangle && _optionalChain([coords, 'optionalAccess', _13 => _13.length]) >= 4 ? transformedRect(ctm, coords[0], coords[1], coords[2], coords[3]) : null;
780
781
  break;
781
782
  }
782
783
  case _pdfmjs.OPS.clip:
@@ -1001,7 +1002,7 @@ function mergeVertices(vertices) {
1001
1002
  const candidates = [];
1002
1003
  for (let dx = -1; dx <= 1; dx++) {
1003
1004
  for (let dy = -1; dy <= 1; dy++) {
1004
- const arr = _optionalChain([buckets, 'access', _12 => _12.get, 'call', _13 => _13(cx + dx), 'optionalAccess', _14 => _14.get, 'call', _15 => _15(cy + dy)]);
1005
+ const arr = _optionalChain([buckets, 'access', _14 => _14.get, 'call', _15 => _15(cx + dx), 'optionalAccess', _16 => _16.get, 'call', _17 => _17(cy + dy)]);
1005
1006
  if (!arr) continue;
1006
1007
  for (const j of arr) {
1007
1008
  if (j > i && !used[j]) candidates.push(j);
@@ -1128,7 +1129,7 @@ function dropShadingClipGrids(clipGrids, lineGrids, fillRects, verticals = []) {
1128
1129
  const area = (b) => Math.max(0, b.x2 - b.x1) * Math.max(0, b.y2 - b.y1);
1129
1130
  const inter = (a, b) => area({ x1: Math.max(a.x1, b.x1), y1: Math.max(a.y1, b.y1), x2: Math.min(a.x2, b.x2), y2: Math.min(a.y2, b.y2) });
1130
1131
  return clipGrids.filter((c) => {
1131
- if (!_optionalChain([c, 'access', _16 => _16.cells, 'optionalAccess', _17 => _17.length]) || c.clipParent) return true;
1132
+ if (!_optionalChain([c, 'access', _18 => _18.cells, 'optionalAccess', _19 => _19.length]) || c.clipParent) return true;
1132
1133
  const sourceCells = c.cells.filter((cell) => !cell.filler);
1133
1134
  if (sourceCells.length === 0) return true;
1134
1135
  const shaded = sourceCells.every((cell) => fillRects.some((f) => near(f.x1, cell.bbox.x1) && near(f.x2, cell.bbox.x2) && near(f.y1, cell.bbox.y1) && near(f.y2, cell.bbox.y2)));
@@ -1138,7 +1139,7 @@ function dropShadingClipGrids(clipGrids, lineGrids, fillRects, verticals = []) {
1138
1139
  const host = lineGrids.find((l) => (
1139
1140
  // Inferred filler cells carry no boundary evidence. Replace their frame only
1140
1141
  // with a finer ruled grid of the same extent, never a larger surrounding form.
1141
- (!c.cells.some((cell) => cell.filler) || near(c.bbox.x1, l.bbox.x1) && near(c.bbox.x2, l.bbox.x2) && near(c.bbox.y1, l.bbox.y1) && near(c.bbox.y2, l.bbox.y2) && l.rowYs.length > c.rowYs.length && sourceCells.every((cell) => [cell.bbox.y1, cell.bbox.y2].every((y) => l.rowYs.some((ly) => near(y, ly))))) && c.bbox.x1 >= l.bbox.x1 - SHADE_CLIP_TOL && c.bbox.x2 <= l.bbox.x2 + SHADE_CLIP_TOL && c.bbox.y1 >= l.bbox.y1 - SHADE_CLIP_TOL && c.bbox.y2 <= l.bbox.y2 + SHADE_CLIP_TOL && c.colXs.every((x) => l.colXs.some((lx) => near(lx, x))) && (clipGrids.reduce((s, o) => s + (_optionalChain([o, 'access', _18 => _18.cells, 'optionalAccess', _19 => _19.some, 'call', _20 => _20((cell) => cell.filler)]) ? o.cells.filter((cell) => !cell.filler).reduce((a, cell) => a + inter(cell.bbox, l.bbox), 0) : inter(o.bbox, l.bbox)), 0) <= area(l.bbox) * SHADE_CLIP_MAX_AREA || l.rowYs.length === c.rowYs.length + 1 && c.rowYs.every((y, i) => near(y, l.rowYs[i])) && l.colXs.length === c.colXs.length && c.colXs.every((x, i) => near(x, l.colXs[i])) && !clipGrids.some((o) => o !== c && inter(o.bbox, l.bbox) > 0))
1142
+ (!c.cells.some((cell) => cell.filler) || near(c.bbox.x1, l.bbox.x1) && near(c.bbox.x2, l.bbox.x2) && near(c.bbox.y1, l.bbox.y1) && near(c.bbox.y2, l.bbox.y2) && l.rowYs.length > c.rowYs.length && sourceCells.every((cell) => [cell.bbox.y1, cell.bbox.y2].every((y) => l.rowYs.some((ly) => near(y, ly))))) && c.bbox.x1 >= l.bbox.x1 - SHADE_CLIP_TOL && c.bbox.x2 <= l.bbox.x2 + SHADE_CLIP_TOL && c.bbox.y1 >= l.bbox.y1 - SHADE_CLIP_TOL && c.bbox.y2 <= l.bbox.y2 + SHADE_CLIP_TOL && c.colXs.every((x) => l.colXs.some((lx) => near(lx, x))) && (clipGrids.reduce((s, o) => s + (_optionalChain([o, 'access', _20 => _20.cells, 'optionalAccess', _21 => _21.some, 'call', _22 => _22((cell) => cell.filler)]) ? o.cells.filter((cell) => !cell.filler).reduce((a, cell) => a + inter(cell.bbox, l.bbox), 0) : inter(o.bbox, l.bbox)), 0) <= area(l.bbox) * SHADE_CLIP_MAX_AREA || l.rowYs.length === c.rowYs.length + 1 && c.rowYs.every((y, i) => near(y, l.rowYs[i])) && l.colXs.length === c.colXs.length && c.colXs.every((x, i) => near(x, l.colXs[i])) && !clipGrids.some((o) => o !== c && inter(o.bbox, l.bbox) > 0))
1142
1143
  ));
1143
1144
  return !host;
1144
1145
  });
@@ -1153,7 +1154,7 @@ function dropHeadBandClipGrids(clipGrids, lineGrids) {
1153
1154
  if (clipGrids.length === 0 || lineGrids.length === 0) return clipGrids;
1154
1155
  const near = (a, b) => Math.abs(a - b) <= SHADE_CLIP_TOL;
1155
1156
  const overlaps = (a, b) => Math.min(a.x2, b.x2) > Math.max(a.x1, b.x1) && Math.min(a.y2, b.y2) > Math.max(a.y1, b.y1);
1156
- return clipGrids.filter((c) => c.clipParent || !_optionalChain([c, 'access', _21 => _21.cells, 'optionalAccess', _22 => _22.length]) || !lineGrids.some((l) => l.rowYs.length > c.rowYs.length && l.colXs.length === c.colXs.length && c.colXs.every((x, k) => near(x, l.colXs[k])) && c.rowYs.every((y, k) => near(y, l.rowYs[k])) && !clipGrids.some((o) => o !== c && overlaps(o.bbox, l.bbox))));
1157
+ return clipGrids.filter((c) => c.clipParent || !_optionalChain([c, 'access', _23 => _23.cells, 'optionalAccess', _24 => _24.length]) || !lineGrids.some((l) => l.rowYs.length > c.rowYs.length && l.colXs.length === c.colXs.length && c.colXs.every((x, k) => near(x, l.colXs[k])) && c.rowYs.every((y, k) => near(y, l.rowYs[k])) && !clipGrids.some((o) => o !== c && overlaps(o.bbox, l.bbox))));
1157
1158
  }
1158
1159
  function enforceMinWidth(colXs, minWidth) {
1159
1160
  if (colXs.length <= 2) return colXs;
@@ -1497,7 +1498,7 @@ function buildClipCellGrids(rects, strokedH, strokedV, pageWidth, pageHeight, te
1497
1498
  for (let dx = -1; dx <= 1 && !duplicate; dx++) {
1498
1499
  const ys2 = buckets.get(bx + dx);
1499
1500
  for (let dy = -1; dy <= 1 && !duplicate; dy++) {
1500
- duplicate = _nullishCoalesce(_optionalChain([ys2, 'optionalAccess', _23 => _23.get, 'call', _24 => _24(by + dy), 'optionalAccess', _25 => _25.some, 'call', _26 => _26((c) => sameRect(c, r))]), () => ( false));
1501
+ duplicate = _nullishCoalesce(_optionalChain([ys2, 'optionalAccess', _25 => _25.get, 'call', _26 => _26(by + dy), 'optionalAccess', _27 => _27.some, 'call', _28 => _28((c) => sameRect(c, r))]), () => ( false));
1501
1502
  }
1502
1503
  }
1503
1504
  if (duplicate) continue;
@@ -1645,7 +1646,7 @@ function buildClipCellGrids(rects, strokedH, strokedV, pageWidth, pageHeight, te
1645
1646
  else groups.set(r, [i]);
1646
1647
  }
1647
1648
  const containers = cells.filter((_, i) => isContainer[i]);
1648
- const groupSize = (i) => _nullishCoalesce(_optionalChain([groups, 'access', _27 => _27.get, 'call', _28 => _28(find(i)), 'optionalAccess', _29 => _29.length]), () => ( 0));
1649
+ const groupSize = (i) => _nullishCoalesce(_optionalChain([groups, 'access', _29 => _29.get, 'call', _30 => _30(find(i)), 'optionalAccess', _31 => _31.length]), () => ( 0));
1649
1650
  const isGridMember = (i) => groupSize(i) >= CLIP_MIN_GROUP;
1650
1651
  const framed = (r) => edgeStroked(strokedH, "h", r.y1, r.x1, r.x2) && edgeStroked(strokedH, "h", r.y2, r.x1, r.x2) && edgeStroked(strokedV, "v", r.x1, r.y1, r.y2) && edgeStroked(strokedV, "v", r.x2, r.y1, r.y2);
1651
1652
  const titledFrame = (r) => r.y1 >= pageHeight * TITLED_FRAME_MIN_TOP && r.x2 - r.x1 >= pageWidth * TITLED_FRAME_MIN_WIDTH && textPoints.some((p) => p.y < r.y1 && p.y > pageHeight * HEADER_BAND && p.x >= r.x1 - CLIP_EDGE_TOL && p.x <= r.x2 + CLIP_EDGE_TOL) && textPoints.some((p) => p.x > r.x1 && p.x < r.x2 && p.y > r.y1 && p.y < r.y2);
@@ -2090,7 +2091,7 @@ function tagScripts(text, lines) {
2090
2091
  const [s, e, kind] = marks[m];
2091
2092
  out = out.slice(0, s) + `<${kind}>` + out.slice(s, e) + `</${kind}>` + out.slice(e);
2092
2093
  }
2093
- return _chunk2ZBLQVAScjs.tidyScriptTags.call(void 0, out);
2094
+ return _chunk3WLZOJIEcjs.tidyScriptTags.call(void 0, out);
2094
2095
  }
2095
2096
 
2096
2097
  // src/pdf/line-wrap.ts
@@ -2147,14 +2148,14 @@ var WrapLexicon = (_class = class {constructor() { _class.prototype.__init.call(
2147
2148
  const n = left.length;
2148
2149
  if (n < 2 || right.length < 2) return null;
2149
2150
  const k1 = pairKey(left.charCodeAt(n - 2), left.charCodeAt(n - 1)), k2 = pairKey(right.charCodeAt(0), right.charCodeAt(1));
2150
- return decideCounts(_nullishCoalesce(_optionalChain([this, 'access', _30 => _30.joined2, 'access', _31 => _31.get, 'call', _32 => _32(k1), 'optionalAccess', _33 => _33.get, 'call', _34 => _34(k2)]), () => ( 0)), _nullishCoalesce(_optionalChain([this, 'access', _35 => _35.spaced2, 'access', _36 => _36.get, 'call', _37 => _37(k1), 'optionalAccess', _38 => _38.get, 'call', _39 => _39(k2)]), () => ( 0)));
2151
+ return decideCounts(_nullishCoalesce(_optionalChain([this, 'access', _32 => _32.joined2, 'access', _33 => _33.get, 'call', _34 => _34(k1), 'optionalAccess', _35 => _35.get, 'call', _36 => _36(k2)]), () => ( 0)), _nullishCoalesce(_optionalChain([this, 'access', _37 => _37.spaced2, 'access', _38 => _38.get, 'call', _39 => _39(k1), 'optionalAccess', _40 => _40.get, 'call', _41 => _41(k2)]), () => ( 0)));
2151
2152
  }
2152
2153
  /** 꺾인 자리 증거: "" 붙음 · " " 띄움 · null 모름 (두 글자 증거가 갈리거나 없으면 한 글자) */
2153
2154
  evidence(left, right) {
2154
2155
  const n = left.length;
2155
2156
  if (n >= 2 && right.length >= 2) {
2156
2157
  const k1 = pairKey(left.charCodeAt(n - 2), left.charCodeAt(n - 1)), k2 = pairKey(right.charCodeAt(0), right.charCodeAt(1));
2157
- const v = decideCounts(_nullishCoalesce(_optionalChain([this, 'access', _40 => _40.joined2, 'access', _41 => _41.get, 'call', _42 => _42(k1), 'optionalAccess', _43 => _43.get, 'call', _44 => _44(k2)]), () => ( 0)), _nullishCoalesce(_optionalChain([this, 'access', _45 => _45.spaced2, 'access', _46 => _46.get, 'call', _47 => _47(k1), 'optionalAccess', _48 => _48.get, 'call', _49 => _49(k2)]), () => ( 0)));
2158
+ const v = decideCounts(_nullishCoalesce(_optionalChain([this, 'access', _42 => _42.joined2, 'access', _43 => _43.get, 'call', _44 => _44(k1), 'optionalAccess', _45 => _45.get, 'call', _46 => _46(k2)]), () => ( 0)), _nullishCoalesce(_optionalChain([this, 'access', _47 => _47.spaced2, 'access', _48 => _48.get, 'call', _49 => _49(k1), 'optionalAccess', _50 => _50.get, 'call', _51 => _51(k2)]), () => ( 0)));
2158
2159
  if (v !== null) return v;
2159
2160
  }
2160
2161
  if (n && right.length) {
@@ -2227,11 +2228,11 @@ function wrapJoiner(prevText, nextText, lex) {
2227
2228
  if (particleContinues(left, right)) return "";
2228
2229
  if (endsAsWord(left)) return " ";
2229
2230
  if (/[A-Za-z]-$/.test(left) && /^[A-Za-z]/.test(right) && !/[가-힣]/.test(prev + next)) {
2230
- return _optionalChain([lex, 'optionalAccess', _50 => _50.joinedWord, 'call', _51 => _51(left, right.replace(/[.,;:!?)]*$/, ""))]) ? "" : " ";
2231
+ return _optionalChain([lex, 'optionalAccess', _52 => _52.joinedWord, 'call', _53 => _53(left, right.replace(/[.,;:!?)]*$/, ""))]) ? "" : " ";
2231
2232
  }
2232
2233
  if (/[·ㆍ‧-]/.test(a) && !/[·ㆍ‧…]{2}$/.test(prev) && /[가-힣A-Za-z0-9]/.test(b)) return "";
2233
2234
  if (/[A-Za-z]/.test(a) && /[A-Za-z]/.test(b) || /\d/.test(a) && /\d/.test(b)) return " ";
2234
- const ev = _optionalChain([lex, 'optionalAccess', _52 => _52.evidence, 'call', _53 => _53(left, right)]);
2235
+ const ev = _optionalChain([lex, 'optionalAccess', _54 => _54.evidence, 'call', _55 => _55(left, right)]);
2235
2236
  if (ev != null) return ev;
2236
2237
  if (lex && /[가-힣A-Za-z0-9]$/.test(left) && /^[가-힣A-Za-z0-9]/.test(right) && lex.joinedWord(left, right.replace(/[.,)」』’”;:]+$/, ""))) return "";
2237
2238
  if (/\d$/.test(left) && COUNTER.test(right)) return "";
@@ -2253,7 +2254,7 @@ function joinPageBreakWraps(blocks, lex) {
2253
2254
  if (a.type !== "paragraph" && a.type !== "list" || b.type !== "paragraph") continue;
2254
2255
  const last = a.bbox && PARA_LAST_LINE.get(a.bbox), fs = last ? last.fontSize : 0;
2255
2256
  if (!last || fs <= 0 || (_nullishCoalesce(pageRight.get(a.pageNumber), () => ( Infinity))) - last.right >= BODY_FULL_TOL * fs) continue;
2256
- if (last.width < BODY_MIN_WIDTH_EM * fs || Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _54 => _54.style, 'optionalAccess', _55 => _55.fontSize]), () => ( 0))) - fs) > 0.15 * fs) continue;
2257
+ if (last.width < BODY_MIN_WIDTH_EM * fs || Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _56 => _56.style, 'optionalAccess', _57 => _57.fontSize]), () => ( 0))) - fs) > 0.15 * fs) continue;
2257
2258
  if (startsNewItem(a.text, b.text)) continue;
2258
2259
  a.text += wrapJoiner(a.text, b.text, lex) + b.text;
2259
2260
  const bl = b.bbox && PARA_LAST_LINE.get(b.bbox);
@@ -2280,7 +2281,7 @@ function bodyLineJoins(lines, lex) {
2280
2281
  for (const l of lines) if (!HANGING.test(l.text) && l.right > inner) inner = l.right;
2281
2282
  const full = (l) => right - l.right < BODY_FULL_TOL * l.fontSize || right - inner <= 1.2 * l.fontSize && inner - l.right < BODY_FULL_TOL * l.fontSize;
2282
2283
  const nextWordNoRoom = (a, b) => {
2283
- const w = _optionalChain([b, 'access', _56 => _56.text, 'access', _57 => _57.trim, 'call', _58 => _58(), 'access', _59 => _59.match, 'call', _60 => _60(/^\S+/), 'optionalAccess', _61 => _61[0]]);
2284
+ const w = _optionalChain([b, 'access', _58 => _58.text, 'access', _59 => _59.trim, 'call', _60 => _60(), 'access', _61 => _61.match, 'call', _62 => _62(/^\S+/), 'optionalAccess', _63 => _63[0]]);
2284
2285
  const n = [...b.text.trim()].length;
2285
2286
  if (!w || n === 0) return false;
2286
2287
  const em = (b.right - b.left) / n;
@@ -2456,7 +2457,7 @@ function cellTextToString(items, wrap) {
2456
2457
  const merged = mergeSuperscriptRows(lines).map((line) => sortLineByX(line));
2457
2458
  const textLines = merged.map((s) => {
2458
2459
  if (s.length === 1) return s[0].text;
2459
- if (s.length === 2 && /^[가-힣]$/.test(s[0].text) && /^[가-힣]$/.test(s[1].text) && !!_optionalChain([wrap, 'optionalAccess', _62 => _62.lex]) && (wrap.lex.isWord(s[0].text + s[1].text) || wrap.lex.evidence(s[0].text, s[1].text) === "" || REGION_LABELS.has(s[0].text + s[1].text)) && s[1].x - (s[0].x + s[0].w) >= Math.max(s[0].fontSize, s[1].fontSize) * 1.5 && s[1].x + s[1].w - s[0].x >= wrap.box.x2 - wrap.box.x1 - Math.max(s[0].fontSize, s[1].fontSize) * 2) return s[0].text + s[1].text;
2460
+ if (s.length === 2 && /^[가-힣]$/.test(s[0].text) && /^[가-힣]$/.test(s[1].text) && !!_optionalChain([wrap, 'optionalAccess', _64 => _64.lex]) && (wrap.lex.isWord(s[0].text + s[1].text) || wrap.lex.evidence(s[0].text, s[1].text) === "" || REGION_LABELS.has(s[0].text + s[1].text)) && s[1].x - (s[0].x + s[0].w) >= Math.max(s[0].fontSize, s[1].fontSize) * 1.5 && s[1].x + s[1].w - s[0].x >= wrap.box.x2 - wrap.box.x1 - Math.max(s[0].fontSize, s[1].fontSize) * 2) return s[0].text + s[1].text;
2460
2461
  const evenSpaced = detectEvenSpacedItems(s, true);
2461
2462
  let result = s[0].text;
2462
2463
  for (let j = 1; j < s.length; j++) {
@@ -2604,7 +2605,7 @@ function mergeCellTextLines(textLines, wrap) {
2604
2605
  merged[merged.length - 1] = prev + curr.trim();
2605
2606
  } else if (!wrap && /[,(]$/.test(prev.trim()) && curr.trim().length <= 15) {
2606
2607
  merged[merged.length - 1] = prev + curr.trim();
2607
- } else if (/[\d,]$/.test(prev) && /^[\d,]+[)\]]?$/.test(curr.trim()) && curr.trim().length <= 10 && !(/\d,\d{3}$/.test(prev) && /^\d/.test(curr.trim())) && !(/(?:^|[^\d,])\d{1,3}$/.test(prev) && /^(\d{1,3}(,\d{3})+|\d{1,3})$/.test(curr.trim()) && !_optionalChain([wrap, 'optionalAccess', _63 => _63.wraps, 'access', _64 => _64[i - 1]])) && !(/(?:^|\s)\d{1,7}$/.test(prev) && /^\d{1,7}$/.test(curr.trim()) && !_optionalChain([wrap, 'optionalAccess', _65 => _65.wraps, 'access', _66 => _66[i - 1]]))) {
2608
+ } else if (/[\d,]$/.test(prev) && /^[\d,]+[)\]]?$/.test(curr.trim()) && curr.trim().length <= 10 && !(/\d,\d{3}$/.test(prev) && /^\d/.test(curr.trim())) && !(/(?:^|[^\d,])\d{1,3}$/.test(prev) && /^(\d{1,3}(,\d{3})+|\d{1,3})$/.test(curr.trim()) && !_optionalChain([wrap, 'optionalAccess', _65 => _65.wraps, 'access', _66 => _66[i - 1]])) && !(/(?:^|\s)\d{1,7}$/.test(prev) && /^\d{1,7}$/.test(curr.trim()) && !_optionalChain([wrap, 'optionalAccess', _67 => _67.wraps, 'access', _68 => _68[i - 1]]))) {
2608
2609
  merged[merged.length - 1] = prev + curr.trim();
2609
2610
  } else {
2610
2611
  merged.push(curr);
@@ -2674,7 +2675,7 @@ function normalizeUndersegmentedTable(originalCells, colXs, items, rowYs) {
2674
2675
  if (numRows > MAX_UNDERSEGMENTED_ROWS || numCols < MIN_UNDERSEGMENTED_COLUMNS) return null;
2675
2676
  if (items.length === 0) return null;
2676
2677
  if (numRows >= 3) {
2677
- if (_optionalChain([rowYs, 'optionalAccess', _67 => _67.length]) !== numRows + 1) return null;
2678
+ if (_optionalChain([rowYs, 'optionalAccess', _69 => _69.length]) !== numRows + 1) return null;
2678
2679
  const rebuilt2 = [];
2679
2680
  let expanded = 0;
2680
2681
  for (let r = 0; r < numRows; r++) {
@@ -2827,7 +2828,7 @@ function dominantStyle(items) {
2827
2828
  let maxCount = 0, dominantSize = 0;
2828
2829
  for (const i of items) {
2829
2830
  if (i.fontSize <= 0) continue;
2830
- const count = (freq.get(i.fontSize) || 0) + Math.max(1, _nullishCoalesce(_optionalChain([i, 'access', _68 => _68.text, 'access', _69 => _69.match, 'call', _70 => _70(/[\p{L}\p{N}]/gu), 'optionalAccess', _71 => _71.length]), () => ( 0)));
2831
+ const count = (freq.get(i.fontSize) || 0) + Math.max(1, _nullishCoalesce(_optionalChain([i, 'access', _70 => _70.text, 'access', _71 => _71.match, 'call', _72 => _72(/[\p{L}\p{N}]/gu), 'optionalAccess', _73 => _73.length]), () => ( 0)));
2831
2832
  freq.set(i.fontSize, count);
2832
2833
  if (count > maxCount) {
2833
2834
  maxCount = count;
@@ -2835,7 +2836,7 @@ function dominantStyle(items) {
2835
2836
  }
2836
2837
  }
2837
2838
  if (dominantSize === 0) return void 0;
2838
- const fontName = _optionalChain([items, 'access', _72 => _72.find, 'call', _73 => _73((i) => i.fontSize === dominantSize), 'optionalAccess', _74 => _74.fontName]) || void 0;
2839
+ const fontName = _optionalChain([items, 'access', _74 => _74.find, 'call', _75 => _75((i) => i.fontSize === dominantSize), 'optionalAccess', _76 => _76.fontName]) || void 0;
2839
2840
  return fontName ? { fontSize: dominantSize, fontName } : { fontSize: dominantSize };
2840
2841
  }
2841
2842
  function normalizeItems(rawItems) {
@@ -2955,7 +2956,7 @@ function splitAroundOverlays(c, overlays) {
2955
2956
  const ov = overlays.filter((o) => {
2956
2957
  for (let at = c.text.indexOf(o.text); at >= 0; at = c.text.indexOf(o.text, at + 1)) {
2957
2958
  const prefix = c.text.slice(0, at);
2958
- const est = c.x + glyphUnits(prefix.replace(/\s+/g, "")) * a0 + (_nullishCoalesce(_optionalChain([prefix, 'access', _75 => _75.match, 'call', _76 => _76(/\s+/g), 'optionalAccess', _77 => _77.length]), () => ( 0))) * ws;
2959
+ const est = c.x + glyphUnits(prefix.replace(/\s+/g, "")) * a0 + (_nullishCoalesce(_optionalChain([prefix, 'access', _77 => _77.match, 'call', _78 => _78(/\s+/g), 'optionalAccess', _79 => _79.length]), () => ( 0))) * ws;
2959
2960
  if (Math.abs(est - o.x) <= OVERLAY_DUP_EM * fs) return false;
2960
2961
  }
2961
2962
  return true;
@@ -3075,7 +3076,7 @@ function mergeSuperscriptLines(lines) {
3075
3076
  return result;
3076
3077
  }
3077
3078
  function mergeLineSimple(items) {
3078
- if (items.length <= 1) return _optionalChain([items, 'access', _78 => _78[0], 'optionalAccess', _79 => _79.text]) || "";
3079
+ if (items.length <= 1) return _optionalChain([items, 'access', _80 => _80[0], 'optionalAccess', _81 => _81.text]) || "";
3079
3080
  const sorted = sortLineByX([...items]);
3080
3081
  const isEvenSpaced = detectEvenSpacedItems(sorted);
3081
3082
  let result = sorted[0].text;
@@ -3220,7 +3221,7 @@ function splitTrailingColumnRegion(items) {
3220
3221
  }
3221
3222
  function panelBlocks(items, panel, pageNum) {
3222
3223
  const lines = groupByY([...items].sort((a, b) => b.y - a.y || a.x - b.x));
3223
- const faceOf = (line) => _nullishCoalesce(_optionalChain([dominantStyle, 'call', _80 => _80(line), 'optionalAccess', _81 => _81.fontName]), () => ( ""));
3224
+ const faceOf = (line) => _nullishCoalesce(_optionalChain([dominantStyle, 'call', _82 => _82(line), 'optionalAccess', _83 => _83.fontName]), () => ( ""));
3224
3225
  const runs = [];
3225
3226
  for (const line of lines) {
3226
3227
  const last = runs[runs.length - 1];
@@ -3395,7 +3396,7 @@ function validWrapBands(items, bands) {
3395
3396
  }
3396
3397
  function inheritedWrapBands(items) {
3397
3398
  const source = XY_WRAP_ITEMS.get(items[0]);
3398
- const present = _optionalChain([source, 'optionalAccess', _82 => _82.length]) === items.length ? new Set(items) : null;
3399
+ const present = _optionalChain([source, 'optionalAccess', _84 => _84.length]) === items.length ? new Set(items) : null;
3399
3400
  const sameLeaf = present && source.every((item) => present.has(item));
3400
3401
  return sameLeaf ? validWrapBands(items, _nullishCoalesce(XY_WRAP_BANDS.get(items[0]), () => ( []))) : [];
3401
3402
  }
@@ -3434,7 +3435,7 @@ function wrappedLineBands(items, inherited) {
3434
3435
  left: box.x,
3435
3436
  right: box.x + box.width,
3436
3437
  y: row.reduce((n, i) => n + i.y, 0) / row.length,
3437
- fontSize: _nullishCoalesce(_optionalChain([dominantStyle, 'call', _83 => _83(row), 'optionalAccess', _84 => _84.fontSize]), () => ( 0)),
3438
+ fontSize: _nullishCoalesce(_optionalChain([dominantStyle, 'call', _85 => _85(row), 'optionalAccess', _86 => _86.fontSize]), () => ( 0)),
3438
3439
  sources: row.map((item) => ({ item, state: { ...item } }))
3439
3440
  };
3440
3441
  });
@@ -3570,10 +3571,10 @@ function pushLineParagraphs(out, yLines, pageNum, lex) {
3570
3571
  const lines = attachDropCaps(yLines).map((items) => ({ items, text: mergeLineSimple(items) })).filter((l) => l.text.trim());
3571
3572
  const geo = lines.map((l) => {
3572
3573
  const b = computeBBox(l.items, pageNum);
3573
- return { text: l.text, left: b.x, right: b.x + b.width, y: l.items.reduce((s, i) => s + i.y, 0) / l.items.length, fontSize: _nullishCoalesce(_optionalChain([dominantStyle, 'call', _85 => _85(l.items), 'optionalAccess', _86 => _86.fontSize]), () => ( 0)) };
3574
+ return { text: l.text, left: b.x, right: b.x + b.width, y: l.items.reduce((s, i) => s + i.y, 0) / l.items.length, fontSize: _nullishCoalesce(_optionalChain([dominantStyle, 'call', _87 => _87(l.items), 'optionalAccess', _88 => _88.fontSize]), () => ( 0)) };
3574
3575
  });
3575
3576
  const joins = bodyLineJoins(geo, lex);
3576
- const first = _optionalChain([lines, 'access', _87 => _87[0], 'optionalAccess', _88 => _88.items, 'access', _89 => _89[0]]);
3577
+ const first = _optionalChain([lines, 'access', _89 => _89[0], 'optionalAccess', _90 => _90.items, 'access', _91 => _91[0]]);
3577
3578
  const bands = first ? _nullishCoalesce(XY_WRAP_BANDS.get(first), () => ( [])) : [];
3578
3579
  const hasBand = (top, bottom) => {
3579
3580
  let lo = 0, hi = bands.length;
@@ -3637,15 +3638,15 @@ function computeMedianFontSizeFromFreq(freq) {
3637
3638
  function detectHeadings(blocks, medianFontSize) {
3638
3639
  for (let bi = 0; bi < blocks.length; bi++) {
3639
3640
  const block = blocks[bi];
3640
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _90 => _90.style, 'optionalAccess', _91 => _91.fontSize])) continue;
3641
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _92 => _92.style, 'optionalAccess', _93 => _93.fontSize])) continue;
3641
3642
  const text = block.text.trim();
3642
3643
  if (text.length === 0 || text.length > 200) continue;
3643
3644
  if (/^\d+$/.test(text) && !isChapterNumber(block, blocks[bi + 1], medianFontSize)) continue;
3644
3645
  const ratio = block.style.fontSize / medianFontSize;
3645
3646
  let level = 0;
3646
- if (ratio >= _chunk2ZBLQVAScjs.HEADING_RATIO_H1) level = 1;
3647
- else if (ratio >= _chunk2ZBLQVAScjs.HEADING_RATIO_H2) level = 2;
3648
- else if (ratio >= _chunk2ZBLQVAScjs.HEADING_RATIO_H3) level = 3;
3647
+ if (ratio >= _chunk3WLZOJIEcjs.HEADING_RATIO_H1) level = 1;
3648
+ else if (ratio >= _chunk3WLZOJIEcjs.HEADING_RATIO_H2) level = 2;
3649
+ else if (ratio >= _chunk3WLZOJIEcjs.HEADING_RATIO_H3) level = 3;
3649
3650
  if (level > 0) {
3650
3651
  block.type = "heading";
3651
3652
  block.level = level;
@@ -3654,21 +3655,21 @@ function detectHeadings(blocks, medianFontSize) {
3654
3655
  }
3655
3656
  }
3656
3657
  function isChapterNumber(block, next, medianFontSize) {
3657
- const size = _nullishCoalesce(_optionalChain([block, 'access', _92 => _92.style, 'optionalAccess', _93 => _93.fontSize]), () => ( 0));
3658
- const nextSize = _nullishCoalesce(_optionalChain([next, 'optionalAccess', _94 => _94.style, 'optionalAccess', _95 => _95.fontSize]), () => ( 0));
3659
- const text = _nullishCoalesce(_optionalChain([next, 'optionalAccess', _96 => _96.text, 'optionalAccess', _97 => _97.trim, 'call', _98 => _98()]), () => ( ""));
3660
- const a = block.bbox, b = _optionalChain([next, 'optionalAccess', _99 => _99.bbox]);
3661
- return /^\d{1,2}$/.test(_nullishCoalesce(_optionalChain([block, 'access', _100 => _100.text, 'optionalAccess', _101 => _101.trim, 'call', _102 => _102()]), () => ( ""))) && size >= medianFontSize * 2.5 && !!next && (next.type === "paragraph" || next.type === "heading") && next.pageNumber === block.pageNumber && nextSize >= medianFontSize * _chunk2ZBLQVAScjs.HEADING_RATIO_H1 && text.length > 0 && text.length <= 80 && !/^[\d\s.]+$/.test(text) && !!a && !!b && a.y > b.y && a.y - (b.y + b.height) <= size * 2;
3658
+ const size = _nullishCoalesce(_optionalChain([block, 'access', _94 => _94.style, 'optionalAccess', _95 => _95.fontSize]), () => ( 0));
3659
+ const nextSize = _nullishCoalesce(_optionalChain([next, 'optionalAccess', _96 => _96.style, 'optionalAccess', _97 => _97.fontSize]), () => ( 0));
3660
+ const text = _nullishCoalesce(_optionalChain([next, 'optionalAccess', _98 => _98.text, 'optionalAccess', _99 => _99.trim, 'call', _100 => _100()]), () => ( ""));
3661
+ const a = block.bbox, b = _optionalChain([next, 'optionalAccess', _101 => _101.bbox]);
3662
+ return /^\d{1,2}$/.test(_nullishCoalesce(_optionalChain([block, 'access', _102 => _102.text, 'optionalAccess', _103 => _103.trim, 'call', _104 => _104()]), () => ( ""))) && size >= medianFontSize * 2.5 && !!next && (next.type === "paragraph" || next.type === "heading") && next.pageNumber === block.pageNumber && nextSize >= medianFontSize * _chunk3WLZOJIEcjs.HEADING_RATIO_H1 && text.length > 0 && text.length <= 80 && !/^[\d\s.]+$/.test(text) && !!a && !!b && a.y > b.y && a.y - (b.y + b.height) <= size * 2;
3662
3663
  }
3663
3664
  function mergeStackedHeadingLines(blocks, medianFontSize) {
3664
3665
  for (let i = 0; i < blocks.length - 1; ) {
3665
3666
  const a = blocks[i], b = blocks[i + 1];
3666
3667
  const ab = a.bbox, bb = b.bbox;
3667
- const af = _nullishCoalesce(_optionalChain([a, 'access', _103 => _103.style, 'optionalAccess', _104 => _104.fontSize]), () => ( 0)), bf = _nullishCoalesce(_optionalChain([b, 'access', _105 => _105.style, 'optionalAccess', _106 => _106.fontSize]), () => ( 0));
3668
+ const af = _nullishCoalesce(_optionalChain([a, 'access', _105 => _105.style, 'optionalAccess', _106 => _106.fontSize]), () => ( 0)), bf = _nullishCoalesce(_optionalChain([b, 'access', _107 => _107.style, 'optionalAccess', _108 => _108.fontSize]), () => ( 0));
3668
3669
  const gap = ab && bb ? ab.y - (bb.y + bb.height) : Infinity;
3669
- const centered = ab && bb && _optionalChain([a, 'access', _107 => _107.style, 'optionalAccess', _108 => _108.fontName]) === _optionalChain([b, 'access', _109 => _109.style, 'optionalAccess', _110 => _110.fontName]) && Math.abs(ab.x + ab.width / 2 - (bb.x + bb.width / 2)) <= Math.max(5, af * 0.5);
3670
+ const centered = ab && bb && _optionalChain([a, 'access', _109 => _109.style, 'optionalAccess', _110 => _110.fontName]) === _optionalChain([b, 'access', _111 => _111.style, 'optionalAccess', _112 => _112.fontName]) && Math.abs(ab.x + ab.width / 2 - (bb.x + bb.width / 2)) <= Math.max(5, af * 0.5);
3670
3671
  const sameAnchor = ab && bb && Math.abs(ab.x - bb.x) <= 5;
3671
- const wrapped = sameAnchor && _optionalChain([a, 'access', _111 => _111.style, 'optionalAccess', _112 => _112.fontName]) === _optionalChain([b, 'access', _113 => _113.style, 'optionalAccess', _114 => _114.fontName]) && af === bf && ab.width >= bb.width * 0.95 && (_nullishCoalesce(_optionalChain([a, 'access', _115 => _115.text, 'optionalAccess', _116 => _116.trim, 'call', _117 => _117(), 'access', _118 => _118.split, 'call', _119 => _119(/\s+/), 'access', _120 => _120.length]), () => ( 0))) >= 3;
3672
+ const wrapped = sameAnchor && _optionalChain([a, 'access', _113 => _113.style, 'optionalAccess', _114 => _114.fontName]) === _optionalChain([b, 'access', _115 => _115.style, 'optionalAccess', _116 => _116.fontName]) && af === bf && ab.width >= bb.width * 0.95 && (_nullishCoalesce(_optionalChain([a, 'access', _117 => _117.text, 'optionalAccess', _118 => _118.trim, 'call', _119 => _119(), 'access', _120 => _120.split, 'call', _121 => _121(/\s+/), 'access', _122 => _122.length]), () => ( 0))) >= 3;
3672
3673
  const displayStack = centered && gap <= Math.min(af, bf) * 0.3 && Math.max(af, bf) <= Math.min(af, bf) * 1.45;
3673
3674
  if (a.type !== "heading" || b.type !== "heading" || !a.text || !b.text || /^\d+$/.test(a.text.trim()) || !ab || !bb || ab.page !== bb.page || !(sameAnchor && af >= medianFontSize * 2 && bf >= medianFontSize * 2) && !wrapped && !(centered && af >= medianFontSize * 1.25 && bf >= medianFontSize * 1.25) || Math.abs(af - bf) > Math.max(af, bf) * 0.15 && !displayStack || gap < -2 || gap > Math.max(af, bf) * 0.45 || a.text.length > (centered ? 120 : 50) || b.text.length > (centered ? 120 : 50)) {
3674
3675
  i++;
@@ -3697,25 +3698,25 @@ function detectTypographyHeadings(blocks) {
3697
3698
  if (page.some((block) => block.type === "heading")) continue;
3698
3699
  const faceWeight = /* @__PURE__ */ new Map();
3699
3700
  for (const block of page) {
3700
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _121 => _121.style, 'optionalAccess', _122 => _122.fontName])) continue;
3701
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _123 => _123.style, 'optionalAccess', _124 => _124.fontName])) continue;
3701
3702
  const faces = FACE_CHARS.get(block);
3702
3703
  if (faces) for (const [face, n] of faces) faceWeight.set(face, (_nullishCoalesce(faceWeight.get(face), () => ( 0))) + n);
3703
3704
  else faceWeight.set(block.style.fontName, (_nullishCoalesce(faceWeight.get(block.style.fontName), () => ( 0))) + block.text.length);
3704
3705
  }
3705
- const bodyFace = _optionalChain([[...faceWeight], 'access', _123 => _123.sort, 'call', _124 => _124((a, b) => b[1] - a[1]), 'access', _125 => _125[0], 'optionalAccess', _126 => _126[0]]);
3706
+ const bodyFace = _optionalChain([[...faceWeight], 'access', _125 => _125.sort, 'call', _126 => _126((a, b) => b[1] - a[1]), 'access', _127 => _127[0], 'optionalAccess', _128 => _128[0]]);
3706
3707
  if (!bodyFace || (_nullishCoalesce(faceWeight.get(bodyFace), () => ( 0))) < 250) continue;
3707
3708
  const sizeWeight = /* @__PURE__ */ new Map();
3708
3709
  for (const block of page) {
3709
- if (block.type !== "paragraph" || !_optionalChain([block, 'access', _127 => _127.style, 'optionalAccess', _128 => _128.fontSize])) continue;
3710
+ if (block.type !== "paragraph" || !_optionalChain([block, 'access', _129 => _129.style, 'optionalAccess', _130 => _130.fontSize])) continue;
3710
3711
  const faces = FACE_CHARS.get(block);
3711
- const chars = faces ? _nullishCoalesce(faces.get(bodyFace), () => ( 0)) : block.style.fontName === bodyFace ? _nullishCoalesce(_optionalChain([block, 'access', _129 => _129.text, 'optionalAccess', _130 => _130.length]), () => ( 0)) : 0;
3712
+ const chars = faces ? _nullishCoalesce(faces.get(bodyFace), () => ( 0)) : block.style.fontName === bodyFace ? _nullishCoalesce(_optionalChain([block, 'access', _131 => _131.text, 'optionalAccess', _132 => _132.length]), () => ( 0)) : 0;
3712
3713
  if (chars) sizeWeight.set(block.style.fontSize, (_nullishCoalesce(sizeWeight.get(block.style.fontSize), () => ( 0))) + chars);
3713
3714
  }
3714
- const bodySize = _nullishCoalesce(_optionalChain([[...sizeWeight], 'access', _131 => _131.sort, 'call', _132 => _132((a, b) => b[1] - a[1]), 'access', _133 => _133[0], 'optionalAccess', _134 => _134[0]]), () => ( 0));
3715
+ const bodySize = _nullishCoalesce(_optionalChain([[...sizeWeight], 'access', _133 => _133.sort, 'call', _134 => _134((a, b) => b[1] - a[1]), 'access', _135 => _135[0], 'optionalAccess', _136 => _136[0]]), () => ( 0));
3715
3716
  for (let i = 0; i < page.length; i++) {
3716
3717
  const block = page[i];
3717
3718
  const { text, bbox, style } = block;
3718
- if (block.type !== "paragraph" || !text || !bbox || !_optionalChain([style, 'optionalAccess', _135 => _135.fontName]) || !style.fontSize) continue;
3719
+ if (block.type !== "paragraph" || !text || !bbox || !_optionalChain([style, 'optionalAccess', _137 => _137.fontName]) || !style.fontSize) continue;
3719
3720
  const title = text.trim();
3720
3721
  const numbered = /^\d+(?:\.\d+)*\.?\s+[A-Z가-힣]/.test(title);
3721
3722
  const faces = FACE_CHARS.get(block);
@@ -3745,16 +3746,16 @@ function detectDocumentStyleHeadings(blocks) {
3745
3746
  for (const page of byPage.values()) {
3746
3747
  const faceChars = /* @__PURE__ */ new Map();
3747
3748
  for (const block of page) {
3748
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _136 => _136.style, 'optionalAccess', _137 => _137.fontName])) continue;
3749
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _138 => _138.style, 'optionalAccess', _139 => _139.fontName])) continue;
3749
3750
  faceChars.set(block.style.fontName, (_nullishCoalesce(faceChars.get(block.style.fontName), () => ( 0))) + block.text.length);
3750
3751
  }
3751
- const bodyFace = _optionalChain([[...faceChars], 'access', _138 => _138.sort, 'call', _139 => _139((a, b) => b[1] - a[1]), 'access', _140 => _140[0], 'optionalAccess', _141 => _141[0]]);
3752
+ const bodyFace = _optionalChain([[...faceChars], 'access', _140 => _140.sort, 'call', _141 => _141((a, b) => b[1] - a[1]), 'access', _142 => _142[0], 'optionalAccess', _143 => _143[0]]);
3752
3753
  if (!bodyFace || (_nullishCoalesce(faceChars.get(bodyFace), () => ( 0))) < 100) continue;
3753
- const labels = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _142 => _142.style, 'optionalAccess', _143 => _143.fontName]) && b.style.fontName !== bodyFace && b.text.trim().length >= 3 && b.text.trim().length <= 40);
3754
+ const labels = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _144 => _144.style, 'optionalAccess', _145 => _145.fontName]) && b.style.fontName !== bodyFace && b.text.trim().length >= 3 && b.text.trim().length <= 40);
3754
3755
  for (const label of labels) {
3755
- const peers = labels.filter((b) => _optionalChain([b, 'access', _144 => _144.style, 'optionalAccess', _145 => _145.fontName]) === _optionalChain([label, 'access', _146 => _146.style, 'optionalAccess', _147 => _147.fontName]) && Math.abs(b.bbox.y - label.bbox.y) <= 3 && Math.abs(b.bbox.x - label.bbox.x) >= 60);
3756
+ const peers = labels.filter((b) => _optionalChain([b, 'access', _146 => _146.style, 'optionalAccess', _147 => _147.fontName]) === _optionalChain([label, 'access', _148 => _148.style, 'optionalAccess', _149 => _149.fontName]) && Math.abs(b.bbox.y - label.bbox.y) <= 3 && Math.abs(b.bbox.x - label.bbox.x) >= 60);
3756
3757
  if (peers.length < 2) continue;
3757
- const value = page.find((b) => b.type === "paragraph" && b.bbox && _optionalChain([b, 'access', _148 => _148.style, 'optionalAccess', _149 => _149.fontName]) !== _optionalChain([label, 'access', _150 => _150.style, 'optionalAccess', _151 => _151.fontName]) && b.bbox.x >= label.bbox.x - 5 && b.bbox.x <= label.bbox.x + 20 && b.bbox.y < label.bbox.y && label.bbox.y - (b.bbox.y + b.bbox.height) <= 60);
3758
+ const value = page.find((b) => b.type === "paragraph" && b.bbox && _optionalChain([b, 'access', _150 => _150.style, 'optionalAccess', _151 => _151.fontName]) !== _optionalChain([label, 'access', _152 => _152.style, 'optionalAccess', _153 => _153.fontName]) && b.bbox.x >= label.bbox.x - 5 && b.bbox.x <= label.bbox.x + 20 && b.bbox.y < label.bbox.y && label.bbox.y - (b.bbox.y + b.bbox.height) <= 60);
3758
3759
  if (value) {
3759
3760
  label.type = "heading";
3760
3761
  label.level = 2;
@@ -3763,7 +3764,7 @@ function detectDocumentStyleHeadings(blocks) {
3763
3764
  const first = page.find((b) => b.type !== "image" && b.type !== "separator");
3764
3765
  const second = page[page.indexOf(first) + 1];
3765
3766
  const third = page[page.indexOf(first) + 2];
3766
- if (!first || !second || !third || first.type !== "list" && first.type !== "paragraph" || second.type !== "paragraph" || !first.text || !second.text || !first.bbox || !second.bbox || !_optionalChain([first, 'access', _152 => _152.style, 'optionalAccess', _153 => _153.fontName]) || !_optionalChain([second, 'access', _154 => _154.style, 'optionalAccess', _155 => _155.fontName]) || !/^\d+(?:\.\d+)*\.\s+/.test(first.text.trim()) || first.style.fontName === bodyFace || second.style.fontName === bodyFace || first.text.length + second.text.length > 140 || Math.abs(first.bbox.x - second.bbox.x) > 30 || first.bbox.y - (second.bbox.y + second.bbox.height) > (_nullishCoalesce(first.style.fontSize, () => ( 0))) * 1.5 || _optionalChain([third, 'access', _156 => _156.style, 'optionalAccess', _157 => _157.fontName]) !== bodyFace) continue;
3767
+ if (!first || !second || !third || first.type !== "list" && first.type !== "paragraph" || second.type !== "paragraph" || !first.text || !second.text || !first.bbox || !second.bbox || !_optionalChain([first, 'access', _154 => _154.style, 'optionalAccess', _155 => _155.fontName]) || !_optionalChain([second, 'access', _156 => _156.style, 'optionalAccess', _157 => _157.fontName]) || !/^\d+(?:\.\d+)*\.\s+/.test(first.text.trim()) || first.style.fontName === bodyFace || second.style.fontName === bodyFace || first.text.length + second.text.length > 140 || Math.abs(first.bbox.x - second.bbox.x) > 30 || first.bbox.y - (second.bbox.y + second.bbox.height) > (_nullishCoalesce(first.style.fontSize, () => ( 0))) * 1.5 || _optionalChain([third, 'access', _158 => _158.style, 'optionalAccess', _159 => _159.fontName]) !== bodyFace) continue;
3767
3768
  first.type = "heading";
3768
3769
  first.level = 1;
3769
3770
  first.text = `${first.text.trim()} ${second.text.trim()}`;
@@ -3787,18 +3788,18 @@ function detectSiblingStyleHeadings(blocks) {
3787
3788
  for (const page of byPage.values()) {
3788
3789
  const bodyChars = /* @__PURE__ */ new Map();
3789
3790
  for (const block of page) {
3790
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _158 => _158.style, 'optionalAccess', _159 => _159.fontName])) continue;
3791
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _160 => _160.style, 'optionalAccess', _161 => _161.fontName])) continue;
3791
3792
  const face = block.style.fontName;
3792
3793
  bodyChars.set(face, (_nullishCoalesce(bodyChars.get(face), () => ( 0))) + block.text.length);
3793
3794
  }
3794
- const bodyFace = _optionalChain([[...bodyChars], 'access', _160 => _160.sort, 'call', _161 => _161((a, b) => b[1] - a[1]), 'access', _162 => _162[0], 'optionalAccess', _163 => _163[0]]);
3795
- const anchors = page.filter((b) => b.type === "heading" && b.text && _optionalChain([b, 'access', _164 => _164.style, 'optionalAccess', _165 => _165.fontName]) && b.style.fontName !== bodyFace);
3795
+ const bodyFace = _optionalChain([[...bodyChars], 'access', _162 => _162.sort, 'call', _163 => _163((a, b) => b[1] - a[1]), 'access', _164 => _164[0], 'optionalAccess', _165 => _165[0]]);
3796
+ const anchors = page.filter((b) => b.type === "heading" && b.text && _optionalChain([b, 'access', _166 => _166.style, 'optionalAccess', _167 => _167.fontName]) && b.style.fontName !== bodyFace);
3796
3797
  for (const anchor of anchors) {
3797
3798
  const numbered = /^([A-Z])\.\d+\s+/.exec(anchor.text.trim());
3798
3799
  const lettered = /^([A-Z])\s+/.exec(anchor.text.trim());
3799
- const peers = anchors.filter((b) => _optionalChain([b, 'access', _166 => _166.style, 'optionalAccess', _167 => _167.fontName]) === _optionalChain([anchor, 'access', _168 => _168.style, 'optionalAccess', _169 => _169.fontName]) && Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _170 => _170.style, 'optionalAccess', _171 => _171.fontSize]), () => ( 0))) - (_nullishCoalesce(_optionalChain([anchor, 'access', _172 => _172.style, 'optionalAccess', _173 => _173.fontSize]), () => ( 0)))) < 0.5);
3800
+ const peers = anchors.filter((b) => _optionalChain([b, 'access', _168 => _168.style, 'optionalAccess', _169 => _169.fontName]) === _optionalChain([anchor, 'access', _170 => _170.style, 'optionalAccess', _171 => _171.fontName]) && Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _172 => _172.style, 'optionalAccess', _173 => _173.fontSize]), () => ( 0))) - (_nullishCoalesce(_optionalChain([anchor, 'access', _174 => _174.style, 'optionalAccess', _175 => _175.fontSize]), () => ( 0)))) < 0.5);
3800
3801
  if (peers.length < 2 && !numbered && !lettered) continue;
3801
- const candidates = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _174 => _174.style, 'optionalAccess', _175 => _175.fontName]) === _optionalChain([anchor, 'access', _176 => _176.style, 'optionalAccess', _177 => _177.fontName]) && Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _178 => _178.style, 'optionalAccess', _179 => _179.fontSize]), () => ( 0))) - (_nullishCoalesce(_optionalChain([anchor, 'access', _180 => _180.style, 'optionalAccess', _181 => _181.fontSize]), () => ( 0)))) < 0.5 && b.text.trim().length >= 3 && b.text.trim().length <= 80 && b.bbox.height <= (_nullishCoalesce(_optionalChain([b, 'access', _182 => _182.style, 'optionalAccess', _183 => _183.fontSize]), () => ( 0))) * 1.6 && /^[A-Z]/.test(b.text.trim()) && !/[.!?:;,]$/.test(b.text.trim()) && !/^(?:Table|Figure|Fig\.?|Appendix)\s+\d/i.test(b.text.trim()));
3802
+ const candidates = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _176 => _176.style, 'optionalAccess', _177 => _177.fontName]) === _optionalChain([anchor, 'access', _178 => _178.style, 'optionalAccess', _179 => _179.fontName]) && Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _180 => _180.style, 'optionalAccess', _181 => _181.fontSize]), () => ( 0))) - (_nullishCoalesce(_optionalChain([anchor, 'access', _182 => _182.style, 'optionalAccess', _183 => _183.fontSize]), () => ( 0)))) < 0.5 && b.text.trim().length >= 3 && b.text.trim().length <= 80 && b.bbox.height <= (_nullishCoalesce(_optionalChain([b, 'access', _184 => _184.style, 'optionalAccess', _185 => _185.fontSize]), () => ( 0))) * 1.6 && /^[A-Z]/.test(b.text.trim()) && !/[.!?:;,]$/.test(b.text.trim()) && !/^(?:Table|Figure|Fig\.?|Appendix)\s+\d/i.test(b.text.trim()));
3802
3803
  const siblings = candidates.filter((b) => numbered ? new RegExp(`^${numbered[1]}\\.\\d+\\s+`).test(b.text.trim()) : lettered ? /^[A-Z]\s+/.test(b.text.trim()) && Math.abs(anchor.bbox.x - b.bbox.x) < 8 : peers.some((h) => h.bbox && Math.abs(h.bbox.x - b.bbox.x) < 8));
3803
3804
  if (siblings.length < (numbered || lettered ? 1 : 2)) continue;
3804
3805
  for (const sibling of siblings) {
@@ -3817,13 +3818,13 @@ function detectRepeatedPageLabels(blocks) {
3817
3818
  }
3818
3819
  for (const page of byPage.values()) {
3819
3820
  const bodyChars = /* @__PURE__ */ new Map();
3820
- for (const b of page) if (b.type === "paragraph" && b.text && _optionalChain([b, 'access', _184 => _184.style, 'optionalAccess', _185 => _185.fontName])) {
3821
+ for (const b of page) if (b.type === "paragraph" && b.text && _optionalChain([b, 'access', _186 => _186.style, 'optionalAccess', _187 => _187.fontName])) {
3821
3822
  const faces = FACE_CHARS.get(b);
3822
3823
  if (faces) for (const [face, n] of faces) bodyChars.set(face, (_nullishCoalesce(bodyChars.get(face), () => ( 0))) + n);
3823
3824
  else bodyChars.set(b.style.fontName, (_nullishCoalesce(bodyChars.get(b.style.fontName), () => ( 0))) + b.text.length);
3824
3825
  }
3825
- const bodyFace = _optionalChain([[...bodyChars], 'access', _186 => _186.sort, 'call', _187 => _187((a, b) => b[1] - a[1]), 'access', _188 => _188[0], 'optionalAccess', _189 => _189[0]]);
3826
- const candidates = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _190 => _190.style, 'optionalAccess', _191 => _191.fontName]) && b.style.fontName !== bodyFace && b.bbox.height <= (_nullishCoalesce(b.style.fontSize, () => ( 0))) * 1.6 && b.text.trim().length >= 5 && b.text.trim().length <= 80);
3826
+ const bodyFace = _optionalChain([[...bodyChars], 'access', _188 => _188.sort, 'call', _189 => _189((a, b) => b[1] - a[1]), 'access', _190 => _190[0], 'optionalAccess', _191 => _191[0]]);
3827
+ const candidates = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _192 => _192.style, 'optionalAccess', _193 => _193.fontName]) && b.style.fontName !== bodyFace && b.bbox.height <= (_nullishCoalesce(b.style.fontSize, () => ( 0))) * 1.6 && b.text.trim().length >= 5 && b.text.trim().length <= 80);
3827
3828
  const groups = /* @__PURE__ */ new Map();
3828
3829
  for (const b of candidates) {
3829
3830
  const key = `${b.style.fontName}:${b.style.fontSize}`;
@@ -3859,19 +3860,19 @@ function detectPageLeadHeadings(blocks) {
3859
3860
  for (const page of byPage.values()) {
3860
3861
  const content = page.filter((b) => b.type !== "image" && b.type !== "separator" && !(b.type === "paragraph" && !b.style));
3861
3862
  const [first, second, third] = content;
3862
- if (!_optionalChain([first, 'optionalAccess', _192 => _192.bbox]) || !first.text || !_optionalChain([first, 'access', _193 => _193.style, 'optionalAccess', _194 => _194.fontSize]) || !second) continue;
3863
+ if (!_optionalChain([first, 'optionalAccess', _194 => _194.bbox]) || !first.text || !_optionalChain([first, 'access', _195 => _195.style, 'optionalAccess', _196 => _196.fontSize]) || !second) continue;
3863
3864
  const firstText = first.text.trim();
3864
3865
  const captionLike = /^(?:Figure|Fig\.?|Table|표|그림)\s*\d/i;
3865
3866
  const hasImage = page.some((b) => b.type === "image");
3866
- const firstIsTitle = first.type === "paragraph" && firstText.length >= 5 && firstText.length <= 80 && first.bbox.height <= first.style.fontSize * 1.6 && (/^(?:CONTENTS|Table of Contents)$/i.test(firstText) || hasImage && /^[A-Z]/.test(firstText) && !captionLike.test(firstText) && second.type === "paragraph" && /^[A-Z]/.test(_nullishCoalesce(_optionalChain([second, 'access', _195 => _195.text, 'optionalAccess', _196 => _196.trim, 'call', _197 => _197()]), () => ( ""))) && (_nullishCoalesce(_optionalChain([second, 'access', _198 => _198.text, 'optionalAccess', _199 => _199.length]), () => ( 0))) >= 100 && second.bbox && first.bbox.y - (second.bbox.y + second.bbox.height) >= first.style.fontSize);
3867
+ const firstIsTitle = first.type === "paragraph" && firstText.length >= 5 && firstText.length <= 80 && first.bbox.height <= first.style.fontSize * 1.6 && (/^(?:CONTENTS|Table of Contents)$/i.test(firstText) || hasImage && /^[A-Z]/.test(firstText) && !captionLike.test(firstText) && second.type === "paragraph" && /^[A-Z]/.test(_nullishCoalesce(_optionalChain([second, 'access', _197 => _197.text, 'optionalAccess', _198 => _198.trim, 'call', _199 => _199()]), () => ( ""))) && (_nullishCoalesce(_optionalChain([second, 'access', _200 => _200.text, 'optionalAccess', _201 => _201.length]), () => ( 0))) >= 100 && second.bbox && first.bbox.y - (second.bbox.y + second.bbox.height) >= first.style.fontSize);
3867
3868
  const firstAboveProse = first.type === "paragraph" && firstText.length >= 5 && firstText.length <= 80 && first.bbox.height <= first.style.fontSize * 2 && second.type === "paragraph" && second.bbox && second.bbox.height >= first.style.fontSize * 4 && Math.abs(first.bbox.x - second.bbox.x) <= first.style.fontSize * 2 && first.bbox.y - (second.bbox.y + second.bbox.height) >= first.style.fontSize * 2 && !captionLike.test(firstText) && !/^(?:doi:|https?:|www\.)/i.test(firstText);
3868
- const firstIsSection = first.type === "list" && /^\d+\.\s+[A-Z][A-Z\s]{12,}$/.test(firstText) && second.type === "paragraph" && (_nullishCoalesce(_optionalChain([second, 'access', _200 => _200.text, 'optionalAccess', _201 => _201.length]), () => ( 0))) >= 100;
3869
+ const firstIsSection = first.type === "list" && /^\d+\.\s+[A-Z][A-Z\s]{12,}$/.test(firstText) && second.type === "paragraph" && (_nullishCoalesce(_optionalChain([second, 'access', _202 => _202.text, 'optionalAccess', _203 => _203.length]), () => ( 0))) >= 100;
3869
3870
  if (firstIsTitle || firstAboveProse || firstIsSection) {
3870
3871
  first.type = "heading";
3871
3872
  first.level = 1;
3872
3873
  }
3873
- if (first.type !== "heading" || captionLike.test(firstText) || second.type !== "paragraph" || !second.text || !second.bbox || !_optionalChain([second, 'access', _202 => _202.style, 'optionalAccess', _203 => _203.fontName]) || !second.style.fontSize || !_optionalChain([third, 'optionalAccess', _204 => _204.text]) || !third.bbox || second.text.trim().length < 5 || second.text.trim().length > 80 || captionLike.test(second.text.trim()) || /^(?:doi:|https?:)/i.test(second.text.trim()) || second.bbox.height > second.style.fontSize * 1.6 || Math.abs(second.bbox.x - third.bbox.x) > 30) continue;
3874
- const distinctFace = _optionalChain([third, 'access', _205 => _205.style, 'optionalAccess', _206 => _206.fontName]) !== second.style.fontName;
3874
+ if (first.type !== "heading" || captionLike.test(firstText) || second.type !== "paragraph" || !second.text || !second.bbox || !_optionalChain([second, 'access', _204 => _204.style, 'optionalAccess', _205 => _205.fontName]) || !second.style.fontSize || !_optionalChain([third, 'optionalAccess', _206 => _206.text]) || !third.bbox || second.text.trim().length < 5 || second.text.trim().length > 80 || captionLike.test(second.text.trim()) || /^(?:doi:|https?:)/i.test(second.text.trim()) || second.bbox.height > second.style.fontSize * 1.6 || Math.abs(second.bbox.x - third.bbox.x) > 30) continue;
3875
+ const distinctFace = _optionalChain([third, 'access', _207 => _207.style, 'optionalAccess', _208 => _208.fontName]) !== second.style.fontName;
3875
3876
  const namedContents = /^Table of Contents$/i.test(second.text.trim());
3876
3877
  if (distinctFace && third.text.length >= 60 || namedContents) {
3877
3878
  second.type = "heading";
@@ -3882,24 +3883,24 @@ function detectPageLeadHeadings(blocks) {
3882
3883
  function refineDocumentStyleHeadings(blocks) {
3883
3884
  const faceChars = /* @__PURE__ */ new Map();
3884
3885
  for (const block of blocks) {
3885
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _207 => _207.style, 'optionalAccess', _208 => _208.fontName])) continue;
3886
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _209 => _209.style, 'optionalAccess', _210 => _210.fontName])) continue;
3886
3887
  faceChars.set(block.style.fontName, (_nullishCoalesce(faceChars.get(block.style.fontName), () => ( 0))) + block.text.length);
3887
3888
  }
3888
3889
  const [bodyFace, bodyChars] = _nullishCoalesce([...faceChars].sort((a, b) => b[1] - a[1])[0], () => ( []));
3889
3890
  if (!bodyFace || !bodyChars || bodyChars < 300) return;
3890
3891
  for (let i = 0; i < blocks.length; i++) {
3891
3892
  const block = blocks[i];
3892
- const text = _nullishCoalesce(_optionalChain([block, 'access', _209 => _209.text, 'optionalAccess', _210 => _210.trim, 'call', _211 => _211()]), () => ( ""));
3893
+ const text = _nullishCoalesce(_optionalChain([block, 'access', _211 => _211.text, 'optionalAccess', _212 => _212.trim, 'call', _213 => _213()]), () => ( ""));
3893
3894
  if (block.type === "heading" && /(?:https?:\/\/|www\.|^arxiv:|^doi:)/i.test(text)) {
3894
3895
  block.type = "paragraph";
3895
3896
  block.level = void 0;
3896
3897
  continue;
3897
3898
  }
3898
3899
  const box = block.bbox, style = block.style;
3899
- if (block.type !== "paragraph" || !box || !_optionalChain([style, 'optionalAccess', _212 => _212.fontName]) || !style.fontSize || style.fontName === bodyFace || (_nullishCoalesce(faceChars.get(style.fontName), () => ( 0))) > bodyChars * 0.25 || text.length < 3 || text.length > 70 || text.includes("\n") || box.height > style.fontSize * 1.6 || /^(?:table|figure|fig\.?|source|doi:|arxiv:|https?:|www\.|[•●○▪▫⮚*∗†])/i.test(text) || /(?:https?:\/\/|www\.|@|[=¼≪þ])/i.test(text) || /^definition\s+\d+[.:]?\s+.*\b(?:is|are|means)\b/i.test(text) || /^[\d\s.,:%+\-–]+$/.test(text)) continue;
3900
+ if (block.type !== "paragraph" || !box || !_optionalChain([style, 'optionalAccess', _214 => _214.fontName]) || !style.fontSize || style.fontName === bodyFace || (_nullishCoalesce(faceChars.get(style.fontName), () => ( 0))) > bodyChars * 0.25 || text.length < 3 || text.length > 70 || text.includes("\n") || box.height > style.fontSize * 1.6 || /^(?:table|figure|fig\.?|source|doi:|arxiv:|https?:|www\.|[•●○▪▫⮚*∗†])/i.test(text) || /(?:https?:\/\/|www\.|@|[=¼≪þ])/i.test(text) || /^definition\s+\d+[.:]?\s+.*\b(?:is|are|means)\b/i.test(text) || /^[\d\s.,:%+\-–]+$/.test(text)) continue;
3900
3901
  const previous = blocks[i - 1], next = blocks[i + 1];
3901
- const pb = _optionalChain([previous, 'optionalAccess', _213 => _213.bbox]), nb = _optionalChain([next, 'optionalAccess', _214 => _214.bbox]);
3902
- if (!pb || !nb || previous.pageNumber !== block.pageNumber || next.pageNumber !== block.pageNumber || previous.type !== "paragraph" && previous.type !== "heading" || next.type !== "paragraph" || _optionalChain([next, 'access', _215 => _215.style, 'optionalAccess', _216 => _216.fontName]) !== bodyFace || !next.text || next.text.length < 40 || style.fontSize < (_nullishCoalesce(next.style.fontSize, () => ( 0))) * 0.95 || pb.y - (box.y + box.height) < style.fontSize * 0.5 || box.y - (nb.y + nb.height) < 0 || box.y - (nb.y + nb.height) > style.fontSize * 2 || box.x + box.width / 2 < nb.x - 10 || box.x + box.width / 2 > nb.x + nb.width + 10) continue;
3902
+ const pb = _optionalChain([previous, 'optionalAccess', _215 => _215.bbox]), nb = _optionalChain([next, 'optionalAccess', _216 => _216.bbox]);
3903
+ if (!pb || !nb || previous.pageNumber !== block.pageNumber || next.pageNumber !== block.pageNumber || previous.type !== "paragraph" && previous.type !== "heading" || next.type !== "paragraph" || _optionalChain([next, 'access', _217 => _217.style, 'optionalAccess', _218 => _218.fontName]) !== bodyFace || !next.text || next.text.length < 40 || style.fontSize < (_nullishCoalesce(next.style.fontSize, () => ( 0))) * 0.95 || pb.y - (box.y + box.height) < style.fontSize * 0.5 || box.y - (nb.y + nb.height) < 0 || box.y - (nb.y + nb.height) > style.fontSize * 2 || box.x + box.width / 2 < nb.x - 10 || box.x + box.width / 2 > nb.x + nb.width + 10) continue;
3903
3904
  block.type = "heading";
3904
3905
  block.level = 2;
3905
3906
  }
@@ -3949,7 +3950,7 @@ function detectMarkerHeadings(blocks) {
3949
3950
  block.level = 4;
3950
3951
  continue;
3951
3952
  }
3952
- if (/^[가-힣]{2,6}$/.test(text) && _optionalChain([block, 'access', _217 => _217.style, 'optionalAccess', _218 => _218.fontSize])) {
3953
+ if (/^[가-힣]{2,6}$/.test(text) && _optionalChain([block, 'access', _219 => _219.style, 'optionalAccess', _220 => _220.fontSize])) {
3953
3954
  const prev = blocks[i - 1];
3954
3955
  const next = blocks[i + 1];
3955
3956
  const prevIsStructural = !prev || prev.type === "table" || prev.type === "heading" || prev.type === "separator";
@@ -3990,7 +3991,7 @@ function detectTableCaptions(blocks) {
3990
3991
  block.table.caption = blocks[i - 1].text.trim();
3991
3992
  blocks.splice(i - 1, 1);
3992
3993
  i--;
3993
- } else if (isCaptionCandidate(blocks[i + 1], block) && _optionalChain([blocks, 'access', _219 => _219[i + 2], 'optionalAccess', _220 => _220.type]) !== "table") {
3994
+ } else if (isCaptionCandidate(blocks[i + 1], block) && _optionalChain([blocks, 'access', _221 => _221[i + 2], 'optionalAccess', _222 => _222.type]) !== "table") {
3994
3995
  block.table.caption = blocks[i + 1].text.trim();
3995
3996
  blocks.splice(i + 1, 1);
3996
3997
  }
@@ -4197,14 +4198,19 @@ function detectSpecialKoreanTables(blocks) {
4197
4198
  flushKvTable();
4198
4199
  return result;
4199
4200
  }
4200
- function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables = false) {
4201
+ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables = false, context = []) {
4202
+ if (context.length && !tables) {
4203
+ const removed = removeHeaderFooterBlocks([...blocks, ...context], pageHeights, [], notes).filter((index) => index < blocks.length);
4204
+ if (removed.length) warnings.push({ message: `${removed.length}\uAC1C \uBA38\uB9AC\uAE00/\uBC14\uB2E5\uAE00 \uC694\uC18C \uC81C\uAC70\uB428`, code: "HIDDEN_TEXT_FILTERED" });
4205
+ return removed;
4206
+ }
4201
4207
  const ZONE_RATIO = 0.12;
4202
4208
  const MIN_REPEAT2 = 3;
4203
4209
  const topEntries = [];
4204
4210
  const bottomEntries = [];
4205
4211
  for (let bi = 0; bi < blocks.length; bi++) {
4206
4212
  const b = blocks[bi];
4207
- const text = !tables ? _optionalChain([b, 'access', _221 => _221.text, 'optionalAccess', _222 => _222.trim, 'call', _223 => _223()]) : b.type === "table" && b.table ? b.table.cells.flat().map((c) => c.text.trim()).filter(Boolean).join(" | ") : void 0;
4213
+ const text = !tables ? _optionalChain([b, 'access', _223 => _223.text, 'optionalAccess', _224 => _224.trim, 'call', _225 => _225()]) : b.type === "table" && b.table ? b.table.cells.flat().map((c) => c.text.trim()).filter(Boolean).join(" | ") : void 0;
4208
4214
  if (!b.bbox || !b.pageNumber || !text) continue;
4209
4215
  const ph = pageHeights.get(b.bbox.page) || pageHeights.get(b.pageNumber);
4210
4216
  if (!ph) continue;
@@ -4235,7 +4241,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
4235
4241
  for (const [p, count] of patternCount) {
4236
4242
  const pages = [..._nullishCoalesce(patternPages.get(p), () => ( []))];
4237
4243
  const span = pages.length ? Math.max(...pages) - Math.min(...pages) + 1 : 0;
4238
- const pageNumbered = !tables && (_nullishCoalesce(_optionalChain([patternNumbers, 'access', _224 => _224.get, 'call', _225 => _225(p), 'optionalAccess', _226 => _226.size]), () => ( 0))) > 1;
4244
+ const pageNumbered = !tables && (_nullishCoalesce(_optionalChain([patternNumbers, 'access', _226 => _226.get, 'call', _227 => _227(p), 'optionalAccess', _228 => _228.size]), () => ( 0))) > 1;
4239
4245
  if (count >= MIN_REPEAT2 && pages.length >= MIN_REPEAT2 && (pages.length >= span * 0.4 || pageNumbered)) {
4240
4246
  repeatedPatterns.add(p);
4241
4247
  }
@@ -4243,8 +4249,8 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
4243
4249
  for (const e of entries) {
4244
4250
  const norm = e.text.replace(/\d+/g, "#");
4245
4251
  if (!repeatedPatterns.has(norm)) continue;
4246
- const noteMark = _optionalChain([e, 'access', _227 => _227.text, 'access', _228 => _228.match, 'call', _229 => _229(/^\d{1,3}\)/), 'optionalAccess', _230 => _230[0]]);
4247
- if (noteMark && _optionalChain([notes, 'optionalAccess', _231 => _231.get, 'call', _232 => _232(e.page), 'optionalAccess', _233 => _233.marks, 'access', _234 => _234.some, 'call', _235 => _235((m) => m.mark === noteMark)])) continue;
4252
+ const noteMark = _optionalChain([e, 'access', _229 => _229.text, 'access', _230 => _230.match, 'call', _231 => _231(/^\d{1,3}\)/), 'optionalAccess', _232 => _232[0]]);
4253
+ if (noteMark && _optionalChain([notes, 'optionalAccess', _233 => _233.get, 'call', _234 => _234(e.page), 'optionalAccess', _235 => _235.marks, 'access', _236 => _236.some, 'call', _237 => _237((m) => m.mark === noteMark)])) continue;
4248
4254
  const cand = blocks[e.blockIdx];
4249
4255
  const cb = cand.bbox;
4250
4256
  const tableNote = /^(?:주\s*(?:\d+\s*[).:]|[::])|(?:자료|출처)\s*[::])/.test(e.text.replace(/ \| /g, " ")) && blocks.some((o) => {
@@ -4258,7 +4264,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
4258
4264
  if (bi === e.blockIdx) continue;
4259
4265
  const o = blocks[bi];
4260
4266
  if (!o.bbox || o.bbox.page !== cb.page) continue;
4261
- const oNorm = _optionalChain([o, 'access', _236 => _236.text, 'optionalAccess', _237 => _237.trim, 'call', _238 => _238(), 'access', _239 => _239.replace, 'call', _240 => _240(/\d+/g, "#")]);
4267
+ const oNorm = _optionalChain([o, 'access', _238 => _238.text, 'optionalAccess', _239 => _239.trim, 'call', _240 => _240(), 'access', _241 => _241.replace, 'call', _242 => _242(/\d+/g, "#")]);
4262
4268
  if (oNorm && repeatedPatterns.has(oNorm)) continue;
4263
4269
  const overlap2 = Math.min(cb.y + cb.height, o.bbox.y + o.bbox.height) - Math.max(cb.y, o.bbox.y);
4264
4270
  if (overlap2 >= cb.height * 0.5) {
@@ -4277,6 +4283,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
4277
4283
 
4278
4284
  // src/pdf/table-meta.ts
4279
4285
  var CLIP_TABLES = /* @__PURE__ */ new WeakSet();
4286
+ var FRAME_TITLE_BLOCKS = /* @__PURE__ */ new WeakMap();
4280
4287
  var TABLE_COLXS = /* @__PURE__ */ new WeakMap();
4281
4288
  var TABLE_ROWYS = /* @__PURE__ */ new WeakMap();
4282
4289
  var TABLE_TAIL = /* @__PURE__ */ new WeakMap();
@@ -4332,7 +4339,7 @@ function recordRowRules(table, cells, bbox, hs) {
4332
4339
  function markImageCell(cell) {
4333
4340
  IMAGE_CELLS.add(cell);
4334
4341
  }
4335
- var emptyCell = (cell) => !cell || !_optionalChain([cell, 'access', _241 => _241.text, 'optionalAccess', _242 => _242.trim, 'call', _243 => _243()]) && !_optionalChain([cell, 'access', _244 => _244.blocks, 'optionalAccess', _245 => _245.length]) && !IMAGE_CELLS.has(cell);
4342
+ var emptyCell = (cell) => !cell || !_optionalChain([cell, 'access', _243 => _243.text, 'optionalAccess', _244 => _244.trim, 'call', _245 => _245()]) && !_optionalChain([cell, 'access', _246 => _246.blocks, 'optionalAccess', _247 => _247.length]) && !IMAGE_CELLS.has(cell);
4336
4343
  function trimTable(table) {
4337
4344
  let cols = table.cols;
4338
4345
  while (cols > 0 && table.cells.every((row) => emptyCell(row[cols - 1]))) cols--;
@@ -4348,7 +4355,7 @@ function trimTable(table) {
4348
4355
  function trimTrailingEmptyTableCols(blocks) {
4349
4356
  for (const b of blocks) {
4350
4357
  if (b.type !== "table" || !b.table) continue;
4351
- for (const row of b.table.cells) for (const cell of row) if (_optionalChain([cell, 'access', _246 => _246.blocks, 'optionalAccess', _247 => _247.length])) trimTrailingEmptyTableCols(cell.blocks);
4358
+ for (const row of b.table.cells) for (const cell of row) if (_optionalChain([cell, 'access', _248 => _248.blocks, 'optionalAccess', _249 => _249.length])) trimTrailingEmptyTableCols(cell.blocks);
4352
4359
  trimTable(b.table);
4353
4360
  }
4354
4361
  }
@@ -4368,7 +4375,7 @@ function mergeSliverColumns(grid, colXs, maxWidth) {
4368
4375
  }
4369
4376
  const ok = owner.every((row) => {
4370
4377
  const o = row[c];
4371
- return !!o && (o.colSpan > 1 || !o.text.trim() && !_optionalChain([o, 'access', _248 => _248.blocks, 'optionalAccess', _249 => _249.length]));
4378
+ return !!o && (o.colSpan > 1 || !o.text.trim() && !_optionalChain([o, 'access', _250 => _250.blocks, 'optionalAccess', _251 => _251.length]));
4372
4379
  });
4373
4380
  if (!ok) continue;
4374
4381
  const spanning = /* @__PURE__ */ new Set();
@@ -4384,6 +4391,262 @@ function mergeSliverColumns(grid, colXs, maxWidth) {
4384
4391
  return merged;
4385
4392
  }
4386
4393
 
4394
+ // src/pdf/image-bullets.ts
4395
+
4396
+ var multiply = (m, t) => [
4397
+ m[0] * t[0] + m[2] * t[1],
4398
+ m[1] * t[0] + m[3] * t[1],
4399
+ m[0] * t[2] + m[2] * t[3],
4400
+ m[1] * t[2] + m[3] * t[3],
4401
+ m[0] * t[4] + m[2] * t[5] + m[4],
4402
+ m[1] * t[4] + m[3] * t[5] + m[5]
4403
+ ];
4404
+ function hollowCircle(image) {
4405
+ if (!_optionalChain([image, 'optionalAccess', _252 => _252.data]) || image.width < 16 || image.width > 128 || image.height < 16 || image.height > 128 || Math.abs(image.width - image.height) > Math.min(image.width, image.height) * 0.1) return false;
4406
+ const stride = image.kind === _pdfmjs.ImageKind.RGB_24BPP ? 3 : image.kind === _pdfmjs.ImageKind.RGBA_32BPP ? 4 : 0;
4407
+ const { width, height, data } = image;
4408
+ if (!stride || data.length < width * height * stride) return false;
4409
+ const dark = [];
4410
+ let white = 0;
4411
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
4412
+ const i = (y * width + x) * stride;
4413
+ if (stride === 4 && data[i + 3] < 240) return false;
4414
+ const min = Math.min(data[i], data[i + 1], data[i + 2]), max = Math.max(data[i], data[i + 1], data[i + 2]);
4415
+ if (max - min > 15) return false;
4416
+ if (min >= 235) white++;
4417
+ if (max < 180) dark.push({ x, y });
4418
+ }
4419
+ if (white < width * height * 0.65 || dark.length < width * height * 0.025 || dark.length > width * height * 0.3) return false;
4420
+ const x0 = Math.min(...dark.map((p) => p.x)), x1 = Math.max(...dark.map((p) => p.x));
4421
+ const y0 = Math.min(...dark.map((p) => p.y)), y1 = Math.max(...dark.map((p) => p.y));
4422
+ const w = x1 - x0 + 1, h = y1 - y0 + 1, radius = (w + h) / 4;
4423
+ const cx = (x0 + x1) / 2, cy = (y0 + y1) / 2;
4424
+ if (Math.abs(w - h) > Math.min(w, h) * 0.15 || w < width * 0.4 || w > width * 0.85 || h < height * 0.4 || h > height * 0.85 || x0 < width * 0.04 || y0 < height * 0.04 || x1 >= width * 0.96 || y1 >= height * 0.96 || Math.abs(cx - width / 2) > width * 0.15 || Math.abs(cy - height / 2) > height * 0.15) return false;
4425
+ const sectors = /* @__PURE__ */ new Set();
4426
+ for (const point of dark) {
4427
+ const r = Math.hypot(point.x - cx, point.y - cy) / radius;
4428
+ if (r < 0.65 || r > 1.15) return false;
4429
+ sectors.add(Math.floor((Math.atan2(point.y - cy, point.x - cx) + Math.PI) / (Math.PI * 2) * 8) % 8);
4430
+ }
4431
+ return sectors.size === 8;
4432
+ }
4433
+ async function resolveImagePixels(page, id) {
4434
+ const objects = id.startsWith("g_") ? page.commonObjs : page.objs;
4435
+ return new Promise((resolve) => {
4436
+ const timer = setTimeout(() => resolve(null), 5e3);
4437
+ try {
4438
+ objects.get(id, (value) => {
4439
+ clearTimeout(timer);
4440
+ resolve(_nullishCoalesce(value, () => ( null)));
4441
+ });
4442
+ } catch (e4) {
4443
+ clearTimeout(timer);
4444
+ resolve(null);
4445
+ }
4446
+ });
4447
+ }
4448
+ function smallVisibleImagePaints(fnArray, argsArray) {
4449
+ const paints = [];
4450
+ let ctm = [1, 0, 0, 1, 0, 0];
4451
+ let alpha = 1, clip = null, unknownClip = false;
4452
+ const stack = [];
4453
+ let pathRect, pendingClip = false;
4454
+ const intersectClip = (box) => {
4455
+ clip = clip ? {
4456
+ x1: Math.max(clip.x1, box.x1),
4457
+ y1: Math.max(clip.y1, box.y1),
4458
+ x2: Math.min(clip.x2, box.x2),
4459
+ y2: Math.min(clip.y2, box.y2)
4460
+ } : box;
4461
+ };
4462
+ const rectangle = (x, y, w, h) => extractImageRegions(
4463
+ [_pdfmjs.OPS.transform, _pdfmjs.OPS.transform, _pdfmjs.OPS.paintImageXObject],
4464
+ [ctm, [w, 0, 0, h, x, y], ["bounds"]]
4465
+ )[0];
4466
+ for (let i = 0; i < fnArray.length; i++) {
4467
+ const op = fnArray[i], args = argsArray[i];
4468
+ if (op === _pdfmjs.OPS.save || op === _pdfmjs.OPS.paintFormXObjectBegin) {
4469
+ stack.push({ ctm, alpha, clip, unknownClip });
4470
+ const matrix = op === _pdfmjs.OPS.paintFormXObjectBegin ? _optionalChain([args, 'optionalAccess', _253 => _253[0]]) : void 0;
4471
+ if (Array.isArray(matrix) && matrix.length >= 6) ctm = multiply(ctm, matrix);
4472
+ const bounds = op === _pdfmjs.OPS.paintFormXObjectBegin ? _optionalChain([args, 'optionalAccess', _254 => _254[1]]) : void 0;
4473
+ if (Array.isArray(bounds) && bounds.length === 4) {
4474
+ const box = rectangle(bounds[0], bounds[1], bounds[2] - bounds[0], bounds[3] - bounds[1]);
4475
+ if (box && ctm[1] === 0 && ctm[2] === 0) intersectClip(box);
4476
+ else unknownClip = true;
4477
+ }
4478
+ } else if (op === _pdfmjs.OPS.restore || op === _pdfmjs.OPS.paintFormXObjectEnd) {
4479
+ const state = stack.pop();
4480
+ ctm = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _255 => _255.ctm]), () => ( [1, 0, 0, 1, 0, 0]));
4481
+ alpha = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _256 => _256.alpha]), () => ( 1));
4482
+ clip = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _257 => _257.clip]), () => ( null));
4483
+ unknownClip = _nullishCoalesce(_optionalChain([state, 'optionalAccess', _258 => _258.unknownClip]), () => ( false));
4484
+ } else if (op === _pdfmjs.OPS.setGState) {
4485
+ for (const [key, value] of _nullishCoalesce(_optionalChain([args, 'optionalAccess', _259 => _259[0]]), () => ( []))) {
4486
+ if (key === "ca") alpha = typeof value === "number" ? value : 0;
4487
+ }
4488
+ } else if (op === _pdfmjs.OPS.constructPath) {
4489
+ const [operations, coordinates] = args;
4490
+ pathRect = pathRect === void 0 && _optionalChain([operations, 'optionalAccess', _260 => _260.length]) === 1 && operations[0] === _pdfmjs.OPS.rectangle && _optionalChain([coordinates, 'optionalAccess', _261 => _261.length]) >= 4 && ctm[1] === 0 && ctm[2] === 0 ? rectangle(coordinates[0], coordinates[1], coordinates[2], coordinates[3]) : null;
4491
+ } else if (op === _pdfmjs.OPS.clip || op === _pdfmjs.OPS.eoClip) pendingClip = true;
4492
+ else if ([
4493
+ _pdfmjs.OPS.endPath,
4494
+ _pdfmjs.OPS.stroke,
4495
+ _pdfmjs.OPS.closeStroke,
4496
+ _pdfmjs.OPS.fill,
4497
+ _pdfmjs.OPS.eoFill,
4498
+ _pdfmjs.OPS.fillStroke,
4499
+ _pdfmjs.OPS.eoFillStroke,
4500
+ _pdfmjs.OPS.closeFillStroke,
4501
+ _pdfmjs.OPS.closeEOFillStroke
4502
+ ].includes(op)) {
4503
+ if (pendingClip) {
4504
+ if (pathRect) intersectClip(pathRect);
4505
+ else unknownClip = true;
4506
+ }
4507
+ pendingClip = false;
4508
+ pathRect = void 0;
4509
+ } else if (op === _pdfmjs.OPS.transform && Array.isArray(args) && args.length >= 6) ctm = multiply(ctm, args);
4510
+ else if (op === _pdfmjs.OPS.paintImageXObject && typeof _optionalChain([args, 'optionalAccess', _262 => _262[0]]) === "string") {
4511
+ if (typeof args[1] !== "number" || typeof args[2] !== "number" || args[1] < 16 || args[1] > 128 || args[2] < 16 || args[2] > 128) continue;
4512
+ const box = extractImageRegions([_pdfmjs.OPS.transform, _pdfmjs.OPS.paintImageXObject], [ctm, args])[0];
4513
+ if (!box || ctm[1] !== 0 || ctm[2] !== 0 || alpha < 0.99 || unknownClip || clip && (box.x1 + (box.x2 - box.x1) * 0.03 < clip.x1 || box.y1 + (box.y2 - box.y1) * 0.03 < clip.y1 || box.x2 - (box.x2 - box.x1) * 0.03 > clip.x2 || box.y2 - (box.y2 - box.y1) * 0.03 > clip.y2)) continue;
4514
+ const width = box.x2 - box.x1, height = box.y2 - box.y1;
4515
+ if (width < 3 || width > 24 || height < 3 || height > 24 || width / height < 0.5 || width / height > 2) continue;
4516
+ paints.push({ id: args[0], box, mirrored: ctm[0] < 0 });
4517
+ }
4518
+ }
4519
+ return paints;
4520
+ }
4521
+ async function restoreImageBullets(items, page, fnArray, argsArray, shapes = /* @__PURE__ */ new Map()) {
4522
+ const candidates = [];
4523
+ for (const { id, box } of smallVisibleImagePaints(fnArray, argsArray)) {
4524
+ const width = box.x2 - box.x1, height = box.y2 - box.y1;
4525
+ if (Math.abs(width - height) > Math.min(width, height) * 0.1) continue;
4526
+ const line = items.filter((item) => !item.isHidden && item.fontSize > 0 && item.x >= box.x2 && item.x - box.x2 <= item.fontSize * 0.7 && Math.abs(item.y + item.h / 2 - (box.y1 + box.y2) / 2) <= item.fontSize * 0.4 && height >= item.fontSize * 0.5 && height <= item.fontSize * 1.2).sort((a, b) => a.x - b.x)[0];
4527
+ if (!line || /^[○●•◦□■∙]/.test(line.text.trim()) || !/\p{L}/u.test(line.text)) continue;
4528
+ const row = items.filter((item) => Math.abs(item.y - line.y) <= 2 && item.x >= line.x);
4529
+ if (row.reduce((n, item) => n + (_nullishCoalesce(_optionalChain([item, 'access', _263 => _263.text, 'access', _264 => _264.match, 'call', _265 => _265(/\p{L}/gu), 'optionalAccess', _266 => _266.length]), () => ( 0))), 0) < 12 || items.some((item) => item !== line && Math.abs(item.y - line.y) <= 2 && item.x < line.x)) continue;
4530
+ candidates.push({ id, x: box.x1, width, line });
4531
+ }
4532
+ let restored = 0;
4533
+ const used = /* @__PURE__ */ new Set();
4534
+ for (const candidate of candidates) {
4535
+ const same = candidates.filter((other) => other.id === candidate.id && other.line !== candidate.line && Math.abs(other.line.x - candidate.line.x) <= 1 && Math.abs(other.x - candidate.x) <= 1 && Math.abs(other.width - candidate.width) <= 1 && other.line.fontSize === candidate.line.fontSize && Math.abs(other.line.y - candidate.line.y) >= candidate.line.fontSize * 2);
4536
+ const numbered = items.filter((item) => !item.isHidden && /^[①-⑮]\s*/.test(item.text.trim()) && item.fontName === candidate.line.fontName && item.fontSize === candidate.line.fontSize && Math.abs(item.x - candidate.x) <= 1 && (_nullishCoalesce(_optionalChain([item, 'access', _267 => _267.text, 'access', _268 => _268.match, 'call', _269 => _269(/\p{L}/gu), 'optionalAccess', _270 => _270.length]), () => ( 0))) >= 12).sort((a, b) => b.y - a.y);
4537
+ const numberedList = numbered.some((item, index) => index > 0 && item.text.trim().charCodeAt(0) === numbered[index - 1].text.trim().charCodeAt(0) + 1);
4538
+ if (!same.length && !numberedList || used.has(candidate.line)) continue;
4539
+ if (!shapes.has(candidate.id)) shapes.set(candidate.id, hollowCircle(await resolveImagePixels(page, candidate.id)));
4540
+ if (!shapes.get(candidate.id)) continue;
4541
+ used.add(candidate.line);
4542
+ items.push({ ...candidate.line, text: "\u25CB", x: candidate.x, w: candidate.width, strike: false, underline: false, hasSpaceBefore: false, syntheticSpace: false });
4543
+ restored++;
4544
+ }
4545
+ return restored;
4546
+ }
4547
+
4548
+ // src/pdf/flow-boxes.ts
4549
+
4550
+ var contains2 = (outer, inner, tolerance = 1) => inner.x1 >= outer.x1 - tolerance && inner.x2 <= outer.x2 + tolerance && inner.y1 >= outer.y1 - tolerance && inner.y2 <= outer.y2 + tolerance;
4551
+ function closed(grid, hs, vs) {
4552
+ const b = grid.bbox;
4553
+ return [b.y1, b.y2].every((y) => hs.some((h) => Math.abs(h.y1 - y) <= 1 && h.x1 <= b.x1 + 1 && h.x2 >= b.x2 - 1)) && [b.x1, b.x2].every((x) => vs.some((v) => Math.abs(v.x1 - x) <= 1 && v.y1 <= b.y1 + 1 && v.y2 >= b.y2 - 1));
4554
+ }
4555
+ function groupFlowBoxUnits(blocks, grids, hs, vs, images) {
4556
+ const candidates = grids.filter((g) => g.bbox.y2 - g.bbox.y1 >= 30 && closed(g, hs, vs) && !grids.some((other) => other !== g && contains2(other.bbox, g.bbox, 0) && (other.bbox.x2 - other.bbox.x1) * (other.bbox.y2 - other.bbox.y1) > (g.bbox.x2 - g.bbox.x1) * (g.bbox.y2 - g.bbox.y1) + 1));
4557
+ const bands = [], visited = /* @__PURE__ */ new Set();
4558
+ for (const first of candidates) {
4559
+ if (visited.has(first)) continue;
4560
+ const row = candidates.filter((g) => Math.abs(g.bbox.y1 - first.bbox.y1) <= 1 && Math.abs(g.bbox.y2 - first.bbox.y2) <= 1).sort((a, b) => a.bbox.x1 - b.bbox.x1);
4561
+ row.forEach((g) => visited.add(g));
4562
+ if (row.length < 4 || row.filter((g) => g.rowYs.length === 2 && g.colXs.length === 2).length < 3) continue;
4563
+ const connectors = [];
4564
+ for (let i = 1; i < row.length; i++) {
4565
+ const left = row[i - 1].bbox, right = row[i].bbox, gap = right.x1 - left.x2;
4566
+ if (gap < 4 || gap > Math.min(left.x2 - left.x1, right.x2 - right.x1) * 0.6) break;
4567
+ const centerX = (left.x2 + right.x1) / 2, centerY = (left.y1 + left.y2) / 2;
4568
+ const connector = images.find((p) => {
4569
+ const w = p.x2 - p.x1, h = p.y2 - p.y1;
4570
+ return p.x1 >= left.x2 && p.x2 <= right.x1 && w >= gap * 0.4 && w <= gap * 0.9 && h >= 3 && h <= (left.y2 - left.y1) * 0.2 && w / h >= 0.8 && w / h <= 1.6 && Math.abs((p.x1 + p.x2) / 2 - centerX) <= gap * 0.15 && Math.abs((p.y1 + p.y2) / 2 - centerY) <= (left.y2 - left.y1) * 0.1;
4571
+ });
4572
+ if (!connector) break;
4573
+ connectors.push(connector);
4574
+ }
4575
+ if (connectors.length !== row.length - 1 || connectors.some((p) => Math.abs(p.x2 - p.x1 - (connectors[0].x2 - connectors[0].x1)) > (connectors[0].x2 - connectors[0].x1) * 0.2 || Math.abs(p.y2 - p.y1 - (connectors[0].y2 - connectors[0].y1)) > (connectors[0].y2 - connectors[0].y1) * 0.2)) continue;
4576
+ bands.push(row);
4577
+ }
4578
+ const members = /* @__PURE__ */ new Map();
4579
+ for (const band of bands) {
4580
+ const columns = band.map((g) => blocks.filter((b) => b.bbox && contains2(g.bbox, {
4581
+ x1: b.bbox.x,
4582
+ y1: b.bbox.y,
4583
+ x2: b.bbox.x + b.bbox.width,
4584
+ y2: b.bbox.y + b.bbox.height
4585
+ })).sort((a, b) => b.bbox.y + b.bbox.height - a.bbox.y - a.bbox.height || a.bbox.x - b.bbox.x));
4586
+ if (columns.some((column) => !column.length)) continue;
4587
+ const unit = columns.flat();
4588
+ for (const block of unit) members.set(block, unit);
4589
+ }
4590
+ const units = [], emitted = /* @__PURE__ */ new Set();
4591
+ for (const block of blocks) {
4592
+ const unit = members.get(block);
4593
+ if (!unit) units.push([block]);
4594
+ else if (!emitted.has(unit)) {
4595
+ units.push(unit);
4596
+ emitted.add(unit);
4597
+ }
4598
+ }
4599
+ return units;
4600
+ }
4601
+ function arrowDirection(image) {
4602
+ if (!_optionalChain([image, 'optionalAccess', _271 => _271.data]) || image.width < 16 || image.width > 128 || image.height < 16 || image.height > 128) return 0;
4603
+ const { width, height, data } = image;
4604
+ const stride = image.kind === _pdfmjs.ImageKind.RGB_24BPP ? 3 : image.kind === _pdfmjs.ImageKind.RGBA_32BPP ? 4 : 0;
4605
+ if (!stride || data.length < width * height * stride) return 0;
4606
+ const ink = [];
4607
+ let white = 0;
4608
+ for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
4609
+ const offset = (y * width + x) * stride;
4610
+ if (stride === 4 && data[offset + 3] < 240) return 0;
4611
+ const min = Math.min(data[offset], data[offset + 1], data[offset + 2]);
4612
+ if (min >= 235) white++;
4613
+ if (min < 230) ink.push({ x, y });
4614
+ }
4615
+ if (white < width * height * 0.55 || !ink.length) return 0;
4616
+ const x0 = Math.min(...ink.map((p) => p.x)), x1 = Math.max(...ink.map((p) => p.x));
4617
+ const y0 = Math.min(...ink.map((p) => p.y)), y1 = Math.max(...ink.map((p) => p.y));
4618
+ const w = x1 - x0 + 1, h = y1 - y0 + 1, centerY = (y0 + y1) / 2;
4619
+ if (w < width * 0.5 || h < height * 0.5 || x0 < width * 0.04 || y0 < height * 0.04 || x1 >= width * 0.96 || y1 >= height * 0.96) return 0;
4620
+ const pointsRight = (mirror) => {
4621
+ const points = ink.map((p) => ({ x: mirror ? x0 + x1 - p.x : p.x, y: p.y }));
4622
+ const tail = points.filter((p) => p.x <= x0 + w * 0.25), tip = points.filter((p) => p.x >= x1 - w * 0.1);
4623
+ if (!tail.length || !tip.length) return false;
4624
+ const span = (points2) => Math.max(...points2.map((p) => p.y)) - Math.min(...points2.map((p) => p.y)) + 1;
4625
+ if (span(tail) > h * 0.4 || span(tip) > h * 0.45 || Math.abs((Math.max(...tail.map((p) => p.y)) + Math.min(...tail.map((p) => p.y))) / 2 - centerY) > h * 0.1 || Math.abs((Math.max(...tip.map((p) => p.y)) + Math.min(...tip.map((p) => p.y))) / 2 - centerY) > h * 0.1) return false;
4626
+ let head = 0;
4627
+ for (let x = Math.ceil(x0 + w * 0.45); x <= x0 + w * 0.75; x++) {
4628
+ const column = points.filter((p) => p.x === x);
4629
+ if (column.length) head = Math.max(head, span(column));
4630
+ }
4631
+ const middle = new Set(points.filter((p) => Math.abs(p.y - centerY) <= 1).map((p) => p.x));
4632
+ return head >= h * 0.8 && middle.size >= w * 0.9;
4633
+ };
4634
+ return pointsRight(false) ? 1 : pointsRight(true) ? -1 : 0;
4635
+ }
4636
+ async function detectRightArrowRegions(page, fnArray, argsArray, directions = /* @__PURE__ */ new Map()) {
4637
+ const regions = [];
4638
+ const paints = smallVisibleImagePaints(fnArray, argsArray);
4639
+ for (const paint of paints) {
4640
+ const row = paints.filter((other) => other.id === paint.id && Math.abs(other.box.y1 - paint.box.y1) <= 1 && Math.abs(other.box.y2 - paint.box.y2) <= 1 && Math.abs(other.box.x2 - other.box.x1 - (paint.box.x2 - paint.box.x1)) <= 1);
4641
+ const positions = new Set(row.map((other) => Math.round(other.box.x1)));
4642
+ if (positions.size < 3) continue;
4643
+ if (!directions.has(paint.id)) directions.set(paint.id, arrowDirection(await resolveImagePixels(page, paint.id)));
4644
+ const direction = _nullishCoalesce(directions.get(paint.id), () => ( 0));
4645
+ if (direction && (paint.mirrored ? -direction : direction) === 1) regions.push(paint.box);
4646
+ }
4647
+ return regions;
4648
+ }
4649
+
4387
4650
  // src/pdf/side-tabs.ts
4388
4651
  var BAND = 0.12;
4389
4652
  var MAX_CHARS = 10;
@@ -4398,12 +4661,13 @@ function isSideTabTable(box, table, others, pageWidth, pageHeight) {
4398
4661
  if (!side) return false;
4399
4662
  const texts = table.cells.flat().map((c) => c.text.replace(/\s+/g, ""));
4400
4663
  if (!texts.some(Boolean) || texts.some((t) => [...t].length > TAB_CELL_CHARS)) return false;
4401
- return others.every((it) => it.y < box.y1 || it.y > box.y2 || (side === "R" ? it.x + it.w <= box.x1 + 1 : it.x >= box.x2 - 1));
4664
+ const overlap2 = others.filter((it) => it.y >= box.y1 && it.y <= box.y2);
4665
+ return overlap2.length > 0 && overlap2.every((it) => side === "R" ? it.x + it.w <= box.x1 + 1 : it.x >= box.x2 - 1);
4402
4666
  }
4403
4667
  function removeSideTabs(blocks, pageWidths) {
4404
4668
  const edges = /* @__PURE__ */ new Map();
4405
4669
  for (const b of blocks) {
4406
- if (!b.bbox || b.pageNumber === void 0 || [..._nullishCoalesce(_optionalChain([b, 'access', _250 => _250.text, 'optionalAccess', _251 => _251.trim, 'call', _252 => _252()]), () => ( ""))].length <= MAX_CHARS) continue;
4670
+ if (!b.bbox || b.pageNumber === void 0 || [..._nullishCoalesce(_optionalChain([b, 'access', _272 => _272.text, 'optionalAccess', _273 => _273.trim, 'call', _274 => _274()]), () => ( ""))].length <= MAX_CHARS) continue;
4407
4671
  const e = _nullishCoalesce(edges.get(b.pageNumber), () => ( { lefts: [], rights: [] }));
4408
4672
  e.lefts.push(b.bbox.x);
4409
4673
  e.rights.push(b.bbox.x + b.bbox.width);
@@ -4419,7 +4683,7 @@ function removeSideTabs(blocks, pageWidths) {
4419
4683
  const fallback = all.length ? { left: q(all.map((e) => e.left), 0.5), right: q(all.map((e) => e.right), 0.5) } : void 0;
4420
4684
  const key = (b) => {
4421
4685
  const w = b.pageNumber !== void 0 ? pageWidths.get(b.pageNumber) : void 0;
4422
- const text = _optionalChain([b, 'access', _253 => _253.text, 'optionalAccess', _254 => _254.trim, 'call', _255 => _255()]);
4686
+ const text = _optionalChain([b, 'access', _275 => _275.text, 'optionalAccess', _276 => _276.trim, 'call', _277 => _277()]);
4423
4687
  const area = _nullishCoalesce((b.pageNumber !== void 0 ? body.get(b.pageNumber) : void 0), () => ( fallback));
4424
4688
  if (b.type === "table") {
4425
4689
  if (!w || !b.bbox || !b.table || !SIDE_TAB_TABLES.has(b.table)) return null;
@@ -4427,7 +4691,7 @@ function removeSideTabs(blocks, pageWidths) {
4427
4691
  }
4428
4692
  if (!w || !area || !b.bbox || !text || [...text].length > MAX_CHARS) return null;
4429
4693
  const side = b.bbox.x + b.bbox.width <= Math.min(w * BAND, area.left - 1) ? "L" : b.bbox.x >= Math.max(w * (1 - BAND), area.right + 1) ? "R" : null;
4430
- return side && text.replace(/\s+/g, "");
4694
+ return side && `${side}\0${text.replace(/\s+/g, "")}`;
4431
4695
  };
4432
4696
  const pages = /* @__PURE__ */ new Map();
4433
4697
  for (const b of blocks) {
@@ -4506,7 +4770,7 @@ function isProseTable(table) {
4506
4770
  if (!(long > 0 && long >= total * 0.5 && longRows >= rows * 0.4)) return false;
4507
4771
  for (let c = 0; c < table.cols; c++) {
4508
4772
  const filled = table.cells.map((row) => row[c]).filter((cell) => cell && cell.colSpan < table.cols && cell.text.trim()).map((cell) => cell.text.trim());
4509
- if (filled.length >= 3 && filled.length >= rows * 0.6 && filled.every((text) => text.length <= 30 && (_nullishCoalesce(_optionalChain([text, 'access', _256 => _256.match, 'call', _257 => _257(/\p{L}/gu), 'optionalAccess', _258 => _258.length]), () => ( 0))) >= 2)) return false;
4773
+ if (filled.length >= 3 && filled.length >= rows * 0.6 && filled.every((text) => text.length <= 30 && (_nullishCoalesce(_optionalChain([text, 'access', _278 => _278.match, 'call', _279 => _279(/\p{L}/gu), 'optionalAccess', _280 => _280.length]), () => ( 0))) >= 2)) return false;
4510
4774
  }
4511
4775
  return true;
4512
4776
  }
@@ -4533,7 +4797,7 @@ function isChartTable(table) {
4533
4797
  const numeric = texts.filter((text) => NUMERIC_CELL.test(text)).length;
4534
4798
  if (numeric < texts.length * 0.5) return false;
4535
4799
  for (let c = 0; c < table.cols; c++) {
4536
- const ticks = table.cells.flatMap((row) => (_nullishCoalesce(_optionalChain([row, 'access', _259 => _259[c], 'optionalAccess', _260 => _260.text]), () => ( ""))).split(/\s+/)).filter((token) => /^-?[\d,]+(?:\.\d+)?%?$/.test(token)).map((token) => Number(token.replace(/[,%]/g, "")));
4800
+ const ticks = table.cells.flatMap((row) => (_nullishCoalesce(_optionalChain([row, 'access', _281 => _281[c], 'optionalAccess', _282 => _282.text]), () => ( ""))).split(/\s+/)).filter((token) => /^-?[\d,]+(?:\.\d+)?%?$/.test(token)).map((token) => Number(token.replace(/[,%]/g, "")));
4537
4801
  if (hasValueAxis(ticks)) return true;
4538
4802
  }
4539
4803
  const values = texts.filter((text) => text.split(/\s+/).every((token) => /^[-−–]?[\d,]*\.?\d+%?$/.test(token))).length;
@@ -4634,15 +4898,39 @@ function sideTabGlyphs(items) {
4634
4898
  if (c) c.push(it);
4635
4899
  else cols.push([it]);
4636
4900
  }
4901
+ const cands = [];
4637
4902
  for (const col of cols) {
4638
- if (col.length < SIDE_TAB_MIN) continue;
4903
+ if (col.length < 2) continue;
4639
4904
  if (col.filter((g) => /[\p{L}\p{N}]/u.test(g.text)).length < col.length * 0.8) continue;
4640
4905
  col.sort((a, b) => b.y - a.y);
4641
4906
  const fs = [...col.map((i) => i.fontSize)].sort((a, b) => a - b)[col.length >> 1];
4642
4907
  if (col.slice(1).some((it, k) => col[k].y - it.y > fs * 3)) continue;
4908
+ cands.push({ col, fs });
4909
+ }
4910
+ const bands = [];
4911
+ for (const c of cands.sort((a, b) => a.col[0].x - b.col[0].x)) {
4912
+ const last = bands[bands.length - 1];
4913
+ if (last) {
4914
+ const lastRight = Math.max(...last.col.map((i) => i.x + i.w));
4915
+ const gap = Math.min(...c.col.map((i) => i.x)) - lastRight;
4916
+ const lTop = Math.max(...last.col.map((i) => i.y)), lBot = Math.min(...last.col.map((i) => i.y));
4917
+ const cTop = c.col[0].y, cBot = c.col[c.col.length - 1].y;
4918
+ if (gap <= Math.max(last.fs, c.fs) * 1.5 && Math.min(lTop, cTop) >= Math.max(lBot, cBot)) {
4919
+ last.col.push(...c.col);
4920
+ last.fs = Math.max(last.fs, c.fs);
4921
+ last.anchored ||= c.col.length >= SIDE_TAB_MIN;
4922
+ continue;
4923
+ }
4924
+ }
4925
+ bands.push({ col: [...c.col], fs: c.fs, anchored: c.col.length >= SIDE_TAB_MIN });
4926
+ }
4927
+ for (const { col, fs, anchored } of bands) {
4928
+ if (!anchored) continue;
4929
+ col.sort((a, b) => b.y - a.y);
4643
4930
  const members = new Set(col);
4644
4931
  const top = col[0].y + fs, bottom = col[col.length - 1].y - fs;
4645
- const others = items.filter((i) => !members.has(i) && i.y <= top && i.y >= bottom);
4932
+ const others = items.filter((i) => !members.has(i) && i.text.trim() && i.y <= top && i.y >= bottom);
4933
+ if (!others.length) continue;
4646
4934
  const left = Math.min(...col.map((i) => i.x)), right = Math.max(...col.map((i) => i.x + i.w));
4647
4935
  const rest = items.filter((i) => !members.has(i) && i.text.trim());
4648
4936
  const outside = rest.every((i) => i.x >= right + fs) || rest.every((i) => i.x + i.w <= left - fs);
@@ -4719,7 +5007,7 @@ function detectAlignedTwoColumnTables(rows, pageNum) {
4719
5007
  continue;
4720
5008
  }
4721
5009
  const top = rows[i - 1];
4722
- const title = _optionalChain([top, 'optionalAccess', _261 => _261.items, 'access', _262 => _262.length]) === 1 && Math.abs(top.items[0].x - first[0].x) <= 5 && top.items[0].text.length <= 65 && top.y - first[0].y <= Math.max(24, first[0].fontSize * 2.8) ? top : void 0;
5010
+ const title = _optionalChain([top, 'optionalAccess', _283 => _283.items, 'access', _284 => _284.length]) === 1 && Math.abs(top.items[0].x - first[0].x) <= 5 && top.items[0].text.length <= 65 && top.y - first[0].y <= Math.max(24, first[0].fontSize * 2.8) ? top : void 0;
4723
5011
  const tableRows = title ? [title, ...body] : body;
4724
5012
  const cells = tableRows.map((row, idx) => {
4725
5013
  if (title && idx === 0) return [{ text: row.items[0].text, colSpan: 2, rowSpan: 1 }, { text: "", colSpan: 1, rowSpan: 1 }];
@@ -4775,12 +5063,12 @@ function isTwoColumnProse(r) {
4775
5063
  if (t.rows < 8) return false;
4776
5064
  const dense = [];
4777
5065
  for (let c = 0; c < t.cols; c++) {
4778
- const filled = t.cells.filter((row) => _optionalChain([row, 'access', _263 => _263[c], 'optionalAccess', _264 => _264.text, 'access', _265 => _265.trim, 'call', _266 => _266()])).length;
5066
+ const filled = t.cells.filter((row) => _optionalChain([row, 'access', _285 => _285[c], 'optionalAccess', _286 => _286.text, 'access', _287 => _287.trim, 'call', _288 => _288()])).length;
4779
5067
  if (filled / t.rows >= 0.3) dense.push(c);
4780
5068
  }
4781
5069
  if (dense.length !== 2) return false;
4782
5070
  for (const c of dense) {
4783
- const lens = t.cells.map((row) => _nullishCoalesce(_optionalChain([row, 'access', _267 => _267[c], 'optionalAccess', _268 => _268.text, 'access', _269 => _269.replace, 'call', _270 => _270(/\s+/g, ""), 'access', _271 => _271.length]), () => ( 0))).filter((n) => n > 0);
5071
+ const lens = t.cells.map((row) => _nullishCoalesce(_optionalChain([row, 'access', _289 => _289[c], 'optionalAccess', _290 => _290.text, 'access', _291 => _291.replace, 'call', _292 => _292(/\s+/g, ""), 'access', _293 => _293.length]), () => ( 0))).filter((n) => n > 0);
4784
5072
  const avg = lens.reduce((s, v) => s + v, 0) / (lens.length || 1);
4785
5073
  if (avg < 12) return false;
4786
5074
  }
@@ -5176,7 +5464,7 @@ function assignRowItems(items, columns, numCols, headerFace) {
5176
5464
  const runs = [];
5177
5465
  for (const it of sorted) {
5178
5466
  const last = runs[runs.length - 1];
5179
- const prev = _optionalChain([last, 'optionalAccess', _272 => _272[last.length - 1]]);
5467
+ const prev = _optionalChain([last, 'optionalAccess', _294 => _294[last.length - 1]]);
5180
5468
  if (prev && it.x - (prev.x + prev.w) <= Math.max(0.5, it.fontSize * 0.05) && !it.hasSpaceBefore) last.push(it);
5181
5469
  else runs.push([it]);
5182
5470
  }
@@ -5250,7 +5538,7 @@ function buildClusterTable(rows, columns, pageNum) {
5250
5538
  () => Array.from({ length: numCols }, () => ({ text: "", colSpan: 1, rowSpan: 1 }))
5251
5539
  );
5252
5540
  const usedItems = /* @__PURE__ */ new Set();
5253
- const headFaces = new Set(_optionalChain([rows, 'access', _273 => _273[0], 'optionalAccess', _274 => _274.items, 'access', _275 => _275.map, 'call', _276 => _276((i) => i.fontName)]));
5541
+ const headFaces = new Set(_optionalChain([rows, 'access', _295 => _295[0], 'optionalAccess', _296 => _296.items, 'access', _297 => _297.map, 'call', _298 => _298((i) => i.fontName)]));
5254
5542
  const headerFace = headFaces.size === 1 && rows.slice(1).every((row) => row.items.every((i) => !headFaces.has(i.fontName))) ? [...headFaces][0] : void 0;
5255
5543
  for (let r = 0; r < numRows; r++) {
5256
5544
  const row = rows[r];
@@ -5280,7 +5568,7 @@ function buildClusterTable(rows, columns, pageNum) {
5280
5568
  const nonEmptyCols = cells[r].filter((c) => c.text.trim()).length;
5281
5569
  if (nonEmptyCols !== 1) continue;
5282
5570
  if (cells[r][0].text.trim() !== "") continue;
5283
- const contentText = _optionalChain([cells, 'access', _277 => _277[r], 'access', _278 => _278.find, 'call', _279 => _279((c) => c.text.trim()), 'optionalAccess', _280 => _280.text, 'access', _281 => _281.trim, 'call', _282 => _282()]) || "";
5571
+ const contentText = _optionalChain([cells, 'access', _299 => _299[r], 'access', _300 => _300.find, 'call', _301 => _301((c) => c.text.trim()), 'optionalAccess', _302 => _302.text, 'access', _303 => _303.trim, 'call', _304 => _304()]) || "";
5284
5572
  if (/^[○●▶\-·]/.test(contentText)) continue;
5285
5573
  for (let pr = r - 1; pr >= 0; pr--) {
5286
5574
  if (cells[pr].some((c) => c.text.trim())) {
@@ -5671,16 +5959,16 @@ function isProseSpread(items) {
5671
5959
  for (let i = 1; i < sorted.length; i++) {
5672
5960
  gaps.push(sorted[i].x - (sorted[i - 1].x + sorted[i - 1].w));
5673
5961
  }
5674
- const maxGap = _chunkSHRRD2TDcjs.safeMax.call(void 0, gaps);
5962
+ const maxGap = _chunk3XSP7V5Pcjs.safeMax.call(void 0, gaps);
5675
5963
  const avgLen = items.reduce((s, i) => s + i.text.length, 0) / items.length;
5676
5964
  if (items.length >= 4 && maxGap < 40 && avgLen < 5) return true;
5677
- const minGap = _chunkSHRRD2TDcjs.safeMin.call(void 0, gaps);
5965
+ const minGap = _chunk3XSP7V5Pcjs.safeMin.call(void 0, gaps);
5678
5966
  return minGap > 0 && maxGap - minGap <= Math.max(2, maxGap * 0.15) && items.filter((i) => /^\P{L}*\p{Ll}/u.test(i.text)).length * 2 >= items.length;
5679
5967
  }
5680
5968
  function detectColumns(yLines) {
5681
5969
  const allItems = yLines.flat();
5682
5970
  if (allItems.length === 0) return null;
5683
- const pageWidth = _chunkSHRRD2TDcjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunkSHRRD2TDcjs.safeMin.call(void 0, allItems.map((i) => i.x));
5971
+ const pageWidth = _chunk3XSP7V5Pcjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunk3XSP7V5Pcjs.safeMin.call(void 0, allItems.map((i) => i.x));
5684
5972
  if (pageWidth < 100) return null;
5685
5973
  let bigoLineIdx = -1;
5686
5974
  for (let i = 0; i < yLines.length; i++) {
@@ -5903,13 +6191,44 @@ var UNDER_SPAN_OVERLAP_RATIO = 0.8;
5903
6191
  var UNDER_BOX_PAIR_MIN_EM = 0.5;
5904
6192
  var UNDER_BOX_PAIR_MAX_EM = 2.2;
5905
6193
  var UNDER_BOX_PAIR_OVERLAP = 0.8;
5906
- function markUnderlineItems(items, horizontals, verticals) {
6194
+ function markUnderlineItems(items, horizontals, verticals, nonRules) {
5907
6195
  const underlines = [];
6196
+ if (_optionalChain([nonRules, 'optionalAccess', _305 => _305.size])) horizontals = horizontals.filter((line) => !nonRules.has(line));
5908
6197
  if (items.length === 0 || horizontals.length === 0) return underlines;
6198
+ const tightOwners = /* @__PURE__ */ new Map();
6199
+ const tightlyOwned = (line) => {
6200
+ const cached = tightOwners.get(line);
6201
+ if (cached !== void 0) return cached;
6202
+ const owners = items.filter((item) => {
6203
+ const below = item.y - line.y1;
6204
+ return item.w > 0 && item.text.trim() && below >= 0.5 && below <= 3 && Math.min(line.x2, item.x + item.w) > Math.max(line.x1, item.x);
6205
+ }).sort((a, b) => a.x - b.x);
6206
+ let owned = owners.length > 0 && (Math.abs(owners[0].x - line.x1) <= UNDER_GRID_EPS || owners.length === 1 && line.x1 > owners[0].x && line.x1 - owners[0].x <= Math.max(owners[0].h, owners[0].fontSize, 1) * 3) && Math.abs(owners[owners.length - 1].x + owners[owners.length - 1].w - line.x2) <= UNDER_GRID_EPS;
6207
+ for (let i = 1; owned && i < owners.length; i++) {
6208
+ const em = Math.max(owners[i].h, owners[i].fontSize, 1);
6209
+ if (owners[i].x - (owners[i - 1].x + owners[i - 1].w) > em * UNDER_COLUMN_GAP_EM) owned = false;
6210
+ }
6211
+ tightOwners.set(line, owned);
6212
+ return owned;
6213
+ };
6214
+ const paragraphUnderline = (line) => {
6215
+ if (!tightlyOwned(line)) return false;
6216
+ const width = line.x2 - line.x1;
6217
+ const ys = [];
6218
+ for (const other of horizontals) {
6219
+ const overlap2 = Math.min(line.x2, other.x2) - Math.max(line.x1, other.x1);
6220
+ if (other.lineWidth > UNDER_MAX_THICKNESS || overlap2 / Math.max(width, other.x2 - other.x1) < UNDER_SPAN_OVERLAP_RATIO || !tightlyOwned(other)) continue;
6221
+ if (!ys.some((y) => Math.abs(y - other.y1) < UNDER_GRID_EPS)) ys.push(other.y1);
6222
+ if (ys.length >= UNDER_REPEATED_SPAN_LEVELS) return true;
6223
+ }
6224
+ return false;
6225
+ };
5909
6226
  for (const line of horizontals) {
5910
6227
  if (line.lineWidth > UNDER_MAX_THICKNESS) continue;
5911
6228
  const enclosed = insideTallCell(line, verticals, 0);
5912
- if (!enclosed && (touchesVertical(line, verticals) || isRepeatedSpanRule(line, horizontals))) continue;
6229
+ const repeated = isRepeatedSpanRule(line, horizontals);
6230
+ const textSeries = repeated && paragraphUnderline(line);
6231
+ if (!enclosed && (touchesVertical(line, verticals) || repeated && !textSeries)) continue;
5913
6232
  const matches = [];
5914
6233
  for (const item of items) {
5915
6234
  const h = item.h > 0 ? item.h : item.fontSize;
@@ -5929,11 +6248,11 @@ function markUnderlineItems(items, horizontals, verticals) {
5929
6248
  covered += m.w;
5930
6249
  }
5931
6250
  const inset = enclosed && insideTallCell(line, verticals, maxH);
5932
- if (enclosed && !inset && (touchesVertical(line, verticals) || isRepeatedSpanRule(line, horizontals))) continue;
6251
+ if (enclosed && !inset && (touchesVertical(line, verticals) || repeated && !textSeries)) continue;
5933
6252
  const pad = Math.max(maxH * UNDER_OWNER_PAD_EM, UNDER_OWNER_PAD_MIN_PT);
5934
6253
  if (line.x1 < x1 - pad || line.x2 > x2 + pad) continue;
5935
6254
  if (covered < (line.x2 - line.x1) * UNDER_MIN_COVERAGE) continue;
5936
- if (hasBoxTopPair(line, maxH, horizontals, inset ? items : void 0)) continue;
6255
+ if (hasBoxTopPair(line, maxH, horizontals, inset || textSeries || tightlyOwned(line) ? items : void 0)) continue;
5937
6256
  matches.sort((a, b) => a.x - b.x);
5938
6257
  let hole = false;
5939
6258
  for (let i = 1; i < matches.length; i++) {
@@ -5964,6 +6283,7 @@ function touchesVertical(line, verticals) {
5964
6283
  for (const v of verticals) {
5965
6284
  if (v.x1 < line.x1 - UNDER_GRID_EPS || v.x1 > line.x2 + UNDER_GRID_EPS) continue;
5966
6285
  const lo = Math.min(v.y1, v.y2), hi = Math.max(v.y1, v.y2);
6286
+ if (hi - lo <= UNDER_GRID_EPS) continue;
5967
6287
  if (lo <= line.y1 + UNDER_GRID_EPS && hi >= line.y1 - UNDER_GRID_EPS) return true;
5968
6288
  }
5969
6289
  return false;
@@ -5979,7 +6299,7 @@ function hasBoxTopPair(line, maxH, horizontals, cellItems) {
5979
6299
  if (ow <= 0) continue;
5980
6300
  const overlap2 = Math.min(line.x2, o.x2) - Math.max(line.x1, o.x1);
5981
6301
  if (overlap2 / Math.max(w, ow) < UNDER_BOX_PAIR_OVERLAP) continue;
5982
- const covered = _nullishCoalesce(_optionalChain([cellItems, 'optionalAccess', _283 => _283.reduce, 'call', _284 => _284((sum, item) => {
6302
+ const covered = _nullishCoalesce(_optionalChain([cellItems, 'optionalAccess', _306 => _306.reduce, 'call', _307 => _307((sum, item) => {
5983
6303
  const below = item.y - o.y1;
5984
6304
  if (below < 0.5 || below > 3 || !item.text.trim()) return sum;
5985
6305
  return sum + Math.max(0, Math.min(o.x2, item.x + item.w) - Math.max(o.x1, item.x));
@@ -6109,8 +6429,8 @@ function edgesOf(box, h, v, hNear = EDGE_NEAR2) {
6109
6429
  }
6110
6430
  function recordClipCellEdges(grids, horizontals, verticals, nonRules) {
6111
6431
  if (!grids.some((g) => g.cells)) return;
6112
- const h = rules(_optionalChain([nonRules, 'optionalAccess', _285 => _285.size]) ? horizontals.filter((l) => !nonRules.has(l)) : horizontals, "h");
6113
- const v = rules(_optionalChain([nonRules, 'optionalAccess', _286 => _286.size]) ? verticals.filter((l) => !nonRules.has(l)) : verticals, "v");
6432
+ const h = rules(_optionalChain([nonRules, 'optionalAccess', _308 => _308.size]) ? horizontals.filter((l) => !nonRules.has(l)) : horizontals, "h");
6433
+ const v = rules(_optionalChain([nonRules, 'optionalAccess', _309 => _309.size]) ? verticals.filter((l) => !nonRules.has(l)) : verticals, "v");
6114
6434
  for (const g of grids) for (const c of _nullishCoalesce(g.cells, () => ( []))) {
6115
6435
  const near = c.filler ? Math.min(EDGE_NEAR2, (c.bbox.y2 - c.bbox.y1) / 3) : EDGE_NEAR2;
6116
6436
  CLIP_CELL_EDGES.set(c, edgesOf(c.bbox, h, v, near));
@@ -6118,12 +6438,12 @@ function recordClipCellEdges(grids, horizontals, verticals, nonRules) {
6118
6438
  }
6119
6439
  function takeClipCellEdges(from, to) {
6120
6440
  const e = CLIP_CELL_EDGES.get(from);
6121
- if (e) _chunk2ZBLQVAScjs.CELL_EDGES.set(to, e);
6441
+ if (e) _chunk3WLZOJIEcjs.CELL_EDGES.set(to, e);
6122
6442
  }
6123
6443
  function joinCellEdges(a, b) {
6124
- const u = _chunk2ZBLQVAScjs.CELL_EDGES.get(a), d = _chunk2ZBLQVAScjs.CELL_EDGES.get(b);
6444
+ const u = _chunk3WLZOJIEcjs.CELL_EDGES.get(a), d = _chunk3WLZOJIEcjs.CELL_EDGES.get(b);
6125
6445
  if (!u || !d) return;
6126
- _chunk2ZBLQVAScjs.CELL_EDGES.set(a, { t: u.t, b: d.b, l: u.l || d.l, r: u.r || d.r });
6446
+ _chunk3WLZOJIEcjs.CELL_EDGES.set(a, { t: u.t, b: d.b, l: u.l || d.l, r: u.r || d.r });
6127
6447
  }
6128
6448
 
6129
6449
  // src/pdf/table-unit-row.ts
@@ -6139,12 +6459,12 @@ function rebuildUnitLine(items, grid) {
6139
6459
  function prependUnitRow(cells, cols, line, usedItems) {
6140
6460
  const text = cleanCellText(line.map((item) => item.text).join(""));
6141
6461
  cells.unshift(Array.from({ length: cols }, (_, c) => ({ text: c === 0 ? text : "", colSpan: c === 0 ? cols : 1, rowSpan: 1 })));
6142
- for (const cell of cells[0]) _chunk2ZBLQVAScjs.CELL_EDGES.set(cell, NO_EDGES);
6462
+ for (const cell of cells[0]) _chunk3WLZOJIEcjs.CELL_EDGES.set(cell, NO_EDGES);
6143
6463
  for (const item of line) usedItems.add(item);
6144
6464
  }
6145
6465
  function attachUnitRow(items, grid, cells, cols, usedItems) {
6146
6466
  const all = cells.flat();
6147
- if (all.filter((c) => c.text.trim()).length * 2 < all.length || UNIT.test(_nullishCoalesce(_optionalChain([cells, 'access', _287 => _287[0], 'optionalAccess', _288 => _288[0], 'optionalAccess', _289 => _289.text]), () => ( "")))) return false;
6467
+ if (all.filter((c) => c.text.trim()).length * 2 < all.length || UNIT.test(_nullishCoalesce(_optionalChain([cells, 'access', _310 => _310[0], 'optionalAccess', _311 => _311[0], 'optionalAccess', _312 => _312.text]), () => ( "")))) return false;
6148
6468
  const above = items.filter((it) => !usedItems.has(it) && it.y >= grid.bbox.y2 && it.y - grid.bbox.y2 <= 8 && it.x >= grid.bbox.x1 - 3 && it.x + it.w <= grid.bbox.x2 + 3);
6149
6469
  let nearest = Infinity;
6150
6470
  for (const it of above) nearest = Math.min(nearest, it.y);
@@ -6173,6 +6493,57 @@ function isPageFrameGrid(grid, cells, pageWidth, pageHeight, items = []) {
6173
6493
  return inner.length === 0 || crossing >= 1 && crossing >= inBig.length * 0.01;
6174
6494
  }
6175
6495
 
6496
+ // src/pdf/shaded-open-table.ts
6497
+ function closeShadedTableEdges(clipGrids, horizontals, verticals, fillRects) {
6498
+ const near = (a, b) => Math.abs(a - b) <= 1.5;
6499
+ let hs = horizontals, vs = verticals;
6500
+ const restored = [];
6501
+ for (const grid of clipGrids) {
6502
+ if (grid.clipParent || grid.rowYs.length !== 2 || grid.colXs.length < 3 || !_optionalChain([grid, 'access', _313 => _313.cells, 'optionalAccess', _314 => _314.length]) || grid.cells.some((c) => c.filler || c.rowSpan !== 1 || c.colSpan !== 1)) continue;
6503
+ const { x1, x2, y1: mid, y2: top } = grid.bbox;
6504
+ if (!grid.cells.every((c) => fillRects.some((f) => near(f.x1, c.bbox.x1) && near(f.x2, c.bbox.x2) && near(f.y1, c.bbox.y1) && near(f.y2, c.bbox.y2)))) continue;
6505
+ const topRule = hs.find((h) => near(h.y1, top) && near(h.x1, x1) && near(h.x2, x2));
6506
+ if (!topRule) continue;
6507
+ const dividers = grid.colXs.slice(1, -1).map((x) => vs.find((v) => near(v.x1, x) && near(v.y2, top) && v.y1 <= mid - 6));
6508
+ if (dividers.some((v) => !v)) continue;
6509
+ const bottom = dividers[0].y1;
6510
+ if (!dividers.every((v) => near(v.y1, bottom))) continue;
6511
+ const bottomRule = hs.find((h) => near(h.y1, bottom) && near(h.x1, x1) && near(h.x2, x2));
6512
+ if (!bottomRule) continue;
6513
+ const missing = [x1, x2].filter((x) => !vs.some((v) => near(v.x1, x) && v.y1 <= bottom + 1.5 && v.y2 >= top - 1.5));
6514
+ if (!missing.length) continue;
6515
+ restored.push({ x1, x2, y1: bottom, y2: top });
6516
+ vs = vs.concat(missing.map((x) => ({ x1: x, x2: x, y1: bottom, y2: top, lineWidth: topRule.lineWidth })));
6517
+ if (!hs.some((h) => near(h.y1, mid) && near(h.x1, x1) && near(h.x2, x2))) {
6518
+ hs = hs.concat({ x1, x2, y1: mid, y2: mid, lineWidth: topRule.lineWidth });
6519
+ }
6520
+ }
6521
+ return { horizontals: hs, verticals: vs, restored };
6522
+ }
6523
+ function nestRestoredShadedGrids(grids, restored, horizontals, verticals) {
6524
+ const near = (a, b) => Math.abs(a - b) <= 1.5;
6525
+ if (restored.length === 0) return;
6526
+ const nested = /* @__PURE__ */ new Set();
6527
+ for (const grid of grids) {
6528
+ const b = grid.bbox;
6529
+ if (!restored.some((r) => near(r.x1, b.x1) && near(r.x2, b.x2) && near(r.y1, b.y1) && near(r.y2, b.y2))) continue;
6530
+ if (grids.some((g) => g !== grid && b.x1 - g.bbox.x1 >= 0.8 && g.bbox.x2 - b.x2 >= 0.8 && b.y1 - g.bbox.y1 >= 0.8 && g.bbox.y2 - b.y2 >= 0.8)) {
6531
+ grid.lineNested = true;
6532
+ nested.add(grid);
6533
+ }
6534
+ }
6535
+ for (const frame of grids) {
6536
+ const b = frame.bbox;
6537
+ if (frame.lineNested || ![...nested].some((g) => g.bbox.x1 > b.x1 && g.bbox.x2 < b.x2 && g.bbox.y1 > b.y1 && g.bbox.y2 < b.y2)) continue;
6538
+ const fullH = horizontals.filter((h) => near(h.x1, b.x1) && near(h.x2, b.x2) && h.y1 >= b.y1 - 1.5 && h.y1 <= b.y2 + 1.5);
6539
+ if (!fullH.some((h) => near(h.y1, b.y1)) || !fullH.some((h) => near(h.y1, b.y2)) || fullH.some((h) => h.y1 > b.y1 + 1.5 && h.y1 < b.y2 - 1.5)) continue;
6540
+ const fullV = verticals.filter((v) => v.y1 <= b.y1 + 1.5 && v.y2 >= b.y2 - 1.5 && v.x1 >= b.x1 - 1.5 && v.x1 <= b.x2 + 1.5);
6541
+ if (!fullV.some((v) => near(v.x1, b.x1)) || !fullV.some((v) => near(v.x1, b.x2)) || fullV.some((v) => v.x1 > b.x1 + 1.5 && v.x1 < b.x2 - 1.5)) continue;
6542
+ frame.colXs = [b.x1, b.x2];
6543
+ frame.rowYs = [b.y2, b.y1];
6544
+ }
6545
+ }
6546
+
6176
6547
  // src/pdf/open-table-ends.ts
6177
6548
  var ALIGN_TOL = 3;
6178
6549
  var MIN_RULES = 3;
@@ -6508,6 +6879,140 @@ function detectTextBoxTables(boxes, items, pageNum) {
6508
6879
  }];
6509
6880
  }
6510
6881
 
6882
+ // src/pdf/frame-cell-blocks.ts
6883
+ var FRAME_READING_UNITS = /* @__PURE__ */ new WeakMap();
6884
+ var FRAME_SOURCE_BOUNDS = /* @__PURE__ */ new WeakMap();
6885
+ function recordFrameReadingUnit(blocks, bbox) {
6886
+ for (const block of blocks) FRAME_SOURCE_BOUNDS.set(block, bbox);
6887
+ if (blocks.length < 2) return;
6888
+ const unit = { blocks, bbox };
6889
+ for (const block of blocks) FRAME_READING_UNITS.set(block, unit);
6890
+ }
6891
+ function frameLayoutBoxes(blocks) {
6892
+ const boxes = [], seen2 = /* @__PURE__ */ new Set();
6893
+ for (const block of blocks) {
6894
+ const frame = FRAME_SOURCE_BOUNDS.get(block);
6895
+ if (frame) {
6896
+ if (!seen2.has(frame)) {
6897
+ boxes.push(frame);
6898
+ seen2.add(frame);
6899
+ }
6900
+ } else if (block.bbox) boxes.push(block.bbox);
6901
+ }
6902
+ return boxes;
6903
+ }
6904
+ function groupFrameParagraphUnits(units, frames) {
6905
+ const source = /* @__PURE__ */ new Map();
6906
+ for (const unit of units) for (const block of unit) source.set(block, unit);
6907
+ const members = /* @__PURE__ */ new Map(), emitted = /* @__PURE__ */ new Set();
6908
+ for (const frame of frames) {
6909
+ if (frame.length < 2 || frame.some((block) => block.type !== "paragraph" || _optionalChain([source, 'access', _315 => _315.get, 'call', _316 => _316(block), 'optionalAccess', _317 => _317.length]) !== 1)) continue;
6910
+ for (const block of frame) members.set(block, frame);
6911
+ }
6912
+ const out = [];
6913
+ for (const unit of units) {
6914
+ const frame = unit.length === 1 ? members.get(unit[0]) : void 0;
6915
+ if (!frame) out.push(unit);
6916
+ else if (!emitted.has(frame)) {
6917
+ out.push(frame);
6918
+ emitted.add(frame);
6919
+ }
6920
+ }
6921
+ for (const unit of out) {
6922
+ if (unit.length < 2 || _optionalChain([FRAME_READING_UNITS, 'access', _318 => _318.get, 'call', _319 => _319(unit[0]), 'optionalAccess', _320 => _320.blocks]) === unit) continue;
6923
+ const bs = unit.map((b) => b.bbox).filter((b) => !!b);
6924
+ if (bs.length !== unit.length) continue;
6925
+ const x = Math.min(...bs.map((b) => b.x)), y = Math.min(...bs.map((b) => b.y));
6926
+ recordFrameReadingUnit(unit, {
6927
+ page: bs[0].page,
6928
+ x,
6929
+ y,
6930
+ width: Math.max(...bs.map((b) => b.x + b.width)) - x,
6931
+ height: Math.max(...bs.map((b) => b.y + b.height)) - y
6932
+ });
6933
+ }
6934
+ return out;
6935
+ }
6936
+ function recordFrameTitle(table, source, pageNum) {
6937
+ if (!CLIP_TABLES.has(table) || table.rows !== 1 || table.cols !== 3 || source.length < 2) return;
6938
+ const cells = table.cells[0];
6939
+ if (cells.length !== 3 || cells.some((c) => c.colSpan !== 1 || c.rowSpan !== 1 || _optionalChain([c, 'access', _321 => _321.blocks, 'optionalAccess', _322 => _322.length]) || c.text.includes("\n"))) return;
6940
+ const [label, spacer, title] = cells;
6941
+ if (!/^(?:붙임|별첨|첨부|부록)\s*\d{1,3}$/.test(label.text.trim()) || spacer.text.trim() || !title.text.trim()) return;
6942
+ if (cells.some((c) => {
6943
+ const e = _chunk3WLZOJIEcjs.CELL_EDGES.get(c);
6944
+ return !e || e.t || e.b || e.l || e.r;
6945
+ })) return;
6946
+ const xs = TABLE_COLXS.get(table), style = dominantStyle(source), fs = _nullishCoalesce(_optionalChain([style, 'optionalAccess', _323 => _323.fontSize]), () => ( 0));
6947
+ if (!xs || xs.length !== 4 || fs <= 0) return;
6948
+ const width = xs[3] - xs[0], gap = xs[2] - xs[1];
6949
+ if (width < fs * 12 || gap <= 0 || gap > fs * 1.5 || xs[1] - xs[0] > width * 0.25 || xs[3] - xs[2] < width * 0.6) return;
6950
+ if (source.some((i) => i.fontName !== source[0].fontName || Math.abs(i.fontSize - fs) > fs * 0.15)) return;
6951
+ if (groupByY([...source].sort((a, b) => b.y - a.y)).length !== 1) return;
6952
+ FRAME_TITLE_BLOCKS.set(table, {
6953
+ type: "paragraph",
6954
+ text: `${label.text.trim()} ${title.text.trim()}`,
6955
+ pageNumber: pageNum,
6956
+ bbox: computeBBox(source, pageNum),
6957
+ style
6958
+ });
6959
+ }
6960
+ var FRAME_RECT_TOL = 1.5;
6961
+ function takePendingNested(pending, cellBox, clipCell) {
6962
+ const out = [];
6963
+ for (let i = pending.length - 1; i >= 0; i--) {
6964
+ const p = pending[i].parent;
6965
+ if (pending[i].contained ? p.x1 >= cellBox.x1 - FRAME_RECT_TOL && p.x2 <= cellBox.x2 + FRAME_RECT_TOL && p.y1 >= cellBox.y1 - FRAME_RECT_TOL && p.y2 <= cellBox.y2 + FRAME_RECT_TOL : clipCell && Math.abs(p.x1 - cellBox.x1) <= FRAME_RECT_TOL && Math.abs(p.x2 - cellBox.x2) <= FRAME_RECT_TOL && Math.abs(p.y1 - cellBox.y1) <= FRAME_RECT_TOL && Math.abs(p.y2 - cellBox.y2) <= FRAME_RECT_TOL) {
6966
+ out.push(pending[i].block);
6967
+ pending.splice(i, 1);
6968
+ }
6969
+ }
6970
+ return out;
6971
+ }
6972
+ function buildFrameCellBlocks(cellItems, nested, pageNum, lex) {
6973
+ const tables = [...nested].sort((a, b) => b.bbox.y + b.bbox.height - (a.bbox.y + a.bbox.height));
6974
+ const blocks = [];
6975
+ let rest = [...cellItems];
6976
+ const pushParagraphs = (items) => {
6977
+ if (items.length === 0) return;
6978
+ const source = items.map((it) => ({ ...it, isHidden: false })).sort((a, b) => b.y - a.y || a.x - b.x);
6979
+ const paragraphs = [];
6980
+ pushLineParagraphs(paragraphs, mergeSuperscriptLines(groupByY(source)), pageNum, lex);
6981
+ for (const block of paragraphs) {
6982
+ block.text = cleanCellText(_nullishCoalesce(block.text, () => ( "")));
6983
+ if (block.text) blocks.push(block);
6984
+ }
6985
+ };
6986
+ for (const tb of tables) {
6987
+ const bottom = tb.bbox.y;
6988
+ pushParagraphs(rest.filter((it) => it.y >= bottom));
6989
+ rest = rest.filter((it) => it.y < bottom);
6990
+ blocks.push(tb);
6991
+ }
6992
+ pushParagraphs(rest);
6993
+ const text = blocks.map((b) => b.type === "table" && b.table ? b.table.cells.flat().map((c) => c.text).filter(Boolean).join("\n") : _nullishCoalesce(b.text, () => ( ""))).filter(Boolean).join("\n");
6994
+ return { blocks, text };
6995
+ }
6996
+
6997
+ // src/pdf/nested-shaded-headers.ts
6998
+ function extendNestedShadedHeaders(clipGrids, lineGrids, horizontals, verticals, fills) {
6999
+ const near = (a, b) => Math.abs(a - b) <= 1.5;
7000
+ const contains3 = (a, b) => b.x1 >= a.x1 - 1.5 && b.x2 <= a.x2 + 1.5 && b.y1 >= a.y1 - 1.5 && b.y2 <= a.y2 + 1.5;
7001
+ const extended = [];
7002
+ for (let i = 0; i < clipGrids.length; i++) {
7003
+ const c = clipGrids[i], parent = c.clipParent;
7004
+ if (!parent || c.rowYs.length !== 2 || c.colXs.length < 3 || !_optionalChain([c, 'access', _324 => _324.cells, 'optionalAccess', _325 => _325.length]) || c.cells.some((cell) => cell.filler || cell.rowSpan !== 1 || cell.colSpan !== 1)) continue;
7005
+ if (!clipGrids.some((g) => g.rowYs.length === 2 && g.colXs.length === 2 && near(g.bbox.x1, parent.x1) && near(g.bbox.x2, parent.x2) && near(g.bbox.y1, parent.y1) && near(g.bbox.y2, parent.y2))) continue;
7006
+ if (!c.cells.every((cell) => fills.some((f) => near(f.x1, cell.bbox.x1) && near(f.x2, cell.bbox.x2) && near(f.y1, cell.bbox.y1) && near(f.y2, cell.bbox.y2)))) continue;
7007
+ const host = lineGrids.find((l) => l.rowYs.length > 2 && l.colXs.length === c.colXs.length && c.colXs.every((x, k) => near(x, l.colXs[k])) && c.rowYs.every((y, k) => near(y, l.rowYs[k])) && contains3(parent, l.bbox) && l.rowYs.every((y) => horizontals.some((h) => near(h.y1, y) && near(h.x1, l.bbox.x1) && near(h.x2, l.bbox.x2))) && l.colXs.every((x) => verticals.some((v) => near(v.x1, x) && v.y1 <= l.bbox.y1 + 1.5 && v.y2 >= l.bbox.y2 - 1.5)) && !clipGrids.some((o) => o !== c && !contains3(o.bbox, l.bbox) && Math.min(o.bbox.x2, l.bbox.x2) > Math.max(o.bbox.x1, l.bbox.x1) && Math.min(o.bbox.y2, l.bbox.y2) > Math.max(o.bbox.y1, l.bbox.y1)));
7008
+ if (!host) continue;
7009
+ const grid = { ...host, clipParent: parent, cells: extractCells(host, horizontals, verticals) };
7010
+ clipGrids[i] = grid;
7011
+ extended.push(grid);
7012
+ }
7013
+ return extended;
7014
+ }
7015
+
6511
7016
  // src/pdf/page-regions.ts
6512
7017
  function splitTwoColumnProse(items, cutX) {
6513
7018
  const left = [];
@@ -6684,7 +7189,7 @@ function stackedTableBands(items) {
6684
7189
  const caption = (start, end) => lines.slice(start, end).some((line) => /^Table\s+\d+\s*[:.]/i.test(mergeLineSimple(line).trim()));
6685
7190
  while (runs.length > 0 && !caption(runs[runs.length - 1].end, lines.length)) runs.pop();
6686
7191
  if (runs.length < 2) return null;
6687
- if (runs.some((run, i) => !caption(run.end, _nullishCoalesce(_optionalChain([runs, 'access', _290 => _290[i + 1], 'optionalAccess', _291 => _291.start]), () => ( lines.length))))) return null;
7192
+ if (runs.some((run, i) => !caption(run.end, _nullishCoalesce(_optionalChain([runs, 'access', _326 => _326[i + 1], 'optionalAccess', _327 => _327.start]), () => ( lines.length))))) return null;
6688
7193
  const tables = runs.map((run) => lines.slice(run.start, run.end).flat());
6689
7194
  const between = runs.slice(0, -1).map((run, i) => lines.slice(run.end, runs[i + 1].start).flat());
6690
7195
  const tail = lines.slice(runs[runs.length - 1].end);
@@ -6835,7 +7340,7 @@ function figureColumnBands(items, figures) {
6835
7340
  }
6836
7341
 
6837
7342
  // src/pdf/page-blocks.ts
6838
- function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeight, extraLines, detectTables = true, carry, lexicon) {
7343
+ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeight, extraLines, detectTables = true, carry, lexicon, verifiedRightArrows = []) {
6839
7344
  if (items.length === 0) {
6840
7345
  if (carry) carry.clip = void 0;
6841
7346
  return [];
@@ -6843,7 +7348,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
6843
7348
  const tab = sideTabGlyphs(items);
6844
7349
  if (tab.size) {
6845
7350
  const glyphs = [...tab].sort((a, b) => b.y - a.y).map((g) => ({ type: "paragraph", text: g.text.trim(), pageNumber: pageNum, bbox: computeBBox([g], pageNum), style: dominantStyle([g]) }));
6846
- return [...glyphs, ...extractPageBlocksWithLines(items.filter((i) => !tab.has(i)), pageNum, opList, pageWidth, pageHeight, extraLines, detectTables, carry, lexicon)];
7351
+ return [...glyphs, ...extractPageBlocksWithLines(items.filter((i) => !tab.has(i)), pageNum, opList, pageWidth, pageHeight, extraLines, detectTables, carry, lexicon, verifiedRightArrows)];
6847
7352
  }
6848
7353
  const lex = _nullishCoalesce(lexicon, () => ( new WrapLexicon()));
6849
7354
  for (const line of streamLines(items)) lex.addLine(mergeLineSimple(line));
@@ -6853,7 +7358,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
6853
7358
  const filled = fillBlanks(items, horizontals, verticals);
6854
7359
  items = filled.items;
6855
7360
  horizontals = filled.horizontals;
6856
- const prevPage = _optionalChain([carry, 'optionalAccess', _292 => _292.page]) === pageNum - 1 ? carry.clip : void 0;
7361
+ const prevPage = _optionalChain([carry, 'optionalAccess', _328 => _328.page]) === pageNum - 1 ? carry.clip : void 0;
6857
7362
  const clipResult = detectTables ? buildClipCellGrids(extracted.clipRects, horizontals, verticals, pageWidth, pageHeight, items.map((it) => ({ x: it.x + it.w / 2, y: it.y + it.h / 2 })), extracted.fillRects, prevPage) : { grids: [], containers: [], page: void 0 };
6858
7363
  if (carry) {
6859
7364
  carry.page = pageNum;
@@ -6871,19 +7376,28 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
6871
7376
  }
6872
7377
  ;
6873
7378
  ({ horizontals, verticals } = filterPageBorderLines(horizontals, verticals, pageWidth, pageHeight));
6874
- ({ horizontals, verticals } = preprocessLines(horizontals, verticals));
7379
+ ({ horizontals, verticals } = preprocessLines(horizontals, verticals, extracted.nonRules));
7380
+ markStrikethroughItems(items, horizontals);
7381
+ wrapStrikethroughRuns(items);
7382
+ const underlines = new Set(markUnderlineItems(items, horizontals, verticals, extracted.nonRules));
7383
+ if (underlines.size) horizontals = horizontals.filter((l) => !underlines.has(l));
7384
+ wrapUnderlineRuns(items);
6875
7385
  horizontals = closeOpenTableEnds(horizontals, verticals, items.every((it) => it.seq !== void 0));
6876
7386
  verticals = closeOpenTableEdges(horizontals, verticals);
6877
7387
  verticals = bridgeSplitColumnVerticals(horizontals, verticals);
6878
7388
  if (detectTables && clipGrids.length === 0) verticals = bridgeSkippedRowVerticals(horizontals, verticals, items);
6879
7389
  if (detectTables && clipGrids.length === 0) ({ horizontals, verticals } = extendHeaderBoxRows(horizontals, verticals, items));
6880
- markStrikethroughItems(items, horizontals);
6881
- wrapStrikethroughRuns(items);
6882
- const underlines = new Set(markUnderlineItems(items, horizontals, verticals));
6883
- if (underlines.size) horizontals = horizontals.filter((l) => !underlines.has(l));
6884
- wrapUnderlineRuns(items);
7390
+ const shadedEdges = detectTables ? closeShadedTableEdges(clipGrids, horizontals, verticals, extracted.fillRects) : void 0;
7391
+ if (shadedEdges) ({ horizontals, verticals } = shadedEdges);
6885
7392
  const lineGrids = detectTables ? buildTableGrids(horizontals, verticals) : [];
7393
+ if (shadedEdges) nestRestoredShadedGrids(lineGrids, shadedEdges.restored, horizontals, verticals);
6886
7394
  const tableClipGrids = dropHeadBandClipGrids(dropInsetClipGrids(dropShadingClipGrids(clipGrids, lineGrids, extracted.fillRects, verticals), lineGrids), lineGrids);
7395
+ recordClipCellEdges(
7396
+ extendNestedShadedHeaders(tableClipGrids, lineGrids, horizontals, verticals, extracted.fillRects),
7397
+ extracted.horizontals.concat(extracted.shortH),
7398
+ extracted.verticals.concat(extracted.shortV),
7399
+ extracted.nonRules
7400
+ );
6887
7401
  const grids = [...tableClipGrids, ...dropGridsInside(lineGrids, tableClipGrids, clipResult.containers)];
6888
7402
  const figures = () => extractImageRegions(opList.fnArray, opList.argsArray, true).filter((r) => r.x2 - r.x1 >= 40 && r.y2 - r.y1 >= 40).map((r) => ({ x: r.x1, y: r.y1, w: r.x2 - r.x1, h: r.y2 - r.y1 }));
6889
7403
  if (grids.length === 1 && grids[0].rowYs.length === 2 && grids[0].colXs.length === 2 && grids[0].bbox.x2 - grids[0].bbox.x1 > pageWidth * 1.2 && grids[0].bbox.y2 - grids[0].bbox.y1 > pageHeight * 1.2) {
@@ -6893,7 +7407,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
6893
7407
  if (detectTables && clipGrids.length === 0 && ruled.length === 0 && lineGrids.length === 0) ruled.push(...detectTextBoxTables(extracted.hiddenBoxes, items, pageNum));
6894
7408
  if (ruled.length > 0) {
6895
7409
  const imageRegions = extractImageRegions(opList.fnArray, opList.argsArray).filter((r) => r.x2 - r.x1 >= 8 && r.y2 - r.y1 >= 8);
6896
- return extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, horizontals, verticals, imageRegions, lex, ruled, rawRules);
7410
+ return extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, horizontals, verticals, imageRegions, lex, ruled, rawRules, verifiedRightArrows);
6897
7411
  }
6898
7412
  if (detectTables && stackedTableBands(items)) {
6899
7413
  return extractPageBlocksFallback(items, pageNum, true, detectTables, lex, figures());
@@ -6904,7 +7418,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
6904
7418
  }
6905
7419
  if (grids.length > 0) {
6906
7420
  const imageRegions = extractImageRegions(opList.fnArray, opList.argsArray).filter((r) => r.x2 - r.x1 >= 8 && r.y2 - r.y1 >= 8);
6907
- return extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, horizontals, verticals, imageRegions, lex, [], rawRules);
7421
+ return extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, horizontals, verticals, imageRegions, lex, [], rawRules, verifiedRightArrows);
6908
7422
  }
6909
7423
  return extractPageBlocksFallback(items, pageNum, true, detectTables, lex, figures());
6910
7424
  }
@@ -7009,42 +7523,10 @@ function isSparseProseGrid(table) {
7009
7523
  const prose = filled.filter((t) => t.length >= 60 && /[.!?。]/.test(t)).reduce((n, t) => n + t.length, 0);
7010
7524
  return prose >= chars * 0.6;
7011
7525
  }
7012
- var FRAME_RECT_TOL = 1.5;
7013
- function takePendingNested(pending, cellBox, clipCell) {
7014
- const out = [];
7015
- for (let i = pending.length - 1; i >= 0; i--) {
7016
- const p = pending[i].parent;
7017
- if (pending[i].contained ? p.x1 >= cellBox.x1 - FRAME_RECT_TOL && p.x2 <= cellBox.x2 + FRAME_RECT_TOL && p.y1 >= cellBox.y1 - FRAME_RECT_TOL && p.y2 <= cellBox.y2 + FRAME_RECT_TOL : clipCell && Math.abs(p.x1 - cellBox.x1) <= FRAME_RECT_TOL && Math.abs(p.x2 - cellBox.x2) <= FRAME_RECT_TOL && Math.abs(p.y1 - cellBox.y1) <= FRAME_RECT_TOL && Math.abs(p.y2 - cellBox.y2) <= FRAME_RECT_TOL) {
7018
- out.push(pending[i].block);
7019
- pending.splice(i, 1);
7020
- }
7021
- }
7022
- return out;
7023
- }
7024
- function buildFrameCellBlocks(cellItems, nested, pageNum, wrap) {
7025
- const tables = [...nested].sort((a, b) => b.bbox.y + b.bbox.height - (a.bbox.y + a.bbox.height));
7026
- const blocks = [];
7027
- let rest = [...cellItems];
7028
- const pushParagraphs = (items) => {
7029
- if (items.length === 0) return;
7030
- for (const line of cleanCellText(cellTextToString(items, wrap)).split("\n")) {
7031
- const t = line.trim();
7032
- if (t) blocks.push({ type: "paragraph", text: t, pageNumber: pageNum });
7033
- }
7034
- };
7035
- for (const tb of tables) {
7036
- const bottom = tb.bbox.y;
7037
- pushParagraphs(rest.filter((it) => it.y >= bottom));
7038
- rest = rest.filter((it) => it.y < bottom);
7039
- blocks.push(tb);
7040
- }
7041
- pushParagraphs(rest);
7042
- const text = blocks.map((b) => b.type === "table" && b.table ? b.table.cells.flat().map((c) => c.text).filter(Boolean).join("\n") : _nullishCoalesce(b.text, () => ( ""))).filter(Boolean).join("\n");
7043
- return { blocks, text };
7044
- }
7045
- function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, horizontals, verticals, imageRegions = [], lex, ruled = [], rawRules = horizontals) {
7526
+ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, horizontals, verticals, imageRegions = [], lex, ruled = [], rawRules = horizontals, verifiedRightArrows = []) {
7046
7527
  const ocrPage = items.length > 0 && items.every((i) => i.fontName === "ocr");
7047
7528
  const blocks = [];
7529
+ const frameParagraphUnits = [];
7048
7530
  const usedItems = /* @__PURE__ */ new Set();
7049
7531
  for (const r of ruled) {
7050
7532
  for (const it of r.items) usedItems.add(it);
@@ -7101,7 +7583,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7101
7583
  const nested = pendingNested.length ? takePendingNested(pendingNested, cell.bbox, !!grid.cells) : [];
7102
7584
  if (nested.length > 0) {
7103
7585
  nestedAttached = true;
7104
- const built = buildFrameCellBlocks(cellItems, nested, pageNum, { box: cell.bbox, lex });
7586
+ const built = buildFrameCellBlocks(cellItems, nested, pageNum, lex);
7105
7587
  irGrid[cell.row][cell.col] = { text: built.text, colSpan: cell.colSpan, rowSpan: cell.rowSpan, blocks: built.blocks };
7106
7588
  if (cellItems.length) recordCellLines(irGrid[cell.row][cell.col], cellItems);
7107
7589
  takeClipCellEdges(cell, irGrid[cell.row][cell.col]);
@@ -7112,6 +7594,9 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7112
7594
  colSpan: cell.colSpan,
7113
7595
  rowSpan: cell.rowSpan
7114
7596
  };
7597
+ if (numRows === 1 && numCols === 1 && cellItems.length) {
7598
+ irGrid[cell.row][cell.col].blocks = buildFrameCellBlocks(cellItems, [], pageNum, lex).blocks;
7599
+ }
7115
7600
  const b = cell.bbox;
7116
7601
  const isBackdrop = (r) => r.x1 <= b.x1 + 1 && r.x2 >= b.x2 - 1 && r.y1 <= b.y1 + 1 && r.y2 >= b.y2 - 1;
7117
7602
  if (imageRegions.some((r) => {
@@ -7141,14 +7626,14 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7141
7626
  if (!assignedItems.has(textItems[ti])) usedItems.delete(tableItems[ti]);
7142
7627
  }
7143
7628
  }
7144
- if (unitLine.length > 0 && rebuiltUsed && !/^\s*\(\s*단위\s*[::]/.test(_nullishCoalesce(_optionalChain([finalGrid, 'access', _293 => _293[0], 'optionalAccess', _294 => _294[0], 'optionalAccess', _295 => _295.text]), () => ( "")))) {
7629
+ if (unitLine.length > 0 && rebuiltUsed && !/^\s*\(\s*단위\s*[::]/.test(_nullishCoalesce(_optionalChain([finalGrid, 'access', _329 => _329[0], 'optionalAccess', _330 => _330[0], 'optionalAccess', _331 => _331.text]), () => ( "")))) {
7145
7630
  prependUnitRow(finalGrid, numCols, unitLine, usedItems);
7146
7631
  finalRows++;
7147
7632
  }
7148
7633
  if (!rebuiltUsed && attachUnitRow(items, grid, finalGrid, numCols, usedItems)) finalRows++;
7149
7634
  let semanticOneColumn = false;
7150
- if (!grid.cells && numCols === 1 && numGridRows >= 2) {
7151
- const populatedRows = finalGrid.filter((row) => _optionalChain([row, 'access', _296 => _296[0], 'optionalAccess', _297 => _297.text, 'access', _298 => _298.trim, 'call', _299 => _299()]));
7635
+ if (!grid.cells && !nestedAttached && numCols === 1 && numGridRows >= 2) {
7636
+ const populatedRows = finalGrid.filter((row) => _optionalChain([row, 'access', _332 => _332[0], 'optionalAccess', _333 => _333.text, 'access', _334 => _334.trim, 'call', _335 => _335()]));
7152
7637
  if (populatedRows.length >= 4) {
7153
7638
  const fontSizes = tableItems.map((item) => item.fontSize).filter((size) => size > 0).sort((a, b) => a - b);
7154
7639
  const medianFont = _nullishCoalesce(fontSizes[Math.floor(fontSizes.length / 2)], () => ( 0));
@@ -7200,6 +7685,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7200
7685
  recordRowRules(irTable, grid.cells, grid.bbox, rawRules);
7201
7686
  }
7202
7687
  TABLE_COLXS.set(irTable, grid.colXs);
7688
+ if (grid.cells) recordFrameTitle(irTable, tableItems, pageNum);
7203
7689
  if (grid.cells && finalRows === numRows) TABLE_ROWYS.set(irTable, grid.rowYs);
7204
7690
  if (grid.continues) CONT_PARTS.set(irTable, grid.continues);
7205
7691
  const hasContent = finalGrid.some((row) => row.some((cell) => cell.text.trim() !== ""));
@@ -7233,7 +7719,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7233
7719
  height: grid.bbox.y2 - grid.bbox.y1
7234
7720
  };
7235
7721
  if (numRows === 1 && numCols === 1 && gridW < pageWidth * 0.35) {
7236
- const prose = _nullishCoalesce(_optionalChain([finalGrid, 'access', _300 => _300[0], 'optionalAccess', _301 => _301[0], 'optionalAccess', _302 => _302.text]), () => ( ""));
7722
+ const prose = _nullishCoalesce(_optionalChain([finalGrid, 'access', _336 => _336[0], 'optionalAccess', _337 => _337[0], 'optionalAccess', _338 => _338.text]), () => ( ""));
7237
7723
  const besideLines = (side) => new Set(side.map((it) => Math.round(it.y / 3))).size;
7238
7724
  const rightLines = items.filter((it) => it.x >= grid.bbox.x2 + 3 && it.y >= grid.bbox.y1 && it.y <= grid.bbox.y2);
7239
7725
  const leftLines = items.filter((it) => it.x + it.w <= grid.bbox.x1 - 3 && it.y >= grid.bbox.y1 && it.y <= grid.bbox.y2);
@@ -7251,7 +7737,14 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7251
7737
  continue;
7252
7738
  }
7253
7739
  }
7254
- if (!grid.cells && shouldDemoteTable(irTable)) {
7740
+ if (!grid.cells && !nestedAttached && shouldDemoteTable(irTable)) {
7741
+ const paragraphs = numRows === 1 && numCols === 1 ? _optionalChain([irTable, 'access', _339 => _339.cells, 'access', _340 => _340[0], 'optionalAccess', _341 => _341[0], 'optionalAccess', _342 => _342.blocks]) : void 0;
7742
+ if (_optionalChain([paragraphs, 'optionalAccess', _343 => _343.length])) {
7743
+ blocks.push(...paragraphs);
7744
+ frameParagraphUnits.push(paragraphs);
7745
+ recordFrameReadingUnit(paragraphs, tableBbox);
7746
+ continue;
7747
+ }
7255
7748
  const demoted = demoteTableToText(irTable);
7256
7749
  if (demoted) {
7257
7750
  const text = numGridRows === 1 ? "\n" + demoted + "\n" : demoted;
@@ -7287,7 +7780,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7287
7780
  const proseColumns = findTwoColumnProseCutX(clusterItems) !== null || detectPersistentColumnGutter(remaining.map((i) => ({ x: i.x, y: i.y, w: i.w, h: i.h > 0 ? i.h : i.fontSize }))) !== null;
7288
7781
  const clusterResults = (proseColumns ? [] : detectClusterTables(clusterItems, pageNum)).filter((cr) => {
7289
7782
  const b = cr.bbox;
7290
- return !blocks.some((x) => x.type === "paragraph" && x.bbox && (_nullishCoalesce(_optionalChain([x, 'access', _303 => _303.text, 'optionalAccess', _304 => _304.match, 'call', _305 => _305(/\p{L}/gu), 'optionalAccess', _306 => _306.length]), () => ( 0))) >= 10 && Math.min(x.bbox.x + x.bbox.width, b.x + b.width) - Math.max(x.bbox.x, b.x) >= 0.8 * b.width && x.bbox.y >= b.y - 2 && x.bbox.y + x.bbox.height <= b.y + b.height + 2);
7783
+ return !blocks.some((x) => x.type === "paragraph" && x.bbox && (_nullishCoalesce(_optionalChain([x, 'access', _344 => _344.text, 'optionalAccess', _345 => _345.match, 'call', _346 => _346(/\p{L}/gu), 'optionalAccess', _347 => _347.length]), () => ( 0))) >= 10 && Math.min(x.bbox.x + x.bbox.width, b.x + b.width) - Math.max(x.bbox.x, b.x) >= 0.8 * b.width && x.bbox.y >= b.y - 2 && x.bbox.y + x.bbox.height <= b.y + b.height + 2);
7291
7784
  });
7292
7785
  if (clusterResults.length > 0) {
7293
7786
  const ciToIdx = /* @__PURE__ */ new Map();
@@ -7305,9 +7798,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7305
7798
  }
7306
7799
  {
7307
7800
  const rects = remaining.map((i) => ({ x: i.x, y: i.y, w: i.w, h: i.h > 0 ? i.h : i.fontSize }));
7308
- for (const b of blocks) {
7309
- if (b.bbox && !(b.table && EMPTY_PARTS.has(b.table))) rects.push({ x: b.bbox.x, y: b.bbox.y, w: b.bbox.width, h: b.bbox.height });
7310
- }
7801
+ for (const b of frameLayoutBoxes(blocks.filter((b2) => !(b2.table && EMPTY_PARTS.has(b2.table))))) rects.push({ x: b.x, y: b.y, w: b.width, h: b.height });
7311
7802
  gutterX = _nullishCoalesce(detectColumnGutter(rects), () => ( findRuledColumnDivider(
7312
7803
  blocks.filter((b) => b.type === "table" && b.bbox && b.table && !EMPTY_PARTS.has(b.table)).map((b) => ({ x: b.bbox.x, y: b.bbox.y, w: b.bbox.width, h: b.bbox.height })),
7313
7804
  horizontals,
@@ -7321,7 +7812,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7321
7812
  if (gutterX !== null) {
7322
7813
  const gx = gutterX;
7323
7814
  const allY = remaining.map((i) => i.y);
7324
- const pageH = _chunkSHRRD2TDcjs.safeMax.call(void 0, allY) - _chunkSHRRD2TDcjs.safeMin.call(void 0, allY);
7815
+ const pageH = _chunk3XSP7V5Pcjs.safeMax.call(void 0, allY) - _chunk3XSP7V5Pcjs.safeMin.call(void 0, allY);
7325
7816
  const gapThreshold = Math.max(15, pageH * 0.03);
7326
7817
  const sides = [
7327
7818
  remaining.filter((i) => i.x + i.w <= gx),
@@ -7341,7 +7832,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7341
7832
  finalTextBlocks = detectListBlocks(textBlocks);
7342
7833
  } else {
7343
7834
  const allY = remaining.map((i) => i.y);
7344
- const pageH = _chunkSHRRD2TDcjs.safeMax.call(void 0, allY) - _chunkSHRRD2TDcjs.safeMin.call(void 0, allY);
7835
+ const pageH = _chunk3XSP7V5Pcjs.safeMax.call(void 0, allY) - _chunk3XSP7V5Pcjs.safeMin.call(void 0, allY);
7345
7836
  const groups = xyCutOrder(remaining, Math.max(15, pageH * 0.03));
7346
7837
  const textBlocks = [];
7347
7838
  for (const group of groups) {
@@ -7354,7 +7845,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7354
7845
  finalTextBlocks = detectListBlocks(textBlocks);
7355
7846
  }
7356
7847
  }
7357
- const units = blocks.map((b) => [b]);
7848
+ const units = groupFrameParagraphUnits(groupFlowBoxUnits(blocks, grids, horizontals, verticals, verifiedRightArrows), frameParagraphUnits);
7358
7849
  let off = 0;
7359
7850
  for (const size of groupSizes) {
7360
7851
  const unit = finalTextBlocks.slice(off, off + size);
@@ -7493,7 +7984,7 @@ function mergeAdjacentTableBlocks(blocks) {
7493
7984
  table: merged,
7494
7985
  bbox: { ...pb, y: cb.y, height: pb.y + pb.height - cb.y }
7495
7986
  };
7496
- } else if (prev.type === "table" && curr.type === "table" && prev.table && curr.table && prev.table.cols === curr.table.cols && prev.table.renderAsTable === curr.table.renderAsTable && !CLIP_TABLES.has(prev.table) && !CLIP_TABLES.has(curr.table)) {
7987
+ } else if (prev.type === "table" && curr.type === "table" && prev.table && curr.table && prev.table.cols === curr.table.cols && prev.table.renderAsTable === curr.table.renderAsTable && !CLIP_TABLES.has(prev.table) && !CLIP_TABLES.has(curr.table) && !separateRepeatedHeadings(prev, curr)) {
7497
7988
  const merged = {
7498
7989
  rows: prev.table.rows + curr.table.rows,
7499
7990
  cols: prev.table.cols,
@@ -7508,6 +7999,12 @@ function mergeAdjacentTableBlocks(blocks) {
7508
7999
  }
7509
8000
  return result;
7510
8001
  }
8002
+ function separateRepeatedHeadings(upper, lower) {
8003
+ const u = upper.table, d = lower.table, ub = upper.bbox, db = lower.bbox;
8004
+ if (!ub || !db || ub.page !== db.page || u.rows < 2 || d.rows < 2 || !u.hasHeader || !d.hasHeader || ub.y - (db.y + db.height) <= 1 || Math.abs(ub.x - db.x) > 1 || Math.abs(ub.width - db.width) > 1) return false;
8005
+ const a = u.cells[0], b = d.cells[0], norm = (text) => text.replace(/<\/?u>|~~|\s+/g, "");
8006
+ return a.filter((cell) => norm(cell.text)).length >= 2 && a.length === b.length && a.every((cell, c) => cell.colSpan === b[c].colSpan && cell.rowSpan === b[c].rowSpan && norm(cell.text) === norm(b[c].text));
8007
+ }
7511
8008
  function streamLines(items) {
7512
8009
  if (items.some((i) => i.seq === void 0)) return groupByY([...items].sort((a, b) => b.y - a.y || a.x - b.x));
7513
8010
  const lines = [];
@@ -7660,7 +8157,7 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
7660
8157
  blocks.push(...columnTextToBlocks(tableText, pageNum, bbox, dominantStyle(items)));
7661
8158
  } else {
7662
8159
  const allY = items.map((i) => i.y);
7663
- const pageHeight = _chunkSHRRD2TDcjs.safeMax.call(void 0, allY) - _chunkSHRRD2TDcjs.safeMin.call(void 0, allY);
8160
+ const pageHeight = _chunk3XSP7V5Pcjs.safeMax.call(void 0, allY) - _chunk3XSP7V5Pcjs.safeMin.call(void 0, allY);
7664
8161
  const gapThreshold = Math.max(15, pageHeight * 0.03);
7665
8162
  const orderedGroups = proseCutX !== null ? splitTwoColumnProse(items, proseCutX) : xyCutOrder(items, gapThreshold);
7666
8163
  for (const group of orderedGroups) {
@@ -7728,5 +8225,14 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
7728
8225
 
7729
8226
 
7730
8227
 
7731
- exports.OCR_DET_MODEL = OCR_DET_MODEL; exports.OCR_REC_MODEL = OCR_REC_MODEL; exports.OCR_REC_DICT = OCR_REC_DICT; exports.getOcrModelsDir = getOcrModelsDir; exports.ensureOcrModels = ensureOcrModels; exports.ocrModelsCached = ocrModelsCached; exports.parseCharacterDict = parseCharacterDict; exports.extractLines = extractLines; exports.extractImageRegions = extractImageRegions; exports.filterHiddenText = filterHiddenText; exports.collapseEvenSpacing = collapseEvenSpacing; exports.normalizeItems = normalizeItems; exports.WrapLexicon = WrapLexicon; exports.startsNewItem = startsNewItem; exports.wrapJoiner = wrapJoiner; exports.joinPageBreakWraps = joinPageBreakWraps; exports.latinSoftWrap = latinSoftWrap; exports.TOC_BLOCKS = TOC_BLOCKS; exports.computeMedianFontSizeFromFreq = computeMedianFontSizeFromFreq; exports.detectHeadings = detectHeadings; exports.mergeStackedHeadingLines = mergeStackedHeadingLines; exports.detectTypographyHeadings = detectTypographyHeadings; exports.detectDocumentStyleHeadings = detectDocumentStyleHeadings; exports.detectSiblingStyleHeadings = detectSiblingStyleHeadings; exports.detectRepeatedPageLabels = detectRepeatedPageLabels; exports.detectPageLeadHeadings = detectPageLeadHeadings; exports.refineDocumentStyleHeadings = refineDocumentStyleHeadings; exports.detectMarkerHeadings = detectMarkerHeadings; exports.detectTableCaptions = detectTableCaptions; exports.detectKoreanListBlocks = detectKoreanListBlocks; exports.removeHeaderFooterBlocks = removeHeaderFooterBlocks; exports.CLIP_TABLES = CLIP_TABLES; exports.TABLE_COLXS = TABLE_COLXS; exports.TABLE_ROWYS = TABLE_ROWYS; exports.TABLE_TAIL = TABLE_TAIL; exports.PART_COLXS = PART_COLXS; exports.EMPTY_PARTS = EMPTY_PARTS; exports.IMAGE_CELLS = IMAGE_CELLS; exports.FILLER_CELLS = FILLER_CELLS; exports.CONT_PARTS = CONT_PARTS; exports.CELL_LINES = CELL_LINES; exports.ROW_RULES = ROW_RULES; exports.trimTrailingEmptyTableCols = trimTrailingEmptyTableCols; exports.NO_EDGES = NO_EDGES; exports.joinCellEdges = joinCellEdges; exports.removeSideTabs = removeSideTabs; exports.extractPageBlocksWithLines = extractPageBlocksWithLines;
7732
- //# sourceMappingURL=chunk-WN5YLP7H.cjs.map
8228
+
8229
+
8230
+
8231
+
8232
+
8233
+
8234
+
8235
+
8236
+
8237
+ exports.OCR_DET_MODEL = OCR_DET_MODEL; exports.OCR_REC_MODEL = OCR_REC_MODEL; exports.OCR_REC_DICT = OCR_REC_DICT; exports.getOcrModelsDir = getOcrModelsDir; exports.ensureOcrModels = ensureOcrModels; exports.ocrModelsCached = ocrModelsCached; exports.parseCharacterDict = parseCharacterDict; exports.extractLines = extractLines; exports.extractImageRegions = extractImageRegions; exports.filterHiddenText = filterHiddenText; exports.collapseEvenSpacing = collapseEvenSpacing; exports.computeBBox = computeBBox; exports.dominantStyle = dominantStyle; exports.normalizeItems = normalizeItems; exports.groupByY = groupByY; exports.mergeLineSimple = mergeLineSimple; exports.WrapLexicon = WrapLexicon; exports.startsNewItem = startsNewItem; exports.wrapJoiner = wrapJoiner; exports.joinPageBreakWraps = joinPageBreakWraps; exports.latinSoftWrap = latinSoftWrap; exports.TOC_BLOCKS = TOC_BLOCKS; exports.computeMedianFontSizeFromFreq = computeMedianFontSizeFromFreq; exports.detectHeadings = detectHeadings; exports.mergeStackedHeadingLines = mergeStackedHeadingLines; exports.detectTypographyHeadings = detectTypographyHeadings; exports.detectDocumentStyleHeadings = detectDocumentStyleHeadings; exports.detectSiblingStyleHeadings = detectSiblingStyleHeadings; exports.detectRepeatedPageLabels = detectRepeatedPageLabels; exports.detectPageLeadHeadings = detectPageLeadHeadings; exports.refineDocumentStyleHeadings = refineDocumentStyleHeadings; exports.detectMarkerHeadings = detectMarkerHeadings; exports.detectTableCaptions = detectTableCaptions; exports.detectKoreanListBlocks = detectKoreanListBlocks; exports.removeHeaderFooterBlocks = removeHeaderFooterBlocks; exports.CLIP_TABLES = CLIP_TABLES; exports.FRAME_TITLE_BLOCKS = FRAME_TITLE_BLOCKS; exports.TABLE_COLXS = TABLE_COLXS; exports.TABLE_ROWYS = TABLE_ROWYS; exports.TABLE_TAIL = TABLE_TAIL; exports.PART_COLXS = PART_COLXS; exports.EMPTY_PARTS = EMPTY_PARTS; exports.IMAGE_CELLS = IMAGE_CELLS; exports.FILLER_CELLS = FILLER_CELLS; exports.CONT_PARTS = CONT_PARTS; exports.CELL_LINES = CELL_LINES; exports.ROW_RULES = ROW_RULES; exports.trimTrailingEmptyTableCols = trimTrailingEmptyTableCols; exports.NO_EDGES = NO_EDGES; exports.joinCellEdges = joinCellEdges; exports.FRAME_READING_UNITS = FRAME_READING_UNITS; exports.recordFrameReadingUnit = recordFrameReadingUnit; exports.restoreImageBullets = restoreImageBullets; exports.detectRightArrowRegions = detectRightArrowRegions; exports.removeSideTabs = removeSideTabs; exports.extractPageBlocksWithLines = extractPageBlocksWithLines;
8238
+ //# sourceMappingURL=chunk-E2644XCO.cjs.map