kordoc 4.14.3 → 4.14.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +16 -4
  2. package/dist/{-7XBPXCXN.js → -Z4TJ3QGK.js} +11 -11
  3. package/dist/{chunk-EBZUZC6F.cjs → chunk-5LAZQCUJ.cjs} +4 -4
  4. package/dist/{chunk-EBZUZC6F.cjs.map → chunk-5LAZQCUJ.cjs.map} +1 -1
  5. package/dist/{chunk-NQCUAGLR.js → chunk-6BWU6SQX.js} +1 -1
  6. package/dist/{chunk-2LQGSDZ6.js.map → chunk-6BWU6SQX.js.map} +1 -1
  7. package/dist/{chunk-2LQGSDZ6.js → chunk-6CUIXJOC.js} +1 -1
  8. package/dist/{chunk-NQCUAGLR.js.map → chunk-6CUIXJOC.js.map} +1 -1
  9. package/dist/{chunk-D6KQKMU3.js → chunk-7SE4EZ45.js} +2 -2
  10. package/dist/{chunk-YGBZABI4.js → chunk-D4U2TXDC.js} +6 -6
  11. package/dist/chunk-DPWWXUOG.js +2222 -0
  12. package/dist/chunk-DPWWXUOG.js.map +1 -0
  13. package/dist/{chunk-FAZR34CA.js → chunk-GLSBEEZJ.js} +2 -2
  14. package/dist/{chunk-L5EH2NVO.js → chunk-GUJ4Q73I.js} +2 -2
  15. package/dist/{chunk-JCVIOLBF.js → chunk-HIJUKZHM.js} +3 -3
  16. package/dist/{chunk-IW2CB755.cjs → chunk-IMAAFSAX.cjs} +392 -42
  17. package/dist/chunk-IMAAFSAX.cjs.map +1 -0
  18. package/dist/{chunk-GTINVM5K.js → chunk-LCW7SEPG.js} +2 -2
  19. package/dist/{chunk-4R67INKT.js → chunk-LFSQAMSM.js} +389 -39
  20. package/dist/chunk-LFSQAMSM.js.map +1 -0
  21. package/dist/{chunk-VJHAUMCF.js → chunk-MG6DJEX4.js} +389 -39
  22. package/dist/chunk-MG6DJEX4.js.map +1 -0
  23. package/dist/{chunk-QGW7NMTX.js → chunk-NLU6LBLY.js} +2 -2
  24. package/dist/{chunk-5VVS2QIJ.cjs → chunk-QEJUY6SK.cjs} +3 -3
  25. package/dist/{chunk-5VVS2QIJ.cjs.map → chunk-QEJUY6SK.cjs.map} +1 -1
  26. package/dist/{chunk-VYOGXNQ3.js → chunk-QIF2VXBQ.js} +2 -2
  27. package/dist/{chunk-I4NNYWIR.js → chunk-TITDJWVZ.js} +2 -2
  28. package/dist/{chunk-NOAQRCV6.cjs → chunk-USHQCF5T.cjs} +676 -75
  29. package/dist/chunk-USHQCF5T.cjs.map +1 -0
  30. package/dist/{chunk-VNFJPTU4.js → chunk-V3DX4DUF.js} +2 -2
  31. package/dist/{chunk-WB5LW52Z.js → chunk-VDN7LMPL.js} +2 -2
  32. package/dist/{chunk-IHZEFW4L.js → chunk-VJIL6PIL.js} +2 -2
  33. package/dist/{chunk-HX4UUF7Y.cjs → chunk-VWUYVEFN.cjs} +1 -1
  34. package/dist/{chunk-HX4UUF7Y.cjs.map → chunk-VWUYVEFN.cjs.map} +1 -1
  35. package/dist/{chunk-EMGF6EEV.cjs → chunk-WJHAU73B.cjs} +2 -2
  36. package/dist/{chunk-EMGF6EEV.cjs.map → chunk-WJHAU73B.cjs.map} +1 -1
  37. package/dist/{chunk-O2PGQNYE.js → chunk-WJJGW5PL.js} +2 -2
  38. package/dist/{chunk-CVEERPMP.js → chunk-XVXHXQIO.js} +9 -9
  39. package/dist/{chunk-4RJ5D7MT.js → chunk-YAKC46HZ.js} +2 -2
  40. package/dist/{chunk-A275ZQLX.js → chunk-YAVHVFRY.js} +653 -52
  41. package/dist/chunk-YAVHVFRY.js.map +1 -0
  42. package/dist/{chunk-UVVEBI22.js → chunk-YT3GC62E.js} +653 -52
  43. package/dist/chunk-YT3GC62E.js.map +1 -0
  44. package/dist/chunks-CCMRL4MJ.js +10 -0
  45. package/dist/cli.js +28 -28
  46. package/dist/cli.js.map +1 -1
  47. package/dist/{formula-CPO2TZGB.cjs → formula-5LOVHAKE.cjs} +9 -9
  48. package/dist/{formula-CPO2TZGB.cjs.map → formula-5LOVHAKE.cjs.map} +1 -1
  49. package/dist/{formula-X44GV7TN.js → formula-7RANCW5L.js} +3 -3
  50. package/dist/{formula-NOIDZEBA.js → formula-7UYJOVTB.js} +4 -4
  51. package/dist/{image-ocr-72RAR4WR.js → image-ocr-I6JOCATS.js} +8 -8
  52. package/dist/{image-ocr-SUGT64ZM.cjs → image-ocr-NYBJEOH2.cjs} +13 -13
  53. package/dist/{image-ocr-SUGT64ZM.cjs.map → image-ocr-NYBJEOH2.cjs.map} +1 -1
  54. package/dist/{image-ocr-R6W6A75P.js → image-ocr-ZV6PDBUQ.js} +6 -6
  55. package/dist/index.cjs +2137 -537
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.cts +4 -3
  58. package/dist/index.d.ts +4 -3
  59. package/dist/index.js +1851 -251
  60. package/dist/index.js.map +1 -1
  61. package/dist/mcp.js +24 -24
  62. package/dist/mcp.js.map +1 -1
  63. package/dist/{model-bundle-57CLEBCO.js → model-bundle-2C5IYDLE.js} +5 -5
  64. package/dist/{models-7ELIFTD7.js → models-SEQZHZFT.js} +5 -5
  65. package/dist/{parser-4NKAYWAX.js → parser-3FNXEP6T.js} +485 -47
  66. package/dist/parser-3FNXEP6T.js.map +1 -0
  67. package/dist/{parser-HWFQRSUQ.js → parser-FJBJXRJK.js} +485 -47
  68. package/dist/parser-FJBJXRJK.js.map +1 -0
  69. package/dist/{parser-RANGXGBD.cjs → parser-HVEKF73B.cjs} +535 -97
  70. package/dist/parser-HVEKF73B.cjs.map +1 -0
  71. package/dist/pdf-ocr-JRDBJ6TA.cjs +14 -0
  72. package/dist/{pdf-ocr-VHSFACH7.cjs.map → pdf-ocr-JRDBJ6TA.cjs.map} +1 -1
  73. package/dist/pdf-ocr-UUBWBEHL.js +16 -0
  74. package/dist/pdf-ocr-VJSF2SQC.js +13 -0
  75. package/dist/{profile-io-V52PL5ZO.js → profile-io-RUFZOZO6.js} +3 -3
  76. package/dist/{rasterize-ZIGLJDOG.js → rasterize-IOYXR5SI.js} +3 -3
  77. package/dist/{redact-TIQEQI3M.js → redact-NMIKVHMP.js} +2 -2
  78. package/dist/{redact-doc-KXZ3TZAG.js → redact-doc-QBHNJ2BU.js} +98 -30
  79. package/dist/redact-doc-QBHNJ2BU.js.map +1 -0
  80. package/dist/{render-U5PE6V2E.js → render-YZ2TEC3N.js} +7 -7
  81. package/dist/seal-ECV44TUH.js +10 -0
  82. package/dist/{setup-YRDM4ODP.js → setup-MPIEP6XT.js} +3 -3
  83. package/dist/visual-ICMOWUCR.js +19 -0
  84. package/dist/{watch-5IOLBATT.js → watch-RYO7MN5B.js} +12 -12
  85. package/package.json +2 -2
  86. package/dist/chunk-4R67INKT.js.map +0 -1
  87. package/dist/chunk-A275ZQLX.js.map +0 -1
  88. package/dist/chunk-IH56ZISC.js +0 -620
  89. package/dist/chunk-IH56ZISC.js.map +0 -1
  90. package/dist/chunk-IW2CB755.cjs.map +0 -1
  91. package/dist/chunk-NOAQRCV6.cjs.map +0 -1
  92. package/dist/chunk-UVVEBI22.js.map +0 -1
  93. package/dist/chunk-VJHAUMCF.js.map +0 -1
  94. package/dist/chunks-I7TEMJXH.js +0 -10
  95. package/dist/parser-4NKAYWAX.js.map +0 -1
  96. package/dist/parser-HWFQRSUQ.js.map +0 -1
  97. package/dist/parser-RANGXGBD.cjs.map +0 -1
  98. package/dist/pdf-ocr-BNC34MNU.js +0 -13
  99. package/dist/pdf-ocr-QX2GB33Q.js +0 -16
  100. package/dist/pdf-ocr-VHSFACH7.cjs +0 -14
  101. package/dist/redact-doc-KXZ3TZAG.js.map +0 -1
  102. package/dist/seal-DNXJBILR.js +0 -10
  103. package/dist/visual-5XWMA4EV.js +0 -19
  104. /package/dist/{-7XBPXCXN.js.map → -Z4TJ3QGK.js.map} +0 -0
  105. /package/dist/{chunk-D6KQKMU3.js.map → chunk-7SE4EZ45.js.map} +0 -0
  106. /package/dist/{chunk-YGBZABI4.js.map → chunk-D4U2TXDC.js.map} +0 -0
  107. /package/dist/{chunk-FAZR34CA.js.map → chunk-GLSBEEZJ.js.map} +0 -0
  108. /package/dist/{chunk-L5EH2NVO.js.map → chunk-GUJ4Q73I.js.map} +0 -0
  109. /package/dist/{chunk-JCVIOLBF.js.map → chunk-HIJUKZHM.js.map} +0 -0
  110. /package/dist/{chunk-GTINVM5K.js.map → chunk-LCW7SEPG.js.map} +0 -0
  111. /package/dist/{chunk-QGW7NMTX.js.map → chunk-NLU6LBLY.js.map} +0 -0
  112. /package/dist/{chunk-VYOGXNQ3.js.map → chunk-QIF2VXBQ.js.map} +0 -0
  113. /package/dist/{chunk-I4NNYWIR.js.map → chunk-TITDJWVZ.js.map} +0 -0
  114. /package/dist/{chunk-VNFJPTU4.js.map → chunk-V3DX4DUF.js.map} +0 -0
  115. /package/dist/{chunk-WB5LW52Z.js.map → chunk-VDN7LMPL.js.map} +0 -0
  116. /package/dist/{chunk-IHZEFW4L.js.map → chunk-VJIL6PIL.js.map} +0 -0
  117. /package/dist/{chunk-O2PGQNYE.js.map → chunk-WJJGW5PL.js.map} +0 -0
  118. /package/dist/{chunk-CVEERPMP.js.map → chunk-XVXHXQIO.js.map} +0 -0
  119. /package/dist/{chunk-4RJ5D7MT.js.map → chunk-YAKC46HZ.js.map} +0 -0
  120. /package/dist/{chunks-I7TEMJXH.js.map → chunks-CCMRL4MJ.js.map} +0 -0
  121. /package/dist/{formula-X44GV7TN.js.map → formula-7RANCW5L.js.map} +0 -0
  122. /package/dist/{formula-NOIDZEBA.js.map → formula-7UYJOVTB.js.map} +0 -0
  123. /package/dist/{image-ocr-72RAR4WR.js.map → image-ocr-I6JOCATS.js.map} +0 -0
  124. /package/dist/{image-ocr-R6W6A75P.js.map → image-ocr-ZV6PDBUQ.js.map} +0 -0
  125. /package/dist/{model-bundle-57CLEBCO.js.map → model-bundle-2C5IYDLE.js.map} +0 -0
  126. /package/dist/{models-7ELIFTD7.js.map → models-SEQZHZFT.js.map} +0 -0
  127. /package/dist/{pdf-ocr-BNC34MNU.js.map → pdf-ocr-UUBWBEHL.js.map} +0 -0
  128. /package/dist/{pdf-ocr-QX2GB33Q.js.map → pdf-ocr-VJSF2SQC.js.map} +0 -0
  129. /package/dist/{profile-io-V52PL5ZO.js.map → profile-io-RUFZOZO6.js.map} +0 -0
  130. /package/dist/{rasterize-ZIGLJDOG.js.map → rasterize-IOYXR5SI.js.map} +0 -0
  131. /package/dist/{redact-TIQEQI3M.js.map → redact-NMIKVHMP.js.map} +0 -0
  132. /package/dist/{render-U5PE6V2E.js.map → render-YZ2TEC3N.js.map} +0 -0
  133. /package/dist/{seal-DNXJBILR.js.map → seal-ECV44TUH.js.map} +0 -0
  134. /package/dist/{setup-YRDM4ODP.js.map → setup-MPIEP6XT.js.map} +0 -0
  135. /package/dist/{visual-5XWMA4EV.js.map → visual-ICMOWUCR.js.map} +0 -0
  136. /package/dist/{watch-5IOLBATT.js.map → watch-RYO7MN5B.js.map} +0 -0
@@ -6,18 +6,28 @@ import {
6
6
  ensureOcrModels,
7
7
  getOcrModelsDir,
8
8
  parseCharacterDict
9
- } from "./chunk-D6KQKMU3.js";
9
+ } from "./chunk-7SE4EZ45.js";
10
10
  import {
11
11
  extractPageBlocksWithLines
12
- } from "./chunk-A275ZQLX.js";
12
+ } from "./chunk-YAVHVFRY.js";
13
13
 
14
14
  // src/ocr/ruling-lines.ts
15
- var INK_LUMA_MAX = 190;
15
+ var INK_LUMA_MAX = 205;
16
16
  var MIN_LINE_LENGTH_PT = 20;
17
17
  var MAX_LINE_WIDTH_PT = 2.5;
18
18
  var GAP_TOL_PX = 2;
19
19
  var BAND_OVERLAP_RATIO = 0.5;
20
20
  var SURROUND_INK_RATIO = 0.35;
21
+ var DOT_MAX_GAP_PT = 1.3;
22
+ var DOT_MAX_DASH_PT = 4;
23
+ var DOT_MAX_PERIOD_PT = 2.2;
24
+ var DOT_MIN_COUNT = 8;
25
+ var DOT_TOUCH_PT = 1.5;
26
+ var FILL_DELTA = 10;
27
+ var FILL_MIN_LENGTH_PT = 10;
28
+ var FILL_MIN_DEPTH_PT = 4;
29
+ var FILL_FLAT_TOL = 12;
30
+ var FILL_FLAT_RATIO = 0.8;
21
31
  function detectRulingLines(rgba, width, height, scale) {
22
32
  const minLenPx = Math.round(MIN_LINE_LENGTH_PT * scale);
23
33
  const maxThickPx = Math.max(1, Math.floor(MAX_LINE_WIDTH_PT * scale));
@@ -26,11 +36,164 @@ function detectRulingLines(rgba, width, height, scale) {
26
36
  const luma = rgba[i] * 77 + rgba[i + 1] * 150 + rgba[i + 2] * 29 >> 8;
27
37
  if (luma <= INK_LUMA_MAX && rgba[i + 3] >= 128) ink[p] = 1;
28
38
  }
29
- const horizontals = detectBands(ink, width, height, minLenPx, maxThickPx, false);
30
- const verticals = detectBands(ink, width, height, minLenPx, maxThickPx, true);
39
+ const solid = (at, line, span) => solidRuns(at, line, span, minLenPx);
40
+ const dot = {
41
+ maxGap: Math.max(2, Math.round(DOT_MAX_GAP_PT * scale)),
42
+ maxDash: Math.max(2, Math.round(DOT_MAX_DASH_PT * scale)),
43
+ maxPeriod: DOT_MAX_PERIOD_PT * scale
44
+ };
45
+ const dotted = (at, line, span) => dottedRuns(at, line, span, minLenPx, dot.maxGap, dot.maxDash, dot.maxPeriod);
46
+ const horizontals = detectBands(ink, width, height, maxThickPx, false, solid);
47
+ const verticals = detectBands(ink, width, height, maxThickPx, true, solid);
48
+ const dotH = detectBands(ink, width, height, maxThickPx, false, dotted);
49
+ const dotV = detectBands(ink, width, height, maxThickPx, true, dotted);
50
+ const tol = Math.max(2, Math.round(DOT_TOUCH_PT * scale));
51
+ const allH = [...horizontals, ...dotH], allV = [...verticals, ...dotV];
52
+ const touchesV = (a) => allV.some((p) => p.x1 >= a.x1 - tol && p.x1 <= a.x2 + tol && a.y1 >= p.y1 - tol && a.y1 <= p.y2 + tol);
53
+ const touchesH = (a) => allH.some((p) => p.y1 >= a.y1 - tol && p.y1 <= a.y2 + tol && a.x1 >= p.x1 - tol && a.x1 <= p.x2 + tol);
54
+ horizontals.push(...dotH.filter(touchesV));
55
+ verticals.push(...dotV.filter(touchesH));
56
+ const inkV = [...verticals];
57
+ const ruleH = horizontals.filter((p) => inkV.some((v) => v.x1 >= p.x1 - tol && v.x1 <= p.x2 + tol && p.y1 >= v.y1 - tol && p.y1 <= v.y2 + tol));
58
+ const fill = fillEdges(rgba, width, height, scale);
59
+ const fillH = fill.horizontals.filter((a) => ruleH.some((p) => Math.abs(p.x1 - a.x1) <= tol && Math.abs(p.x2 - a.x2) <= tol));
60
+ horizontals.push(...fillH);
61
+ const edgeH = [...ruleH, ...fillH];
62
+ verticals.push(...fill.verticals.filter((a) => inkV.some((p) => Math.abs(p.x1 - a.x1) <= tol && p.y1 <= a.y2 + tol && p.y2 >= a.y1 - tol) || edgeH.some((p) => (Math.abs(p.x1 - a.x1) <= tol || Math.abs(p.x2 - a.x1) <= tol) && p.y1 >= a.y1 - tol && p.y1 <= a.y2 + tol)));
31
63
  return { horizontals, verticals };
32
64
  }
33
- function detectBands(ink, width, height, minLenPx, maxThickPx, transpose) {
65
+ function fillEdges(rgba, width, height, scale) {
66
+ const k = Math.max(1, Math.round(scale));
67
+ const w = Math.floor(width / k), h = Math.floor(height / k), n = w * h;
68
+ const luma = new Uint8Array(n);
69
+ const hist = new Uint32Array(256);
70
+ for (let y = 0; y < h; y++) {
71
+ for (let x = 0; x < w; x++) {
72
+ let mx = 0;
73
+ for (let by = 0; by < k; by++) {
74
+ let i = ((y * k + by) * width + x * k) * 4;
75
+ for (let bx = 0; bx < k; bx++, i += 4) {
76
+ const l = rgba[i] * 77 + rgba[i + 1] * 150 + rgba[i + 2] * 29 >> 8;
77
+ if (l > mx) mx = l;
78
+ }
79
+ }
80
+ luma[y * w + x] = mx;
81
+ hist[mx]++;
82
+ }
83
+ }
84
+ let bg = 255;
85
+ for (let v = 0; v < 256; v++) if (hist[v] > hist[bg]) bg = v;
86
+ const tint = new Uint8Array(n);
87
+ for (let p = 0; p < n; p++) if (luma[p] < bg - FILL_DELTA) tint[p] = 1;
88
+ const depth = Math.max(2, Math.round(FILL_MIN_DEPTH_PT * scale / k));
89
+ const minLen = Math.round(FILL_MIN_LENGTH_PT * scale / k);
90
+ const solid = (at, line, span) => solidRuns(at, line, span, minLen);
91
+ const run = new Uint16Array(n);
92
+ const mask = new Uint8Array(n);
93
+ const out = { horizontals: [], verticals: [] };
94
+ for (const [dx, dy] of [[0, 1], [0, -1], [1, 0], [-1, 0]]) {
95
+ const step = dy * w + dx;
96
+ const ys = dy > 0 ? [h - 1, -1, -1] : [0, h, 1];
97
+ const xs = dx > 0 ? [w - 1, -1, -1] : [0, w, 1];
98
+ for (let y = ys[0]; y !== ys[1]; y += ys[2]) {
99
+ for (let x = xs[0]; x !== xs[1]; x += xs[2]) {
100
+ const p = y * w + x;
101
+ const nx = x + dx, ny = y + dy;
102
+ run[p] = tint[p] ? nx >= 0 && nx < w && ny >= 0 && ny < h ? Math.min(65535, run[p + step] + 1) : 1 : 0;
103
+ }
104
+ }
105
+ mask.fill(0);
106
+ for (let y = 0; y < h; y++) {
107
+ for (let x = 0; x < w; x++) {
108
+ const p = y * w + x;
109
+ if (run[p] < depth) continue;
110
+ const ox = x - dx, oy = y - dy;
111
+ if (ox < 0 || oy < 0 || ox >= w || oy >= h || !tint[p - step]) mask[p] = 1;
112
+ }
113
+ }
114
+ const vertical = dx !== 0;
115
+ const flat = (s) => {
116
+ const d = depth >> 1;
117
+ const vals = [];
118
+ if (vertical) {
119
+ const x = Math.round(s.x1) + dx * d;
120
+ for (let y = Math.round(s.y1); y <= s.y2; y++) if (x >= 0 && x < w) vals.push(luma[y * w + x]);
121
+ } else {
122
+ const y = Math.round(s.y1) + dy * d;
123
+ for (let x = Math.round(s.x1); x <= s.x2; x++) if (y >= 0 && y < h) vals.push(luma[y * w + x]);
124
+ }
125
+ if (!vals.length) return false;
126
+ const med = [...vals].sort((a, b) => a - b)[vals.length >> 1];
127
+ return vals.filter((v) => Math.abs(v - med) <= FILL_FLAT_TOL).length >= vals.length * FILL_FLAT_RATIO;
128
+ };
129
+ for (const s of detectBands(mask, w, h, 1, vertical, solid)) {
130
+ if (!flat(s)) continue;
131
+ const c = (v) => v * k + (k - 1) / 2;
132
+ (vertical ? out.verticals : out.horizontals).push({ x1: c(s.x1), y1: c(s.y1), x2: c(s.x2), y2: c(s.y2), thicknessPx: 1 });
133
+ }
134
+ }
135
+ return out;
136
+ }
137
+ function solidRuns(at, line, span, minLenPx) {
138
+ const runs = [];
139
+ let runStart = -1;
140
+ let gap = 0;
141
+ for (let pos = 0; pos <= span; pos++) {
142
+ const on = pos < span && at(line, pos) === 1;
143
+ if (on) {
144
+ if (runStart < 0) runStart = pos;
145
+ gap = 0;
146
+ } else if (runStart >= 0) {
147
+ if (++gap > GAP_TOL_PX || pos >= span) {
148
+ const hi = pos - gap;
149
+ if (hi - runStart + 1 >= minLenPx) runs.push({ lo: runStart, hi });
150
+ runStart = -1;
151
+ gap = 0;
152
+ }
153
+ }
154
+ }
155
+ return runs;
156
+ }
157
+ function dottedRuns(at, line, span, minLenPx, maxGap, maxDash, maxPeriod) {
158
+ const runs = [];
159
+ const chain = [];
160
+ const median = (xs) => xs.sort((a, b) => a - b)[xs.length >> 1];
161
+ const flush = () => {
162
+ const cnt = chain.length >> 1;
163
+ if (cnt >= DOT_MIN_COUNT && chain[chain.length - 1] - chain[0] + 1 >= minLenPx) {
164
+ const periods = [], dashes = [], gaps = [];
165
+ for (let k = 0; k < cnt; k++) {
166
+ dashes.push(chain[2 * k + 1] - chain[2 * k] + 1);
167
+ if (k) {
168
+ periods.push(chain[2 * k] - chain[2 * k - 2]);
169
+ gaps.push(chain[2 * k] - chain[2 * k - 1] - 1);
170
+ }
171
+ }
172
+ if (median(periods) <= maxPeriod || median(dashes) >= 1.5 * median(gaps)) runs.push({ lo: chain[0], hi: chain[chain.length - 1] });
173
+ }
174
+ chain.length = 0;
175
+ };
176
+ let s = -1;
177
+ for (let pos = 0; pos <= span; pos++) {
178
+ const on = pos < span && at(line, pos) === 1;
179
+ if (on) {
180
+ if (s < 0) s = pos;
181
+ continue;
182
+ }
183
+ if (s < 0) continue;
184
+ const lo = s, hi = pos - 1;
185
+ s = -1;
186
+ if (hi - lo + 1 > maxDash) {
187
+ flush();
188
+ continue;
189
+ }
190
+ if (chain.length && lo - chain[chain.length - 1] - 1 > maxGap) flush();
191
+ chain.push(lo, hi);
192
+ }
193
+ flush();
194
+ return runs;
195
+ }
196
+ function detectBands(ink, width, height, maxThickPx, transpose, readRuns) {
34
197
  const lines = transpose ? width : height;
35
198
  const span = transpose ? height : width;
36
199
  const at = transpose ? (line, pos) => ink[pos * width + line] : (line, pos) => ink[line * width + pos];
@@ -55,23 +218,7 @@ function detectBands(ink, width, height, minLenPx, maxThickPx, transpose) {
55
218
  );
56
219
  };
57
220
  for (let line = 0; line < lines; line++) {
58
- const runs = [];
59
- let runStart = -1;
60
- let gap = 0;
61
- for (let pos = 0; pos <= span; pos++) {
62
- const on = pos < span && at(line, pos) === 1;
63
- if (on) {
64
- if (runStart < 0) runStart = pos;
65
- gap = 0;
66
- } else if (runStart >= 0) {
67
- if (++gap > GAP_TOL_PX || pos >= span) {
68
- const hi = pos - gap;
69
- if (hi - runStart + 1 >= minLenPx) runs.push({ lo: runStart, hi });
70
- runStart = -1;
71
- gap = 0;
72
- }
73
- }
74
- }
221
+ const runs = readRuns(at, line, span);
75
222
  const next = [];
76
223
  const used = /* @__PURE__ */ new Set();
77
224
  for (const band of open) {
@@ -257,6 +404,113 @@ function splitRowBands(gray, w, h, ink, minBandRatio) {
257
404
  return { y0, y1, x0, x1 };
258
405
  });
259
406
  }
407
+ function components(gray, w, h, ink) {
408
+ const isInk = (v) => ink.darkInk ? v <= ink.threshold : v > ink.threshold;
409
+ const comps = [];
410
+ const label = new Int32Array(w * h);
411
+ const stack = [];
412
+ for (let p0 = 0; p0 < w * h; p0++) {
413
+ if (label[p0] || !isInk(gray[p0])) continue;
414
+ const c = { x0: w, x1: 0, y0: h, y1: 0, id: comps.length + 1 };
415
+ label[p0] = c.id;
416
+ stack.push(p0);
417
+ while (stack.length) {
418
+ const p = stack.pop();
419
+ const x = p % w, y = p / w | 0;
420
+ if (x < c.x0) c.x0 = x;
421
+ if (x + 1 > c.x1) c.x1 = x + 1;
422
+ if (y < c.y0) c.y0 = y;
423
+ if (y + 1 > c.y1) c.y1 = y + 1;
424
+ for (let dy = -1; dy <= 1; dy++) for (let dx = -1; dx <= 1; dx++) {
425
+ const nx = x + dx, ny = y + dy;
426
+ if (nx < 0 || ny < 0 || nx >= w || ny >= h) continue;
427
+ const q = ny * w + nx;
428
+ if (!label[q] && isInk(gray[q])) {
429
+ label[q] = c.id;
430
+ stack.push(q);
431
+ }
432
+ }
433
+ }
434
+ if (c.y1 - c.y0 < h * 0.85 && c.x1 - c.x0 < w * 0.85) comps.push(c);
435
+ }
436
+ return { comps, label };
437
+ }
438
+ function leadingTriangle(gray, w, h, ink) {
439
+ const { comps, label } = components(gray, w, h, ink);
440
+ let charH = 0;
441
+ for (const c of comps) charH = Math.max(charH, c.y1 - c.y0);
442
+ const first = comps.filter((c) => c.y1 - c.y0 >= charH * 0.4).sort((a, b) => a.x0 - b.x0)[0];
443
+ if (!first || charH < 8) return null;
444
+ const cw = first.x1 - first.x0, ch = first.y1 - first.y0;
445
+ if (cw < ch * 0.8 || cw > ch * 1.8) return null;
446
+ const rowSpan = (y) => {
447
+ let n = 0, lo = -1, hi = -1, runs = 0, prev = false;
448
+ for (let x = first.x0; x < first.x1; x++) {
449
+ const on = label[y * w + x] === first.id;
450
+ if (on) {
451
+ n++;
452
+ if (lo < 0) lo = x - first.x0;
453
+ hi = x - first.x0;
454
+ if (!prev) runs++;
455
+ }
456
+ prev = on;
457
+ }
458
+ return { n, lo, hi, runs };
459
+ };
460
+ const base = Math.max(rowSpan(first.y1 - 1).n, rowSpan(first.y1 - 2).n);
461
+ if (base < cw * 0.7) return null;
462
+ for (let y = first.y0; y < first.y0 + Math.max(1, Math.round(ch * 0.2)); y++) {
463
+ const r = rowSpan(y);
464
+ if (r.n === 0) continue;
465
+ if (r.hi - r.lo + 1 > cw * 0.4 || (r.lo + r.hi) / 2 < cw * 0.25 || (r.lo + r.hi) / 2 > cw * 0.75) return null;
466
+ }
467
+ const mid = rowSpan(first.y0 + Math.round(ch * 0.6));
468
+ if (mid.lo < 0 || mid.lo > cw * 0.3 || mid.hi < cw * 0.7) return null;
469
+ return mid.runs >= 2 ? "\u25B3" : "\u25B2";
470
+ }
471
+ function leaderRuns(gray, w, h, ink, minDots) {
472
+ const comps = components(gray, w, h, ink).comps.sort((a, b) => a.x0 - b.x0);
473
+ const blobs = [];
474
+ for (const c of comps) {
475
+ const last = blobs[blobs.length - 1];
476
+ if (last && c.x0 < last.x1) {
477
+ last.x1 = Math.max(last.x1, c.x1);
478
+ last.y0 = Math.min(last.y0, c.y0);
479
+ last.y1 = Math.max(last.y1, c.y1);
480
+ } else blobs.push({ x0: c.x0, x1: c.x1, y0: c.y0, y1: c.y1 });
481
+ }
482
+ let charH = 0;
483
+ for (const b of blobs) charH = Math.max(charH, b.y1 - b.y0);
484
+ if (charH < 8) return [];
485
+ const small = (c) => c.x1 - c.x0 <= charH * 0.3 && c.y1 - c.y0 <= charH * 0.3;
486
+ let bandTop = h, bandBot = 0;
487
+ for (const c of comps) if (!small(c)) {
488
+ bandTop = Math.min(bandTop, c.y0);
489
+ bandBot = Math.max(bandBot, c.y1);
490
+ }
491
+ const cy = (c) => (c.y0 + c.y1) / 2;
492
+ const isDot = (b) => small(b) && cy(b) >= bandTop && cy(b) <= bandBot;
493
+ const runs = [];
494
+ for (let i = 0; i < blobs.length; ) {
495
+ if (!isDot(blobs[i])) {
496
+ i++;
497
+ continue;
498
+ }
499
+ let j = i;
500
+ while (j + 1 < blobs.length && isDot(blobs[j + 1]) && blobs[j + 1].x0 - blobs[j].x1 <= charH && Math.abs(cy(blobs[j + 1]) - cy(blobs[i])) <= charH * 0.2) j++;
501
+ const x0 = blobs[i].x0, x1 = blobs[j].x1, y = cy(blobs[i]);
502
+ const onLine = comps.some((c) => !small(c) && c.y0 <= y && c.y1 >= y && (c.x1 <= x0 + 2 && c.x1 >= x0 - 2 * charH || c.x0 >= x1 - 2 && c.x0 <= x1 + 2 * charH));
503
+ const run = blobs.slice(i, j + 1).filter((b) => b.x0 > 0 && b.x1 < w);
504
+ const spread = (xs) => {
505
+ const v = [...xs].sort((a, b) => a - b).slice(xs.length >= 5 ? 1 : 0, xs.length >= 5 ? -1 : void 0);
506
+ return v[v.length - 1] / Math.max(1, v[0]);
507
+ };
508
+ const even = run.length >= 2 && spread(run.map((b) => b.x1 - b.x0)) <= 2.5 && spread(run.map((b) => b.y1 - b.y0)) <= 2.5 && spread(run.slice(1).map((b, k) => b.x0 - run[k].x0)) <= 1.8;
509
+ if (j - i + 1 >= minDots && onLine && even) runs.push([x0, x1]);
510
+ i = j + 1;
511
+ }
512
+ return runs;
513
+ }
260
514
  function inkBounds(gray, w, h, ink) {
261
515
  const isInk = (v) => ink.darkInk ? v <= ink.threshold : v > ink.threshold;
262
516
  const colInk = new Uint32Array(w);
@@ -294,6 +548,7 @@ function restoreSymbols(text) {
294
548
  s = s.replace(/^([Oo])(\s?)(?=[\uac00-\ud7a3])/, "\u25CB$2");
295
549
  s = s.replace(/(?<![A-Za-z])O{2,}(?![A-Za-z])/g, (m, i) => /[\uac00-\ud7a3]$/.test(s.slice(Math.max(0, i - 2), i).trimEnd()) || /^\s?[\uac00-\ud7a3]/.test(s.slice(i + m.length)) ? "\u25CB".repeat(m.length) : m);
296
550
  s = s.replace(/[\u2206\u0394]/g, "\u25B3");
551
+ s = s.replace(/\(cid:\d*\)/g, "");
297
552
  return smartQuotes(joinDigitGroups(s));
298
553
  }
299
554
  function joinDigitGroups(s) {
@@ -329,6 +584,53 @@ function smartQuotes(s) {
329
584
  function isDotFragment(text) {
330
585
  return /^[\s.\u00b7\u2024\u2025\u2026\u2027\u2219\u22c5\u318d]+$/.test(text);
331
586
  }
587
+ function joinLeaderItems(items, ends) {
588
+ const gone = /* @__PURE__ */ new Set();
589
+ const sameLine = (a, b) => Math.abs(a.y + a.h / 2 - (b.y + b.h / 2)) <= Math.max(a.h, b.h) / 2;
590
+ const merge = (left, right) => {
591
+ const x2 = Math.max(left.x + left.w, right.x + right.w), y2 = Math.max(left.y + left.h, right.y + right.h);
592
+ left.text = left.text.replace(/\s*\u2026$/, "") + " \u2026 " + right.text.replace(/^\u2026\s*/, "");
593
+ left.x = Math.min(left.x, right.x);
594
+ left.y = Math.min(left.y, right.y);
595
+ left.w = x2 - left.x;
596
+ left.h = y2 - left.y;
597
+ left.confidence = Math.min(left.confidence, right.confidence);
598
+ gone.add(right);
599
+ };
600
+ const neighbor = (it, toLeft) => {
601
+ let best = null;
602
+ for (const o of items) {
603
+ if (o === it || gone.has(o) || !sameLine(o, it)) continue;
604
+ if (toLeft ? o.x + o.w > it.x + 2 : o.x < it.x + it.w - 2) continue;
605
+ if (!best || (toLeft ? o.x + o.w > best.x + best.w : o.x < best.x)) best = o;
606
+ }
607
+ return best;
608
+ };
609
+ for (const it of [...items].sort((a, b) => b.x - a.x)) {
610
+ if (gone.has(it) || !ends.get(it)?.lead) continue;
611
+ const left = neighbor(it, true);
612
+ if (left) merge(left, it);
613
+ }
614
+ for (const it of [...items].sort((a, b) => a.x - b.x)) {
615
+ if (gone.has(it) || !ends.get(it)?.trail) continue;
616
+ const right = neighbor(it, false);
617
+ if (right) merge(it, right);
618
+ }
619
+ const toc = items.filter((it) => !gone.has(it) && /\s\u2026\s\d{1,4}$/.test(it.text));
620
+ if (toc.length >= 2) {
621
+ for (const it of items) {
622
+ if (gone.has(it) || toc.includes(it) || !/^[\s.:\u00b7\u2026]*\d{1,4}$/.test(it.text)) continue;
623
+ const x2 = it.x + it.w;
624
+ if (toc.filter((t) => Math.abs(t.x + t.w - x2) <= Math.max(t.h, it.h)).length < 2) continue;
625
+ const left = neighbor(it, true);
626
+ if (!left || toc.includes(left)) continue;
627
+ left.text = left.text.replace(/[\s.:\u00b7\u2026]+$/, "");
628
+ it.text = it.text.replace(/^[\s.:\u00b7\u2026]+/, "");
629
+ merge(left, it);
630
+ }
631
+ }
632
+ return items.filter((it) => !gone.has(it));
633
+ }
332
634
  function restoreBulletItems(items) {
333
635
  for (const it of items) {
334
636
  if (it.text !== "O" && it.text !== "o") continue;
@@ -419,7 +721,8 @@ var DEFAULT_OCR_TUNING = Object.freeze({
419
721
  splitTall: true,
420
722
  minInkContrast: 35,
421
723
  postprocess: true,
422
- tightBoxes: true
724
+ tightBoxes: true,
725
+ splitLeaders: true
423
726
  });
424
727
  var DET_MIN_SIZE = 3;
425
728
  var DET_MAX_BOXES = 1e3;
@@ -427,6 +730,9 @@ var REC_MIN_WIDTH = 320;
427
730
  var REC_BATCH_MAX_PIXELS = 48 * 16e3;
428
731
  var TALL_RATIO = 1.5;
429
732
  var ROTATE_RATIO = 3;
733
+ var LEADER_MIN_DOTS = 4;
734
+ var LEADER_CONTEXT = 0.5;
735
+ var MIN_INK_RATIO = 0.01;
430
736
  var DET_MEAN = [0.485, 0.456, 0.406];
431
737
  var DET_STD = [0.229, 0.224, 0.225];
432
738
  var OcrEngine = class _OcrEngine {
@@ -489,11 +795,13 @@ var OcrEngine = class _OcrEngine {
489
795
  if (width < DET_MIN_SIZE || height < DET_MIN_SIZE) return [];
490
796
  const boxes = await this.detect(rgba, width, height, tuning);
491
797
  const jobs = [];
798
+ const joins = [];
492
799
  let group = 0;
493
800
  for (const b of boxes) {
494
801
  const gray = grayCrop(rgba, width, b);
495
802
  const ink = inkStats(gray);
496
803
  if (tuning.minInkContrast > 0 && ink.contrast < tuning.minInkContrast) continue;
804
+ if (tuning.minInkContrast > 0 && ink.inkRatio < MIN_INK_RATIO) continue;
497
805
  if (tuning.splitTall && b.h >= b.w * TALL_RATIO) {
498
806
  const bands = splitRowBands(gray, b.w, b.h, ink, 0.45);
499
807
  if (bands.length >= 2) {
@@ -506,6 +814,24 @@ var OcrEngine = class _OcrEngine {
506
814
  continue;
507
815
  }
508
816
  }
817
+ const leaders = tuning.splitLeaders ? leaderRuns(gray, b.w, b.h, ink, LEADER_MIN_DOTS) : [];
818
+ if (leaders.length) {
819
+ const join2 = joins.length;
820
+ joins.push({ box: b, parts: [], trailDots: false });
821
+ let x0 = 0, dots = false;
822
+ for (const [a, c] of [...leaders, [b.w, b.w]]) {
823
+ const bare = { x: b.x + x0, y: b.y, w: a - x0, h: b.h };
824
+ const end = c > a ? Math.min(c, a + Math.round(b.h * LEADER_CONTEXT)) : a;
825
+ x0 = c;
826
+ if (bare.w >= DET_MIN_SIZE && inkStats(grayCrop(rgba, width, bare)).contrast >= Math.max(1, tuning.minInkContrast)) {
827
+ jobs.push({ box: { ...bare, w: end - (bare.x - b.x) }, rot: 0, group: group++, join: join2, dotsBefore: dots, trimDots: end > a });
828
+ dots = false;
829
+ }
830
+ if (c > a) dots = true;
831
+ }
832
+ joins[join2].trailDots = dots;
833
+ continue;
834
+ }
509
835
  jobs.push({ box: b, rot: 0, group: group++ });
510
836
  }
511
837
  const results = await this.recognizeJobs(rgba, width, jobs, tuning.recBatch);
@@ -516,27 +842,50 @@ var OcrEngine = class _OcrEngine {
516
842
  const cur = best.get(job.group);
517
843
  if (!cur || r.confidence > cur.confidence) best.set(job.group, { job, ...r });
518
844
  });
519
- const items = [];
845
+ let items = [];
520
846
  for (const { job, text: raw, confidence } of best.values()) {
521
- const text = tuning.postprocess ? restoreSymbols(raw.trim()) : raw;
847
+ let text = tuning.postprocess ? restoreSymbols(raw.trim()) : raw;
522
848
  if (!text.trim()) continue;
849
+ if (tuning.postprocess && /^\d/.test(text) && job.rot === 0) {
850
+ const g = grayCrop(rgba, width, job.box);
851
+ const tri = leadingTriangle(g, job.box.w, job.box.h, inkStats(g));
852
+ if (tri) text = tri + text;
853
+ }
523
854
  if (tuning.postprocess && isDotFragment(text)) continue;
524
855
  if (confidence < tuning.textScore) {
525
856
  if (stats) stats.droppedLowConf++;
526
857
  continue;
527
858
  }
528
- let b = job.box;
529
- if (tuning.tightBoxes) {
530
- const gray = grayCrop(rgba, width, b);
531
- const t = inkBounds(gray, b.w, b.h, inkStats(gray));
532
- b = { x: b.x + t.x0, y: b.y + t.y0, w: t.x1 - t.x0, h: t.y1 - t.y0 };
859
+ if (job.join !== void 0) {
860
+ if (job.trimDots) text = text.replace(/[\s.:\u00b7\u2022\u2024\u2025\u2026\u2219\u22c5\u318d]+$/u, "");
861
+ if (text) joins[job.join].parts.push({ x: job.box.x, text, dotsBefore: job.dotsBefore === true, confidence });
862
+ continue;
533
863
  }
534
- items.push({ text, x: b.x, y: b.y, w: b.w, h: b.h, confidence });
864
+ items.push({ text, ...this.itemBox(rgba, width, job.box, tuning), confidence });
535
865
  }
866
+ const leaderEnds = /* @__PURE__ */ new Map();
867
+ for (const j of joins) {
868
+ if (!j.parts.length) continue;
869
+ j.parts.sort((a, b) => a.x - b.x);
870
+ let text = "";
871
+ for (const p of j.parts) text += (p.dotsBefore ? text ? " \u2026 " : "\u2026" : text ? " " : "") + p.text;
872
+ if (j.trailDots) text += " \u2026";
873
+ const item = { text, ...this.itemBox(rgba, width, j.box, tuning), confidence: Math.min(...j.parts.map((p) => p.confidence)) };
874
+ items.push(item);
875
+ leaderEnds.set(item, { lead: j.parts[0].dotsBefore, trail: j.trailDots });
876
+ }
877
+ if (leaderEnds.size) items = joinLeaderItems(items, leaderEnds);
536
878
  if (tuning.postprocess) restoreBulletItems(items);
537
879
  items.sort((a, b) => a.y - b.y || a.x - b.x);
538
880
  return items;
539
881
  }
882
+ /** 결과 좌표 — det 박스 그대로 또는 박스 안 잉크 외곽 (tightBoxes) */
883
+ itemBox(rgba, width, b, tuning) {
884
+ if (!tuning.tightBoxes) return b;
885
+ const gray = grayCrop(rgba, width, b);
886
+ const t = inkBounds(gray, b.w, b.h, inkStats(gray));
887
+ return { x: b.x + t.x0, y: b.y + t.y0, w: t.x1 - t.x0, h: t.y1 - t.y0 };
888
+ }
540
889
  // ─── det ─────────────────────────────────────────────
541
890
  async detect(rgba, width, height, tuning) {
542
891
  const ratio = tuning.detLongSide / Math.max(width, height);
@@ -802,7 +1151,7 @@ function rotateRgba(rgba, width, height, deg) {
802
1151
  // src/ocr/pdf-ocr.ts
803
1152
  var OCR_RENDER_SCALE = 3;
804
1153
  var PAGE_TIMEOUT_MS = 12e4;
805
- async function runPdfOcr(buffer, targets, mode, warnings, onProgress, detectTables = true) {
1154
+ async function runPdfOcr(buffer, targets, mode, warnings, onProgress, detectTables = true, vectorOps) {
806
1155
  const result = /* @__PURE__ */ new Map();
807
1156
  if (targets.size === 0) return result;
808
1157
  const pdfiumMod = await tryImport2(
@@ -828,7 +1177,7 @@ async function runPdfOcr(buffer, targets, mode, warnings, onProgress, detectTabl
828
1177
  onProgress?.(++done, targets.size);
829
1178
  try {
830
1179
  const blocks = await withTimeout(
831
- ocrOnePage(page, pageNo, mode, engine, warnings, detectTables),
1180
+ ocrOnePage(page, pageNo, mode, engine, warnings, detectTables, vectorOps?.get(pageNo)),
832
1181
  PAGE_TIMEOUT_MS,
833
1182
  `OCR \uD398\uC774\uC9C0 ${pageNo} \uD0C0\uC784\uC544\uC6C3 (${PAGE_TIMEOUT_MS / 1e3}\uCD08)`
834
1183
  );
@@ -847,7 +1196,7 @@ async function runPdfOcr(buffer, targets, mode, warnings, onProgress, detectTabl
847
1196
  }
848
1197
  return result;
849
1198
  }
850
- async function ocrOnePage(page, pageNo, mode, engine, warnings, detectTables) {
1199
+ async function ocrOnePage(page, pageNo, mode, engine, warnings, detectTables, vectorOps) {
851
1200
  const { originalWidth: pdfW, originalHeight: pdfH } = page.getOriginalSize();
852
1201
  const rendered = await page.render({
853
1202
  scale: OCR_RENDER_SCALE,
@@ -856,7 +1205,7 @@ async function ocrOnePage(page, pageNo, mode, engine, warnings, detectTables) {
856
1205
  const { data: bgra, width: rw, height: rh } = rendered;
857
1206
  const rgba = bgraToRgba(bgra);
858
1207
  if (mode === "builtin") {
859
- const { rgba: upright } = deskewPage(rgba, rw, rh);
1208
+ const upright = vectorOps ? rgba : deskewPage(rgba, rw, rh).rgba;
860
1209
  const stats = { droppedLowConf: 0 };
861
1210
  const items = await engine.recognizePage(upright, rw, rh, stats);
862
1211
  if (stats.droppedLowConf > 0) {
@@ -867,6 +1216,7 @@ async function ocrOnePage(page, pageNo, mode, engine, warnings, detectTables) {
867
1216
  });
868
1217
  }
869
1218
  const scale = rh / pdfH;
1219
+ if (vectorOps) return ocrItemsToBlocks(items, pageNo, pdfW, pdfH, scale, void 0, detectTables, vectorOps);
870
1220
  const ruling = detectRulingLines(upright, rw, rh, scale);
871
1221
  const extraLines = rulingToPdfLines(ruling, scale, pdfH);
872
1222
  return ocrItemsToBlocks(items, pageNo, pdfW, pdfH, scale, extraLines, detectTables);
@@ -885,7 +1235,7 @@ async function ocrOnePage(page, pageNo, mode, engine, warnings, detectTables) {
885
1235
  }
886
1236
  return [{ type: "paragraph", text: text.trim(), pageNumber: pageNo }];
887
1237
  }
888
- function ocrItemsToBlocks(items, pageNumber, pdfW, pdfH, scale, extraLines, detectTables = true) {
1238
+ function ocrItemsToBlocks(items, pageNumber, pdfW, pdfH, scale, extraLines, detectTables = true, opList = { fnArray: [], argsArray: [] }) {
889
1239
  const norm = items.map((it) => {
890
1240
  const h = it.h / scale;
891
1241
  return {
@@ -901,7 +1251,7 @@ function ocrItemsToBlocks(items, pageNumber, pdfW, pdfH, scale, extraLines, dete
901
1251
  isHidden: false
902
1252
  };
903
1253
  });
904
- return extractPageBlocksWithLines(norm, pageNumber, { fnArray: [], argsArray: [] }, pdfW, pdfH, extraLines, detectTables);
1254
+ return extractPageBlocksWithLines(norm, pageNumber, opList, pdfW, pdfH, extraLines, detectTables);
905
1255
  }
906
1256
  async function tryImport2(name, loader) {
907
1257
  try {
@@ -946,4 +1296,4 @@ export {
946
1296
  runPdfOcr,
947
1297
  ocrItemsToBlocks
948
1298
  };
949
- //# sourceMappingURL=chunk-VJHAUMCF.js.map
1299
+ //# sourceMappingURL=chunk-MG6DJEX4.js.map