kordoc 3.17.0 → 3.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +5 -0
  2. package/dist/{-3KPDRR3A.js → -OUCPI6B3.js} +9 -7
  3. package/dist/{chunk-NKICMZ7F.js → chunk-4YEZTZAR.js} +2 -2
  4. package/dist/{chunk-EL2Y4BL2.cjs → chunk-5HDBLRVP.cjs} +45 -9
  5. package/dist/chunk-5HDBLRVP.cjs.map +1 -0
  6. package/dist/{chunk-HVEEFHN7.js → chunk-6Y4KKPC3.js} +2 -2
  7. package/dist/{chunk-E6NQWOFQ.js → chunk-GIXXV52X.js} +39 -3
  8. package/dist/chunk-GIXXV52X.js.map +1 -0
  9. package/dist/{chunk-VUS6LRVY.js → chunk-PWHM3KAA.js} +535 -83
  10. package/dist/chunk-PWHM3KAA.js.map +1 -0
  11. package/dist/{chunk-TDIDUEBH.js → chunk-VP34RO24.js} +3 -3
  12. package/dist/{chunk-WHMNPQXW.js → chunk-YWIYGXLI.js} +39 -3
  13. package/dist/chunk-YWIYGXLI.js.map +1 -0
  14. package/dist/{chunk-SADQWCWR.js → chunk-ZTUQYITH.js} +3 -3
  15. package/dist/cli.js +18 -15
  16. package/dist/cli.js.map +1 -1
  17. package/dist/index.cjs +862 -411
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +118 -1
  20. package/dist/index.d.ts +118 -1
  21. package/dist/index.js +592 -141
  22. package/dist/index.js.map +1 -1
  23. package/dist/mcp.js +22 -10
  24. package/dist/mcp.js.map +1 -1
  25. package/dist/{parser-LHBXIKXX.js → parser-5D6BQYTX.js} +2 -2
  26. package/dist/{parser-CYJMOXUR.js → parser-NZAE7PBE.js} +3 -3
  27. package/dist/{parser-I5GC4QQ5.cjs → parser-S34YR2SH.cjs} +14 -14
  28. package/dist/{parser-I5GC4QQ5.cjs.map → parser-S34YR2SH.cjs.map} +1 -1
  29. package/dist/render-HRAW7ASR.js +10 -0
  30. package/dist/seal-CK64CXWO.js +10 -0
  31. package/dist/{watch-VT7BSLNI.js → watch-2EFXBRYK.js} +7 -7
  32. package/package.json +1 -1
  33. package/dist/chunk-E6NQWOFQ.js.map +0 -1
  34. package/dist/chunk-EL2Y4BL2.cjs.map +0 -1
  35. package/dist/chunk-VUS6LRVY.js.map +0 -1
  36. package/dist/chunk-WHMNPQXW.js.map +0 -1
  37. package/dist/render-HY7KKYPV.js +0 -10
  38. package/dist/seal-ITGYHENO.js +0 -10
  39. /package/dist/{-3KPDRR3A.js.map → -OUCPI6B3.js.map} +0 -0
  40. /package/dist/{chunk-NKICMZ7F.js.map → chunk-4YEZTZAR.js.map} +0 -0
  41. /package/dist/{chunk-HVEEFHN7.js.map → chunk-6Y4KKPC3.js.map} +0 -0
  42. /package/dist/{chunk-TDIDUEBH.js.map → chunk-VP34RO24.js.map} +0 -0
  43. /package/dist/{chunk-SADQWCWR.js.map → chunk-ZTUQYITH.js.map} +0 -0
  44. /package/dist/{parser-LHBXIKXX.js.map → parser-5D6BQYTX.js.map} +0 -0
  45. /package/dist/{parser-CYJMOXUR.js.map → parser-NZAE7PBE.js.map} +0 -0
  46. /package/dist/{render-HY7KKYPV.js.map → render-HRAW7ASR.js.map} +0 -0
  47. /package/dist/{seal-ITGYHENO.js.map → seal-CK64CXWO.js.map} +0 -0
  48. /package/dist/{watch-VT7BSLNI.js.map → watch-2EFXBRYK.js.map} +0 -0
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  classifyError,
12
12
  compareSectionPaths,
13
13
  convertTableToText,
14
+ dedupeRunningHeaders,
14
15
  flattenLayoutTables,
15
16
  isPathTraversal,
16
17
  mapPuaText,
@@ -19,7 +20,7 @@ import {
19
20
  sanitizeHref,
20
21
  stripDtd,
21
22
  toArrayBuffer
22
- } from "./chunk-E6NQWOFQ.js";
23
+ } from "./chunk-GIXXV52X.js";
23
24
  import {
24
25
  parsePageRange
25
26
  } from "./chunk-GE43BE46.js";
@@ -2527,11 +2528,11 @@ function formatRoman(n, upper) {
2527
2528
  const values = [1e3, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
2528
2529
  const symbols = upper ? ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] : ["m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i"];
2529
2530
  let result = "";
2530
- let num3 = n;
2531
+ let num4 = n;
2531
2532
  for (let i = 0; i < values.length; i++) {
2532
- while (num3 >= values[i]) {
2533
+ while (num4 >= values[i]) {
2533
2534
  result += symbols[i];
2534
- num3 -= values[i];
2535
+ num4 -= values[i];
2535
2536
  }
2536
2537
  }
2537
2538
  return result;
@@ -2539,11 +2540,11 @@ function formatRoman(n, upper) {
2539
2540
  function formatLatin(n, upper) {
2540
2541
  if (n <= 0) return "";
2541
2542
  let result = "";
2542
- let num3 = n;
2543
- while (num3 > 0) {
2544
- num3--;
2545
- result = String.fromCharCode((upper ? 65 : 97) + num3 % 26) + result;
2546
- num3 = Math.floor(num3 / 26);
2543
+ let num4 = n;
2544
+ while (num4 > 0) {
2545
+ num4--;
2546
+ result = String.fromCharCode((upper ? 65 : 97) + num4 % 26) + result;
2547
+ num4 = Math.floor(num4 / 26);
2547
2548
  }
2548
2549
  return result;
2549
2550
  }
@@ -2551,15 +2552,15 @@ function formatEastAsianNumber(n, digits, units, zero) {
2551
2552
  if (n === 0) return zero;
2552
2553
  if (n < 0 || n > 99999) return String(n);
2553
2554
  let result = "";
2554
- let num3 = n;
2555
+ let num4 = n;
2555
2556
  let unit = 0;
2556
- while (num3 > 0) {
2557
- const d = num3 % 10;
2557
+ while (num4 > 0) {
2558
+ const d = num4 % 10;
2558
2559
  if (d > 0) {
2559
2560
  const digitStr = d === 1 && unit > 0 ? "" : digits[d];
2560
2561
  result = digitStr + units[unit] + result;
2561
2562
  }
2562
- num3 = Math.floor(num3 / 10);
2563
+ num4 = Math.floor(num4 / 10);
2563
2564
  unit++;
2564
2565
  }
2565
2566
  return result;
@@ -2606,8 +2607,8 @@ function expandNumberingFormat(formatStr, counters, numbering) {
2606
2607
  const idx = levelRef - 1;
2607
2608
  const counterVal = counters[idx] ?? 0;
2608
2609
  const start = numbering.startNumbers[idx] ?? 1;
2609
- const num3 = counterVal > 0 ? start - 1 + counterVal : start;
2610
- result += formatNumber(num3, headFormatToNumFmt(numbering.numberFormats[idx] ?? 0));
2610
+ const num4 = counterVal > 0 ? start - 1 + counterVal : start;
2611
+ result += formatNumber(num4, headFormatToNumFmt(numbering.numberFormats[idx] ?? 0));
2611
2612
  i += 2;
2612
2613
  continue;
2613
2614
  }
@@ -2756,6 +2757,141 @@ function extractHwp5ImagesLenient(lcfb, blocks, warnings) {
2756
2757
  return resolveImageBlocks(binDataMap, blocks, warnings);
2757
2758
  }
2758
2759
 
2760
+ // src/image/transcode.ts
2761
+ import { deflateSync } from "zlib";
2762
+ var CRC_TABLE = (() => {
2763
+ const table = new Uint32Array(256);
2764
+ for (let n = 0; n < 256; n++) {
2765
+ let c = n;
2766
+ for (let k = 0; k < 8; k++) {
2767
+ c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
2768
+ }
2769
+ table[n] = c >>> 0;
2770
+ }
2771
+ return table;
2772
+ })();
2773
+ function crc32(bytes) {
2774
+ let c = 4294967295;
2775
+ for (let i = 0; i < bytes.length; i++) {
2776
+ c = CRC_TABLE[(c ^ bytes[i]) & 255] ^ c >>> 8;
2777
+ }
2778
+ return (c ^ 4294967295) >>> 0;
2779
+ }
2780
+ var BI_RGB = 0;
2781
+ var MAX_DIM = 32767;
2782
+ var MAX_PIXELS = 64e6;
2783
+ function bmpToPng(bmp) {
2784
+ if (bmp.length < 54) return null;
2785
+ if (bmp[0] !== 66 || bmp[1] !== 77) return null;
2786
+ const dv = new DataView(bmp.buffer, bmp.byteOffset, bmp.byteLength);
2787
+ const dataOffset = dv.getUint32(10, true);
2788
+ const headerSize = dv.getUint32(14, true);
2789
+ if (headerSize < 40) return null;
2790
+ const width = dv.getInt32(18, true);
2791
+ const rawHeight = dv.getInt32(22, true);
2792
+ const bitCount = dv.getUint16(28, true);
2793
+ const compression = dv.getUint32(30, true);
2794
+ if (compression !== BI_RGB) return null;
2795
+ if (bitCount !== 24 && bitCount !== 32) return null;
2796
+ if (width <= 0 || rawHeight === 0) return null;
2797
+ if (width > MAX_DIM || Math.abs(rawHeight) > MAX_DIM) return null;
2798
+ const topDown = rawHeight < 0;
2799
+ const height = Math.abs(rawHeight);
2800
+ if (width * height > MAX_PIXELS) return null;
2801
+ const bytesPerPixel = bitCount >> 3;
2802
+ const rowStride = width * bytesPerPixel + 3 & ~3;
2803
+ if (dataOffset + rowStride * height > bmp.length) return null;
2804
+ const rgba = new Uint8Array(width * height * 4);
2805
+ let anyAlpha = 0;
2806
+ for (let y = 0; y < height; y++) {
2807
+ const srcRow = topDown ? y : height - 1 - y;
2808
+ let src = dataOffset + srcRow * rowStride;
2809
+ let dst = y * width * 4;
2810
+ for (let x = 0; x < width; x++) {
2811
+ rgba[dst] = bmp[src + 2];
2812
+ rgba[dst + 1] = bmp[src + 1];
2813
+ rgba[dst + 2] = bmp[src];
2814
+ const a = bitCount === 32 ? bmp[src + 3] : 255;
2815
+ rgba[dst + 3] = a;
2816
+ anyAlpha |= a;
2817
+ src += bytesPerPixel;
2818
+ dst += 4;
2819
+ }
2820
+ }
2821
+ if (bitCount === 32 && anyAlpha === 0) {
2822
+ for (let i = 3; i < rgba.length; i += 4) rgba[i] = 255;
2823
+ }
2824
+ return encodePng(width, height, rgba);
2825
+ }
2826
+ var PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71, 13, 10, 26, 10);
2827
+ function chunk(type, data) {
2828
+ const body = new Uint8Array(4 + data.length);
2829
+ body[0] = type.charCodeAt(0);
2830
+ body[1] = type.charCodeAt(1);
2831
+ body[2] = type.charCodeAt(2);
2832
+ body[3] = type.charCodeAt(3);
2833
+ body.set(data, 4);
2834
+ const out = new Uint8Array(8 + data.length + 4);
2835
+ const dv = new DataView(out.buffer);
2836
+ dv.setUint32(0, data.length, false);
2837
+ out.set(body, 4);
2838
+ dv.setUint32(8 + data.length, crc32(body), false);
2839
+ return out;
2840
+ }
2841
+ function encodePng(width, height, rgba) {
2842
+ const ihdr = new Uint8Array(13);
2843
+ const iv = new DataView(ihdr.buffer);
2844
+ iv.setUint32(0, width, false);
2845
+ iv.setUint32(4, height, false);
2846
+ ihdr[8] = 8;
2847
+ ihdr[9] = 6;
2848
+ const stride = width * 4;
2849
+ const raw = new Uint8Array((stride + 1) * height);
2850
+ for (let y = 0; y < height; y++) {
2851
+ const rowStart = y * (stride + 1);
2852
+ raw[rowStart] = 0;
2853
+ raw.set(rgba.subarray(y * stride, y * stride + stride), rowStart + 1);
2854
+ }
2855
+ const idat = deflateSync(raw);
2856
+ const ihdrChunk = chunk("IHDR", ihdr);
2857
+ const idatChunk = chunk("IDAT", idat);
2858
+ const iendChunk = chunk("IEND", new Uint8Array(0));
2859
+ const out = new Uint8Array(PNG_SIGNATURE.length + ihdrChunk.length + idatChunk.length + iendChunk.length);
2860
+ let o = 0;
2861
+ out.set(PNG_SIGNATURE, o);
2862
+ o += PNG_SIGNATURE.length;
2863
+ out.set(ihdrChunk, o);
2864
+ o += ihdrChunk.length;
2865
+ out.set(idatChunk, o);
2866
+ o += idatChunk.length;
2867
+ out.set(iendChunk, o);
2868
+ return out;
2869
+ }
2870
+ var MAX_INLINE_MD_BYTES = 4 * 1024 * 1024;
2871
+ function escapeRegExp(s) {
2872
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2873
+ }
2874
+ function inlineImagesIntoMarkdown(markdown, images, opts) {
2875
+ const compress = opts?.compress !== false;
2876
+ let out = markdown;
2877
+ for (const img of images) {
2878
+ let bytes = img.data;
2879
+ let mime = img.mimeType;
2880
+ if (compress && mime === "image/bmp") {
2881
+ const png = bmpToPng(img.data);
2882
+ if (png) {
2883
+ bytes = png;
2884
+ mime = "image/png";
2885
+ }
2886
+ }
2887
+ const base64 = Buffer.from(bytes).toString("base64");
2888
+ const dataUri = `data:${mime};base64,${base64}`;
2889
+ const re = new RegExp(`!\\[image\\]\\((?:images/)?${escapeRegExp(img.filename)}\\)`, "g");
2890
+ out = out.replace(re, () => `![image](${dataUri})`);
2891
+ }
2892
+ return out;
2893
+ }
2894
+
2759
2895
  // src/hwp5/aes.ts
2760
2896
  var S_BOX = new Uint8Array([
2761
2897
  99,
@@ -3804,12 +3940,25 @@ function parseHwp5Document(buffer, options) {
3804
3940
  }
3805
3941
  const blocks = [...doc.headerBlocks, ...bodyBlocks, ...doc.footerBlocks];
3806
3942
  const images = cfb ? extractHwp5Images(cfb.FileIndex, blocks, warnings) : extractHwp5ImagesLenient(lenientCfb, blocks, warnings);
3807
- const flatBlocks = flattenLayoutTables(blocks);
3943
+ let flatBlocks = flattenLayoutTables(blocks);
3944
+ if (options?.dedupeRunningHeaders) {
3945
+ const deduped = dedupeRunningHeaders(flatBlocks);
3946
+ const removed = flatBlocks.length - deduped.length;
3947
+ if (removed > 0) warnings.push({ message: `\uBC18\uBCF5 \uB7EC\uB2DD \uD5E4\uB354 ${removed}\uAC1C \uC81C\uAC70`, code: "HIDDEN_TEXT_FILTERED" });
3948
+ flatBlocks = deduped;
3949
+ }
3808
3950
  if (docInfo) {
3809
3951
  detectHwp5Headings(flatBlocks, docInfo);
3810
3952
  }
3811
3953
  const outline = flatBlocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
3812
- const markdown = blocksToMarkdown(flatBlocks);
3954
+ let markdown = blocksToMarkdown(flatBlocks);
3955
+ if (options?.inlineImages && images.length > 0) {
3956
+ try {
3957
+ markdown = inlineImagesIntoMarkdown(markdown, images, { compress: true });
3958
+ } catch (inlineErr) {
3959
+ warnings.push({ message: `\uC774\uBBF8\uC9C0 \uC778\uB77C\uC778 \uC2E4\uD328 \u2014 \uC6D0\uBCF8 \uD30C\uC77C \uCC38\uC870\uB85C \uD3F4\uBC31: ${inlineErr instanceof Error ? inlineErr.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`, code: "SKIPPED_IMAGE" });
3960
+ }
3961
+ }
3813
3962
  return { markdown, blocks: flatBlocks, metadata, outline: outline.length > 0 ? outline : void 0, warnings: warnings.length > 0 ? warnings : void 0, images: images.length > 0 ? images : void 0 };
3814
3963
  }
3815
3964
  function parseDocInfoStream(cfb, compressed) {
@@ -4175,11 +4324,11 @@ function applyCtrlEffect(ctrl, records, ctx) {
4175
4324
  const attr = ctrl.data.readUInt32LE(4);
4176
4325
  const type = attr & 15;
4177
4326
  const format = attr >>> 4 & 255;
4178
- const num3 = ctx.doc.autoCounters.get(type) ?? 1;
4179
- ctx.doc.autoCounters.set(type, num3 + 1);
4327
+ const num4 = ctx.doc.autoCounters.get(type) ?? 1;
4328
+ ctx.doc.autoCounters.set(type, num4 + 1);
4180
4329
  const prefix = ctrl.data.length >= 14 ? wcharAt(ctrl.data, 12) : "";
4181
4330
  const suffix = ctrl.data.length >= 16 ? wcharAt(ctrl.data, 14) : "";
4182
- ctrl.inlineText = `${prefix}${formatNumber(num3, shapeFormatToNumFmt(format))}${suffix}`;
4331
+ ctrl.inlineText = `${prefix}${formatNumber(num4, shapeFormatToNumFmt(format))}${suffix}`;
4183
4332
  }
4184
4333
  return;
4185
4334
  }
@@ -4187,8 +4336,8 @@ function applyCtrlEffect(ctrl, records, ctx) {
4187
4336
  if (ctrl.data.length >= 10) {
4188
4337
  const attr = ctrl.data.readUInt32LE(4);
4189
4338
  const type = attr & 15;
4190
- const num3 = ctrl.data.readUInt16LE(8);
4191
- if (num3 > 0) ctx.doc.autoCounters.set(type, num3);
4339
+ const num4 = ctrl.data.readUInt16LE(8);
4340
+ if (num4 > 0) ctx.doc.autoCounters.set(type, num4);
4192
4341
  }
4193
4342
  return;
4194
4343
  }
@@ -4250,7 +4399,7 @@ function blocksPlainText(blocks, sep) {
4250
4399
  return parts.join(sep).trim();
4251
4400
  }
4252
4401
  function applyNoteEffect(ctrl, records, ctx, autoType) {
4253
- const num3 = ctx.doc.autoCounters.get(autoType) ?? 1;
4402
+ const num4 = ctx.doc.autoCounters.get(autoType) ?? 1;
4254
4403
  let before = "";
4255
4404
  let after = "";
4256
4405
  let shape = 0;
@@ -4261,11 +4410,11 @@ function applyNoteEffect(ctrl, records, ctx, autoType) {
4261
4410
  if (ctrl.data.length >= 16) {
4262
4411
  shape = ctrl.data.readUInt32LE(12) & 255;
4263
4412
  }
4264
- const formatted = formatNumber(num3, shapeFormatToNumFmt(shape));
4413
+ const formatted = formatNumber(num4, shapeFormatToNumFmt(shape));
4265
4414
  const marker = before || after ? `${before}${formatted}${after}` : `${formatted})`;
4266
4415
  const content = blocksPlainText(parseListHeaderParagraphs(ctrl, records, ctx), " ");
4267
- if ((ctx.doc.autoCounters.get(autoType) ?? 1) <= num3) {
4268
- ctx.doc.autoCounters.set(autoType, num3 + 1);
4416
+ if ((ctx.doc.autoCounters.get(autoType) ?? 1) <= num4) {
4417
+ ctx.doc.autoCounters.set(autoType, num4 + 1);
4269
4418
  }
4270
4419
  ctrl.inlineText = marker;
4271
4420
  if (content) ctrl.footnote = content.startsWith(marker) ? content : `${marker} ${content}`;
@@ -16803,9 +16952,9 @@ var MAX_ROWS2 = 1e4;
16803
16952
  var MAX_COLS2 = 200;
16804
16953
  function cleanNumericValue(raw) {
16805
16954
  if (!/^-?\d+\.\d+$/.test(raw)) return raw;
16806
- const num3 = parseFloat(raw);
16807
- if (!isFinite(num3)) return raw;
16808
- const cleaned = parseFloat(num3.toPrecision(15)).toString();
16955
+ const num4 = parseFloat(raw);
16956
+ if (!isFinite(num4)) return raw;
16957
+ const cleaned = parseFloat(num4.toPrecision(15)).toString();
16809
16958
  return cleaned;
16810
16959
  }
16811
16960
  function parseCellRef(ref) {
@@ -17148,17 +17297,17 @@ function decodeRk(rk) {
17148
17297
  const fDiv100 = (rk & 1) !== 0;
17149
17298
  const fInt = (rk & 2) !== 0;
17150
17299
  const val30 = rk >> 2;
17151
- let num3;
17300
+ let num4;
17152
17301
  if (fInt) {
17153
- num3 = val30;
17302
+ num4 = val30;
17154
17303
  } else {
17155
17304
  const high32 = (rk & 4294967292) >>> 0;
17156
17305
  const buf = Buffer.alloc(8);
17157
17306
  buf.writeUInt32LE(0, 0);
17158
17307
  buf.writeUInt32LE(high32, 4);
17159
- num3 = buf.readDoubleLE(0);
17308
+ num4 = buf.readDoubleLE(0);
17160
17309
  }
17161
- return fDiv100 ? num3 / 100 : num3;
17310
+ return fDiv100 ? num4 / 100 : num4;
17162
17311
  }
17163
17312
  function decodeMulRk(data) {
17164
17313
  if (data.length < 6) return null;
@@ -17858,9 +18007,9 @@ function nodeToLatex(el) {
17858
18007
  case "f": {
17859
18008
  const n = firstKid(el, "num");
17860
18009
  const d = firstKid(el, "den");
17861
- const num3 = n ? childrenToLatex(n) : "";
18010
+ const num4 = n ? childrenToLatex(n) : "";
17862
18011
  const den = d ? childrenToLatex(d) : "";
17863
- return "\\frac" + grp(num3) + grp(den);
18012
+ return "\\frac" + grp(num4) + grp(den);
17864
18013
  }
17865
18014
  // 첨자
17866
18015
  case "sSup": {
@@ -20155,7 +20304,7 @@ function parseCentralDirectory(buf) {
20155
20304
  }
20156
20305
  return { entries, cdOffset, cdSize, eocdOffset };
20157
20306
  }
20158
- var CRC_TABLE = (() => {
20307
+ var CRC_TABLE2 = (() => {
20159
20308
  const table = new Uint32Array(256);
20160
20309
  for (let n = 0; n < 256; n++) {
20161
20310
  let c = n;
@@ -20164,10 +20313,10 @@ var CRC_TABLE = (() => {
20164
20313
  }
20165
20314
  return table;
20166
20315
  })();
20167
- function crc32(data) {
20316
+ function crc322(data) {
20168
20317
  let crc = 4294967295;
20169
20318
  for (let i = 0; i < data.length; i++) {
20170
- crc = CRC_TABLE[(crc ^ data[i]) & 255] ^ crc >>> 8;
20319
+ crc = CRC_TABLE2[(crc ^ data[i]) & 255] ^ crc >>> 8;
20171
20320
  }
20172
20321
  return (crc ^ 4294967295) >>> 0;
20173
20322
  }
@@ -20206,7 +20355,7 @@ function patchZipEntries(original, replacements, additions) {
20206
20355
  const hview = new DataView(header.buffer, header.byteOffset, header.byteLength);
20207
20356
  const method = e.method;
20208
20357
  const compData = method === 0 ? newData : new Uint8Array(deflateRawSync(newData));
20209
- const crc = crc32(newData);
20358
+ const crc = crc322(newData);
20210
20359
  const flags = e.flags & ~8;
20211
20360
  hview.setUint16(6, flags, true);
20212
20361
  hview.setUint32(14, crc, true);
@@ -20224,7 +20373,7 @@ function patchZipEntries(original, replacements, additions) {
20224
20373
  const deflated = new Uint8Array(deflateRawSync(data));
20225
20374
  const method = deflated.length < data.length ? 8 : 0;
20226
20375
  const compData = method === 8 ? deflated : data;
20227
- const crc = crc32(data);
20376
+ const crc = crc322(data);
20228
20377
  const header = new Uint8Array(30 + nameBytes.length);
20229
20378
  const hv = new DataView(header.buffer);
20230
20379
  hv.setUint32(0, LOCAL_SIG, true);
@@ -21253,7 +21402,7 @@ function generateManifest(chartParts = []) {
21253
21402
  </opf:spine>
21254
21403
  </opf:package>`;
21255
21404
  }
21256
- function buildCharProperties(theme, gongmun, ratioVariants = []) {
21405
+ function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls = []) {
21257
21406
  let body = 1e3, code = 900, h1 = 1800, h2 = 1400, h3 = 1200, h4 = 1100;
21258
21407
  if (gongmun) {
21259
21408
  body = gongmun.bodyHeight;
@@ -21285,6 +21434,7 @@ function buildCharProperties(theme, gongmun, ratioVariants = []) {
21285
21434
  charPr(rows.length + 3, body, true, true, 0, theme.body, r)
21286
21435
  );
21287
21436
  }
21437
+ rows.push(...extraCharPrXmls);
21288
21438
  return `<hh:charProperties itemCnt="${rows.length}">
21289
21439
  ${rows.join("\n")}
21290
21440
  </hh:charProperties>`;
@@ -21338,9 +21488,9 @@ ${heads}
21338
21488
  </hh:numbering>
21339
21489
  </hh:numberings>`;
21340
21490
  }
21341
- function generateHeaderXml(theme, gongmun, ratioVariants = []) {
21491
+ function generateHeaderXml(theme, gongmun, ratioVariants = [], remap = null) {
21342
21492
  const bodyFace = gongmun?.bodyFont === "gothic" ? "\uB9D1\uC740 \uACE0\uB515" : "\uD568\uCD08\uB86C\uBC14\uD0D5";
21343
- const charPropsXml = buildCharProperties(theme, gongmun, ratioVariants);
21493
+ const charPropsXml = buildCharProperties(theme, gongmun, ratioVariants, remap?.charPrXmls ?? []);
21344
21494
  const paraPropsXml = buildParaProperties(gongmun);
21345
21495
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
21346
21496
  <hh:head xmlns:hh="${NS_HEAD}" xmlns:hp="${NS_PARA}" xmlns:hc="${NS_CORE}" version="1.4" secCnt="1">
@@ -21395,7 +21545,7 @@ function generateHeaderXml(theme, gongmun, ratioVariants = []) {
21395
21545
  </hh:font>
21396
21546
  </hh:fontface>
21397
21547
  </hh:fontfaces>
21398
- <hh:borderFills itemCnt="2">
21548
+ <hh:borderFills itemCnt="${2 + (remap?.borderFillXmls.length ?? 0)}">
21399
21549
  <hh:borderFill id="1" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">
21400
21550
  <hh:slash type="NONE" Crooked="0" isCounter="0"/>
21401
21551
  <hh:backSlash type="NONE" Crooked="0" isCounter="0"/>
@@ -21411,7 +21561,7 @@ function generateHeaderXml(theme, gongmun, ratioVariants = []) {
21411
21561
  <hh:rightBorder type="SOLID" width="0.12 mm" color="#000000"/>
21412
21562
  <hh:topBorder type="SOLID" width="0.12 mm" color="#000000"/>
21413
21563
  <hh:bottomBorder type="SOLID" width="0.12 mm" color="#000000"/>
21414
- </hh:borderFill>
21564
+ </hh:borderFill>${remap && remap.borderFillXmls.length ? "\n" + remap.borderFillXmls.join("\n") : ""}
21415
21565
  </hh:borderFills>
21416
21566
  ${charPropsXml}
21417
21567
  <hh:tabProperties itemCnt="0"/>
@@ -22143,23 +22293,47 @@ var tableIdCounter = TABLE_ID_BASE;
22143
22293
  function nextTableId() {
22144
22294
  return ++tableIdCounter;
22145
22295
  }
22146
- function generateTable(rows, theme) {
22296
+ var warnedTables = /* @__PURE__ */ new Set();
22297
+ function warnProfileMismatch(tblId, tp, rowCnt, colCnt) {
22298
+ if (warnedTables.has(tblId)) return;
22299
+ warnedTables.add(tblId);
22300
+ console.warn(`[kordoc] format profile: table ${tp.rows}x${tp.cols} vs document ${rowCnt}x${colCnt} \u2014 \uD504\uB85C\uD544 \uBB34\uC2DC`);
22301
+ }
22302
+ function usableProfile(tp, tblId, rowCnt, colCnt) {
22303
+ if (!tp) return null;
22304
+ if (tp.rows !== rowCnt || tp.cols !== colCnt) {
22305
+ warnProfileMismatch(tblId, tp, rowCnt, colCnt);
22306
+ return null;
22307
+ }
22308
+ return tp;
22309
+ }
22310
+ function resolveColWidths(tp, colCnt, fallbackTotal) {
22311
+ if (tp?.colWidths && tp.colWidths.length === colCnt) return tp.colWidths;
22312
+ const w = tp?.width ? Math.floor(tp.width / colCnt) : Math.floor(fallbackTotal / colCnt);
22313
+ return Array(colCnt).fill(w);
22314
+ }
22315
+ function generateTable(rows, theme, tp = null) {
22147
22316
  const rowCnt = rows.length;
22148
22317
  const colCnt = Math.max(...rows.map((r) => r.length), 1);
22149
- const cellW = Math.floor(44e3 / colCnt);
22150
22318
  const cellH = 1500;
22151
- const tblW = cellW * colCnt;
22152
- const tblH = cellH * rowCnt;
22153
22319
  const tblId = nextTableId();
22320
+ const prof = usableProfile(tp, tblId, rowCnt, colCnt);
22321
+ const colW = resolveColWidths(prof, colCnt, 44e3);
22322
+ const tblW = colW.reduce((a, b) => a + b, 0);
22323
+ const tblH = cellH * rowCnt;
22154
22324
  const useHeaderStyle = theme.tableHeader !== theme.body || theme.tableHeaderBold;
22155
22325
  const trElements = rows.map((row, rowIdx) => {
22156
22326
  const cells = row.length < colCnt ? [...row, ...Array(colCnt - row.length).fill("")] : row;
22157
22327
  const isHeaderRow = rowIdx === 0;
22158
22328
  const headerCharPr = isHeaderRow && useHeaderStyle ? CHAR_TABLE_HEADER : CHAR_NORMAL;
22159
22329
  const tdElements = cells.map((cell, colIdx) => {
22160
- const runs = generateRuns(cell, headerCharPr);
22330
+ const k = `${rowIdx},${colIdx}`;
22331
+ const bf = prof?.cellBf.get(k) ?? 2;
22332
+ const ch = prof?.cellChar.get(k) ?? headerCharPr;
22333
+ const h = prof?.cellH.get(k) ?? cellH;
22334
+ const runs = generateRuns(cell, ch);
22161
22335
  const p = `<hp:p paraPrIDRef="0" styleIDRef="0">${runs}</hp:p>`;
22162
- return `<hp:tc name="" header="${isHeaderRow ? 1 : 0}" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="2"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${p}</hp:subList><hp:cellAddr colAddr="${colIdx}" rowAddr="${rowIdx}"/><hp:cellSpan colSpan="1" rowSpan="1"/><hp:cellSz width="${cellW}" height="${cellH}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
22336
+ return `<hp:tc name="" header="${isHeaderRow ? 1 : 0}" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="${bf}"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${p}</hp:subList><hp:cellAddr colAddr="${colIdx}" rowAddr="${rowIdx}"/><hp:cellSpan colSpan="1" rowSpan="1"/><hp:cellSz width="${colW[colIdx]}" height="${h}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
22163
22337
  }).join("");
22164
22338
  return `<hp:tr>${tdElements}</hp:tr>`;
22165
22339
  }).join("");
@@ -22190,35 +22364,42 @@ function layoutHtmlRows(rows) {
22190
22364
  function unescapeHtml(s) {
22191
22365
  return s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&amp;/g, "&");
22192
22366
  }
22193
- function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3) {
22367
+ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, tp = null) {
22194
22368
  const rows = parseHtmlTable(rawHtml);
22195
22369
  if (!rows || rows.length === 0) return null;
22196
22370
  const { placed, rowCnt, colCnt } = layoutHtmlRows(rows);
22197
22371
  if (rowCnt === 0 || colCnt === 0) return null;
22198
- const colW = Math.floor(totalWidth / colCnt);
22199
22372
  const cellH = 1500;
22200
- const tblW = colW * colCnt;
22201
22373
  const tblId = nextTableId();
22374
+ const prof = usableProfile(tp, tblId, rowCnt, colCnt);
22375
+ const colW = resolveColWidths(prof, colCnt, totalWidth);
22376
+ const tblW = colW.reduce((a, b) => a + b, 0);
22202
22377
  const useHeaderStyle = theme.tableHeader !== theme.body || theme.tableHeaderBold;
22378
+ const spanW = (c, colSpan) => colW.slice(c, c + colSpan).reduce((a, b) => a + b, 0);
22203
22379
  const tcXmls = placed.map((cell) => {
22380
+ const k = `${cell.r},${cell.c}`;
22381
+ const bf = prof?.cellBf.get(k) ?? 2;
22204
22382
  const headerCharPr = cell.isHeader && useHeaderStyle ? CHAR_TABLE_HEADER : CHAR_NORMAL;
22383
+ const ch = prof?.cellChar.get(k) ?? headerCharPr;
22205
22384
  const { lines } = htmlCellInnerToLines(cell.inner);
22206
22385
  const paras = lines.map(
22207
- (line) => `<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="${headerCharPr}"><hp:t>${escapeXml(unescapeHtml(line))}</hp:t></hp:run></hp:p>`
22386
+ (line) => `<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="${ch}"><hp:t>${escapeXml(unescapeHtml(line))}</hp:t></hp:run></hp:p>`
22208
22387
  );
22388
+ const cellW = spanW(cell.c, cell.colSpan);
22209
22389
  let nestedH = 0;
22210
22390
  for (const nested of extractTopLevelTables(cell.inner)) {
22211
- const nestedXml = generateHtmlTableXml(nested, theme, Math.max(colW * cell.colSpan - 1020, 4e3));
22391
+ const nestedXml = generateHtmlTableXml(nested, theme, Math.max(cellW - 1020, 4e3));
22212
22392
  if (nestedXml) {
22213
22393
  paras.push(`<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="0">${nestedXml}</hp:run></hp:p>`);
22214
22394
  nestedH += (nested.match(/<tr[\s>]/gi) ?? []).length * cellH + 300;
22215
22395
  }
22216
22396
  }
22217
22397
  if (paras.length === 0) {
22218
- paras.push(`<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="${headerCharPr}"><hp:t></hp:t></hp:run></hp:p>`);
22398
+ paras.push(`<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="${ch}"><hp:t></hp:t></hp:run></hp:p>`);
22219
22399
  }
22220
- const cellHeight = Math.max(cellH * cell.rowSpan, Math.max(lines.length, 1) * 800 + nestedH);
22221
- return `<hp:tc name="" header="${cell.isHeader ? 1 : 0}" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="2"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${paras.join("")}</hp:subList><hp:cellAddr colAddr="${cell.c}" rowAddr="${cell.r}"/><hp:cellSpan colSpan="${cell.colSpan}" rowSpan="${cell.rowSpan}"/><hp:cellSz width="${colW * cell.colSpan}" height="${cellHeight}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
22400
+ const contentH = Math.max(cellH * cell.rowSpan, Math.max(lines.length, 1) * 800 + nestedH);
22401
+ const cellHeight = Math.max(prof?.cellH.get(k) ?? 0, contentH);
22402
+ return `<hp:tc name="" header="${cell.isHeader ? 1 : 0}" hasMargin="0" protect="0" editable="1" dirty="0" borderFillIDRef="${bf}"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0">${paras.join("")}</hp:subList><hp:cellAddr colAddr="${cell.c}" rowAddr="${cell.r}"/><hp:cellSpan colSpan="${cell.colSpan}" rowSpan="${cell.rowSpan}"/><hp:cellSz width="${cellW}" height="${cellHeight}"/><hp:cellMargin left="141" right="141" top="141" bottom="141"/></hp:tc>`;
22222
22403
  });
22223
22404
  const trXmls = [];
22224
22405
  for (let r = 0; r < rowCnt; r++) {
@@ -22384,9 +22565,9 @@ function readCommand(input, idx, depth) {
22384
22565
  const command = name.value;
22385
22566
  if (command === "\\") return { value: "#", next: name.next };
22386
22567
  if (command === "frac") {
22387
- const num3 = readGroupOrToken(input, name.next, depth);
22388
- const den = readGroupOrToken(input, num3.next, depth);
22389
- return { value: `{${num3.value}} over {${den.value}}`, next: den.next };
22568
+ const num4 = readGroupOrToken(input, name.next, depth);
22569
+ const den = readGroupOrToken(input, num4.next, depth);
22570
+ return { value: `{${num4.value}} over {${den.value}}`, next: den.next };
22390
22571
  }
22391
22572
  if (command === "sqrt") {
22392
22573
  let cursor = skipSpaces(input, name.next);
@@ -22517,9 +22698,10 @@ function generateSecPr(gongmun) {
22517
22698
  } : { top: 8504, bottom: 4252, left: 5670, right: 4252, header: 2835, footer: 2835 };
22518
22699
  return `<hp:secPr textDirection="HORIZONTAL" spaceColumns="1134" tabStop="8000" outlineShapeIDRef="1" memoShapeIDRef="0" textVerticalWidthHead="0" masterPageCnt="0"><hp:grid lineGrid="0" charGrid="0" wonggojiFormat="0"/><hp:startNum pageStartsOn="BOTH" page="0" pic="0" tbl="0" equation="0"/><hp:visibility hideFirstHeader="0" hideFirstFooter="0" hideFirstMasterPage="0" border="SHOW_ALL" fill="SHOW_ALL" hideFirstPageNum="0" hideFirstEmptyLine="0" showLineNumber="0"/><hp:pagePr landscape="WIDELY" width="59528" height="84188" gutterType="LEFT_ONLY"><hp:margin header="${m.header}" footer="${m.footer}" gutter="0" left="${m.left}" right="${m.right}" top="${m.top}" bottom="${m.bottom}"/></hp:pagePr><hp:footNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="-1" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="283" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="EACH_COLUMN" beneathText="0"/></hp:footNotePr><hp:endNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="14692344" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="0" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="END_OF_DOCUMENT" beneathText="0"/></hp:endNotePr></hp:secPr>`;
22519
22700
  }
22520
- function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null) {
22701
+ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null, remap = null) {
22521
22702
  const paraXmls = [];
22522
22703
  let isFirst = true;
22704
+ let tableSeq = 0;
22523
22705
  const orderedCounters = {};
22524
22706
  let prevWasOrdered = false;
22525
22707
  for (let blockIdx = 0; blockIdx < blocks.length; blockIdx++) {
@@ -22627,11 +22809,12 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22627
22809
  paraXmls.push(`<hp:p paraPrIDRef="0" styleIDRef="0">${secRun}</hp:p>`);
22628
22810
  isFirst = false;
22629
22811
  }
22630
- xml = generateTable(block.rows, theme);
22812
+ xml = generateTable(block.rows, theme, remap?.tables.get(tableSeq) ?? null);
22813
+ tableSeq++;
22631
22814
  }
22632
22815
  break;
22633
22816
  case "html_table": {
22634
- const tbl = generateHtmlTableXml(block.text || "", theme);
22817
+ const tbl = generateHtmlTableXml(block.text || "", theme, 44e3, remap?.tables.get(tableSeq) ?? null);
22635
22818
  if (tbl) {
22636
22819
  if (isFirst) {
22637
22820
  const secRun = `<hp:run charPrIDRef="0">${generateSecPr(gongmun)}<hp:t></hp:t></hp:run>`;
@@ -22639,6 +22822,7 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22639
22822
  isFirst = false;
22640
22823
  }
22641
22824
  xml = `<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="0">${tbl}</hp:run></hp:p>`;
22825
+ tableSeq++;
22642
22826
  } else {
22643
22827
  const plain = (block.text || "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
22644
22828
  xml = plain ? generateParagraph(plain) : "";
@@ -22665,6 +22849,93 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22665
22849
  </hs:sec>`;
22666
22850
  }
22667
22851
 
22852
+ // src/hwpx/gen-profile.ts
22853
+ function parseHu(s) {
22854
+ if (s == null) return void 0;
22855
+ const n = parseInt(String(s).trim(), 10);
22856
+ return Number.isFinite(n) ? n : void 0;
22857
+ }
22858
+ function edgeXml(tag, d) {
22859
+ return d ? `<hh:${tag} type="${d.type}" width="${d.width}" color="${d.color}"/>` : `<hh:${tag} type="NONE" width="0.1 mm" color="#000000"/>`;
22860
+ }
22861
+ function borderFillDefToXml(id, def) {
22862
+ const fill = def.fill?.faceColor ? `<hh:fillBrush><hh:winBrush faceColor="${def.fill.faceColor}" hatchColor="#000000" alpha="0"/></hh:fillBrush>` : "";
22863
+ return ` <hh:borderFill id="${id}" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">
22864
+ <hh:slash type="NONE" Crooked="0" isCounter="0"/>
22865
+ <hh:backSlash type="NONE" Crooked="0" isCounter="0"/>
22866
+ ${edgeXml("leftBorder", def.leftBorder)}
22867
+ ${edgeXml("rightBorder", def.rightBorder)}
22868
+ ${edgeXml("topBorder", def.topBorder)}
22869
+ ${edgeXml("bottomBorder", def.bottomBorder)}${fill ? `
22870
+ ${fill}` : ""}
22871
+ </hh:borderFill>`;
22872
+ }
22873
+ function profileCharPrXml(id, def) {
22874
+ const height = parseHu(def.height_hwpunit) ?? 1e3;
22875
+ const color = def.textColor ?? "#000000";
22876
+ const font = def.fontRef_hangul != null ? parseInt(def.fontRef_hangul, 10) || 0 : 0;
22877
+ const boldAttr = def.bold ? ` bold="1"` : "";
22878
+ const italicAttr = def.italic ? ` italic="1"` : "";
22879
+ const underline = def.underline ? `
22880
+ <hh:underline type="BOTTOM" shape="SOLID" color="${color}"/>` : "";
22881
+ return ` <hh:charPr id="${id}" height="${height}" textColor="${color}" shadeColor="none" useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="1"${boldAttr}${italicAttr}>
22882
+ <hh:fontRef hangul="${font}" latin="${font}" hanja="${font}" japanese="${font}" other="${font}" symbol="${font}" user="${font}"/>
22883
+ <hh:ratio hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
22884
+ <hh:spacing hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>
22885
+ <hh:relSz hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
22886
+ <hh:offset hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>${underline}
22887
+ </hh:charPr>`;
22888
+ }
22889
+ function buildProfileRemap(profile, charPrBase, borderFillBase = 3) {
22890
+ const remap = { borderFillXmls: [], charPrXmls: [], tables: /* @__PURE__ */ new Map() };
22891
+ let bfNext = borderFillBase;
22892
+ let charNext = charPrBase;
22893
+ for (const t of profile.tables) {
22894
+ const localBf = {};
22895
+ for (const [key, def] of Object.entries(t.used_border_fills ?? {})) {
22896
+ const gid = bfNext++;
22897
+ remap.borderFillXmls.push(borderFillDefToXml(gid, def));
22898
+ localBf[key] = gid;
22899
+ }
22900
+ const localChar = {};
22901
+ for (const [key, def] of Object.entries(t.used_char_prs ?? {})) {
22902
+ const gid = charNext++;
22903
+ remap.charPrXmls.push(profileCharPrXml(gid, def));
22904
+ localChar[key] = gid;
22905
+ }
22906
+ let colWidths;
22907
+ if (t.col_widths_hwpunit && t.col_widths_hwpunit.length === t.cols) {
22908
+ const parsed = t.col_widths_hwpunit.map(parseHu);
22909
+ if (parsed.every((n) => n != null)) colWidths = parsed;
22910
+ }
22911
+ const tr = {
22912
+ rows: t.rows,
22913
+ cols: t.cols,
22914
+ width: parseHu(t.width_hwpunit),
22915
+ colWidths,
22916
+ cellBf: /* @__PURE__ */ new Map(),
22917
+ cellChar: /* @__PURE__ */ new Map(),
22918
+ cellH: /* @__PURE__ */ new Map()
22919
+ };
22920
+ for (const cell of t.cells) {
22921
+ const k = `${cell.row},${cell.col}`;
22922
+ if (cell.borderFillIDRef != null && cell.borderFillIDRef in localBf) {
22923
+ tr.cellBf.set(k, localBf[cell.borderFillIDRef]);
22924
+ }
22925
+ if (cell.charPrIDRef != null && cell.charPrIDRef in localChar) {
22926
+ tr.cellChar.set(k, localChar[cell.charPrIDRef]);
22927
+ }
22928
+ const h = parseHu(cell.height_hwpunit);
22929
+ if (h != null) tr.cellH.set(k, h);
22930
+ }
22931
+ remap.tables.set(t.table_index, tr);
22932
+ }
22933
+ return remap;
22934
+ }
22935
+ function profileCharPrBase(ratioVariantCount) {
22936
+ return CHAR_VARIANT_BASE + ratioVariantCount * 4;
22937
+ }
22938
+
22668
22939
  // src/hwpx/generator.ts
22669
22940
  async function markdownToHwpx(markdown, options) {
22670
22941
  const theme = resolveTheme(options?.theme);
@@ -22672,13 +22943,14 @@ async function markdownToHwpx(markdown, options) {
22672
22943
  const blocks = parseMarkdownToBlocks(markdown);
22673
22944
  const gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null;
22674
22945
  const fit = gongmun && gongmunList ? computeGongmunFitPlan(blocks, gongmun, gongmunList) : null;
22946
+ const remap = options?.profile ? buildProfileRemap(options.profile, profileCharPrBase(fit?.variants?.length ?? 0)) : null;
22675
22947
  const chartParts = [];
22676
- const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts);
22948
+ const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, remap);
22677
22949
  const zip = new JSZip7();
22678
22950
  zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
22679
22951
  zip.file("META-INF/container.xml", generateContainerXml());
22680
22952
  zip.file("Contents/content.hpf", generateManifest(chartParts));
22681
- zip.file("Contents/header.xml", generateHeaderXml(theme, gongmun, fit?.variants ?? []));
22953
+ zip.file("Contents/header.xml", generateHeaderXml(theme, gongmun, fit?.variants ?? [], remap));
22682
22954
  zip.file("Contents/section0.xml", sectionXml);
22683
22955
  for (const part of chartParts) zip.file(part.name, part.xml);
22684
22956
  zip.file("Preview/PrvText.txt", buildPrvText(blocks));
@@ -23310,8 +23582,186 @@ async function placeSealHwpx(hwpxBuffer, ops) {
23310
23582
  };
23311
23583
  }
23312
23584
 
23313
- // src/roundtrip/patcher.ts
23585
+ // src/hwpx/extract-profile.ts
23314
23586
  import JSZip9 from "jszip";
23587
+ function elemsByLocal(root, name) {
23588
+ const all = root.getElementsByTagName("*");
23589
+ const out = [];
23590
+ for (let i = 0; i < all.length; i++) {
23591
+ const el = all[i];
23592
+ const tag = (el.tagName || el.localName || "").replace(/^[^:]+:/, "");
23593
+ if (tag === name) out.push(el);
23594
+ }
23595
+ return out;
23596
+ }
23597
+ function borderDefOf(el) {
23598
+ if (!el) return void 0;
23599
+ const type = el.getAttribute("type") || "NONE";
23600
+ const width = el.getAttribute("width") || "0.1 mm";
23601
+ const color = el.getAttribute("color") || "#000000";
23602
+ return { type, width, color };
23603
+ }
23604
+ function parseBorderFills(headerDoc) {
23605
+ const map = /* @__PURE__ */ new Map();
23606
+ for (const bf of elemsByLocal(headerDoc, "borderFill")) {
23607
+ const id = bf.getAttribute("id");
23608
+ if (!id) continue;
23609
+ const def = {
23610
+ leftBorder: borderDefOf(findChildByLocalName(bf, "leftBorder")),
23611
+ rightBorder: borderDefOf(findChildByLocalName(bf, "rightBorder")),
23612
+ topBorder: borderDefOf(findChildByLocalName(bf, "topBorder")),
23613
+ bottomBorder: borderDefOf(findChildByLocalName(bf, "bottomBorder"))
23614
+ };
23615
+ const fillBrush = findChildByLocalName(bf, "fillBrush");
23616
+ const winBrush = fillBrush ? findChildByLocalName(fillBrush, "winBrush") : null;
23617
+ const face = winBrush?.getAttribute("faceColor");
23618
+ if (face && face !== "none") def.fill = { faceColor: face };
23619
+ map.set(id, def);
23620
+ }
23621
+ return map;
23622
+ }
23623
+ function parseCharPrs(headerDoc) {
23624
+ const map = /* @__PURE__ */ new Map();
23625
+ for (const cp of elemsByLocal(headerDoc, "charPr")) {
23626
+ const id = cp.getAttribute("id");
23627
+ if (!id) continue;
23628
+ const def = {};
23629
+ const h = cp.getAttribute("height");
23630
+ if (h) def.height_hwpunit = h;
23631
+ const color = cp.getAttribute("textColor");
23632
+ if (color) def.textColor = color;
23633
+ if (cp.getAttribute("bold") === "1") def.bold = true;
23634
+ if (cp.getAttribute("italic") === "1") def.italic = true;
23635
+ if (findChildByLocalName(cp, "underline")) def.underline = true;
23636
+ const fontRef = findChildByLocalName(cp, "fontRef");
23637
+ const hangul = fontRef?.getAttribute("hangul");
23638
+ if (hangul) def.fontRef_hangul = hangul;
23639
+ map.set(id, def);
23640
+ }
23641
+ return map;
23642
+ }
23643
+ function isTopLevelTable(tbl) {
23644
+ let p = tbl.parentNode;
23645
+ while (p) {
23646
+ const tag = (p.tagName || p.localName || "").replace(/^[^:]+:/, "");
23647
+ if (tag === "tbl") return false;
23648
+ p = p.parentNode;
23649
+ }
23650
+ return true;
23651
+ }
23652
+ function num(s) {
23653
+ if (s == null) return void 0;
23654
+ const n = parseInt(s, 10);
23655
+ return Number.isFinite(n) ? n : void 0;
23656
+ }
23657
+ function parseTable3(tbl, tableIndex, borderFills, charPrs) {
23658
+ const rows = num(tbl.getAttribute("rowCnt")) ?? 0;
23659
+ const cols = num(tbl.getAttribute("colCnt")) ?? 0;
23660
+ const sz = findChildByLocalName(tbl, "sz");
23661
+ const width = sz?.getAttribute("width") || void 0;
23662
+ const cells = [];
23663
+ const usedBf = /* @__PURE__ */ new Set();
23664
+ const usedCp = /* @__PURE__ */ new Set();
23665
+ const colWidths = new Array(cols).fill(void 0);
23666
+ for (const tc of elemsByLocal(tbl, "tc")) {
23667
+ if (nearestTable(tc) !== tbl) continue;
23668
+ const addr = findChildByLocalName(tc, "cellAddr");
23669
+ const span = findChildByLocalName(tc, "cellSpan");
23670
+ const csz = findChildByLocalName(tc, "cellSz");
23671
+ const row = num(addr?.getAttribute("rowAddr")) ?? 0;
23672
+ const col = num(addr?.getAttribute("colAddr")) ?? 0;
23673
+ const colSpan = num(span?.getAttribute("colSpan")) ?? 1;
23674
+ const rowSpan = num(span?.getAttribute("rowSpan")) ?? 1;
23675
+ const bfId = tc.getAttribute("borderFillIDRef") || void 0;
23676
+ const cpId = firstRunCharPr(tc);
23677
+ const cell = { row, col, rowSpan, colSpan };
23678
+ const w = csz?.getAttribute("width");
23679
+ const hh = csz?.getAttribute("height");
23680
+ if (w) cell.width_hwpunit = w;
23681
+ if (hh) cell.height_hwpunit = hh;
23682
+ if (bfId) {
23683
+ cell.borderFillIDRef = bfId;
23684
+ usedBf.add(bfId);
23685
+ }
23686
+ if (cpId) {
23687
+ cell.charPrIDRef = cpId;
23688
+ usedCp.add(cpId);
23689
+ }
23690
+ cells.push(cell);
23691
+ if (row === 0 && colSpan === 1 && col < cols && w) colWidths[col] = w;
23692
+ }
23693
+ const table = {
23694
+ table_index: tableIndex,
23695
+ rows,
23696
+ cols,
23697
+ cells,
23698
+ used_border_fills: pick(borderFills, usedBf)
23699
+ };
23700
+ if (width) table.width_hwpunit = width;
23701
+ if (colWidths.every((w) => w != null)) table.col_widths_hwpunit = colWidths;
23702
+ const cp = pick(charPrs, usedCp);
23703
+ if (Object.keys(cp).length) table.used_char_prs = cp;
23704
+ return table;
23705
+ }
23706
+ function nearestTable(tc) {
23707
+ let p = tc.parentNode;
23708
+ while (p) {
23709
+ const tag = (p.tagName || p.localName || "").replace(/^[^:]+:/, "");
23710
+ if (tag === "tbl") return p;
23711
+ p = p.parentNode;
23712
+ }
23713
+ return null;
23714
+ }
23715
+ function firstRunCharPr(tc) {
23716
+ for (const run of elemsByLocal(tc, "run")) {
23717
+ if (nearestCell(run) !== tc) continue;
23718
+ const id = run.getAttribute("charPrIDRef");
23719
+ if (id) return id;
23720
+ }
23721
+ return void 0;
23722
+ }
23723
+ function nearestCell(el) {
23724
+ let p = el.parentNode;
23725
+ while (p) {
23726
+ const tag = (p.tagName || p.localName || "").replace(/^[^:]+:/, "");
23727
+ if (tag === "tc") return p;
23728
+ p = p.parentNode;
23729
+ }
23730
+ return null;
23731
+ }
23732
+ function pick(map, keys) {
23733
+ const out = {};
23734
+ for (const k of keys) {
23735
+ const v = map.get(k);
23736
+ if (v !== void 0) out[k] = v;
23737
+ }
23738
+ return out;
23739
+ }
23740
+ async function hwpxToProfile(input) {
23741
+ const buf = input instanceof ArrayBuffer ? input : toArrayBuffer(input);
23742
+ const zip = await JSZip9.loadAsync(buf);
23743
+ const parser = createXmlParser();
23744
+ const headerFile = zip.file("Contents/header.xml") ?? zip.file(/[Hh]eader\.xml$/)?.[0];
23745
+ let headerXml = "<root/>";
23746
+ if (headerFile) headerXml = await headerFile.async("text");
23747
+ const headerDoc = parser.parseFromString(headerXml, "text/xml");
23748
+ const borderFills = parseBorderFills(headerDoc);
23749
+ const charPrs = parseCharPrs(headerDoc);
23750
+ const sectionFiles = zip.file(/[Ss]ection\d+\.xml$/).sort((a, b) => (num(a.name.match(/(\d+)\.xml$/)?.[1] ?? null) ?? 0) - (num(b.name.match(/(\d+)\.xml$/)?.[1] ?? null) ?? 0));
23751
+ const tables = [];
23752
+ let tableIndex = 0;
23753
+ for (const f of sectionFiles) {
23754
+ const doc = parser.parseFromString(await f.async("text"), "text/xml");
23755
+ for (const tbl of elemsByLocal(doc, "tbl")) {
23756
+ if (!isTopLevelTable(tbl)) continue;
23757
+ tables.push(parseTable3(tbl, tableIndex++, borderFills, charPrs));
23758
+ }
23759
+ }
23760
+ return { schema_version: "0.1.0", tables };
23761
+ }
23762
+
23763
+ // src/roundtrip/patcher.ts
23764
+ import JSZip10 from "jszip";
23315
23765
 
23316
23766
  // src/roundtrip/table-rows.ts
23317
23767
  var ROW_OBJECT_RE = /<(?:[A-Za-z0-9_]+:)?(?:tbl|pic|equation|ole|container|shape|drawingObject|drawText|video|chart|fieldBegin|fieldEnd|ctrl)\b/;
@@ -23949,7 +24399,7 @@ async function patchHwpx(original, editedMarkdown, options) {
23949
24399
  }
23950
24400
  let zip;
23951
24401
  try {
23952
- zip = await JSZip9.loadAsync(original);
24402
+ zip = await JSZip10.loadAsync(original);
23953
24403
  } catch {
23954
24404
  return { success: false, applied: 0, skipped, error: "ZIP \uB85C\uB4DC \uC2E4\uD328" };
23955
24405
  }
@@ -24040,16 +24490,16 @@ function buildOrigUnits(blocks) {
24040
24490
  for (let i = 0; i < blocks.length; i++) {
24041
24491
  const block = blocks[i];
24042
24492
  let consume = 1;
24043
- let chunk;
24493
+ let chunk2;
24044
24494
  if (block.type === "paragraph" && block.text && /^\[별표\s*\d+/.test(sanitizeText(block.text))) {
24045
24495
  const next = blocks[i + 1];
24046
24496
  if (next?.type === "paragraph" && next.text && /관련\)?$/.test(next.text)) consume = 2;
24047
- chunk = blocksToMarkdown(blocks.slice(i, i + consume));
24497
+ chunk2 = blocksToMarkdown(blocks.slice(i, i + consume));
24048
24498
  } else {
24049
- chunk = blocksToMarkdown([block]);
24499
+ chunk2 = blocksToMarkdown([block]);
24050
24500
  }
24051
- if (chunk) {
24052
- const subUnits = splitMarkdownUnits(chunk);
24501
+ if (chunk2) {
24502
+ const subUnits = splitMarkdownUnits(chunk2);
24053
24503
  const isFragment = consume === 2 || (block.type === "paragraph" || block.type === "heading") && subUnits.length > 1;
24054
24504
  for (let s = 0; s < subUnits.length; s++) {
24055
24505
  const u = { ...subUnits[s], blockIdx: i, fragment: isFragment || void 0 };
@@ -24883,19 +25333,19 @@ function resolveTableMappings(blocks, scanTables) {
24883
25333
  if (scanTables[k].rows === table.rows && scanTables[k].cols === table.cols) cands.push(k);
24884
25334
  }
24885
25335
  if (cands.length === 0) continue;
24886
- let pick = cands[0];
25336
+ let pick2 = cands[0];
24887
25337
  if (cands.length > 1) {
24888
25338
  let best = tableContentScore(table, scanTables[cands[0]]);
24889
25339
  for (let ci = 1; ci < cands.length; ci++) {
24890
25340
  const sc = tableContentScore(table, scanTables[cands[ci]]);
24891
25341
  if (sc > best) {
24892
25342
  best = sc;
24893
- pick = cands[ci];
25343
+ pick2 = cands[ci];
24894
25344
  }
24895
25345
  }
24896
25346
  }
24897
- result.set(i, scanTables[pick]);
24898
- si = pick + 1;
25347
+ result.set(i, scanTables[pick2]);
25348
+ si = pick2 + 1;
24899
25349
  }
24900
25350
  return result;
24901
25351
  }
@@ -25371,7 +25821,7 @@ function stageParaPatch(scan, para, newPlain, skip) {
25371
25821
  }
25372
25822
 
25373
25823
  // src/validate.ts
25374
- import JSZip10 from "jszip";
25824
+ import JSZip11 from "jszip";
25375
25825
  import { DOMParser as DOMParser5 } from "@xmldom/xmldom";
25376
25826
  var REQUIRED_FILES = [
25377
25827
  "mimetype",
@@ -25389,7 +25839,7 @@ async function validateHwpx(buffer) {
25389
25839
  const issues = [];
25390
25840
  let zip;
25391
25841
  try {
25392
- zip = await JSZip10.loadAsync(buffer);
25842
+ zip = await JSZip11.loadAsync(buffer);
25393
25843
  } catch (err) {
25394
25844
  return {
25395
25845
  ok: false,
@@ -25457,10 +25907,10 @@ async function validateHwpx(buffer) {
25457
25907
  }
25458
25908
 
25459
25909
  // src/roundtrip/session.ts
25460
- import JSZip11 from "jszip";
25910
+ import JSZip12 from "jszip";
25461
25911
  async function buildState(bytes) {
25462
25912
  const parsed = await parseHwpxDocument(u8ToArrayBuffer2(bytes));
25463
- const zip = await JSZip11.loadAsync(bytes);
25913
+ const zip = await JSZip12.loadAsync(bytes);
25464
25914
  const sectionPaths = await resolveSectionEntryNames(zip);
25465
25915
  if (sectionPaths.length === 0) {
25466
25916
  throw new Error("HWPX \uC139\uC158 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
@@ -25955,7 +26405,7 @@ async function blocksToPdf(blocks, options) {
25955
26405
  }
25956
26406
 
25957
26407
  // src/render/svg-render.ts
25958
- import JSZip12 from "jszip";
26408
+ import JSZip13 from "jszip";
25959
26409
 
25960
26410
  // src/render/layout.ts
25961
26411
  function toInt32(v, fallback = 0) {
@@ -26044,7 +26494,7 @@ function elements(el) {
26044
26494
  for (let i = 0; i < kids2.length; i++) if (kids2[i].nodeType === 1) out.push(kids2[i]);
26045
26495
  return out;
26046
26496
  }
26047
- function num(el, attr, fallback = 0) {
26497
+ function num2(el, attr, fallback = 0) {
26048
26498
  return el ? toInt32(el.getAttribute(attr) ?? void 0, fallback) : fallback;
26049
26499
  }
26050
26500
  function shiftParaVert(p, delta) {
@@ -26052,7 +26502,7 @@ function shiftParaVert(p, delta) {
26052
26502
  if (ln(lsa) !== "linesegarray") continue;
26053
26503
  for (const seg of elements(lsa)) {
26054
26504
  if (ln(seg) !== "lineseg") continue;
26055
- seg.setAttribute("vertpos", String(num(seg, "vertpos") + delta));
26505
+ seg.setAttribute("vertpos", String(num2(seg, "vertpos") + delta));
26056
26506
  }
26057
26507
  }
26058
26508
  }
@@ -26142,9 +26592,9 @@ function reflowTablesIn(p, doc, styles, mode, counter) {
26142
26592
  if (ln(tc) !== "tc") continue;
26143
26593
  const csz = findChildByLocalName(tc, "cellSz");
26144
26594
  const cm = findChildByLocalName(tc, "cellMargin");
26145
- const cellW = num(csz, "width");
26146
- const mL = cm ? num(cm, "left", 141) : 141;
26147
- const mR = cm ? num(cm, "right", 141) : 141;
26595
+ const cellW = num2(csz, "width");
26596
+ const mL = cm ? num2(cm, "left", 141) : 141;
26597
+ const mR = cm ? num2(cm, "right", 141) : 141;
26148
26598
  const areaW = Math.max(500, cellW - mL - mR);
26149
26599
  const sub = findChildByLocalName(tc, "subList");
26150
26600
  if (sub) reflowBlockFlow(sub, doc, styles, areaW, mode, counter, 0);
@@ -26195,7 +26645,7 @@ function elements2(el) {
26195
26645
  }
26196
26646
  return out;
26197
26647
  }
26198
- function num2(el, attr, fallback = 0) {
26648
+ function num3(el, attr, fallback = 0) {
26199
26649
  return el ? toInt32(el.getAttribute(attr) ?? void 0, fallback) : fallback;
26200
26650
  }
26201
26651
  function findFirst(el, name, depth = 0) {
@@ -26263,8 +26713,8 @@ function buildPara(p) {
26263
26713
  } else if (OBJ_TAGS.has(cn)) {
26264
26714
  const sz = findChildByLocalName(ch, "sz");
26265
26715
  const pos = findChildByLocalName(ch, "pos");
26266
- const w = num2(sz, "width") || num2(findChildByLocalName(ch, "curSz"), "width") || num2(findChildByLocalName(ch, "orgSz"), "width");
26267
- const h = num2(sz, "height") || num2(findChildByLocalName(ch, "curSz"), "height") || num2(findChildByLocalName(ch, "orgSz"), "height");
26716
+ const w = num3(sz, "width") || num3(findChildByLocalName(ch, "curSz"), "width") || num3(findChildByLocalName(ch, "orgSz"), "width");
26717
+ const h = num3(sz, "height") || num3(findChildByLocalName(ch, "curSz"), "height") || num3(findChildByLocalName(ch, "orgSz"), "height");
26268
26718
  objs.push({
26269
26719
  el: ch,
26270
26720
  tag: cn,
@@ -26280,12 +26730,12 @@ function buildPara(p) {
26280
26730
  }
26281
26731
  } else if (tag === "linesegarray") {
26282
26732
  segs = elements2(runEl).filter((s) => ln2(s) === "lineseg").map((s) => ({
26283
- textpos: num2(s, "textpos"),
26284
- vertpos: num2(s, "vertpos"),
26285
- horzpos: num2(s, "horzpos"),
26286
- horzsize: num2(s, "horzsize"),
26287
- textheight: num2(s, "textheight", 1e3),
26288
- baseline: num2(s, "baseline", 850)
26733
+ textpos: num3(s, "textpos"),
26734
+ vertpos: num3(s, "vertpos"),
26735
+ horzpos: num3(s, "horzpos"),
26736
+ horzsize: num3(s, "horzsize"),
26737
+ textheight: num3(s, "textheight", 1e3),
26738
+ baseline: num3(s, "baseline", 850)
26289
26739
  }));
26290
26740
  }
26291
26741
  }
@@ -26455,11 +26905,11 @@ function anchorObject(o, ox, oy, baseV, areaW, ctx) {
26455
26905
  const { PW, PH, ML, MT, BODY_W, BODY_H } = ctx.geom;
26456
26906
  const pos = findChildByLocalName(o.el, "pos");
26457
26907
  const om = findChildByLocalName(o.el, "outMargin");
26458
- const omT = num2(om, "top"), omB = num2(om, "bottom");
26908
+ const omT = num3(om, "top"), omB = num3(om, "bottom");
26459
26909
  const w = o.width, h = o.height;
26460
26910
  if (!pos) return { x: ox, y: oy + baseV };
26461
- const vo = num2(pos, "vertOffset");
26462
- const ho = num2(pos, "horzOffset");
26911
+ const vo = num3(pos, "vertOffset");
26912
+ const ho = num3(pos, "horzOffset");
26463
26913
  const vrel = pos.getAttribute("vertRelTo") ?? "PARA";
26464
26914
  const hrel = pos.getAttribute("horzRelTo") ?? "PARA";
26465
26915
  const va = pos.getAttribute("vertAlign") ?? "TOP";
@@ -26496,8 +26946,8 @@ function drawObject(o, x, y, baseV, areaW, ctx, depth) {
26496
26946
  if (!OBJ_TAGS.has(tag)) continue;
26497
26947
  const sz = findChildByLocalName(ch, "sz");
26498
26948
  const off = findChildByLocalName(ch, "offset");
26499
- const sub = { el: ch, tag, index: 0, inline: true, width: num2(sz, "width"), height: num2(sz, "height") };
26500
- drawObject(sub, x + num2(off, "x"), y + num2(off, "y"), baseV, areaW, ctx, depth + 1);
26949
+ const sub = { el: ch, tag, index: 0, inline: true, width: num3(sz, "width"), height: num3(sz, "height") };
26950
+ drawObject(sub, x + num3(off, "x"), y + num3(off, "y"), baseV, areaW, ctx, depth + 1);
26501
26951
  }
26502
26952
  } else if (o.tag === "equation") {
26503
26953
  warnOnce(ctx, "equation", "\uC218\uC2DD \uAC1C\uCCB4\uB294 \uB80C\uB354 \uBBF8\uC9C0\uC6D0 \u2014 \uC0DD\uB7B5");
@@ -26515,16 +26965,16 @@ function drawShape(o, x, y, ctx, depth) {
26515
26965
  const el = o.el;
26516
26966
  const orgSz = findChildByLocalName(el, "orgSz");
26517
26967
  const curSz = findChildByLocalName(el, "curSz");
26518
- const ow = num2(orgSz, "width"), oh = num2(orgSz, "height");
26519
- const w = num2(curSz, "width") || ow || o.width;
26520
- const h = num2(curSz, "height") || oh || o.height;
26968
+ const ow = num3(orgSz, "width"), oh = num3(orgSz, "height");
26969
+ const w = num3(curSz, "width") || ow || o.width;
26970
+ const h = num3(curSz, "height") || oh || o.height;
26521
26971
  const sx = ow > 0 ? w / ow : 1;
26522
26972
  const sy = oh > 0 ? h / oh : 1;
26523
26973
  const lineShape = findChildByLocalName(el, "lineShape");
26524
26974
  const lstyle = lineShape?.getAttribute("style") ?? "SOLID";
26525
26975
  const strokeCol = lineShape?.getAttribute("color") || "#000000";
26526
26976
  const hasStroke = lstyle !== "NONE";
26527
- const strokeW = hasStroke ? shapeStrokePt(lineShape ? num2(lineShape, "width") : 33) : 0;
26977
+ const strokeW = hasStroke ? shapeStrokePt(lineShape ? num3(lineShape, "width") : 33) : 0;
26528
26978
  const dash = /DASH|DOT/.test(lstyle) ? ` stroke-dasharray="${lstyle.includes("DOT") ? "1,1.5" : "3,1.5"}"` : "";
26529
26979
  const strokeAttr = hasStroke ? ` stroke="${escapeXml3(strokeCol)}" stroke-width="${strokeW.toFixed(2)}"${dash}` : "";
26530
26980
  const fillBrush = findChildByLocalName(el, "fillBrush");
@@ -26538,12 +26988,12 @@ function drawShape(o, x, y, ctx, depth) {
26538
26988
  emit(ctx, `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}"${fillAttr}${strokeAttr}/>`);
26539
26989
  } else if (o.tag === "line") {
26540
26990
  const s = findChildByLocalName(el, "startPt"), e = findChildByLocalName(el, "endPt");
26541
- const x1 = x + num2(s, "x") * sx, y1 = y + num2(s, "y") * sy;
26542
- const x2 = x + num2(e, "x") * sx, y2 = y + num2(e, "y") * sy;
26991
+ const x1 = x + num3(s, "x") * sx, y1 = y + num3(s, "y") * sy;
26992
+ const x2 = x + num3(e, "x") * sx, y2 = y + num3(e, "y") * sy;
26543
26993
  emit(ctx, `<line x1="${pt(x1)}" y1="${pt(y1)}" x2="${pt(x2)}" y2="${pt(y2)}" stroke="${escapeXml3(strokeCol)}" stroke-width="${(strokeW || 0.3).toFixed(2)}"${dash}/>`);
26544
26994
  } else if (o.tag === "polygon" || o.tag === "curv") {
26545
26995
  const pts = [];
26546
- for (const c of elements2(el)) if (ln2(c) === "pt") pts.push(`${pt(x + num2(c, "x") * sx)},${pt(y + num2(c, "y") * sy)}`);
26996
+ for (const c of elements2(el)) if (ln2(c) === "pt") pts.push(`${pt(x + num3(c, "x") * sx)},${pt(y + num3(c, "y") * sy)}`);
26547
26997
  if (pts.length >= 2) emit(ctx, `<polygon points="${pts.join(" ")}"${fillAttr}${strokeAttr}/>`);
26548
26998
  } else if (o.tag === "arc") {
26549
26999
  emit(ctx, `<ellipse cx="${pt(x + w / 2)}" cy="${pt(y + h / 2)}" rx="${pt(w / 2)}" ry="${pt(h / 2)}" fill="none"${strokeAttr || ` stroke="${escapeXml3(strokeCol)}" stroke-width="0.3"`}/>`);
@@ -26571,9 +27021,9 @@ function cellContentExtent(cell) {
26571
27021
  const pos = findChildByLocalName(o.el, "pos");
26572
27022
  if ((pos?.getAttribute("vertRelTo") ?? "PARA") !== "PARA") continue;
26573
27023
  const om = findChildByLocalName(o.el, "outMargin");
26574
- const pushed = baseV - (num2(om, "top") + o.height + num2(om, "bottom"));
27024
+ const pushed = baseV - (num3(om, "top") + o.height + num3(om, "bottom"));
26575
27025
  const anchor = pushed >= -100 ? pushed : baseV;
26576
- ext = Math.max(ext, anchor + num2(om, "top") + num2(pos, "vertOffset") + o.height);
27026
+ ext = Math.max(ext, anchor + num3(om, "top") + num3(pos, "vertOffset") + o.height);
26577
27027
  }
26578
27028
  }
26579
27029
  return ext;
@@ -26584,8 +27034,8 @@ function edgeLine(x1, y1, x2, y2, e) {
26584
27034
  }
26585
27035
  function collectCells(tbl) {
26586
27036
  const inMargin = findChildByLocalName(tbl, "inMargin");
26587
- const defL = num2(inMargin, "left", 141), defR = num2(inMargin, "right", 141);
26588
- const defT = num2(inMargin, "top", 141), defB = num2(inMargin, "bottom", 141);
27037
+ const defL = num3(inMargin, "left", 141), defR = num3(inMargin, "right", 141);
27038
+ const defT = num3(inMargin, "top", 141), defB = num3(inMargin, "bottom", 141);
26589
27039
  const cells = [];
26590
27040
  for (const tr of elements2(tbl)) {
26591
27041
  if (ln2(tr) !== "tr") continue;
@@ -26598,18 +27048,18 @@ function collectCells(tbl) {
26598
27048
  if (!addr || !csz) continue;
26599
27049
  cells.push({
26600
27050
  el: tc,
26601
- ca: num2(addr, "colAddr"),
26602
- ra: num2(addr, "rowAddr"),
26603
- cs: Math.max(1, num2(span, "colSpan", 1)),
26604
- rs: Math.max(1, num2(span, "rowSpan", 1)),
26605
- w: num2(csz, "width"),
26606
- h: num2(csz, "height"),
27051
+ ca: num3(addr, "colAddr"),
27052
+ ra: num3(addr, "rowAddr"),
27053
+ cs: Math.max(1, num3(span, "colSpan", 1)),
27054
+ rs: Math.max(1, num3(span, "rowSpan", 1)),
27055
+ w: num3(csz, "width"),
27056
+ h: num3(csz, "height"),
26607
27057
  bfId: tc.getAttribute("borderFillIDRef"),
26608
27058
  sub: findChildByLocalName(tc, "subList"),
26609
- marginL: cm ? num2(cm, "left", defL) : defL,
26610
- marginR: cm ? num2(cm, "right", defR) : defR,
26611
- marginT: cm ? num2(cm, "top", defT) : defT,
26612
- marginB: cm ? num2(cm, "bottom", defB) : defB
27059
+ marginL: cm ? num3(cm, "left", defL) : defL,
27060
+ marginR: cm ? num3(cm, "right", defR) : defR,
27061
+ marginT: cm ? num3(cm, "top", defT) : defT,
27062
+ marginB: cm ? num3(cm, "bottom", defB) : defB
26613
27063
  });
26614
27064
  }
26615
27065
  }
@@ -26639,7 +27089,7 @@ function drawTable(tbl, tx, ty, ctx, depth) {
26639
27089
  const nCols = Math.max(...cells.map((c) => c.ca + c.cs));
26640
27090
  const nRows = Math.max(...cells.map((c) => c.ra + c.rs));
26641
27091
  const colCons = cells.map((c) => ({ a: c.ca, b: c.ca + c.cs, size: c.w }));
26642
- const colX = solveBoundaries(colCons, nCols, num2(tblSz, "width") || void 0);
27092
+ const colX = solveBoundaries(colCons, nCols, num3(tblSz, "width") || void 0);
26643
27093
  const rowH = solveRowHeights(
26644
27094
  cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: c.h, contentH: c.rs === 1 ? cellContentExtent(c) : void 0 })),
26645
27095
  nRows
@@ -26691,7 +27141,7 @@ function imageSymbol(loaded, ctx) {
26691
27141
  }
26692
27142
  function drawPic(pic, x, y, ctx) {
26693
27143
  const sz = findChildByLocalName(pic, "sz");
26694
- const w = num2(sz, "width", 5669), h = num2(sz, "height", 5669);
27144
+ const w = num3(sz, "width", 5669), h = num3(sz, "height", 5669);
26695
27145
  const img = findFirst(pic, "img");
26696
27146
  const ref = img?.getAttribute("binaryItemIDRef");
26697
27147
  const loaded = ref != null ? ctx.images.get(ref) : void 0;
@@ -26704,11 +27154,11 @@ function drawPic(pic, x, y, ctx) {
26704
27154
  const clip = findChildByLocalName(pic, "imgClip");
26705
27155
  const imgDim = findChildByLocalName(pic, "imgDim");
26706
27156
  const orgSz = findChildByLocalName(pic, "orgSz");
26707
- const dimW = num2(imgDim, "dimwidth"), dimH = num2(imgDim, "dimheight");
26708
- const refW = dimW > 0 ? dimW : num2(orgSz, "width");
26709
- const refH = dimH > 0 ? dimH : num2(orgSz, "height");
26710
- const cl = num2(clip, "left"), ct = num2(clip, "top");
26711
- const cr = num2(clip, "right", refW), cb = num2(clip, "bottom", refH);
27157
+ const dimW = num3(imgDim, "dimwidth"), dimH = num3(imgDim, "dimheight");
27158
+ const refW = dimW > 0 ? dimW : num3(orgSz, "width");
27159
+ const refH = dimH > 0 ? dimH : num3(orgSz, "height");
27160
+ const cl = num3(clip, "left"), ct = num3(clip, "top");
27161
+ const cr = num3(clip, "right", refW), cb = num3(clip, "bottom", refH);
26712
27162
  const cropped = refW > 0 && refH > 0 && clip != null && (cl > 0 || ct > 0 || cr < refW || cb < refH) && cr > cl && cb > ct;
26713
27163
  const symId = imageSymbol(loaded, ctx);
26714
27164
  if (cropped) {
@@ -26731,23 +27181,23 @@ function sniffMime(name, bytes) {
26731
27181
  function readSectionGeom(root) {
26732
27182
  const pagePr = findFirst(root, "pagePr");
26733
27183
  const margin = pagePr ? findChildByLocalName(pagePr, "margin") : null;
26734
- let PW = num2(pagePr, "width", 59528), PH = num2(pagePr, "height", 84188);
27184
+ let PW = num3(pagePr, "width", 59528), PH = num3(pagePr, "height", 84188);
26735
27185
  if (pagePr?.getAttribute("landscape") === "NARROWLY" && PW < PH) {
26736
27186
  const t = PW;
26737
27187
  PW = PH;
26738
27188
  PH = t;
26739
27189
  }
26740
- const ML = num2(margin, "left", 8504);
26741
- const MT = num2(margin, "top", 5668) + num2(margin, "header", 0);
26742
- const BODY_H = PH - MT - num2(margin, "bottom", 4252) - num2(margin, "footer", 0);
26743
- const BODY_W = PW - ML - num2(margin, "right", 8504);
27190
+ const ML = num3(margin, "left", 8504);
27191
+ const MT = num3(margin, "top", 5668) + num3(margin, "header", 0);
27192
+ const BODY_H = PH - MT - num3(margin, "bottom", 4252) - num3(margin, "footer", 0);
27193
+ const BODY_W = PW - ML - num3(margin, "right", 8504);
26744
27194
  return { PW, PH, ML, MT, BODY_W, BODY_H };
26745
27195
  }
26746
27196
  function renderSectionToPages(root, geom, ctxBase, hasCache, reflowMode) {
26747
27197
  const { PW, PH, ML, MT, BODY_W, BODY_H } = geom;
26748
27198
  if (!hasCache) reflowSection(root, ctxBase.styles, { BODY_W, BODY_H }, reflowMode);
26749
27199
  const colPr = findFirst(root, "colPr");
26750
- const multiCol = num2(colPr, "colCount", 1) > 1;
27200
+ const multiCol = num3(colPr, "colCount", 1) > 1;
26751
27201
  const paraSegPages = /* @__PURE__ */ new Map();
26752
27202
  let nPages = 1;
26753
27203
  let maxTopV = 0;
@@ -26762,13 +27212,13 @@ function renderSectionToPages(root, geom, ctxBase, hasCache, reflowMode) {
26762
27212
  const pagesOf = [];
26763
27213
  let paraFirst = true;
26764
27214
  for (const s of segEls) {
26765
- const v = num2(s, "vertpos");
26766
- const h = num2(s, "horzpos");
27215
+ const v = num3(s, "vertpos");
27216
+ const h = num3(s, "horzpos");
26767
27217
  const brk = v < prevV ? !multiCol || h <= prevH : paraFirst && v === prevV && h <= prevH;
26768
27218
  if (brk) cur++;
26769
27219
  paraFirst = false;
26770
27220
  pagesOf.push(cur);
26771
- maxTopV = Math.max(maxTopV, v + num2(s, "textheight", 1e3));
27221
+ maxTopV = Math.max(maxTopV, v + num3(s, "textheight", 1e3));
26772
27222
  prevV = v;
26773
27223
  prevH = h;
26774
27224
  }
@@ -26795,7 +27245,7 @@ async function renderHwpxToSvg(input, options) {
26795
27245
  precheckZipSize(ab, MAX_DECOMPRESS_SIZE, MAX_ZIP_ENTRIES);
26796
27246
  let zip;
26797
27247
  try {
26798
- zip = await JSZip12.loadAsync(input);
27248
+ zip = await JSZip13.loadAsync(input);
26799
27249
  } catch {
26800
27250
  throw new KordocError("HWPX(ZIP) \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4 \u2014 \uB80C\uB354\uB294 HWPX\uB9CC \uC9C0\uC6D0");
26801
27251
  }
@@ -26998,7 +27448,7 @@ async function parseHwp(buffer, options) {
26998
27448
  async function parsePdf(buffer, options) {
26999
27449
  let parsePdfDocument;
27000
27450
  try {
27001
- const mod = await import("./parser-LHBXIKXX.js");
27451
+ const mod = await import("./parser-5D6BQYTX.js");
27002
27452
  parsePdfDocument = mod.parsePdfDocument;
27003
27453
  } catch {
27004
27454
  return {
@@ -27113,6 +27563,7 @@ export {
27113
27563
  fillWithUniqueGuard,
27114
27564
  fitRatioForFewerLines,
27115
27565
  formatFillValue,
27566
+ hwpxToProfile,
27116
27567
  inferFieldType,
27117
27568
  isHwpxFile,
27118
27569
  isLabelCell,