kordoc 4.17.4 → 4.17.6

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 (119) hide show
  1. package/dist/{-SQRLFE4N.js → -Y6U3UTVZ.js} +11 -11
  2. package/dist/{chunk-RCS7WXOM.js → chunk-226C4AJR.js} +2 -2
  3. package/dist/{chunk-ODVIUG6Q.js → chunk-2WUE6JIT.js} +2 -2
  4. package/dist/{chunk-AOONZC4S.cjs → chunk-4LU6NGTL.cjs} +3 -3
  5. package/dist/{chunk-AOONZC4S.cjs.map → chunk-4LU6NGTL.cjs.map} +1 -1
  6. package/dist/{chunk-HY33WBAH.js → chunk-5VHV6W7W.js} +2 -2
  7. package/dist/{chunk-W3OY3SLY.js → chunk-6A4Z6VYA.js} +2 -2
  8. package/dist/{chunk-IERSVUW6.js → chunk-7F7CUU22.js} +2 -2
  9. package/dist/{chunk-TMHMJUYU.js → chunk-7R7NFGHY.js} +6 -6
  10. package/dist/{chunk-VJP7O6BL.js → chunk-AYMTRCLC.js} +2 -2
  11. package/dist/{chunk-P2ZPPRM7.js → chunk-B3RQHQCC.js} +2 -2
  12. package/dist/{chunk-PTMYCK7R.js → chunk-BPLEMV4B.js} +2 -2
  13. package/dist/{chunk-WNF3TSV3.cjs → chunk-CZOPNDTO.cjs} +426 -324
  14. package/dist/chunk-CZOPNDTO.cjs.map +1 -0
  15. package/dist/{chunk-EXBZHI25.cjs → chunk-FVESLY6V.cjs} +2 -2
  16. package/dist/{chunk-EXBZHI25.cjs.map → chunk-FVESLY6V.cjs.map} +1 -1
  17. package/dist/{chunk-7TE6TK52.js → chunk-HRJAAWEP.js} +2 -2
  18. package/dist/{chunk-AFXX3YSP.cjs → chunk-L5JX2GAM.cjs} +6 -6
  19. package/dist/{chunk-AFXX3YSP.cjs.map → chunk-L5JX2GAM.cjs.map} +1 -1
  20. package/dist/{chunk-GNORDND5.cjs → chunk-LLFXHX7K.cjs} +12 -12
  21. package/dist/{chunk-GNORDND5.cjs.map → chunk-LLFXHX7K.cjs.map} +1 -1
  22. package/dist/{chunk-O5T5OIJM.js → chunk-MOM67IND.js} +2 -2
  23. package/dist/{chunk-AAQR4RIX.js → chunk-MOVFO74W.js} +2 -2
  24. package/dist/{chunk-4D52VUGA.js → chunk-PGHIQ6E5.js} +3 -3
  25. package/dist/{chunk-PVJFCDND.js → chunk-QKEPDJ2D.js} +341 -239
  26. package/dist/chunk-QKEPDJ2D.js.map +1 -0
  27. package/dist/{chunk-KIYHQQVO.cjs → chunk-S26THA3Q.cjs} +3 -3
  28. package/dist/{chunk-KIYHQQVO.cjs.map → chunk-S26THA3Q.cjs.map} +1 -1
  29. package/dist/{chunk-DD6AY6EI.js → chunk-T5O6HEHG.js} +2 -2
  30. package/dist/{chunk-PNXJYEOR.js → chunk-TOCNK4VO.js} +2 -2
  31. package/dist/{chunk-FSCVZR4A.js → chunk-U6NLEEIN.js} +4 -4
  32. package/dist/{chunk-HQ6TM2JE.js → chunk-VHIGYTRO.js} +3 -3
  33. package/dist/{chunk-YBIWPCUX.js → chunk-YCMPQRHV.js} +342 -240
  34. package/dist/chunk-YCMPQRHV.js.map +1 -0
  35. package/dist/{chunk-NNNRN6BY.js → chunk-ZQA7Q3GV.js} +2 -2
  36. package/dist/{chunk-6DXSRQ65.js → chunk-ZQBBMUFA.js} +2 -2
  37. package/dist/{chunk-SSY6FQLS.js → chunk-ZS5KKM4L.js} +10 -10
  38. package/dist/chunks-S72SPTCL.js +10 -0
  39. package/dist/cli.js +26 -26
  40. package/dist/{formula-U37MTMBD.cjs → formula-3IQFGZXS.cjs} +9 -9
  41. package/dist/{formula-U37MTMBD.cjs.map → formula-3IQFGZXS.cjs.map} +1 -1
  42. package/dist/{formula-WZH5CMA3.js → formula-B72X7SFX.js} +3 -3
  43. package/dist/{formula-U3MJXXIL.js → formula-U7K3K4AE.js} +4 -4
  44. package/dist/{image-ocr-OXU55EW3.cjs → image-ocr-GYYVTTDG.cjs} +15 -15
  45. package/dist/{image-ocr-OXU55EW3.cjs.map → image-ocr-GYYVTTDG.cjs.map} +1 -1
  46. package/dist/{image-ocr-HYWDBN72.js → image-ocr-UGL5PWJ3.js} +6 -6
  47. package/dist/{image-ocr-V6MICC6R.js → image-ocr-YCBQ7HUD.js} +9 -9
  48. package/dist/index.cjs +259 -259
  49. package/dist/index.js +5 -5
  50. package/dist/mcp.js +22 -22
  51. package/dist/{model-bundle-AHBUQ6SD.js → model-bundle-Z4KSW4P5.js} +5 -5
  52. package/dist/{models-UF7B5LLG.js → models-HCI2GHBA.js} +5 -5
  53. package/dist/{parser-IXRGUYZW.cjs → parser-MZKMFBI3.cjs} +175 -157
  54. package/dist/parser-MZKMFBI3.cjs.map +1 -0
  55. package/dist/{parser-T4FBG2FR.js → parser-NFOHA5VI.js} +28 -10
  56. package/dist/{parser-F6N6ID25.js.map → parser-NFOHA5VI.js.map} +1 -1
  57. package/dist/{parser-F6N6ID25.js → parser-XCHUEHOX.js} +31 -13
  58. package/dist/{parser-T4FBG2FR.js.map → parser-XCHUEHOX.js.map} +1 -1
  59. package/dist/pdf-ocr-PXU6MBUZ.cjs +16 -0
  60. package/dist/{pdf-ocr-2CITOAIG.cjs.map → pdf-ocr-PXU6MBUZ.cjs.map} +1 -1
  61. package/dist/pdf-ocr-QQ6MJCXT.js +19 -0
  62. package/dist/pdf-ocr-WADZZ2YQ.js +15 -0
  63. package/dist/{profile-io-GM3NVLV3.js → profile-io-3BZXXOIW.js} +3 -3
  64. package/dist/{rasterize-4A3LJXTG.js → rasterize-SLLX5CQN.js} +3 -3
  65. package/dist/{redact-doc-SQ7C3LIG.js → redact-doc-CCOUCCQA.js} +11 -11
  66. package/dist/{render-6LTQZG4W.js → render-7OLLRV4U.js} +7 -7
  67. package/dist/seal-WGSATSQC.js +10 -0
  68. package/dist/{setup-DGBJOROA.js → setup-GONHHIMX.js} +3 -3
  69. package/dist/visual-C5D42ZAJ.js +20 -0
  70. package/dist/{watch-DJVJRSLE.js → watch-EWWEQI33.js} +12 -12
  71. package/package.json +1 -1
  72. package/dist/chunk-PVJFCDND.js.map +0 -1
  73. package/dist/chunk-WNF3TSV3.cjs.map +0 -1
  74. package/dist/chunk-YBIWPCUX.js.map +0 -1
  75. package/dist/chunks-VNSLMJQD.js +0 -10
  76. package/dist/parser-IXRGUYZW.cjs.map +0 -1
  77. package/dist/pdf-ocr-2CITOAIG.cjs +0 -16
  78. package/dist/pdf-ocr-RG2MFWBX.js +0 -15
  79. package/dist/pdf-ocr-U7Z4IUMA.js +0 -19
  80. package/dist/seal-ROSVLTRQ.js +0 -10
  81. package/dist/visual-6W34SFIW.js +0 -20
  82. /package/dist/{-SQRLFE4N.js.map → -Y6U3UTVZ.js.map} +0 -0
  83. /package/dist/{chunk-RCS7WXOM.js.map → chunk-226C4AJR.js.map} +0 -0
  84. /package/dist/{chunk-ODVIUG6Q.js.map → chunk-2WUE6JIT.js.map} +0 -0
  85. /package/dist/{chunk-HY33WBAH.js.map → chunk-5VHV6W7W.js.map} +0 -0
  86. /package/dist/{chunk-W3OY3SLY.js.map → chunk-6A4Z6VYA.js.map} +0 -0
  87. /package/dist/{chunk-IERSVUW6.js.map → chunk-7F7CUU22.js.map} +0 -0
  88. /package/dist/{chunk-TMHMJUYU.js.map → chunk-7R7NFGHY.js.map} +0 -0
  89. /package/dist/{chunk-VJP7O6BL.js.map → chunk-AYMTRCLC.js.map} +0 -0
  90. /package/dist/{chunk-P2ZPPRM7.js.map → chunk-B3RQHQCC.js.map} +0 -0
  91. /package/dist/{chunk-PTMYCK7R.js.map → chunk-BPLEMV4B.js.map} +0 -0
  92. /package/dist/{chunk-7TE6TK52.js.map → chunk-HRJAAWEP.js.map} +0 -0
  93. /package/dist/{chunk-O5T5OIJM.js.map → chunk-MOM67IND.js.map} +0 -0
  94. /package/dist/{chunk-AAQR4RIX.js.map → chunk-MOVFO74W.js.map} +0 -0
  95. /package/dist/{chunk-4D52VUGA.js.map → chunk-PGHIQ6E5.js.map} +0 -0
  96. /package/dist/{chunk-DD6AY6EI.js.map → chunk-T5O6HEHG.js.map} +0 -0
  97. /package/dist/{chunk-PNXJYEOR.js.map → chunk-TOCNK4VO.js.map} +0 -0
  98. /package/dist/{chunk-FSCVZR4A.js.map → chunk-U6NLEEIN.js.map} +0 -0
  99. /package/dist/{chunk-HQ6TM2JE.js.map → chunk-VHIGYTRO.js.map} +0 -0
  100. /package/dist/{chunk-NNNRN6BY.js.map → chunk-ZQA7Q3GV.js.map} +0 -0
  101. /package/dist/{chunk-6DXSRQ65.js.map → chunk-ZQBBMUFA.js.map} +0 -0
  102. /package/dist/{chunk-SSY6FQLS.js.map → chunk-ZS5KKM4L.js.map} +0 -0
  103. /package/dist/{chunks-VNSLMJQD.js.map → chunks-S72SPTCL.js.map} +0 -0
  104. /package/dist/{formula-WZH5CMA3.js.map → formula-B72X7SFX.js.map} +0 -0
  105. /package/dist/{formula-U3MJXXIL.js.map → formula-U7K3K4AE.js.map} +0 -0
  106. /package/dist/{image-ocr-HYWDBN72.js.map → image-ocr-UGL5PWJ3.js.map} +0 -0
  107. /package/dist/{image-ocr-V6MICC6R.js.map → image-ocr-YCBQ7HUD.js.map} +0 -0
  108. /package/dist/{model-bundle-AHBUQ6SD.js.map → model-bundle-Z4KSW4P5.js.map} +0 -0
  109. /package/dist/{models-UF7B5LLG.js.map → models-HCI2GHBA.js.map} +0 -0
  110. /package/dist/{pdf-ocr-RG2MFWBX.js.map → pdf-ocr-QQ6MJCXT.js.map} +0 -0
  111. /package/dist/{pdf-ocr-U7Z4IUMA.js.map → pdf-ocr-WADZZ2YQ.js.map} +0 -0
  112. /package/dist/{profile-io-GM3NVLV3.js.map → profile-io-3BZXXOIW.js.map} +0 -0
  113. /package/dist/{rasterize-4A3LJXTG.js.map → rasterize-SLLX5CQN.js.map} +0 -0
  114. /package/dist/{redact-doc-SQ7C3LIG.js.map → redact-doc-CCOUCCQA.js.map} +0 -0
  115. /package/dist/{render-6LTQZG4W.js.map → render-7OLLRV4U.js.map} +0 -0
  116. /package/dist/{seal-ROSVLTRQ.js.map → seal-WGSATSQC.js.map} +0 -0
  117. /package/dist/{setup-DGBJOROA.js.map → setup-GONHHIMX.js.map} +0 -0
  118. /package/dist/{visual-6W34SFIW.js.map → visual-C5D42ZAJ.js.map} +0 -0
  119. /package/dist/{watch-DJVJRSLE.js.map → watch-EWWEQI33.js.map} +0 -0
@@ -4,15 +4,15 @@
4
4
 
5
5
 
6
6
 
7
- var _chunkAFXX3YSPcjs = require('./chunk-AFXX3YSP.cjs');
7
+ var _chunkL5JX2GAMcjs = require('./chunk-L5JX2GAM.cjs');
8
8
 
9
9
 
10
10
 
11
- var _chunkAOONZC4Scjs = require('./chunk-AOONZC4S.cjs');
11
+ var _chunk4LU6NGTLcjs = require('./chunk-4LU6NGTL.cjs');
12
12
 
13
13
 
14
14
 
15
- var _chunkEXBZHI25cjs = require('./chunk-EXBZHI25.cjs');
15
+ var _chunkFVESLY6Vcjs = require('./chunk-FVESLY6V.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 _chunkAOONZC4Scjs.getModelsDir.call(void 0, "ppocr");
43
+ return _chunk4LU6NGTLcjs.getModelsDir.call(void 0, "ppocr");
44
44
  }
45
45
  async function ensureOcrModels(onProgress) {
46
- return _chunkAOONZC4Scjs.ensureModelsIn.call(void 0, getOcrModelsDir(), ALL_OCR_MODELS, onProgress);
46
+ return _chunk4LU6NGTLcjs.ensureModelsIn.call(void 0, getOcrModelsDir(), ALL_OCR_MODELS, onProgress);
47
47
  }
48
48
  async function ocrModelsCached() {
49
49
  const dir = getOcrModelsDir();
@@ -2090,7 +2090,7 @@ function tagScripts(text, lines) {
2090
2090
  const [s, e, kind] = marks[m];
2091
2091
  out = out.slice(0, s) + `<${kind}>` + out.slice(s, e) + `</${kind}>` + out.slice(e);
2092
2092
  }
2093
- return _chunkAFXX3YSPcjs.tidyScriptTags.call(void 0, out);
2093
+ return _chunkL5JX2GAMcjs.tidyScriptTags.call(void 0, out);
2094
2094
  }
2095
2095
 
2096
2096
  // src/pdf/line-wrap.ts
@@ -3236,6 +3236,324 @@ function panelBlocks(items, panel, pageNum) {
3236
3236
  });
3237
3237
  }
3238
3238
 
3239
+ // src/pdf/xy-cut.ts
3240
+ var MAX_XYCUT_DEPTH = 50;
3241
+ var XYCUT_MIN_GAP = 5;
3242
+ var CROSS_LAYOUT_BETA = 2;
3243
+ var CROSS_OVERLAP_RATIO = 0.1;
3244
+ var CROSS_MIN_OVERLAPS = 2;
3245
+ var CROSS_MAX_MASK_RATIO = 0.2;
3246
+ var NARROW_ELEMENT_WIDTH_RATIO = 0.1;
3247
+ var PROSE_GUTTER_MIN_GAP = 6;
3248
+ var XY_WRAP_BANDS = /* @__PURE__ */ new WeakMap();
3249
+ var XY_WRAP_ITEMS = /* @__PURE__ */ new WeakMap();
3250
+ var leaf = (items, wrapped) => {
3251
+ wrapped = validWrapBands(items, wrapped);
3252
+ const source = wrapped.length ? [...items] : [];
3253
+ for (const item of items) {
3254
+ if (wrapped.length) {
3255
+ XY_WRAP_BANDS.set(item, wrapped);
3256
+ XY_WRAP_ITEMS.set(item, source);
3257
+ } else {
3258
+ XY_WRAP_BANDS.delete(item);
3259
+ XY_WRAP_ITEMS.delete(item);
3260
+ }
3261
+ }
3262
+ return [items];
3263
+ };
3264
+ function xyCutOrder(items, gapThreshold, depth = 0, wrapped) {
3265
+ if (items.length === 0) return [];
3266
+ const newRegion = wrapped === void 0;
3267
+ wrapped ??= inheritedWrapBands(items);
3268
+ if (items.length <= 2 || depth >= MAX_XYCUT_DEPTH) return leaf(items, wrapped);
3269
+ if (depth === 0 && items.length >= 3) {
3270
+ const cross = identifyCrossLayoutItems(items);
3271
+ if (cross.size > 0 && cross.size <= items.length * CROSS_MAX_MASK_RATIO) {
3272
+ const rest = items.filter((i) => !cross.has(i));
3273
+ if (rest.length > 0) {
3274
+ const groups = xyCutOrder(rest, gapThreshold, 1);
3275
+ return mergeCrossLayoutGroups(groups, [...cross]);
3276
+ }
3277
+ }
3278
+ }
3279
+ const minGap = Math.max(XYCUT_MIN_GAP, gapThreshold);
3280
+ const sortedY = [...items].sort((a, b) => b.y - a.y);
3281
+ let hCut = findHorizontalCut(sortedY, wrapped);
3282
+ if (newRegion && hCut.gap >= minGap) {
3283
+ wrapped = wrappedLineBands(items, wrapped);
3284
+ hCut = findHorizontalCut(sortedY, wrapped);
3285
+ }
3286
+ const vCut = findVerticalCutWithOutlierFilter(items, minGap);
3287
+ const hValid = hCut.gap >= minGap;
3288
+ const vValid = (vCut.gap >= minGap || vCut.gap >= PROSE_GUTTER_MIN_GAP && isProseGutter(items, vCut.position)) && !splitsSpacedLabel(items, vCut.position);
3289
+ let useHorizontal;
3290
+ if (hValid && vValid) useHorizontal = vCut.gap <= hCut.gap * 1.5 || staggeredSides(items, vCut.position);
3291
+ else if (hValid) useHorizontal = true;
3292
+ else if (vValid) useHorizontal = false;
3293
+ else return _nullishCoalesce(splitEdgeSpannedColumns(items, gapThreshold, depth), () => ( leaf(items, wrapped)));
3294
+ if (useHorizontal) {
3295
+ const upper = items.filter((i) => i.y > hCut.position);
3296
+ const lower = items.filter((i) => i.y <= hCut.position);
3297
+ if (upper.length > 0 && lower.length > 0 && upper.length < items.length) {
3298
+ return [...xyCutOrder(upper, gapThreshold, depth + 1, wrapped), ...xyCutOrder(lower, gapThreshold, depth + 1, wrapped)];
3299
+ }
3300
+ } else {
3301
+ const left = items.filter((i) => i.x + i.w / 2 < vCut.position);
3302
+ const right = items.filter((i) => i.x + i.w / 2 >= vCut.position);
3303
+ if (left.length > 0 && right.length > 0 && left.length < items.length) {
3304
+ return [...xyCutOrder(left, gapThreshold, depth + 1), ...xyCutOrder(right, gapThreshold, depth + 1)];
3305
+ }
3306
+ }
3307
+ return leaf(items, wrapped);
3308
+ }
3309
+ function splitsSpacedLabel(items, cutX) {
3310
+ const lone = (i) => /^[가-힣]$/.test(i.text.trim());
3311
+ const sameRow = (a, b) => Math.min(a.y, b.y) > Math.max(a.y - a.h, b.y - b.h);
3312
+ const left = items.filter((i) => i.x + i.w / 2 < cutX);
3313
+ const right = items.filter((i) => i.x + i.w / 2 >= cutX);
3314
+ let spaced = 0;
3315
+ for (const r of right) {
3316
+ if (right.some((o) => o !== r && o.x < r.x && sameRow(o, r))) continue;
3317
+ const row = left.filter((l2) => sameRow(l2, r));
3318
+ if (row.length === 0) continue;
3319
+ const l = row.reduce((a, b) => b.x + b.w > a.x + a.w ? b : a);
3320
+ if (!lone(l) || !lone(r)) return false;
3321
+ spaced++;
3322
+ }
3323
+ return spaced > 0;
3324
+ }
3325
+ function staggeredSides(items, cutX) {
3326
+ const left = items.filter((i) => i.x + i.w / 2 < cutX);
3327
+ const right = items.filter((i) => i.x + i.w / 2 >= cutX);
3328
+ if (left.length * right.length > 2e5) return false;
3329
+ const shareRow = (a, b) => Math.min(a.y, b.y) > Math.max(a.y - a.h, b.y - b.h);
3330
+ if (left.some((a) => right.some((b) => shareRow(a, b)))) return false;
3331
+ const sides = [...items].sort((a, b) => b.y - a.y).map((i) => i.x + i.w / 2 < cutX);
3332
+ let switches = 0;
3333
+ for (let k = 1; k < sides.length; k++) if (sides[k] !== sides[k - 1]) switches++;
3334
+ return switches >= 3;
3335
+ }
3336
+ function identifyCrossLayoutItems(items) {
3337
+ const cross = /* @__PURE__ */ new Set();
3338
+ if (items.length < 3) return cross;
3339
+ let maxWidth = 0;
3340
+ for (const i of items) {
3341
+ if (i.w > maxWidth) maxWidth = i.w;
3342
+ }
3343
+ const threshold = CROSS_LAYOUT_BETA * maxWidth;
3344
+ for (const item of items) {
3345
+ if (item.w < threshold) continue;
3346
+ let overlaps = 0;
3347
+ for (const other of items) {
3348
+ if (other === item) continue;
3349
+ const left = Math.max(item.x, other.x);
3350
+ const right = Math.min(item.x + item.w, other.x + other.w);
3351
+ const overlapW = right - left;
3352
+ if (overlapW <= 0) continue;
3353
+ const smaller = Math.min(item.w, other.w);
3354
+ if (smaller > 0 && overlapW / smaller >= CROSS_OVERLAP_RATIO) {
3355
+ overlaps++;
3356
+ if (overlaps >= CROSS_MIN_OVERLAPS) break;
3357
+ }
3358
+ }
3359
+ if (overlaps >= CROSS_MIN_OVERLAPS) cross.add(item);
3360
+ }
3361
+ return cross;
3362
+ }
3363
+ function mergeCrossLayoutGroups(groups, cross) {
3364
+ if (cross.length === 0) return groups;
3365
+ const sortedCross = [...cross].sort((a, b) => b.y + b.h - (a.y + a.h) || a.x - b.x);
3366
+ const groupTop = (g) => {
3367
+ let top = -Infinity;
3368
+ for (const i of g) {
3369
+ const t = i.y + i.h;
3370
+ if (t > top) top = t;
3371
+ }
3372
+ return top;
3373
+ };
3374
+ const result = [];
3375
+ let gi = 0, ci = 0;
3376
+ while (gi < groups.length || ci < sortedCross.length) {
3377
+ if (ci >= sortedCross.length) {
3378
+ result.push(groups[gi++]);
3379
+ continue;
3380
+ }
3381
+ if (gi >= groups.length) {
3382
+ result.push([sortedCross[ci++]]);
3383
+ continue;
3384
+ }
3385
+ const crossTop = sortedCross[ci].y + sortedCross[ci].h;
3386
+ if (crossTop >= groupTop(groups[gi])) result.push([sortedCross[ci++]]);
3387
+ else result.push(groups[gi++]);
3388
+ }
3389
+ return result;
3390
+ }
3391
+ function validWrapBands(items, bands) {
3392
+ if (!bands.length) return [];
3393
+ const present = new Set(items);
3394
+ return bands.filter((b) => b.sources.every(({ item: a, state: s }) => present.has(a) && a.text === s.text && a.x === s.x && a.y === s.y && a.w === s.w && a.h === s.h && a.fontSize === s.fontSize && a.fontName === s.fontName && a.isHidden === s.isHidden && a.hasSpaceBefore === s.hasSpaceBefore && a.syntheticSpace === s.syntheticSpace && a.strike === s.strike && a.underline === s.underline && a.seq === s.seq && a.rotated === s.rotated));
3395
+ }
3396
+ function inheritedWrapBands(items) {
3397
+ 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 sameLeaf = present && source.every((item) => present.has(item));
3400
+ return sameLeaf ? validWrapBands(items, _nullishCoalesce(XY_WRAP_BANDS.get(items[0]), () => ( []))) : [];
3401
+ }
3402
+ function tocRecordBoundaries(rows) {
3403
+ const out = /* @__PURE__ */ new Set();
3404
+ if (rows.length < 2) return out;
3405
+ const records = rows.map((row, index) => {
3406
+ const visible = row.filter((i) => i.text.trim()).sort((a, b) => a.x - b.x);
3407
+ let start = visible.length - 1;
3408
+ if (start < 1 || !/^\d+$/.test(visible[start].text.trim())) return null;
3409
+ for (; start > 0; start--) {
3410
+ const a = visible[start - 1], b = visible[start];
3411
+ if (!/^\d+$/.test(a.text.trim()) || b.x - (a.x + a.w) > 0.5 * b.fontSize) break;
3412
+ }
3413
+ const nums = visible.slice(start), label = visible.slice(0, start).filter((i) => !/^[·.⋯…]{4,}$/.test(i.text.trim()));
3414
+ const fs = nums[0].fontSize;
3415
+ if (!/^\d{1,4}$/.test(nums.map((i) => i.text.trim()).join("")) || fs <= 0 || !label.some((i) => /[\p{L}]/u.test(i.text)) || nums[0].x - Math.max(...label.map((i) => i.x + i.w)) < Math.max(2 * fs, 30)) return null;
3416
+ return { right: Math.max(...nums.map((i) => i.x + i.w)), fs, index };
3417
+ }).filter((record) => record !== null).sort((a, b) => a.right - b.right);
3418
+ for (let i = 0; i + 1 < records.length; i++) {
3419
+ const a = records[i], b = records[i + 1];
3420
+ if (Math.abs(a.right - b.right) <= 0.5 * Math.min(a.fs, b.fs) && Math.abs(a.fs - b.fs) <= 0.15 * Math.min(a.fs, b.fs)) {
3421
+ if (a.index + 1 < rows.length) out.add(a.index);
3422
+ if (b.index + 1 < rows.length) out.add(b.index);
3423
+ }
3424
+ }
3425
+ return out;
3426
+ }
3427
+ function wrappedLineBands(items, inherited) {
3428
+ const rows = groupByY(items);
3429
+ const records = tocRecordBoundaries(rows);
3430
+ const lines = rows.map((row) => {
3431
+ const box = computeBBox(row, 0);
3432
+ return {
3433
+ text: mergeLineSimple(row).replace(/<\/?u>|~~/g, ""),
3434
+ left: box.x,
3435
+ right: box.x + box.width,
3436
+ 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
+ sources: row.map((item) => ({ item, state: { ...item } }))
3439
+ };
3440
+ });
3441
+ const joins = bodyLineJoins(lines);
3442
+ const fresh = lines.slice(0, -1).flatMap((line, i) => joins[i] === "\n" || records.has(i) || line.text.trim() === lines[i + 1].text.trim() ? [] : [{ top: line.y, bottom: lines[i + 1].y, sources: [...line.sources, ...lines[i + 1].sources] }]);
3443
+ const freshKeys = new Set(fresh.map((b) => `${b.top}:${b.bottom}`));
3444
+ return [...inherited.filter((b) => !freshKeys.has(`${b.top}:${b.bottom}`)), ...fresh].sort((a, b) => b.top - a.top);
3445
+ }
3446
+ function findHorizontalCut(sorted, wrapped) {
3447
+ if (sorted.length < 2) return { position: 0, gap: 0 };
3448
+ let largestGap = 0;
3449
+ let position = 0;
3450
+ let wrapIndex = 0;
3451
+ for (let i = 1; i < sorted.length; i++) {
3452
+ const prevBottom = sorted[i - 1].y - sorted[i - 1].h;
3453
+ const currTop = sorted[i].y;
3454
+ const gap = prevBottom - currTop;
3455
+ if (gap <= 0) continue;
3456
+ const at = (prevBottom + currTop) / 2;
3457
+ while (wrapIndex < wrapped.length && at <= wrapped[wrapIndex].bottom) wrapIndex++;
3458
+ const band = wrapped[wrapIndex];
3459
+ if (gap > largestGap && !(band && at < band.top && at > band.bottom)) {
3460
+ largestGap = gap;
3461
+ position = at;
3462
+ }
3463
+ }
3464
+ return { position, gap: largestGap };
3465
+ }
3466
+ function findVerticalCutWithOutlierFilter(items, minGap) {
3467
+ const edgeCut = findVerticalCut(items);
3468
+ if (edgeCut.gap >= minGap) return edgeCut;
3469
+ if (items.length >= 3) {
3470
+ let minX = Infinity, maxX = -Infinity;
3471
+ for (const i of items) {
3472
+ if (i.x < minX) minX = i.x;
3473
+ const r = i.x + i.w;
3474
+ if (r > maxX) maxX = r;
3475
+ }
3476
+ const narrowThreshold = (maxX - minX) * NARROW_ELEMENT_WIDTH_RATIO;
3477
+ const filtered = items.filter((i) => i.w >= narrowThreshold);
3478
+ if (filtered.length >= 2 && filtered.length < items.length && filtered.length >= items.length * 0.7) {
3479
+ const filteredCut = findVerticalCut(filtered);
3480
+ if (filteredCut.gap > edgeCut.gap && filteredCut.gap >= minGap) {
3481
+ return filteredCut;
3482
+ }
3483
+ }
3484
+ }
3485
+ return edgeCut;
3486
+ }
3487
+ function findVerticalCut(items) {
3488
+ if (items.length < 2) return { position: 0, gap: 0 };
3489
+ const sorted = [...items].sort((a, b) => a.x - b.x || a.x + a.w - (b.x + b.w));
3490
+ let largestGap = 0;
3491
+ let position = 0;
3492
+ let prevRight = null;
3493
+ for (const it of sorted) {
3494
+ const left = it.x;
3495
+ const right = it.x + it.w;
3496
+ if (prevRight !== null && left > prevRight) {
3497
+ const gap = left - prevRight;
3498
+ if (gap > largestGap) {
3499
+ largestGap = gap;
3500
+ position = (prevRight + left) / 2;
3501
+ }
3502
+ }
3503
+ prevRight = prevRight === null ? right : Math.max(prevRight, right);
3504
+ }
3505
+ return { position, gap: largestGap };
3506
+ }
3507
+ function isProseGutter(items, x) {
3508
+ const sideLines = (side) => {
3509
+ const lines = [];
3510
+ for (const item of [...side].sort((a, b) => b.y - a.y)) {
3511
+ const line = lines.find((l) => Math.abs(l.y - item.y) <= 2);
3512
+ if (line) {
3513
+ line.chars += item.text.length;
3514
+ line.left = Math.min(line.left, item.x);
3515
+ line.right = Math.max(line.right, item.x + item.w);
3516
+ } else lines.push({ y: item.y, chars: item.text.length, left: item.x, right: item.x + item.w });
3517
+ }
3518
+ return lines;
3519
+ };
3520
+ const left = sideLines(items.filter((i) => i.x + i.w / 2 < x));
3521
+ const right = sideLines(items.filter((i) => i.x + i.w / 2 >= x));
3522
+ if (left.length < 4 || right.length < 4) return false;
3523
+ const prose = (lines) => {
3524
+ const width = Math.max(...lines.map((l) => l.right)) - Math.min(...lines.map((l) => l.left));
3525
+ const full = lines.filter((l) => l.chars >= 25 && l.right - l.left >= width * 0.6).length;
3526
+ return full >= lines.length * 0.6;
3527
+ };
3528
+ if (!prose(left) || !prose(right)) return false;
3529
+ const span = (lines) => [Math.min(...lines.map((l) => l.y)), Math.max(...lines.map((l) => l.y))];
3530
+ const [l0, l1] = span(left), [r0, r1] = span(right);
3531
+ return Math.min(l1, r1) - Math.max(l0, r0) >= Math.min(l1 - l0, r1 - r0) * 0.5;
3532
+ }
3533
+ function splitEdgeSpannedColumns(items, gapThreshold, depth) {
3534
+ let minX = Infinity, maxX = -Infinity;
3535
+ for (const i of items) {
3536
+ minX = Math.min(minX, i.x);
3537
+ maxX = Math.max(maxX, i.x + i.w);
3538
+ }
3539
+ const narrow = items.filter((i) => i.w < (maxX - minX) * 0.5);
3540
+ if (narrow.length === items.length || narrow.length < 8) return null;
3541
+ const cut = findVerticalCut(narrow);
3542
+ if (cut.gap < PROSE_GUTTER_MIN_GAP || !isProseGutter(narrow, cut.position)) return null;
3543
+ const crossing = items.filter((i) => i.x < cut.position && i.x + i.w > cut.position);
3544
+ const rest = items.filter((i) => !crossing.includes(i));
3545
+ const restTop = Math.max(...rest.map((i) => i.y)), restBottom = Math.min(...rest.map((i) => i.y));
3546
+ const above = crossing.filter((i) => i.y > restTop), below = crossing.filter((i) => i.y < restBottom);
3547
+ if (above.length + below.length !== crossing.length) return null;
3548
+ const left = rest.filter((i) => i.x + i.w / 2 < cut.position), right = rest.filter((i) => i.x + i.w / 2 >= cut.position);
3549
+ return [
3550
+ ...above.length ? [above] : [],
3551
+ ...xyCutOrder(left, gapThreshold, depth + 1),
3552
+ ...xyCutOrder(right, gapThreshold, depth + 1),
3553
+ ...below.length ? [below] : []
3554
+ ];
3555
+ }
3556
+
3239
3557
  // src/pdf/paragraph-lines.ts
3240
3558
  var FACE_CHARS = /* @__PURE__ */ new WeakMap();
3241
3559
  function hasNumberedStyledTitle(lines) {
@@ -3250,9 +3568,29 @@ function pushLineParagraphs(out, yLines, pageNum, lex) {
3250
3568
  const lines = attachDropCaps(yLines).map((items) => ({ items, text: mergeLineSimple(items) })).filter((l) => l.text.trim());
3251
3569
  const geo = lines.map((l) => {
3252
3570
  const b = computeBBox(l.items, pageNum);
3253
- 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', _82 => _82(l.items), 'optionalAccess', _83 => _83.fontSize]), () => ( 0)) };
3571
+ 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)) };
3254
3572
  });
3255
3573
  const joins = bodyLineJoins(geo, lex);
3574
+ const first = _optionalChain([lines, 'access', _87 => _87[0], 'optionalAccess', _88 => _88.items, 'access', _89 => _89[0]]);
3575
+ const bands = first ? _nullishCoalesce(XY_WRAP_BANDS.get(first), () => ( [])) : [];
3576
+ const hasBand = (top, bottom) => {
3577
+ let lo = 0, hi = bands.length;
3578
+ while (lo < hi) {
3579
+ const mid = lo + hi >>> 1;
3580
+ if (bands[mid].top > top + 3) lo = mid + 1;
3581
+ else hi = mid;
3582
+ }
3583
+ for (; lo < bands.length && bands[lo].top >= top - 3; lo++) {
3584
+ if (Math.abs(bands[lo].bottom - bottom) <= 3) return true;
3585
+ }
3586
+ return false;
3587
+ };
3588
+ for (let i = 0; i + 1 < geo.length; i++) {
3589
+ if (joins[i] === "\n" && Math.abs(geo[i + 1].fontSize - geo[i].fontSize) <= 0.15 * geo[i].fontSize && !startsNewItem(geo[i].text, geo[i + 1].text) && hasBand(geo[i].y, geo[i + 1].y)) {
3590
+ joins[i] = wrapJoiner(geo[i].text, geo[i + 1].text, lex);
3591
+ }
3592
+ }
3593
+ for (const i of tocRecordBoundaries(lines.map((line) => line.items))) joins[i] = "\n";
3256
3594
  for (let i = 0; i + 1 < geo.length; i++) {
3257
3595
  if (/^\d{1,2}$/.test(geo[i].text.trim()) && geo[i].fontSize >= geo[i + 1].fontSize * 1.2) joins[i] = "\n";
3258
3596
  }
@@ -3297,15 +3635,15 @@ function computeMedianFontSizeFromFreq(freq) {
3297
3635
  function detectHeadings(blocks, medianFontSize) {
3298
3636
  for (let bi = 0; bi < blocks.length; bi++) {
3299
3637
  const block = blocks[bi];
3300
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _84 => _84.style, 'optionalAccess', _85 => _85.fontSize])) continue;
3638
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _90 => _90.style, 'optionalAccess', _91 => _91.fontSize])) continue;
3301
3639
  const text = block.text.trim();
3302
3640
  if (text.length === 0 || text.length > 200) continue;
3303
3641
  if (/^\d+$/.test(text) && !isChapterNumber(block, blocks[bi + 1], medianFontSize)) continue;
3304
3642
  const ratio = block.style.fontSize / medianFontSize;
3305
3643
  let level = 0;
3306
- if (ratio >= _chunkAFXX3YSPcjs.HEADING_RATIO_H1) level = 1;
3307
- else if (ratio >= _chunkAFXX3YSPcjs.HEADING_RATIO_H2) level = 2;
3308
- else if (ratio >= _chunkAFXX3YSPcjs.HEADING_RATIO_H3) level = 3;
3644
+ if (ratio >= _chunkL5JX2GAMcjs.HEADING_RATIO_H1) level = 1;
3645
+ else if (ratio >= _chunkL5JX2GAMcjs.HEADING_RATIO_H2) level = 2;
3646
+ else if (ratio >= _chunkL5JX2GAMcjs.HEADING_RATIO_H3) level = 3;
3309
3647
  if (level > 0) {
3310
3648
  block.type = "heading";
3311
3649
  block.level = level;
@@ -3314,21 +3652,21 @@ function detectHeadings(blocks, medianFontSize) {
3314
3652
  }
3315
3653
  }
3316
3654
  function isChapterNumber(block, next, medianFontSize) {
3317
- const size = _nullishCoalesce(_optionalChain([block, 'access', _86 => _86.style, 'optionalAccess', _87 => _87.fontSize]), () => ( 0));
3318
- const nextSize = _nullishCoalesce(_optionalChain([next, 'optionalAccess', _88 => _88.style, 'optionalAccess', _89 => _89.fontSize]), () => ( 0));
3319
- const text = _nullishCoalesce(_optionalChain([next, 'optionalAccess', _90 => _90.text, 'optionalAccess', _91 => _91.trim, 'call', _92 => _92()]), () => ( ""));
3320
- const a = block.bbox, b = _optionalChain([next, 'optionalAccess', _93 => _93.bbox]);
3321
- return /^\d{1,2}$/.test(_nullishCoalesce(_optionalChain([block, 'access', _94 => _94.text, 'optionalAccess', _95 => _95.trim, 'call', _96 => _96()]), () => ( ""))) && size >= medianFontSize * 2.5 && !!next && (next.type === "paragraph" || next.type === "heading") && next.pageNumber === block.pageNumber && nextSize >= medianFontSize * _chunkAFXX3YSPcjs.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;
3655
+ const size = _nullishCoalesce(_optionalChain([block, 'access', _92 => _92.style, 'optionalAccess', _93 => _93.fontSize]), () => ( 0));
3656
+ const nextSize = _nullishCoalesce(_optionalChain([next, 'optionalAccess', _94 => _94.style, 'optionalAccess', _95 => _95.fontSize]), () => ( 0));
3657
+ const text = _nullishCoalesce(_optionalChain([next, 'optionalAccess', _96 => _96.text, 'optionalAccess', _97 => _97.trim, 'call', _98 => _98()]), () => ( ""));
3658
+ const a = block.bbox, b = _optionalChain([next, 'optionalAccess', _99 => _99.bbox]);
3659
+ 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 * _chunkL5JX2GAMcjs.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;
3322
3660
  }
3323
3661
  function mergeStackedHeadingLines(blocks, medianFontSize) {
3324
3662
  for (let i = 0; i < blocks.length - 1; ) {
3325
3663
  const a = blocks[i], b = blocks[i + 1];
3326
3664
  const ab = a.bbox, bb = b.bbox;
3327
- const af = _nullishCoalesce(_optionalChain([a, 'access', _97 => _97.style, 'optionalAccess', _98 => _98.fontSize]), () => ( 0)), bf = _nullishCoalesce(_optionalChain([b, 'access', _99 => _99.style, 'optionalAccess', _100 => _100.fontSize]), () => ( 0));
3665
+ 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));
3328
3666
  const gap = ab && bb ? ab.y - (bb.y + bb.height) : Infinity;
3329
- const centered = ab && bb && _optionalChain([a, 'access', _101 => _101.style, 'optionalAccess', _102 => _102.fontName]) === _optionalChain([b, 'access', _103 => _103.style, 'optionalAccess', _104 => _104.fontName]) && Math.abs(ab.x + ab.width / 2 - (bb.x + bb.width / 2)) <= Math.max(5, af * 0.5);
3667
+ 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);
3330
3668
  const sameAnchor = ab && bb && Math.abs(ab.x - bb.x) <= 5;
3331
- const wrapped = sameAnchor && _optionalChain([a, 'access', _105 => _105.style, 'optionalAccess', _106 => _106.fontName]) === _optionalChain([b, 'access', _107 => _107.style, 'optionalAccess', _108 => _108.fontName]) && af === bf && ab.width >= bb.width * 0.95 && (_nullishCoalesce(_optionalChain([a, 'access', _109 => _109.text, 'optionalAccess', _110 => _110.trim, 'call', _111 => _111(), 'access', _112 => _112.split, 'call', _113 => _113(/\s+/), 'access', _114 => _114.length]), () => ( 0))) >= 3;
3669
+ 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;
3332
3670
  const displayStack = centered && gap <= Math.min(af, bf) * 0.3 && Math.max(af, bf) <= Math.min(af, bf) * 1.45;
3333
3671
  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)) {
3334
3672
  i++;
@@ -3357,25 +3695,25 @@ function detectTypographyHeadings(blocks) {
3357
3695
  if (page.some((block) => block.type === "heading")) continue;
3358
3696
  const faceWeight = /* @__PURE__ */ new Map();
3359
3697
  for (const block of page) {
3360
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _115 => _115.style, 'optionalAccess', _116 => _116.fontName])) continue;
3698
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _121 => _121.style, 'optionalAccess', _122 => _122.fontName])) continue;
3361
3699
  const faces = FACE_CHARS.get(block);
3362
3700
  if (faces) for (const [face, n] of faces) faceWeight.set(face, (_nullishCoalesce(faceWeight.get(face), () => ( 0))) + n);
3363
3701
  else faceWeight.set(block.style.fontName, (_nullishCoalesce(faceWeight.get(block.style.fontName), () => ( 0))) + block.text.length);
3364
3702
  }
3365
- const bodyFace = _optionalChain([[...faceWeight], 'access', _117 => _117.sort, 'call', _118 => _118((a, b) => b[1] - a[1]), 'access', _119 => _119[0], 'optionalAccess', _120 => _120[0]]);
3703
+ 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]]);
3366
3704
  if (!bodyFace || (_nullishCoalesce(faceWeight.get(bodyFace), () => ( 0))) < 250) continue;
3367
3705
  const sizeWeight = /* @__PURE__ */ new Map();
3368
3706
  for (const block of page) {
3369
- if (block.type !== "paragraph" || !_optionalChain([block, 'access', _121 => _121.style, 'optionalAccess', _122 => _122.fontSize])) continue;
3707
+ if (block.type !== "paragraph" || !_optionalChain([block, 'access', _127 => _127.style, 'optionalAccess', _128 => _128.fontSize])) continue;
3370
3708
  const faces = FACE_CHARS.get(block);
3371
- const chars = faces ? _nullishCoalesce(faces.get(bodyFace), () => ( 0)) : block.style.fontName === bodyFace ? _nullishCoalesce(_optionalChain([block, 'access', _123 => _123.text, 'optionalAccess', _124 => _124.length]), () => ( 0)) : 0;
3709
+ 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;
3372
3710
  if (chars) sizeWeight.set(block.style.fontSize, (_nullishCoalesce(sizeWeight.get(block.style.fontSize), () => ( 0))) + chars);
3373
3711
  }
3374
- const bodySize = _nullishCoalesce(_optionalChain([[...sizeWeight], 'access', _125 => _125.sort, 'call', _126 => _126((a, b) => b[1] - a[1]), 'access', _127 => _127[0], 'optionalAccess', _128 => _128[0]]), () => ( 0));
3712
+ 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));
3375
3713
  for (let i = 0; i < page.length; i++) {
3376
3714
  const block = page[i];
3377
3715
  const { text, bbox, style } = block;
3378
- if (block.type !== "paragraph" || !text || !bbox || !_optionalChain([style, 'optionalAccess', _129 => _129.fontName]) || !style.fontSize) continue;
3716
+ if (block.type !== "paragraph" || !text || !bbox || !_optionalChain([style, 'optionalAccess', _135 => _135.fontName]) || !style.fontSize) continue;
3379
3717
  const title = text.trim();
3380
3718
  const numbered = /^\d+(?:\.\d+)*\.?\s+[A-Z가-힣]/.test(title);
3381
3719
  const faces = FACE_CHARS.get(block);
@@ -3405,16 +3743,16 @@ function detectDocumentStyleHeadings(blocks) {
3405
3743
  for (const page of byPage.values()) {
3406
3744
  const faceChars = /* @__PURE__ */ new Map();
3407
3745
  for (const block of page) {
3408
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _130 => _130.style, 'optionalAccess', _131 => _131.fontName])) continue;
3746
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _136 => _136.style, 'optionalAccess', _137 => _137.fontName])) continue;
3409
3747
  faceChars.set(block.style.fontName, (_nullishCoalesce(faceChars.get(block.style.fontName), () => ( 0))) + block.text.length);
3410
3748
  }
3411
- const bodyFace = _optionalChain([[...faceChars], 'access', _132 => _132.sort, 'call', _133 => _133((a, b) => b[1] - a[1]), 'access', _134 => _134[0], 'optionalAccess', _135 => _135[0]]);
3749
+ 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]]);
3412
3750
  if (!bodyFace || (_nullishCoalesce(faceChars.get(bodyFace), () => ( 0))) < 100) continue;
3413
- const labels = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _136 => _136.style, 'optionalAccess', _137 => _137.fontName]) && b.style.fontName !== bodyFace && b.text.trim().length >= 3 && b.text.trim().length <= 40);
3751
+ 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);
3414
3752
  for (const label of labels) {
3415
- const peers = labels.filter((b) => _optionalChain([b, 'access', _138 => _138.style, 'optionalAccess', _139 => _139.fontName]) === _optionalChain([label, 'access', _140 => _140.style, 'optionalAccess', _141 => _141.fontName]) && Math.abs(b.bbox.y - label.bbox.y) <= 3 && Math.abs(b.bbox.x - label.bbox.x) >= 60);
3753
+ 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);
3416
3754
  if (peers.length < 2) continue;
3417
- const value = page.find((b) => b.type === "paragraph" && b.bbox && _optionalChain([b, 'access', _142 => _142.style, 'optionalAccess', _143 => _143.fontName]) !== _optionalChain([label, 'access', _144 => _144.style, 'optionalAccess', _145 => _145.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);
3755
+ 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);
3418
3756
  if (value) {
3419
3757
  label.type = "heading";
3420
3758
  label.level = 2;
@@ -3423,7 +3761,7 @@ function detectDocumentStyleHeadings(blocks) {
3423
3761
  const first = page.find((b) => b.type !== "image" && b.type !== "separator");
3424
3762
  const second = page[page.indexOf(first) + 1];
3425
3763
  const third = page[page.indexOf(first) + 2];
3426
- if (!first || !second || !third || first.type !== "list" && first.type !== "paragraph" || second.type !== "paragraph" || !first.text || !second.text || !first.bbox || !second.bbox || !_optionalChain([first, 'access', _146 => _146.style, 'optionalAccess', _147 => _147.fontName]) || !_optionalChain([second, 'access', _148 => _148.style, 'optionalAccess', _149 => _149.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', _150 => _150.style, 'optionalAccess', _151 => _151.fontName]) !== bodyFace) continue;
3764
+ 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;
3427
3765
  first.type = "heading";
3428
3766
  first.level = 1;
3429
3767
  first.text = `${first.text.trim()} ${second.text.trim()}`;
@@ -3447,18 +3785,18 @@ function detectSiblingStyleHeadings(blocks) {
3447
3785
  for (const page of byPage.values()) {
3448
3786
  const bodyChars = /* @__PURE__ */ new Map();
3449
3787
  for (const block of page) {
3450
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _152 => _152.style, 'optionalAccess', _153 => _153.fontName])) continue;
3788
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _158 => _158.style, 'optionalAccess', _159 => _159.fontName])) continue;
3451
3789
  const face = block.style.fontName;
3452
3790
  bodyChars.set(face, (_nullishCoalesce(bodyChars.get(face), () => ( 0))) + block.text.length);
3453
3791
  }
3454
- const bodyFace = _optionalChain([[...bodyChars], 'access', _154 => _154.sort, 'call', _155 => _155((a, b) => b[1] - a[1]), 'access', _156 => _156[0], 'optionalAccess', _157 => _157[0]]);
3455
- const anchors = page.filter((b) => b.type === "heading" && b.text && _optionalChain([b, 'access', _158 => _158.style, 'optionalAccess', _159 => _159.fontName]) && b.style.fontName !== bodyFace);
3792
+ 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]]);
3793
+ const anchors = page.filter((b) => b.type === "heading" && b.text && _optionalChain([b, 'access', _164 => _164.style, 'optionalAccess', _165 => _165.fontName]) && b.style.fontName !== bodyFace);
3456
3794
  for (const anchor of anchors) {
3457
3795
  const numbered = /^([A-Z])\.\d+\s+/.exec(anchor.text.trim());
3458
3796
  const lettered = /^([A-Z])\s+/.exec(anchor.text.trim());
3459
- const peers = anchors.filter((b) => _optionalChain([b, 'access', _160 => _160.style, 'optionalAccess', _161 => _161.fontName]) === _optionalChain([anchor, 'access', _162 => _162.style, 'optionalAccess', _163 => _163.fontName]) && Math.abs((_nullishCoalesce(_optionalChain([b, 'access', _164 => _164.style, 'optionalAccess', _165 => _165.fontSize]), () => ( 0))) - (_nullishCoalesce(_optionalChain([anchor, 'access', _166 => _166.style, 'optionalAccess', _167 => _167.fontSize]), () => ( 0)))) < 0.5);
3797
+ 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);
3460
3798
  if (peers.length < 2 && !numbered && !lettered) continue;
3461
- const candidates = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _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 && b.text.trim().length >= 3 && b.text.trim().length <= 80 && b.bbox.height <= (_nullishCoalesce(_optionalChain([b, 'access', _176 => _176.style, 'optionalAccess', _177 => _177.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()));
3799
+ 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()));
3462
3800
  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));
3463
3801
  if (siblings.length < (numbered || lettered ? 1 : 2)) continue;
3464
3802
  for (const sibling of siblings) {
@@ -3477,13 +3815,13 @@ function detectRepeatedPageLabels(blocks) {
3477
3815
  }
3478
3816
  for (const page of byPage.values()) {
3479
3817
  const bodyChars = /* @__PURE__ */ new Map();
3480
- for (const b of page) if (b.type === "paragraph" && b.text && _optionalChain([b, 'access', _178 => _178.style, 'optionalAccess', _179 => _179.fontName])) {
3818
+ for (const b of page) if (b.type === "paragraph" && b.text && _optionalChain([b, 'access', _184 => _184.style, 'optionalAccess', _185 => _185.fontName])) {
3481
3819
  const faces = FACE_CHARS.get(b);
3482
3820
  if (faces) for (const [face, n] of faces) bodyChars.set(face, (_nullishCoalesce(bodyChars.get(face), () => ( 0))) + n);
3483
3821
  else bodyChars.set(b.style.fontName, (_nullishCoalesce(bodyChars.get(b.style.fontName), () => ( 0))) + b.text.length);
3484
3822
  }
3485
- const bodyFace = _optionalChain([[...bodyChars], 'access', _180 => _180.sort, 'call', _181 => _181((a, b) => b[1] - a[1]), 'access', _182 => _182[0], 'optionalAccess', _183 => _183[0]]);
3486
- const candidates = page.filter((b) => b.type === "paragraph" && b.text && b.bbox && _optionalChain([b, 'access', _184 => _184.style, 'optionalAccess', _185 => _185.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);
3823
+ 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]]);
3824
+ 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);
3487
3825
  const groups = /* @__PURE__ */ new Map();
3488
3826
  for (const b of candidates) {
3489
3827
  const key = `${b.style.fontName}:${b.style.fontSize}`;
@@ -3519,19 +3857,19 @@ function detectPageLeadHeadings(blocks) {
3519
3857
  for (const page of byPage.values()) {
3520
3858
  const content = page.filter((b) => b.type !== "image" && b.type !== "separator" && !(b.type === "paragraph" && !b.style));
3521
3859
  const [first, second, third] = content;
3522
- if (!_optionalChain([first, 'optionalAccess', _186 => _186.bbox]) || !first.text || !_optionalChain([first, 'access', _187 => _187.style, 'optionalAccess', _188 => _188.fontSize]) || !second) continue;
3860
+ if (!_optionalChain([first, 'optionalAccess', _192 => _192.bbox]) || !first.text || !_optionalChain([first, 'access', _193 => _193.style, 'optionalAccess', _194 => _194.fontSize]) || !second) continue;
3523
3861
  const firstText = first.text.trim();
3524
3862
  const captionLike = /^(?:Figure|Fig\.?|Table|표|그림)\s*\d/i;
3525
3863
  const hasImage = page.some((b) => b.type === "image");
3526
- 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', _189 => _189.text, 'optionalAccess', _190 => _190.trim, 'call', _191 => _191()]), () => ( ""))) && (_nullishCoalesce(_optionalChain([second, 'access', _192 => _192.text, 'optionalAccess', _193 => _193.length]), () => ( 0))) >= 100 && second.bbox && first.bbox.y - (second.bbox.y + second.bbox.height) >= first.style.fontSize);
3864
+ 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);
3527
3865
  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);
3528
- const firstIsSection = first.type === "list" && /^\d+\.\s+[A-Z][A-Z\s]{12,}$/.test(firstText) && second.type === "paragraph" && (_nullishCoalesce(_optionalChain([second, 'access', _194 => _194.text, 'optionalAccess', _195 => _195.length]), () => ( 0))) >= 100;
3866
+ 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;
3529
3867
  if (firstIsTitle || firstAboveProse || firstIsSection) {
3530
3868
  first.type = "heading";
3531
3869
  first.level = 1;
3532
3870
  }
3533
- if (first.type !== "heading" || captionLike.test(firstText) || second.type !== "paragraph" || !second.text || !second.bbox || !_optionalChain([second, 'access', _196 => _196.style, 'optionalAccess', _197 => _197.fontName]) || !second.style.fontSize || !_optionalChain([third, 'optionalAccess', _198 => _198.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;
3534
- const distinctFace = _optionalChain([third, 'access', _199 => _199.style, 'optionalAccess', _200 => _200.fontName]) !== second.style.fontName;
3871
+ 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;
3872
+ const distinctFace = _optionalChain([third, 'access', _205 => _205.style, 'optionalAccess', _206 => _206.fontName]) !== second.style.fontName;
3535
3873
  const namedContents = /^Table of Contents$/i.test(second.text.trim());
3536
3874
  if (distinctFace && third.text.length >= 60 || namedContents) {
3537
3875
  second.type = "heading";
@@ -3542,24 +3880,24 @@ function detectPageLeadHeadings(blocks) {
3542
3880
  function refineDocumentStyleHeadings(blocks) {
3543
3881
  const faceChars = /* @__PURE__ */ new Map();
3544
3882
  for (const block of blocks) {
3545
- if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _201 => _201.style, 'optionalAccess', _202 => _202.fontName])) continue;
3883
+ if (block.type !== "paragraph" || !block.text || !_optionalChain([block, 'access', _207 => _207.style, 'optionalAccess', _208 => _208.fontName])) continue;
3546
3884
  faceChars.set(block.style.fontName, (_nullishCoalesce(faceChars.get(block.style.fontName), () => ( 0))) + block.text.length);
3547
3885
  }
3548
3886
  const [bodyFace, bodyChars] = _nullishCoalesce([...faceChars].sort((a, b) => b[1] - a[1])[0], () => ( []));
3549
3887
  if (!bodyFace || !bodyChars || bodyChars < 300) return;
3550
3888
  for (let i = 0; i < blocks.length; i++) {
3551
3889
  const block = blocks[i];
3552
- const text = _nullishCoalesce(_optionalChain([block, 'access', _203 => _203.text, 'optionalAccess', _204 => _204.trim, 'call', _205 => _205()]), () => ( ""));
3890
+ const text = _nullishCoalesce(_optionalChain([block, 'access', _209 => _209.text, 'optionalAccess', _210 => _210.trim, 'call', _211 => _211()]), () => ( ""));
3553
3891
  if (block.type === "heading" && /(?:https?:\/\/|www\.|^arxiv:|^doi:)/i.test(text)) {
3554
3892
  block.type = "paragraph";
3555
3893
  block.level = void 0;
3556
3894
  continue;
3557
3895
  }
3558
3896
  const box = block.bbox, style = block.style;
3559
- if (block.type !== "paragraph" || !box || !_optionalChain([style, 'optionalAccess', _206 => _206.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;
3897
+ 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;
3560
3898
  const previous = blocks[i - 1], next = blocks[i + 1];
3561
- const pb = _optionalChain([previous, 'optionalAccess', _207 => _207.bbox]), nb = _optionalChain([next, 'optionalAccess', _208 => _208.bbox]);
3562
- if (!pb || !nb || previous.pageNumber !== block.pageNumber || next.pageNumber !== block.pageNumber || previous.type !== "paragraph" && previous.type !== "heading" || next.type !== "paragraph" || _optionalChain([next, 'access', _209 => _209.style, 'optionalAccess', _210 => _210.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;
3899
+ const pb = _optionalChain([previous, 'optionalAccess', _213 => _213.bbox]), nb = _optionalChain([next, 'optionalAccess', _214 => _214.bbox]);
3900
+ 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;
3563
3901
  block.type = "heading";
3564
3902
  block.level = 2;
3565
3903
  }
@@ -3609,7 +3947,7 @@ function detectMarkerHeadings(blocks) {
3609
3947
  block.level = 4;
3610
3948
  continue;
3611
3949
  }
3612
- if (/^[가-힣]{2,6}$/.test(text) && _optionalChain([block, 'access', _211 => _211.style, 'optionalAccess', _212 => _212.fontSize])) {
3950
+ if (/^[가-힣]{2,6}$/.test(text) && _optionalChain([block, 'access', _217 => _217.style, 'optionalAccess', _218 => _218.fontSize])) {
3613
3951
  const prev = blocks[i - 1];
3614
3952
  const next = blocks[i + 1];
3615
3953
  const prevIsStructural = !prev || prev.type === "table" || prev.type === "heading" || prev.type === "separator";
@@ -3650,7 +3988,7 @@ function detectTableCaptions(blocks) {
3650
3988
  block.table.caption = blocks[i - 1].text.trim();
3651
3989
  blocks.splice(i - 1, 1);
3652
3990
  i--;
3653
- } else if (isCaptionCandidate(blocks[i + 1], block) && _optionalChain([blocks, 'access', _213 => _213[i + 2], 'optionalAccess', _214 => _214.type]) !== "table") {
3991
+ } else if (isCaptionCandidate(blocks[i + 1], block) && _optionalChain([blocks, 'access', _219 => _219[i + 2], 'optionalAccess', _220 => _220.type]) !== "table") {
3654
3992
  block.table.caption = blocks[i + 1].text.trim();
3655
3993
  blocks.splice(i + 1, 1);
3656
3994
  }
@@ -3864,7 +4202,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
3864
4202
  const bottomEntries = [];
3865
4203
  for (let bi = 0; bi < blocks.length; bi++) {
3866
4204
  const b = blocks[bi];
3867
- const text = !tables ? _optionalChain([b, 'access', _215 => _215.text, 'optionalAccess', _216 => _216.trim, 'call', _217 => _217()]) : b.type === "table" && b.table ? b.table.cells.flat().map((c) => c.text.trim()).filter(Boolean).join(" | ") : void 0;
4205
+ 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;
3868
4206
  if (!b.bbox || !b.pageNumber || !text) continue;
3869
4207
  const ph = pageHeights.get(b.bbox.page) || pageHeights.get(b.pageNumber);
3870
4208
  if (!ph) continue;
@@ -3895,7 +4233,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
3895
4233
  for (const [p, count] of patternCount) {
3896
4234
  const pages = [..._nullishCoalesce(patternPages.get(p), () => ( []))];
3897
4235
  const span = pages.length ? Math.max(...pages) - Math.min(...pages) + 1 : 0;
3898
- const pageNumbered = !tables && (_nullishCoalesce(_optionalChain([patternNumbers, 'access', _218 => _218.get, 'call', _219 => _219(p), 'optionalAccess', _220 => _220.size]), () => ( 0))) > 1;
4236
+ const pageNumbered = !tables && (_nullishCoalesce(_optionalChain([patternNumbers, 'access', _224 => _224.get, 'call', _225 => _225(p), 'optionalAccess', _226 => _226.size]), () => ( 0))) > 1;
3899
4237
  if (count >= MIN_REPEAT && pages.length >= MIN_REPEAT && (pages.length >= span * 0.4 || pageNumbered)) {
3900
4238
  repeatedPatterns.add(p);
3901
4239
  }
@@ -3903,8 +4241,8 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
3903
4241
  for (const e of entries) {
3904
4242
  const norm = e.text.replace(/\d+/g, "#");
3905
4243
  if (!repeatedPatterns.has(norm)) continue;
3906
- const noteMark = _optionalChain([e, 'access', _221 => _221.text, 'access', _222 => _222.match, 'call', _223 => _223(/^\d{1,3}\)/), 'optionalAccess', _224 => _224[0]]);
3907
- if (noteMark && _optionalChain([notes, 'optionalAccess', _225 => _225.get, 'call', _226 => _226(e.page), 'optionalAccess', _227 => _227.marks, 'access', _228 => _228.some, 'call', _229 => _229((m) => m.mark === noteMark)])) continue;
4244
+ const noteMark = _optionalChain([e, 'access', _227 => _227.text, 'access', _228 => _228.match, 'call', _229 => _229(/^\d{1,3}\)/), 'optionalAccess', _230 => _230[0]]);
4245
+ 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;
3908
4246
  const cand = blocks[e.blockIdx];
3909
4247
  const cb = cand.bbox;
3910
4248
  const tableNote = /^(?:주\s*(?:\d+\s*[).:]|[::])|(?:자료|출처)\s*[::])/.test(e.text.replace(/ \| /g, " ")) && blocks.some((o) => {
@@ -3918,7 +4256,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
3918
4256
  if (bi === e.blockIdx) continue;
3919
4257
  const o = blocks[bi];
3920
4258
  if (!o.bbox || o.bbox.page !== cb.page) continue;
3921
- const oNorm = _optionalChain([o, 'access', _230 => _230.text, 'optionalAccess', _231 => _231.trim, 'call', _232 => _232(), 'access', _233 => _233.replace, 'call', _234 => _234(/\d+/g, "#")]);
4259
+ const oNorm = _optionalChain([o, 'access', _236 => _236.text, 'optionalAccess', _237 => _237.trim, 'call', _238 => _238(), 'access', _239 => _239.replace, 'call', _240 => _240(/\d+/g, "#")]);
3922
4260
  if (oNorm && repeatedPatterns.has(oNorm)) continue;
3923
4261
  const overlap2 = Math.min(cb.y + cb.height, o.bbox.y + o.bbox.height) - Math.max(cb.y, o.bbox.y);
3924
4262
  if (overlap2 >= cb.height * 0.5) {
@@ -3992,7 +4330,7 @@ function recordRowRules(table, cells, bbox, hs) {
3992
4330
  function markImageCell(cell) {
3993
4331
  IMAGE_CELLS.add(cell);
3994
4332
  }
3995
- var emptyCell = (cell) => !cell || !_optionalChain([cell, 'access', _235 => _235.text, 'optionalAccess', _236 => _236.trim, 'call', _237 => _237()]) && !_optionalChain([cell, 'access', _238 => _238.blocks, 'optionalAccess', _239 => _239.length]) && !IMAGE_CELLS.has(cell);
4333
+ 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);
3996
4334
  function trimTable(table) {
3997
4335
  let cols = table.cols;
3998
4336
  while (cols > 0 && table.cells.every((row) => emptyCell(row[cols - 1]))) cols--;
@@ -4008,7 +4346,7 @@ function trimTable(table) {
4008
4346
  function trimTrailingEmptyTableCols(blocks) {
4009
4347
  for (const b of blocks) {
4010
4348
  if (b.type !== "table" || !b.table) continue;
4011
- for (const row of b.table.cells) for (const cell of row) if (_optionalChain([cell, 'access', _240 => _240.blocks, 'optionalAccess', _241 => _241.length])) trimTrailingEmptyTableCols(cell.blocks);
4349
+ 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);
4012
4350
  trimTable(b.table);
4013
4351
  }
4014
4352
  }
@@ -4028,7 +4366,7 @@ function mergeSliverColumns(grid, colXs, maxWidth) {
4028
4366
  }
4029
4367
  const ok = owner.every((row) => {
4030
4368
  const o = row[c];
4031
- return !!o && (o.colSpan > 1 || !o.text.trim() && !_optionalChain([o, 'access', _242 => _242.blocks, 'optionalAccess', _243 => _243.length]));
4369
+ return !!o && (o.colSpan > 1 || !o.text.trim() && !_optionalChain([o, 'access', _248 => _248.blocks, 'optionalAccess', _249 => _249.length]));
4032
4370
  });
4033
4371
  if (!ok) continue;
4034
4372
  const spanning = /* @__PURE__ */ new Set();
@@ -4094,7 +4432,7 @@ function isProseTable(table) {
4094
4432
  if (!(long > 0 && long >= total * 0.5 && longRows >= rows * 0.4)) return false;
4095
4433
  for (let c = 0; c < table.cols; c++) {
4096
4434
  const filled = table.cells.map((row) => row[c]).filter((cell) => cell && cell.colSpan < table.cols && cell.text.trim()).map((cell) => cell.text.trim());
4097
- if (filled.length >= 3 && filled.length >= rows * 0.6 && filled.every((text) => text.length <= 30 && (_nullishCoalesce(_optionalChain([text, 'access', _244 => _244.match, 'call', _245 => _245(/\p{L}/gu), 'optionalAccess', _246 => _246.length]), () => ( 0))) >= 2)) return false;
4435
+ if (filled.length >= 3 && filled.length >= rows * 0.6 && filled.every((text) => text.length <= 30 && (_nullishCoalesce(_optionalChain([text, 'access', _250 => _250.match, 'call', _251 => _251(/\p{L}/gu), 'optionalAccess', _252 => _252.length]), () => ( 0))) >= 2)) return false;
4098
4436
  }
4099
4437
  return true;
4100
4438
  }
@@ -4121,7 +4459,7 @@ function isChartTable(table) {
4121
4459
  const numeric = texts.filter((text) => NUMERIC_CELL.test(text)).length;
4122
4460
  if (numeric < texts.length * 0.5) return false;
4123
4461
  for (let c = 0; c < table.cols; c++) {
4124
- const ticks = table.cells.flatMap((row) => (_nullishCoalesce(_optionalChain([row, 'access', _247 => _247[c], 'optionalAccess', _248 => _248.text]), () => ( ""))).split(/\s+/)).filter((token) => /^-?[\d,]+(?:\.\d+)?%?$/.test(token)).map((token) => Number(token.replace(/[,%]/g, "")));
4462
+ const ticks = table.cells.flatMap((row) => (_nullishCoalesce(_optionalChain([row, 'access', _253 => _253[c], 'optionalAccess', _254 => _254.text]), () => ( ""))).split(/\s+/)).filter((token) => /^-?[\d,]+(?:\.\d+)?%?$/.test(token)).map((token) => Number(token.replace(/[,%]/g, "")));
4125
4463
  if (hasValueAxis(ticks)) return true;
4126
4464
  }
4127
4465
  const values = texts.filter((text) => text.split(/\s+/).every((token) => /^[-−–]?[\d,]*\.?\d+%?$/.test(token))).length;
@@ -4275,7 +4613,7 @@ function detectAlignedTwoColumnTables(rows, pageNum) {
4275
4613
  continue;
4276
4614
  }
4277
4615
  const top = rows[i - 1];
4278
- const title = _optionalChain([top, 'optionalAccess', _249 => _249.items, 'access', _250 => _250.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;
4616
+ const title = _optionalChain([top, 'optionalAccess', _255 => _255.items, 'access', _256 => _256.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;
4279
4617
  const tableRows = title ? [title, ...body] : body;
4280
4618
  const cells = tableRows.map((row, idx) => {
4281
4619
  if (title && idx === 0) return [{ text: row.items[0].text, colSpan: 2, rowSpan: 1 }, { text: "", colSpan: 1, rowSpan: 1 }];
@@ -4331,12 +4669,12 @@ function isTwoColumnProse(r) {
4331
4669
  if (t.rows < 8) return false;
4332
4670
  const dense = [];
4333
4671
  for (let c = 0; c < t.cols; c++) {
4334
- const filled = t.cells.filter((row) => _optionalChain([row, 'access', _251 => _251[c], 'optionalAccess', _252 => _252.text, 'access', _253 => _253.trim, 'call', _254 => _254()])).length;
4672
+ const filled = t.cells.filter((row) => _optionalChain([row, 'access', _257 => _257[c], 'optionalAccess', _258 => _258.text, 'access', _259 => _259.trim, 'call', _260 => _260()])).length;
4335
4673
  if (filled / t.rows >= 0.3) dense.push(c);
4336
4674
  }
4337
4675
  if (dense.length !== 2) return false;
4338
4676
  for (const c of dense) {
4339
- const lens = t.cells.map((row) => _nullishCoalesce(_optionalChain([row, 'access', _255 => _255[c], 'optionalAccess', _256 => _256.text, 'access', _257 => _257.replace, 'call', _258 => _258(/\s+/g, ""), 'access', _259 => _259.length]), () => ( 0))).filter((n) => n > 0);
4677
+ const lens = t.cells.map((row) => _nullishCoalesce(_optionalChain([row, 'access', _261 => _261[c], 'optionalAccess', _262 => _262.text, 'access', _263 => _263.replace, 'call', _264 => _264(/\s+/g, ""), 'access', _265 => _265.length]), () => ( 0))).filter((n) => n > 0);
4340
4678
  const avg = lens.reduce((s, v) => s + v, 0) / (lens.length || 1);
4341
4679
  if (avg < 12) return false;
4342
4680
  }
@@ -4732,7 +5070,7 @@ function assignRowItems(items, columns, numCols, headerFace) {
4732
5070
  const runs = [];
4733
5071
  for (const it of sorted) {
4734
5072
  const last = runs[runs.length - 1];
4735
- const prev = _optionalChain([last, 'optionalAccess', _260 => _260[last.length - 1]]);
5073
+ const prev = _optionalChain([last, 'optionalAccess', _266 => _266[last.length - 1]]);
4736
5074
  if (prev && it.x - (prev.x + prev.w) <= Math.max(0.5, it.fontSize * 0.05) && !it.hasSpaceBefore) last.push(it);
4737
5075
  else runs.push([it]);
4738
5076
  }
@@ -4806,7 +5144,7 @@ function buildClusterTable(rows, columns, pageNum) {
4806
5144
  () => Array.from({ length: numCols }, () => ({ text: "", colSpan: 1, rowSpan: 1 }))
4807
5145
  );
4808
5146
  const usedItems = /* @__PURE__ */ new Set();
4809
- const headFaces = new Set(_optionalChain([rows, 'access', _261 => _261[0], 'optionalAccess', _262 => _262.items, 'access', _263 => _263.map, 'call', _264 => _264((i) => i.fontName)]));
5147
+ const headFaces = new Set(_optionalChain([rows, 'access', _267 => _267[0], 'optionalAccess', _268 => _268.items, 'access', _269 => _269.map, 'call', _270 => _270((i) => i.fontName)]));
4810
5148
  const headerFace = headFaces.size === 1 && rows.slice(1).every((row) => row.items.every((i) => !headFaces.has(i.fontName))) ? [...headFaces][0] : void 0;
4811
5149
  for (let r = 0; r < numRows; r++) {
4812
5150
  const row = rows[r];
@@ -4836,7 +5174,7 @@ function buildClusterTable(rows, columns, pageNum) {
4836
5174
  const nonEmptyCols = cells[r].filter((c) => c.text.trim()).length;
4837
5175
  if (nonEmptyCols !== 1) continue;
4838
5176
  if (cells[r][0].text.trim() !== "") continue;
4839
- const contentText = _optionalChain([cells, 'access', _265 => _265[r], 'access', _266 => _266.find, 'call', _267 => _267((c) => c.text.trim()), 'optionalAccess', _268 => _268.text, 'access', _269 => _269.trim, 'call', _270 => _270()]) || "";
5177
+ const contentText = _optionalChain([cells, 'access', _271 => _271[r], 'access', _272 => _272.find, 'call', _273 => _273((c) => c.text.trim()), 'optionalAccess', _274 => _274.text, 'access', _275 => _275.trim, 'call', _276 => _276()]) || "";
4840
5178
  if (/^[○●▶\-·]/.test(contentText)) continue;
4841
5179
  for (let pr = r - 1; pr >= 0; pr--) {
4842
5180
  if (cells[pr].some((c) => c.text.trim())) {
@@ -4936,242 +5274,6 @@ function findRuledColumnDivider(regions, horizontals, verticals, pageWidth, page
4936
5274
  return candidates.length === 1 ? candidates[0] : null;
4937
5275
  }
4938
5276
 
4939
- // src/pdf/xy-cut.ts
4940
- var MAX_XYCUT_DEPTH = 50;
4941
- var XYCUT_MIN_GAP = 5;
4942
- var CROSS_LAYOUT_BETA = 2;
4943
- var CROSS_OVERLAP_RATIO = 0.1;
4944
- var CROSS_MIN_OVERLAPS = 2;
4945
- var CROSS_MAX_MASK_RATIO = 0.2;
4946
- var NARROW_ELEMENT_WIDTH_RATIO = 0.1;
4947
- var PROSE_GUTTER_MIN_GAP = 6;
4948
- function xyCutOrder(items, gapThreshold, depth = 0) {
4949
- if (items.length === 0) return [];
4950
- if (items.length <= 2 || depth >= MAX_XYCUT_DEPTH) return [items];
4951
- if (depth === 0 && items.length >= 3) {
4952
- const cross = identifyCrossLayoutItems(items);
4953
- if (cross.size > 0 && cross.size <= items.length * CROSS_MAX_MASK_RATIO) {
4954
- const rest = items.filter((i) => !cross.has(i));
4955
- if (rest.length > 0) {
4956
- const groups = xyCutOrder(rest, gapThreshold, 1);
4957
- return mergeCrossLayoutGroups(groups, [...cross]);
4958
- }
4959
- }
4960
- }
4961
- const minGap = Math.max(XYCUT_MIN_GAP, gapThreshold);
4962
- const hCut = findHorizontalCut(items);
4963
- const vCut = findVerticalCutWithOutlierFilter(items, minGap);
4964
- const hValid = hCut.gap >= minGap;
4965
- const vValid = (vCut.gap >= minGap || vCut.gap >= PROSE_GUTTER_MIN_GAP && isProseGutter(items, vCut.position)) && !splitsSpacedLabel(items, vCut.position);
4966
- let useHorizontal;
4967
- if (hValid && vValid) useHorizontal = vCut.gap <= hCut.gap * 1.5 || staggeredSides(items, vCut.position);
4968
- else if (hValid) useHorizontal = true;
4969
- else if (vValid) useHorizontal = false;
4970
- else return _nullishCoalesce(splitEdgeSpannedColumns(items, gapThreshold, depth), () => ( [items]));
4971
- if (useHorizontal) {
4972
- const upper = items.filter((i) => i.y > hCut.position);
4973
- const lower = items.filter((i) => i.y <= hCut.position);
4974
- if (upper.length > 0 && lower.length > 0 && upper.length < items.length) {
4975
- return [...xyCutOrder(upper, gapThreshold, depth + 1), ...xyCutOrder(lower, gapThreshold, depth + 1)];
4976
- }
4977
- } else {
4978
- const left = items.filter((i) => i.x + i.w / 2 < vCut.position);
4979
- const right = items.filter((i) => i.x + i.w / 2 >= vCut.position);
4980
- if (left.length > 0 && right.length > 0 && left.length < items.length) {
4981
- return [...xyCutOrder(left, gapThreshold, depth + 1), ...xyCutOrder(right, gapThreshold, depth + 1)];
4982
- }
4983
- }
4984
- return [items];
4985
- }
4986
- function splitsSpacedLabel(items, cutX) {
4987
- const lone = (i) => /^[가-힣]$/.test(i.text.trim());
4988
- const sameRow = (a, b) => Math.min(a.y, b.y) > Math.max(a.y - a.h, b.y - b.h);
4989
- const left = items.filter((i) => i.x + i.w / 2 < cutX);
4990
- const right = items.filter((i) => i.x + i.w / 2 >= cutX);
4991
- let spaced = 0;
4992
- for (const r of right) {
4993
- if (right.some((o) => o !== r && o.x < r.x && sameRow(o, r))) continue;
4994
- const row = left.filter((l2) => sameRow(l2, r));
4995
- if (row.length === 0) continue;
4996
- const l = row.reduce((a, b) => b.x + b.w > a.x + a.w ? b : a);
4997
- if (!lone(l) || !lone(r)) return false;
4998
- spaced++;
4999
- }
5000
- return spaced > 0;
5001
- }
5002
- function staggeredSides(items, cutX) {
5003
- const left = items.filter((i) => i.x + i.w / 2 < cutX);
5004
- const right = items.filter((i) => i.x + i.w / 2 >= cutX);
5005
- if (left.length * right.length > 2e5) return false;
5006
- const shareRow = (a, b) => Math.min(a.y, b.y) > Math.max(a.y - a.h, b.y - b.h);
5007
- if (left.some((a) => right.some((b) => shareRow(a, b)))) return false;
5008
- const sides = [...items].sort((a, b) => b.y - a.y).map((i) => i.x + i.w / 2 < cutX);
5009
- let switches = 0;
5010
- for (let k = 1; k < sides.length; k++) if (sides[k] !== sides[k - 1]) switches++;
5011
- return switches >= 3;
5012
- }
5013
- function identifyCrossLayoutItems(items) {
5014
- const cross = /* @__PURE__ */ new Set();
5015
- if (items.length < 3) return cross;
5016
- let maxWidth = 0;
5017
- for (const i of items) {
5018
- if (i.w > maxWidth) maxWidth = i.w;
5019
- }
5020
- const threshold = CROSS_LAYOUT_BETA * maxWidth;
5021
- for (const item of items) {
5022
- if (item.w < threshold) continue;
5023
- let overlaps = 0;
5024
- for (const other of items) {
5025
- if (other === item) continue;
5026
- const left = Math.max(item.x, other.x);
5027
- const right = Math.min(item.x + item.w, other.x + other.w);
5028
- const overlapW = right - left;
5029
- if (overlapW <= 0) continue;
5030
- const smaller = Math.min(item.w, other.w);
5031
- if (smaller > 0 && overlapW / smaller >= CROSS_OVERLAP_RATIO) {
5032
- overlaps++;
5033
- if (overlaps >= CROSS_MIN_OVERLAPS) break;
5034
- }
5035
- }
5036
- if (overlaps >= CROSS_MIN_OVERLAPS) cross.add(item);
5037
- }
5038
- return cross;
5039
- }
5040
- function mergeCrossLayoutGroups(groups, cross) {
5041
- if (cross.length === 0) return groups;
5042
- const sortedCross = [...cross].sort((a, b) => b.y + b.h - (a.y + a.h) || a.x - b.x);
5043
- const groupTop = (g) => {
5044
- let top = -Infinity;
5045
- for (const i of g) {
5046
- const t = i.y + i.h;
5047
- if (t > top) top = t;
5048
- }
5049
- return top;
5050
- };
5051
- const result = [];
5052
- let gi = 0, ci = 0;
5053
- while (gi < groups.length || ci < sortedCross.length) {
5054
- if (ci >= sortedCross.length) {
5055
- result.push(groups[gi++]);
5056
- continue;
5057
- }
5058
- if (gi >= groups.length) {
5059
- result.push([sortedCross[ci++]]);
5060
- continue;
5061
- }
5062
- const crossTop = sortedCross[ci].y + sortedCross[ci].h;
5063
- if (crossTop >= groupTop(groups[gi])) result.push([sortedCross[ci++]]);
5064
- else result.push(groups[gi++]);
5065
- }
5066
- return result;
5067
- }
5068
- function findHorizontalCut(items) {
5069
- if (items.length < 2) return { position: 0, gap: 0 };
5070
- const sorted = [...items].sort((a, b) => b.y - a.y);
5071
- let largestGap = 0;
5072
- let position = 0;
5073
- for (let i = 1; i < sorted.length; i++) {
5074
- const prevBottom = sorted[i - 1].y - sorted[i - 1].h;
5075
- const currTop = sorted[i].y;
5076
- const gap = prevBottom - currTop;
5077
- if (gap > largestGap) {
5078
- largestGap = gap;
5079
- position = (prevBottom + currTop) / 2;
5080
- }
5081
- }
5082
- return { position, gap: largestGap };
5083
- }
5084
- function findVerticalCutWithOutlierFilter(items, minGap) {
5085
- const edgeCut = findVerticalCut(items);
5086
- if (edgeCut.gap >= minGap) return edgeCut;
5087
- if (items.length >= 3) {
5088
- let minX = Infinity, maxX = -Infinity;
5089
- for (const i of items) {
5090
- if (i.x < minX) minX = i.x;
5091
- const r = i.x + i.w;
5092
- if (r > maxX) maxX = r;
5093
- }
5094
- const narrowThreshold = (maxX - minX) * NARROW_ELEMENT_WIDTH_RATIO;
5095
- const filtered = items.filter((i) => i.w >= narrowThreshold);
5096
- if (filtered.length >= 2 && filtered.length < items.length && filtered.length >= items.length * 0.7) {
5097
- const filteredCut = findVerticalCut(filtered);
5098
- if (filteredCut.gap > edgeCut.gap && filteredCut.gap >= minGap) {
5099
- return filteredCut;
5100
- }
5101
- }
5102
- }
5103
- return edgeCut;
5104
- }
5105
- function findVerticalCut(items) {
5106
- if (items.length < 2) return { position: 0, gap: 0 };
5107
- const sorted = [...items].sort((a, b) => a.x - b.x || a.x + a.w - (b.x + b.w));
5108
- let largestGap = 0;
5109
- let position = 0;
5110
- let prevRight = null;
5111
- for (const it of sorted) {
5112
- const left = it.x;
5113
- const right = it.x + it.w;
5114
- if (prevRight !== null && left > prevRight) {
5115
- const gap = left - prevRight;
5116
- if (gap > largestGap) {
5117
- largestGap = gap;
5118
- position = (prevRight + left) / 2;
5119
- }
5120
- }
5121
- prevRight = prevRight === null ? right : Math.max(prevRight, right);
5122
- }
5123
- return { position, gap: largestGap };
5124
- }
5125
- function isProseGutter(items, x) {
5126
- const sideLines = (side) => {
5127
- const lines = [];
5128
- for (const item of [...side].sort((a, b) => b.y - a.y)) {
5129
- const line = lines.find((l) => Math.abs(l.y - item.y) <= 2);
5130
- if (line) {
5131
- line.chars += item.text.length;
5132
- line.left = Math.min(line.left, item.x);
5133
- line.right = Math.max(line.right, item.x + item.w);
5134
- } else lines.push({ y: item.y, chars: item.text.length, left: item.x, right: item.x + item.w });
5135
- }
5136
- return lines;
5137
- };
5138
- const left = sideLines(items.filter((i) => i.x + i.w / 2 < x));
5139
- const right = sideLines(items.filter((i) => i.x + i.w / 2 >= x));
5140
- if (left.length < 4 || right.length < 4) return false;
5141
- const prose = (lines) => {
5142
- const width = Math.max(...lines.map((l) => l.right)) - Math.min(...lines.map((l) => l.left));
5143
- const full = lines.filter((l) => l.chars >= 25 && l.right - l.left >= width * 0.6).length;
5144
- return full >= lines.length * 0.6;
5145
- };
5146
- if (!prose(left) || !prose(right)) return false;
5147
- const span = (lines) => [Math.min(...lines.map((l) => l.y)), Math.max(...lines.map((l) => l.y))];
5148
- const [l0, l1] = span(left), [r0, r1] = span(right);
5149
- return Math.min(l1, r1) - Math.max(l0, r0) >= Math.min(l1 - l0, r1 - r0) * 0.5;
5150
- }
5151
- function splitEdgeSpannedColumns(items, gapThreshold, depth) {
5152
- let minX = Infinity, maxX = -Infinity;
5153
- for (const i of items) {
5154
- minX = Math.min(minX, i.x);
5155
- maxX = Math.max(maxX, i.x + i.w);
5156
- }
5157
- const narrow = items.filter((i) => i.w < (maxX - minX) * 0.5);
5158
- if (narrow.length === items.length || narrow.length < 8) return null;
5159
- const cut = findVerticalCut(narrow);
5160
- if (cut.gap < PROSE_GUTTER_MIN_GAP || !isProseGutter(narrow, cut.position)) return null;
5161
- const crossing = items.filter((i) => i.x < cut.position && i.x + i.w > cut.position);
5162
- const rest = items.filter((i) => !crossing.includes(i));
5163
- const restTop = Math.max(...rest.map((i) => i.y)), restBottom = Math.min(...rest.map((i) => i.y));
5164
- const above = crossing.filter((i) => i.y > restTop), below = crossing.filter((i) => i.y < restBottom);
5165
- if (above.length + below.length !== crossing.length) return null;
5166
- const left = rest.filter((i) => i.x + i.w / 2 < cut.position), right = rest.filter((i) => i.x + i.w / 2 >= cut.position);
5167
- return [
5168
- ...above.length ? [above] : [],
5169
- ...xyCutOrder(left, gapThreshold, depth + 1),
5170
- ...xyCutOrder(right, gapThreshold, depth + 1),
5171
- ...below.length ? [below] : []
5172
- ];
5173
- }
5174
-
5175
5277
  // src/pdf/two-column.ts
5176
5278
  var GUTTER_SCAN_LO = 0.3;
5177
5279
  var GUTTER_SCAN_HI = 0.7;
@@ -5463,16 +5565,16 @@ function isProseSpread(items) {
5463
5565
  for (let i = 1; i < sorted.length; i++) {
5464
5566
  gaps.push(sorted[i].x - (sorted[i - 1].x + sorted[i - 1].w));
5465
5567
  }
5466
- const maxGap = _chunkEXBZHI25cjs.safeMax.call(void 0, gaps);
5568
+ const maxGap = _chunkFVESLY6Vcjs.safeMax.call(void 0, gaps);
5467
5569
  const avgLen = items.reduce((s, i) => s + i.text.length, 0) / items.length;
5468
5570
  if (items.length >= 4 && maxGap < 40 && avgLen < 5) return true;
5469
- const minGap = _chunkEXBZHI25cjs.safeMin.call(void 0, gaps);
5571
+ const minGap = _chunkFVESLY6Vcjs.safeMin.call(void 0, gaps);
5470
5572
  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;
5471
5573
  }
5472
5574
  function detectColumns(yLines) {
5473
5575
  const allItems = yLines.flat();
5474
5576
  if (allItems.length === 0) return null;
5475
- const pageWidth = _chunkEXBZHI25cjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunkEXBZHI25cjs.safeMin.call(void 0, allItems.map((i) => i.x));
5577
+ const pageWidth = _chunkFVESLY6Vcjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunkFVESLY6Vcjs.safeMin.call(void 0, allItems.map((i) => i.x));
5476
5578
  if (pageWidth < 100) return null;
5477
5579
  let bigoLineIdx = -1;
5478
5580
  for (let i = 0; i < yLines.length; i++) {
@@ -5771,7 +5873,7 @@ function hasBoxTopPair(line, maxH, horizontals, cellItems) {
5771
5873
  if (ow <= 0) continue;
5772
5874
  const overlap2 = Math.min(line.x2, o.x2) - Math.max(line.x1, o.x1);
5773
5875
  if (overlap2 / Math.max(w, ow) < UNDER_BOX_PAIR_OVERLAP) continue;
5774
- const covered = _nullishCoalesce(_optionalChain([cellItems, 'optionalAccess', _271 => _271.reduce, 'call', _272 => _272((sum, item) => {
5876
+ const covered = _nullishCoalesce(_optionalChain([cellItems, 'optionalAccess', _277 => _277.reduce, 'call', _278 => _278((sum, item) => {
5775
5877
  const below = item.y - o.y1;
5776
5878
  if (below < 0.5 || below > 3 || !item.text.trim()) return sum;
5777
5879
  return sum + Math.max(0, Math.min(o.x2, item.x + item.w) - Math.max(o.x1, item.x));
@@ -5901,8 +6003,8 @@ function edgesOf(box, h, v, hNear = EDGE_NEAR2) {
5901
6003
  }
5902
6004
  function recordClipCellEdges(grids, horizontals, verticals, nonRules) {
5903
6005
  if (!grids.some((g) => g.cells)) return;
5904
- const h = rules(_optionalChain([nonRules, 'optionalAccess', _273 => _273.size]) ? horizontals.filter((l) => !nonRules.has(l)) : horizontals, "h");
5905
- const v = rules(_optionalChain([nonRules, 'optionalAccess', _274 => _274.size]) ? verticals.filter((l) => !nonRules.has(l)) : verticals, "v");
6006
+ const h = rules(_optionalChain([nonRules, 'optionalAccess', _279 => _279.size]) ? horizontals.filter((l) => !nonRules.has(l)) : horizontals, "h");
6007
+ const v = rules(_optionalChain([nonRules, 'optionalAccess', _280 => _280.size]) ? verticals.filter((l) => !nonRules.has(l)) : verticals, "v");
5906
6008
  for (const g of grids) for (const c of _nullishCoalesce(g.cells, () => ( []))) {
5907
6009
  const near = c.filler ? Math.min(EDGE_NEAR2, (c.bbox.y2 - c.bbox.y1) / 3) : EDGE_NEAR2;
5908
6010
  CLIP_CELL_EDGES.set(c, edgesOf(c.bbox, h, v, near));
@@ -5910,12 +6012,12 @@ function recordClipCellEdges(grids, horizontals, verticals, nonRules) {
5910
6012
  }
5911
6013
  function takeClipCellEdges(from, to) {
5912
6014
  const e = CLIP_CELL_EDGES.get(from);
5913
- if (e) _chunkAFXX3YSPcjs.CELL_EDGES.set(to, e);
6015
+ if (e) _chunkL5JX2GAMcjs.CELL_EDGES.set(to, e);
5914
6016
  }
5915
6017
  function joinCellEdges(a, b) {
5916
- const u = _chunkAFXX3YSPcjs.CELL_EDGES.get(a), d = _chunkAFXX3YSPcjs.CELL_EDGES.get(b);
6018
+ const u = _chunkL5JX2GAMcjs.CELL_EDGES.get(a), d = _chunkL5JX2GAMcjs.CELL_EDGES.get(b);
5917
6019
  if (!u || !d) return;
5918
- _chunkAFXX3YSPcjs.CELL_EDGES.set(a, { t: u.t, b: d.b, l: u.l || d.l, r: u.r || d.r });
6020
+ _chunkL5JX2GAMcjs.CELL_EDGES.set(a, { t: u.t, b: d.b, l: u.l || d.l, r: u.r || d.r });
5919
6021
  }
5920
6022
 
5921
6023
  // src/pdf/table-unit-row.ts
@@ -5931,12 +6033,12 @@ function rebuildUnitLine(items, grid) {
5931
6033
  function prependUnitRow(cells, cols, line, usedItems) {
5932
6034
  const text = cleanCellText(line.map((item) => item.text).join(""));
5933
6035
  cells.unshift(Array.from({ length: cols }, (_, c) => ({ text: c === 0 ? text : "", colSpan: c === 0 ? cols : 1, rowSpan: 1 })));
5934
- for (const cell of cells[0]) _chunkAFXX3YSPcjs.CELL_EDGES.set(cell, NO_EDGES);
6036
+ for (const cell of cells[0]) _chunkL5JX2GAMcjs.CELL_EDGES.set(cell, NO_EDGES);
5935
6037
  for (const item of line) usedItems.add(item);
5936
6038
  }
5937
6039
  function attachUnitRow(items, grid, cells, cols, usedItems) {
5938
6040
  const all = cells.flat();
5939
- if (all.filter((c) => c.text.trim()).length * 2 < all.length || UNIT.test(_nullishCoalesce(_optionalChain([cells, 'access', _275 => _275[0], 'optionalAccess', _276 => _276[0], 'optionalAccess', _277 => _277.text]), () => ( "")))) return false;
6041
+ if (all.filter((c) => c.text.trim()).length * 2 < all.length || UNIT.test(_nullishCoalesce(_optionalChain([cells, 'access', _281 => _281[0], 'optionalAccess', _282 => _282[0], 'optionalAccess', _283 => _283.text]), () => ( "")))) return false;
5940
6042
  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);
5941
6043
  let nearest = Infinity;
5942
6044
  for (const it of above) nearest = Math.min(nearest, it.y);
@@ -6476,7 +6578,7 @@ function stackedTableBands(items) {
6476
6578
  const caption = (start, end) => lines.slice(start, end).some((line) => /^Table\s+\d+\s*[:.]/i.test(mergeLineSimple(line).trim()));
6477
6579
  while (runs.length > 0 && !caption(runs[runs.length - 1].end, lines.length)) runs.pop();
6478
6580
  if (runs.length < 2) return null;
6479
- if (runs.some((run, i) => !caption(run.end, _nullishCoalesce(_optionalChain([runs, 'access', _278 => _278[i + 1], 'optionalAccess', _279 => _279.start]), () => ( lines.length))))) return null;
6581
+ if (runs.some((run, i) => !caption(run.end, _nullishCoalesce(_optionalChain([runs, 'access', _284 => _284[i + 1], 'optionalAccess', _285 => _285.start]), () => ( lines.length))))) return null;
6480
6582
  const tables = runs.map((run) => lines.slice(run.start, run.end).flat());
6481
6583
  const between = runs.slice(0, -1).map((run, i) => lines.slice(run.end, runs[i + 1].start).flat());
6482
6584
  const tail = lines.slice(runs[runs.length - 1].end);
@@ -6640,7 +6742,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
6640
6742
  const filled = fillBlanks(items, horizontals, verticals);
6641
6743
  items = filled.items;
6642
6744
  horizontals = filled.horizontals;
6643
- const prevPage = _optionalChain([carry, 'optionalAccess', _280 => _280.page]) === pageNum - 1 ? carry.clip : void 0;
6745
+ const prevPage = _optionalChain([carry, 'optionalAccess', _286 => _286.page]) === pageNum - 1 ? carry.clip : void 0;
6644
6746
  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 };
6645
6747
  if (carry) {
6646
6748
  carry.page = pageNum;
@@ -6928,14 +7030,14 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
6928
7030
  if (!assignedItems.has(textItems[ti])) usedItems.delete(tableItems[ti]);
6929
7031
  }
6930
7032
  }
6931
- if (unitLine.length > 0 && rebuiltUsed && !/^\s*\(\s*단위\s*[::]/.test(_nullishCoalesce(_optionalChain([finalGrid, 'access', _281 => _281[0], 'optionalAccess', _282 => _282[0], 'optionalAccess', _283 => _283.text]), () => ( "")))) {
7033
+ if (unitLine.length > 0 && rebuiltUsed && !/^\s*\(\s*단위\s*[::]/.test(_nullishCoalesce(_optionalChain([finalGrid, 'access', _287 => _287[0], 'optionalAccess', _288 => _288[0], 'optionalAccess', _289 => _289.text]), () => ( "")))) {
6932
7034
  prependUnitRow(finalGrid, numCols, unitLine, usedItems);
6933
7035
  finalRows++;
6934
7036
  }
6935
7037
  if (!rebuiltUsed && attachUnitRow(items, grid, finalGrid, numCols, usedItems)) finalRows++;
6936
7038
  let semanticOneColumn = false;
6937
7039
  if (!grid.cells && numCols === 1 && numGridRows >= 2) {
6938
- const populatedRows = finalGrid.filter((row) => _optionalChain([row, 'access', _284 => _284[0], 'optionalAccess', _285 => _285.text, 'access', _286 => _286.trim, 'call', _287 => _287()]));
7040
+ const populatedRows = finalGrid.filter((row) => _optionalChain([row, 'access', _290 => _290[0], 'optionalAccess', _291 => _291.text, 'access', _292 => _292.trim, 'call', _293 => _293()]));
6939
7041
  if (populatedRows.length >= 4) {
6940
7042
  const fontSizes = tableItems.map((item) => item.fontSize).filter((size) => size > 0).sort((a, b) => a - b);
6941
7043
  const medianFont = _nullishCoalesce(fontSizes[Math.floor(fontSizes.length / 2)], () => ( 0));
@@ -7014,7 +7116,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7014
7116
  height: grid.bbox.y2 - grid.bbox.y1
7015
7117
  };
7016
7118
  if (numRows === 1 && numCols === 1 && gridW < pageWidth * 0.35) {
7017
- const prose = _nullishCoalesce(_optionalChain([finalGrid, 'access', _288 => _288[0], 'optionalAccess', _289 => _289[0], 'optionalAccess', _290 => _290.text]), () => ( ""));
7119
+ const prose = _nullishCoalesce(_optionalChain([finalGrid, 'access', _294 => _294[0], 'optionalAccess', _295 => _295[0], 'optionalAccess', _296 => _296.text]), () => ( ""));
7018
7120
  const besideLines = (side) => new Set(side.map((it) => Math.round(it.y / 3))).size;
7019
7121
  const rightLines = items.filter((it) => it.x >= grid.bbox.x2 + 3 && it.y >= grid.bbox.y1 && it.y <= grid.bbox.y2);
7020
7122
  const leftLines = items.filter((it) => it.x + it.w <= grid.bbox.x1 - 3 && it.y >= grid.bbox.y1 && it.y <= grid.bbox.y2);
@@ -7068,7 +7170,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7068
7170
  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;
7069
7171
  const clusterResults = (proseColumns ? [] : detectClusterTables(clusterItems, pageNum)).filter((cr) => {
7070
7172
  const b = cr.bbox;
7071
- return !blocks.some((x) => x.type === "paragraph" && x.bbox && (_nullishCoalesce(_optionalChain([x, 'access', _291 => _291.text, 'optionalAccess', _292 => _292.match, 'call', _293 => _293(/\p{L}/gu), 'optionalAccess', _294 => _294.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);
7173
+ return !blocks.some((x) => x.type === "paragraph" && x.bbox && (_nullishCoalesce(_optionalChain([x, 'access', _297 => _297.text, 'optionalAccess', _298 => _298.match, 'call', _299 => _299(/\p{L}/gu), 'optionalAccess', _300 => _300.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);
7072
7174
  });
7073
7175
  if (clusterResults.length > 0) {
7074
7176
  const ciToIdx = /* @__PURE__ */ new Map();
@@ -7102,7 +7204,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7102
7204
  if (gutterX !== null) {
7103
7205
  const gx = gutterX;
7104
7206
  const allY = remaining.map((i) => i.y);
7105
- const pageH = _chunkEXBZHI25cjs.safeMax.call(void 0, allY) - _chunkEXBZHI25cjs.safeMin.call(void 0, allY);
7207
+ const pageH = _chunkFVESLY6Vcjs.safeMax.call(void 0, allY) - _chunkFVESLY6Vcjs.safeMin.call(void 0, allY);
7106
7208
  const gapThreshold = Math.max(15, pageH * 0.03);
7107
7209
  const sides = [
7108
7210
  remaining.filter((i) => i.x + i.w <= gx),
@@ -7122,7 +7224,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
7122
7224
  finalTextBlocks = detectListBlocks(textBlocks);
7123
7225
  } else {
7124
7226
  const allY = remaining.map((i) => i.y);
7125
- const pageH = _chunkEXBZHI25cjs.safeMax.call(void 0, allY) - _chunkEXBZHI25cjs.safeMin.call(void 0, allY);
7227
+ const pageH = _chunkFVESLY6Vcjs.safeMax.call(void 0, allY) - _chunkFVESLY6Vcjs.safeMin.call(void 0, allY);
7126
7228
  const groups = xyCutOrder(remaining, Math.max(15, pageH * 0.03));
7127
7229
  const textBlocks = [];
7128
7230
  for (const group of groups) {
@@ -7441,7 +7543,7 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
7441
7543
  blocks.push(...columnTextToBlocks(tableText, pageNum, bbox, dominantStyle(items)));
7442
7544
  } else {
7443
7545
  const allY = items.map((i) => i.y);
7444
- const pageHeight = _chunkEXBZHI25cjs.safeMax.call(void 0, allY) - _chunkEXBZHI25cjs.safeMin.call(void 0, allY);
7546
+ const pageHeight = _chunkFVESLY6Vcjs.safeMax.call(void 0, allY) - _chunkFVESLY6Vcjs.safeMin.call(void 0, allY);
7445
7547
  const gapThreshold = Math.max(15, pageHeight * 0.03);
7446
7548
  const orderedGroups = proseCutX !== null ? splitTwoColumnProse(items, proseCutX) : xyCutOrder(items, gapThreshold);
7447
7549
  for (const group of orderedGroups) {
@@ -7509,4 +7611,4 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
7509
7611
 
7510
7612
 
7511
7613
  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.extractPageBlocksWithLines = extractPageBlocksWithLines;
7512
- //# sourceMappingURL=chunk-WNF3TSV3.cjs.map
7614
+ //# sourceMappingURL=chunk-CZOPNDTO.cjs.map