kordoc 4.0.7 → 4.0.8

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 (111) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +823 -806
  3. package/dist/{-6HWEFXVV.js → -LE4RLXVA.js} +9 -9
  4. package/dist/{chunk-BKWHX3RC.js → chunk-2DZQF6YJ.js} +3 -3
  5. package/dist/chunk-2DZQF6YJ.js.map +1 -0
  6. package/dist/{chunk-6GBLFQMA.js → chunk-5RPYBC2Q.js} +1 -1
  7. package/dist/chunk-5RPYBC2Q.js.map +1 -0
  8. package/dist/{chunk-U25XGCNH.cjs → chunk-6XAAYAWL.cjs} +142 -3
  9. package/dist/chunk-6XAAYAWL.cjs.map +1 -0
  10. package/dist/{chunk-TJJTLM76.js → chunk-7S3M4N4E.js} +666 -742
  11. package/dist/chunk-7S3M4N4E.js.map +1 -0
  12. package/dist/{chunk-Q7EN4EUJ.js → chunk-BNU5QGIZ.js} +2 -2
  13. package/dist/chunk-BNU5QGIZ.js.map +1 -0
  14. package/dist/{chunk-NGSHDBQR.js → chunk-D35VBACN.js} +3 -3
  15. package/dist/chunk-D35VBACN.js.map +1 -0
  16. package/dist/{chunk-X34YWRL5.cjs → chunk-DCZVOIEO.cjs} +1 -1
  17. package/dist/chunk-DCZVOIEO.cjs.map +1 -0
  18. package/dist/{chunk-AIQ3ISQU.js → chunk-GE43BE46.js} +1 -1
  19. package/dist/chunk-GE43BE46.js.map +1 -0
  20. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  21. package/dist/{chunk-CNM75ZSX.js → chunk-HMUEU7D7.js} +2 -2
  22. package/dist/chunk-HMUEU7D7.js.map +1 -0
  23. package/dist/{chunk-CFQLK3LM.js → chunk-MEPHGCPQ.js} +1 -1
  24. package/dist/chunk-MEPHGCPQ.js.map +1 -0
  25. package/dist/{chunk-3TBUDJDE.js → chunk-MOL7MDBG.js} +1 -1
  26. package/dist/chunk-MOL7MDBG.js.map +1 -0
  27. package/dist/{chunk-5OKHAJ62.js → chunk-OQPILS7B.js} +142 -3
  28. package/dist/chunk-OQPILS7B.js.map +1 -0
  29. package/dist/{chunk-ONXVBURQ.js → chunk-RROH5WHO.js} +2 -2
  30. package/dist/chunk-RROH5WHO.js.map +1 -0
  31. package/dist/{chunk-2SN3CKME.js → chunk-UEIYETCQ.js} +142 -3
  32. package/dist/chunk-UEIYETCQ.js.map +1 -0
  33. package/dist/cli.js +18 -18
  34. package/dist/cli.js.map +1 -1
  35. package/dist/{detect-NTR2FUEG.js → detect-RI2MQ33K.js} +2 -2
  36. package/dist/{formula-ZYUDQHD3.cjs → formula-5NKVS2LR.cjs} +1 -1
  37. package/dist/formula-5NKVS2LR.cjs.map +1 -0
  38. package/dist/{formula-KOQV353G.js → formula-JCNF43NE.js} +1 -1
  39. package/dist/formula-JCNF43NE.js.map +1 -0
  40. package/dist/{formula-MEDGYQXS.js → formula-RXVSQPXI.js} +1 -1
  41. package/dist/formula-RXVSQPXI.js.map +1 -0
  42. package/dist/index.cjs +1018 -1094
  43. package/dist/index.cjs.map +1 -1
  44. package/dist/index.d.cts +1 -1
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.js +780 -856
  47. package/dist/index.js.map +1 -1
  48. package/dist/mcp.js +14 -14
  49. package/dist/mcp.js.map +1 -1
  50. package/dist/page-range-737B4EZW.js +8 -0
  51. package/dist/page-range-LNMXJU6W.js +7 -0
  52. package/dist/page-range-P7SDW6LR.cjs +8 -0
  53. package/dist/page-range-P7SDW6LR.cjs.map +1 -0
  54. package/dist/{parser-E6U5TNAU.cjs → parser-ITMU2WN5.cjs} +214 -38
  55. package/dist/parser-ITMU2WN5.cjs.map +1 -0
  56. package/dist/{parser-UGB3NIVH.js → parser-KMMUS73Q.js} +183 -7
  57. package/dist/parser-KMMUS73Q.js.map +1 -0
  58. package/dist/{parser-5EHWYJMC.js → parser-TCTCSBYZ.js} +185 -9
  59. package/dist/parser-TCTCSBYZ.js.map +1 -0
  60. package/dist/{profile-io-CAKRPQRD.js → profile-io-SLN4P76T.js} +3 -3
  61. package/dist/{provider-H4WWSPOV.js → provider-4ZJKV3DC.js} +1 -1
  62. package/dist/provider-4ZJKV3DC.js.map +1 -0
  63. package/dist/{provider-7H4CPZYS.js → provider-AKROB7WQ.js} +1 -1
  64. package/dist/provider-AKROB7WQ.js.map +1 -0
  65. package/dist/{provider-5K7O3Z2O.cjs → provider-G4C2V2PD.cjs} +1 -1
  66. package/dist/provider-G4C2V2PD.cjs.map +1 -0
  67. package/dist/render-25BT623I.js +10 -0
  68. package/dist/seal-R4TETA4C.js +10 -0
  69. package/dist/{setup-QSJ2INNS.js → setup-57FB3LSP.js} +1 -1
  70. package/dist/setup-57FB3LSP.js.map +1 -0
  71. package/dist/{watch-RMX427YR.js → watch-OHQWSVPE.js} +9 -9
  72. package/dist/watch-OHQWSVPE.js.map +1 -0
  73. package/package.json +97 -97
  74. package/dist/chunk-2SN3CKME.js.map +0 -1
  75. package/dist/chunk-3TBUDJDE.js.map +0 -1
  76. package/dist/chunk-5OKHAJ62.js.map +0 -1
  77. package/dist/chunk-6GBLFQMA.js.map +0 -1
  78. package/dist/chunk-AIQ3ISQU.js.map +0 -1
  79. package/dist/chunk-BKWHX3RC.js.map +0 -1
  80. package/dist/chunk-CFQLK3LM.js.map +0 -1
  81. package/dist/chunk-CNM75ZSX.js.map +0 -1
  82. package/dist/chunk-NGSHDBQR.js.map +0 -1
  83. package/dist/chunk-ONXVBURQ.js.map +0 -1
  84. package/dist/chunk-Q7EN4EUJ.js.map +0 -1
  85. package/dist/chunk-TJJTLM76.js.map +0 -1
  86. package/dist/chunk-U25XGCNH.cjs.map +0 -1
  87. package/dist/chunk-X34YWRL5.cjs.map +0 -1
  88. package/dist/formula-KOQV353G.js.map +0 -1
  89. package/dist/formula-MEDGYQXS.js.map +0 -1
  90. package/dist/formula-ZYUDQHD3.cjs.map +0 -1
  91. package/dist/page-range-CIRRJPXJ.js +0 -7
  92. package/dist/page-range-OF5I4PQY.js +0 -8
  93. package/dist/page-range-TPIRSA3J.cjs +0 -8
  94. package/dist/page-range-TPIRSA3J.cjs.map +0 -1
  95. package/dist/parser-5EHWYJMC.js.map +0 -1
  96. package/dist/parser-E6U5TNAU.cjs.map +0 -1
  97. package/dist/parser-UGB3NIVH.js.map +0 -1
  98. package/dist/provider-5K7O3Z2O.cjs.map +0 -1
  99. package/dist/provider-7H4CPZYS.js.map +0 -1
  100. package/dist/provider-H4WWSPOV.js.map +0 -1
  101. package/dist/render-P6663O4I.js +0 -10
  102. package/dist/seal-7PPTXKKV.js +0 -10
  103. package/dist/setup-QSJ2INNS.js.map +0 -1
  104. package/dist/watch-RMX427YR.js.map +0 -1
  105. /package/dist/{-6HWEFXVV.js.map → -LE4RLXVA.js.map} +0 -0
  106. /package/dist/{detect-NTR2FUEG.js.map → detect-RI2MQ33K.js.map} +0 -0
  107. /package/dist/{page-range-CIRRJPXJ.js.map → page-range-737B4EZW.js.map} +0 -0
  108. /package/dist/{page-range-OF5I4PQY.js.map → page-range-LNMXJU6W.js.map} +0 -0
  109. /package/dist/{profile-io-CAKRPQRD.js.map → profile-io-SLN4P76T.js.map} +0 -0
  110. /package/dist/{render-P6663O4I.js.map → render-25BT623I.js.map} +0 -0
  111. /package/dist/{seal-7PPTXKKV.js.map → seal-R4TETA4C.js.map} +0 -0
@@ -3,16 +3,17 @@ import {
3
3
  HEADING_RATIO_H1,
4
4
  HEADING_RATIO_H2,
5
5
  HEADING_RATIO_H3,
6
- blocksToMarkdown
7
- } from "./chunk-2SN3CKME.js";
6
+ blocksToMarkdown,
7
+ encodePng
8
+ } from "./chunk-UEIYETCQ.js";
8
9
  import {
9
10
  parsePageRange
10
- } from "./chunk-3TBUDJDE.js";
11
+ } from "./chunk-MOL7MDBG.js";
11
12
  import {
12
13
  KordocError,
13
14
  safeMax,
14
15
  safeMin
15
- } from "./chunk-CNM75ZSX.js";
16
+ } from "./chunk-HMUEU7D7.js";
16
17
 
17
18
  // src/pdf/line-extract.ts
18
19
  import { OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
@@ -1223,6 +1224,170 @@ function normalizeUndersegmentedTable(originalCells, colXs, items) {
1223
1224
  return rebuilt;
1224
1225
  }
1225
1226
 
1227
+ // src/pdf/image-extract.ts
1228
+ import { OPS as OPS3, ImageKind } from "pdfjs-dist/legacy/build/pdf.mjs";
1229
+ var IMAGE_RESOLVE_TIMEOUT_MS = 5e3;
1230
+ function resolveImgData(page, objId) {
1231
+ const store = objId.startsWith("g_") ? page.commonObjs : page.objs;
1232
+ return new Promise((resolve) => {
1233
+ let done = false;
1234
+ const timer = setTimeout(() => {
1235
+ if (!done) {
1236
+ done = true;
1237
+ resolve(null);
1238
+ }
1239
+ }, IMAGE_RESOLVE_TIMEOUT_MS);
1240
+ try {
1241
+ store.get(objId, (data) => {
1242
+ if (!done) {
1243
+ done = true;
1244
+ clearTimeout(timer);
1245
+ resolve(data ?? null);
1246
+ }
1247
+ });
1248
+ } catch {
1249
+ if (!done) {
1250
+ done = true;
1251
+ clearTimeout(timer);
1252
+ resolve(null);
1253
+ }
1254
+ }
1255
+ });
1256
+ }
1257
+ var MIN_DIM = 8;
1258
+ var MAX_PIXELS = 36e6;
1259
+ var MAX_IMAGES_PER_DOC = 200;
1260
+ var MAX_TOTAL_IMAGE_BYTES = 128 * 1024 * 1024;
1261
+ function createPdfImageState() {
1262
+ return { imageIndex: 0, totalBytes: 0, seen: /* @__PURE__ */ new Map(), capWarned: false };
1263
+ }
1264
+ function fnv1a(data) {
1265
+ let h = 2166136261;
1266
+ for (let i = 0; i < data.length; i++) {
1267
+ h ^= data[i];
1268
+ h = Math.imul(h, 16777619);
1269
+ }
1270
+ return h >>> 0;
1271
+ }
1272
+ function toRgba(img) {
1273
+ const { width: w, height: h, kind, data } = img;
1274
+ if (!data || !w || !h) return null;
1275
+ const rgba = new Uint8Array(w * h * 4);
1276
+ if (kind === ImageKind.RGBA_32BPP) {
1277
+ if (data.length < w * h * 4) return null;
1278
+ rgba.set(data.subarray(0, w * h * 4));
1279
+ return rgba;
1280
+ }
1281
+ if (kind === ImageKind.RGB_24BPP) {
1282
+ if (data.length < w * h * 3) return null;
1283
+ for (let i = 0, s = 0, d = 0; i < w * h; i++, s += 3, d += 4) {
1284
+ rgba[d] = data[s];
1285
+ rgba[d + 1] = data[s + 1];
1286
+ rgba[d + 2] = data[s + 2];
1287
+ rgba[d + 3] = 255;
1288
+ }
1289
+ return rgba;
1290
+ }
1291
+ if (kind === ImageKind.GRAYSCALE_1BPP) {
1292
+ const stride = w + 7 >> 3;
1293
+ if (data.length < stride * h) return null;
1294
+ for (let y = 0; y < h; y++) {
1295
+ for (let x = 0; x < w; x++) {
1296
+ const bit = data[y * stride + (x >> 3)] >> 7 - (x & 7) & 1;
1297
+ const v = bit ? 255 : 0;
1298
+ const d = (y * w + x) * 4;
1299
+ rgba[d] = v;
1300
+ rgba[d + 1] = v;
1301
+ rgba[d + 2] = v;
1302
+ rgba[d + 3] = 255;
1303
+ }
1304
+ }
1305
+ return rgba;
1306
+ }
1307
+ return null;
1308
+ }
1309
+ async function extractPageImages(page, fnArray, argsArray, pageNumber, state, warnings) {
1310
+ const blocks = [];
1311
+ const images = [];
1312
+ const pageSeenIds = /* @__PURE__ */ new Set();
1313
+ for (let i = 0; i < fnArray.length; i++) {
1314
+ const op = fnArray[i];
1315
+ let imgData = null;
1316
+ let dedupeId = null;
1317
+ if (op === OPS3.paintImageXObject || op === OPS3.paintImageXObjectRepeat) {
1318
+ const objId = argsArray[i]?.[0];
1319
+ if (typeof objId !== "string" || pageSeenIds.has(objId)) continue;
1320
+ pageSeenIds.add(objId);
1321
+ dedupeId = objId;
1322
+ imgData = await resolveImgData(page, objId);
1323
+ } else if (op === OPS3.paintInlineImageXObject) {
1324
+ imgData = argsArray[i]?.[0];
1325
+ } else {
1326
+ continue;
1327
+ }
1328
+ if (!imgData?.data || !imgData.width || !imgData.height) continue;
1329
+ const { width: w, height: h } = imgData;
1330
+ if (w < MIN_DIM || h < MIN_DIM) continue;
1331
+ if (w * h > MAX_PIXELS) {
1332
+ warnings.push({ page: pageNumber, message: `\uC774\uBBF8\uC9C0 \uD06C\uAE30 \uCD08\uACFC\uB85C \uCD94\uCD9C \uC0DD\uB7B5 (${w}\xD7${h})`, code: "SKIPPED_IMAGE" });
1333
+ continue;
1334
+ }
1335
+ const hash = `${w}x${h}k${imgData.kind ?? "?"}h${fnv1a(imgData.data)}${dedupeId ? "" : "inline"}`;
1336
+ if (state.seen.has(hash)) continue;
1337
+ if (state.imageIndex >= MAX_IMAGES_PER_DOC || state.totalBytes >= MAX_TOTAL_IMAGE_BYTES) {
1338
+ if (!state.capWarned) {
1339
+ state.capWarned = true;
1340
+ warnings.push({ page: pageNumber, message: `\uC774\uBBF8\uC9C0 \uCD94\uCD9C \uC0C1\uD55C \uB3C4\uB2EC (${MAX_IMAGES_PER_DOC}\uAC1C/128MB) \u2014 \uC774\uD6C4 \uC774\uBBF8\uC9C0 \uC0DD\uB7B5`, code: "SKIPPED_IMAGE" });
1341
+ }
1342
+ continue;
1343
+ }
1344
+ const rgba = toRgba(imgData);
1345
+ if (!rgba) continue;
1346
+ const png = encodePng(w, h, rgba);
1347
+ state.imageIndex++;
1348
+ state.totalBytes += png.length;
1349
+ const filename = `image_${String(state.imageIndex).padStart(3, "0")}.png`;
1350
+ state.seen.set(hash, filename);
1351
+ images.push({ filename, data: png, mimeType: "image/png" });
1352
+ blocks.push({ type: "image", text: filename, pageNumber });
1353
+ }
1354
+ return { blocks, images };
1355
+ }
1356
+ function injectPageImageBlocks(blocks, pageImages) {
1357
+ if (pageImages.size === 0) return;
1358
+ const lastIndexForPage = /* @__PURE__ */ new Map();
1359
+ for (let i = 0; i < blocks.length; i++) {
1360
+ const p = blocks[i].pageNumber;
1361
+ if (p !== void 0) lastIndexForPage.set(p, i);
1362
+ }
1363
+ const pageAtIndex = /* @__PURE__ */ new Map();
1364
+ for (const [p, last] of lastIndexForPage) pageAtIndex.set(last, p);
1365
+ const result = [];
1366
+ const injected = /* @__PURE__ */ new Set();
1367
+ for (let i = 0; i < blocks.length; i++) {
1368
+ result.push(blocks[i]);
1369
+ const p = pageAtIndex.get(i);
1370
+ if (p !== void 0 && pageImages.has(p)) {
1371
+ result.push(...pageImages.get(p));
1372
+ injected.add(p);
1373
+ }
1374
+ }
1375
+ for (const p of [...pageImages.keys()].sort((a, b) => a - b)) {
1376
+ if (injected.has(p)) continue;
1377
+ let at = result.length;
1378
+ for (let i = 0; i < result.length; i++) {
1379
+ const bp = result[i].pageNumber;
1380
+ if (bp !== void 0 && bp > p) {
1381
+ at = i;
1382
+ break;
1383
+ }
1384
+ }
1385
+ result.splice(at, 0, ...pageImages.get(p));
1386
+ }
1387
+ blocks.length = 0;
1388
+ blocks.push(...result);
1389
+ }
1390
+
1226
1391
  // src/pdf/quality.ts
1227
1392
  var RARE_JONG = /* @__PURE__ */ new Set([3, 5, 6, 9, 10, 11, 12, 13, 14, 15, 18, 24, 25, 26]);
1228
1393
  var MOJIBAKE_MIN_HANGUL = 30;
@@ -3390,7 +3555,7 @@ function mergeKoreanLines(text) {
3390
3555
 
3391
3556
  // src/pdf/formula-ocr.ts
3392
3557
  async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
3393
- const formulaMod = await import("./formula-KOQV353G.js");
3558
+ const formulaMod = await import("./formula-JCNF43NE.js");
3394
3559
  const { FormulaPipeline, ensureFormulaModels } = formulaMod;
3395
3560
  await ensureFormulaModels((p) => {
3396
3561
  if (p.phase === "download" && p.total) {
@@ -3585,6 +3750,9 @@ async function parsePdfDocument(buffer, options) {
3585
3750
  const pageHeights = /* @__PURE__ */ new Map();
3586
3751
  const pagesWithLargeImage = /* @__PURE__ */ new Set();
3587
3752
  const skippedImagePages = /* @__PURE__ */ new Map();
3753
+ const imageState = createPdfImageState();
3754
+ const extractedImages = [];
3755
+ const pageImageBlocks = /* @__PURE__ */ new Map();
3588
3756
  let parsedPages = 0;
3589
3757
  for (let i = 1; i <= effectivePageCount; i++) {
3590
3758
  if (pageFilter && !pageFilter.has(i)) continue;
@@ -3622,6 +3790,12 @@ async function parsePdfDocument(buffer, options) {
3622
3790
  }
3623
3791
  const pageBlocks = extractPageBlocksWithLines(visible, i, opList, viewport.width, viewport.height);
3624
3792
  for (const b of pageBlocks) blocks.push(b);
3793
+ try {
3794
+ const { blocks: imgBlocks, images: pageImages } = await extractPageImages(page, opList.fnArray, opList.argsArray, i, imageState, warnings);
3795
+ if (imgBlocks.length > 0) pageImageBlocks.set(i, imgBlocks);
3796
+ extractedImages.push(...pageImages);
3797
+ } catch {
3798
+ }
3625
3799
  let pageText = "";
3626
3800
  for (const b of pageBlocks) {
3627
3801
  const t = b.text || "";
@@ -3643,11 +3817,11 @@ async function parsePdfDocument(buffer, options) {
3643
3817
  if (totalChars / Math.max(parsedPageCount, 1) < 10) {
3644
3818
  if (options?.ocr) {
3645
3819
  try {
3646
- const { ocrPages } = await import("./provider-7H4CPZYS.js");
3820
+ const { ocrPages } = await import("./provider-AKROB7WQ.js");
3647
3821
  const ocrBlocks = await ocrPages(doc, options.ocr, pageFilter, effectivePageCount);
3648
3822
  if (ocrBlocks.length > 0) {
3649
3823
  const ocrMarkdown = ocrBlocks.map((b) => b.text || "").filter(Boolean).join("\n\n");
3650
- return { markdown: ocrMarkdown, blocks: ocrBlocks, metadata, warnings, isImageBased: true, pageQuality, qualitySummary: summarizeDocumentQuality(pageQuality) };
3824
+ return { markdown: ocrMarkdown, blocks: ocrBlocks, metadata, warnings, isImageBased: true, pageQuality, qualitySummary: summarizeDocumentQuality(pageQuality), images: extractedImages.length > 0 ? extractedImages : void 0 };
3651
3825
  }
3652
3826
  } catch {
3653
3827
  }
@@ -3684,6 +3858,7 @@ async function parsePdfDocument(buffer, options) {
3684
3858
  }
3685
3859
  }
3686
3860
  mergeCrossPageTables(blocks);
3861
+ injectPageImageBlocks(blocks, pageImageBlocks);
3687
3862
  if (options?.formulaOcr && formulaBuffer) {
3688
3863
  try {
3689
3864
  await applyFormulaOcr(formulaBuffer, blocks, pageFilter, effectivePageCount, warnings, options.onProgress);
@@ -3712,7 +3887,8 @@ async function parsePdfDocument(buffer, options) {
3712
3887
  warnings: warnings.length > 0 ? warnings : void 0,
3713
3888
  isImageBased: isImageBased || void 0,
3714
3889
  pageQuality,
3715
- qualitySummary: summarizeDocumentQuality(pageQuality)
3890
+ qualitySummary: summarizeDocumentQuality(pageQuality),
3891
+ images: extractedImages.length > 0 ? extractedImages : void 0
3716
3892
  };
3717
3893
  } finally {
3718
3894
  await doc.destroy().catch(() => {
@@ -3762,4 +3938,4 @@ export {
3762
3938
  parsePdfDocument,
3763
3939
  removeHeaderFooterBlocks
3764
3940
  };
3765
- //# sourceMappingURL=parser-5EHWYJMC.js.map
3941
+ //# sourceMappingURL=parser-TCTCSBYZ.js.map