kordoc 4.4.0 → 4.5.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 (104) hide show
  1. package/README.md +18 -3
  2. package/dist/{-R6NUMPRV.js → -CWYIC4ES.js} +9 -9
  3. package/dist/{chunk-W6CUD7V3.js → chunk-2CF2WXBG.js} +3 -3
  4. package/dist/{chunk-YOZ7ZRCD.js → chunk-45EUJ2P6.js} +310 -76
  5. package/dist/chunk-45EUJ2P6.js.map +1 -0
  6. package/dist/{chunk-HNRULYUH.js → chunk-7ZQKECQT.js} +2 -2
  7. package/dist/{chunk-RZURSA4N.js → chunk-CBUC73JM.js} +3 -3
  8. package/dist/chunk-DCZVOIEO.cjs.map +1 -1
  9. package/dist/{chunk-ONS7JKVA.js → chunk-EYLOFSA5.js} +2 -2
  10. package/dist/{chunk-ONS7JKVA.js.map → chunk-EYLOFSA5.js.map} +1 -1
  11. package/dist/{chunk-YVYU267E.js → chunk-FT2EXMMP.js} +16 -5
  12. package/dist/chunk-FT2EXMMP.js.map +1 -0
  13. package/dist/{chunk-V35DRUJC.js → chunk-GCHH4WHT.js} +2 -2
  14. package/dist/{chunk-UDGPM5R5.cjs → chunk-GLPLLT4Q.cjs} +4 -4
  15. package/dist/chunk-GLPLLT4Q.cjs.map +1 -0
  16. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  17. package/dist/{chunk-HFJF477F.js → chunk-M4I5F6GK.js} +16 -5
  18. package/dist/chunk-M4I5F6GK.js.map +1 -0
  19. package/dist/{chunk-GHGZU2LQ.js → chunk-NBOVSNSR.js} +2 -2
  20. package/dist/{chunk-AB322K3O.cjs → chunk-TCPO6XAY.cjs} +17 -6
  21. package/dist/chunk-TCPO6XAY.cjs.map +1 -0
  22. package/dist/{chunk-5KLE3U23.js → chunk-TP4P7M4I.js} +2 -2
  23. package/dist/{chunk-P7YPCK7C.js → chunk-TTEHX4FN.js} +2 -2
  24. package/dist/{chunk-SKM6KZUH.cjs → chunk-U3ZNF4SO.cjs} +9 -9
  25. package/dist/chunk-U3ZNF4SO.cjs.map +1 -0
  26. package/dist/{chunk-A73RMJ6B.js → chunk-UEWW3DH2.js} +1 -1
  27. package/dist/{chunk-A73RMJ6B.js.map → chunk-UEWW3DH2.js.map} +1 -1
  28. package/dist/{chunk-H2KMJOB6.cjs → chunk-UQ6KDJWE.cjs} +2 -2
  29. package/dist/chunk-UQ6KDJWE.cjs.map +1 -0
  30. package/dist/{chunk-65DYCXGC.js → chunk-WDIPTY3Q.js} +3 -3
  31. package/dist/{chunk-XCIC7U6Y.js → chunk-XYSTZIIL.js} +2 -2
  32. package/dist/{chunk-QXYB74QF.js → chunk-ZHNUH2IW.js} +2 -2
  33. package/dist/chunk-ZV5OKQ3Z.cjs.map +1 -1
  34. package/dist/chunks-EYDY4Y6O.js +10 -0
  35. package/dist/cli.js +54 -19
  36. package/dist/cli.js.map +1 -1
  37. package/dist/formula-CG4S7TWO.cjs.map +1 -1
  38. package/dist/{image-ocr-U2DRRFL3.js → image-ocr-BWQIUUVC.js} +13 -5
  39. package/dist/image-ocr-BWQIUUVC.js.map +1 -0
  40. package/dist/{image-ocr-XC52AQDV.js → image-ocr-EDZOUU6Q.js} +14 -6
  41. package/dist/image-ocr-EDZOUU6Q.js.map +1 -0
  42. package/dist/{image-ocr-F2BQA26V.cjs → image-ocr-KZ4MGVJ3.cjs} +19 -11
  43. package/dist/image-ocr-KZ4MGVJ3.cjs.map +1 -0
  44. package/dist/index.cjs +647 -413
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +42 -2
  47. package/dist/index.d.ts +42 -2
  48. package/dist/index.js +305 -71
  49. package/dist/index.js.map +1 -1
  50. package/dist/mcp.js +63 -30
  51. package/dist/mcp.js.map +1 -1
  52. package/dist/page-range-P7SDW6LR.cjs.map +1 -1
  53. package/dist/{parser-TFPGQWCC.js → parser-6OJOFJ64.js} +5 -5
  54. package/dist/{parser-FFQN67O6.cjs → parser-7G2QFIYZ.cjs} +24 -24
  55. package/dist/parser-7G2QFIYZ.cjs.map +1 -0
  56. package/dist/{parser-ESGFWWCT.js → parser-JLEKXA2Z.js} +6 -6
  57. package/dist/pdf-ocr-364VNE6N.cjs +13 -0
  58. package/dist/pdf-ocr-364VNE6N.cjs.map +1 -0
  59. package/dist/{pdf-ocr-WE5TMRFU.js → pdf-ocr-OWUZLWQ3.js} +5 -5
  60. package/dist/pdf-ocr-YQGMCT53.js +12 -0
  61. package/dist/{profile-io-O6BDCUJN.js → profile-io-FMPT6VEZ.js} +3 -3
  62. package/dist/{rasterize-V22VCCE7.js → rasterize-LARCX6CS.js} +2 -2
  63. package/dist/render-4WHQ7JCX.js +10 -0
  64. package/dist/seal-BX6YA6PI.js +10 -0
  65. package/dist/{watch-HGKBICED.js → watch-Y2VKD2MN.js} +9 -9
  66. package/package.json +1 -1
  67. package/dist/chunk-AB322K3O.cjs.map +0 -1
  68. package/dist/chunk-H2KMJOB6.cjs.map +0 -1
  69. package/dist/chunk-HFJF477F.js.map +0 -1
  70. package/dist/chunk-SKM6KZUH.cjs.map +0 -1
  71. package/dist/chunk-UDGPM5R5.cjs.map +0 -1
  72. package/dist/chunk-YOZ7ZRCD.js.map +0 -1
  73. package/dist/chunk-YVYU267E.js.map +0 -1
  74. package/dist/chunks-QMGCI5DG.js +0 -10
  75. package/dist/image-ocr-F2BQA26V.cjs.map +0 -1
  76. package/dist/image-ocr-U2DRRFL3.js.map +0 -1
  77. package/dist/image-ocr-XC52AQDV.js.map +0 -1
  78. package/dist/parser-FFQN67O6.cjs.map +0 -1
  79. package/dist/pdf-ocr-4R646OO6.js +0 -12
  80. package/dist/pdf-ocr-UQBZH3HE.cjs +0 -13
  81. package/dist/pdf-ocr-UQBZH3HE.cjs.map +0 -1
  82. package/dist/render-3BSVTTZE.js +0 -10
  83. package/dist/seal-6ZSEJVOD.js +0 -10
  84. /package/dist/{-R6NUMPRV.js.map → -CWYIC4ES.js.map} +0 -0
  85. /package/dist/{chunk-W6CUD7V3.js.map → chunk-2CF2WXBG.js.map} +0 -0
  86. /package/dist/{chunk-HNRULYUH.js.map → chunk-7ZQKECQT.js.map} +0 -0
  87. /package/dist/{chunk-RZURSA4N.js.map → chunk-CBUC73JM.js.map} +0 -0
  88. /package/dist/{chunk-V35DRUJC.js.map → chunk-GCHH4WHT.js.map} +0 -0
  89. /package/dist/{chunk-GHGZU2LQ.js.map → chunk-NBOVSNSR.js.map} +0 -0
  90. /package/dist/{chunk-5KLE3U23.js.map → chunk-TP4P7M4I.js.map} +0 -0
  91. /package/dist/{chunk-P7YPCK7C.js.map → chunk-TTEHX4FN.js.map} +0 -0
  92. /package/dist/{chunk-65DYCXGC.js.map → chunk-WDIPTY3Q.js.map} +0 -0
  93. /package/dist/{chunk-XCIC7U6Y.js.map → chunk-XYSTZIIL.js.map} +0 -0
  94. /package/dist/{chunk-QXYB74QF.js.map → chunk-ZHNUH2IW.js.map} +0 -0
  95. /package/dist/{chunks-QMGCI5DG.js.map → chunks-EYDY4Y6O.js.map} +0 -0
  96. /package/dist/{parser-TFPGQWCC.js.map → parser-6OJOFJ64.js.map} +0 -0
  97. /package/dist/{parser-ESGFWWCT.js.map → parser-JLEKXA2Z.js.map} +0 -0
  98. /package/dist/{pdf-ocr-4R646OO6.js.map → pdf-ocr-OWUZLWQ3.js.map} +0 -0
  99. /package/dist/{pdf-ocr-WE5TMRFU.js.map → pdf-ocr-YQGMCT53.js.map} +0 -0
  100. /package/dist/{profile-io-O6BDCUJN.js.map → profile-io-FMPT6VEZ.js.map} +0 -0
  101. /package/dist/{rasterize-V22VCCE7.js.map → rasterize-LARCX6CS.js.map} +0 -0
  102. /package/dist/{render-3BSVTTZE.js.map → render-4WHQ7JCX.js.map} +0 -0
  103. /package/dist/{seal-6ZSEJVOD.js.map → seal-BX6YA6PI.js.map} +0 -0
  104. /package/dist/{watch-HGKBICED.js.map → watch-Y2VKD2MN.js.map} +0 -0
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  flattenLayoutTables,
9
9
  inlineImagesIntoMarkdown,
10
10
  mapPuaText
11
- } from "./chunk-XCIC7U6Y.js";
11
+ } from "./chunk-XYSTZIIL.js";
12
12
  import {
13
13
  parsePageRange
14
14
  } from "./chunk-GE43BE46.js";
@@ -27,7 +27,7 @@ import {
27
27
  sanitizeHref,
28
28
  stripDtd,
29
29
  toArrayBuffer
30
- } from "./chunk-ONS7JKVA.js";
30
+ } from "./chunk-EYLOFSA5.js";
31
31
 
32
32
  // src/index.ts
33
33
  import { readFile } from "fs/promises";
@@ -22666,6 +22666,26 @@ function charVariantBase(richAssets, isGongmun = true) {
22666
22666
  var GONGMUN_BODY_RATIO = 95;
22667
22667
 
22668
22668
  // src/hwpx/md-runs.ts
22669
+ var HYPERLINK_FIELDID = 627600491;
22670
+ var FIELD_ID_BASE = 18e8;
22671
+ var FOOTNOTE_INST_BASE = 185e7;
22672
+ var inlineDoc = null;
22673
+ function beginInlineDoc(footnotes) {
22674
+ inlineDoc = { footnotes, fieldSeq: 0, noteSeq: 0, inNote: false };
22675
+ }
22676
+ function endInlineDoc() {
22677
+ inlineDoc = null;
22678
+ }
22679
+ function extractFootnoteDefs(md2) {
22680
+ const defs = /* @__PURE__ */ new Map();
22681
+ const out = md2.replace(/\r\n?/g, "\n").split("\n").filter((line) => {
22682
+ const m = /^\[\^([^\]\s]+)\]:\s?(.*)$/.exec(line);
22683
+ if (!m) return true;
22684
+ defs.set(m[1], m[2].trim());
22685
+ return false;
22686
+ }).join("\n");
22687
+ return { md: defs.size > 0 ? out : md2, defs };
22688
+ }
22669
22689
  function buildPrvText(blocks) {
22670
22690
  const lines = [];
22671
22691
  let bytes = 0;
@@ -22857,8 +22877,45 @@ function parseInlineMarkdown(text) {
22857
22877
  return `\0${literals.length - 1}\0`;
22858
22878
  });
22859
22879
  text = text.replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1");
22860
- text = text.replace(/\[([^\]]*)\]\(([^)]*)\)/g, (_, t, u) => t || u);
22861
22880
  text = text.replace(/~~([^~]+)~~/g, "$1");
22881
+ let spans;
22882
+ if (inlineDoc) {
22883
+ spans = [];
22884
+ const re = /\[\^([^\]\s]+)\]|\[([^\]]*)\]\(([^)]*)\)/g;
22885
+ let last = 0;
22886
+ for (const m of text.matchAll(re)) {
22887
+ const idx = m.index;
22888
+ if (idx > last) spans.push(...emphasisSpans(text.slice(last, idx)));
22889
+ if (m[1] !== void 0) {
22890
+ const def = inlineDoc.inNote ? void 0 : inlineDoc.footnotes.get(m[1]);
22891
+ if (def !== void 0) spans.push({ text: "", bold: false, italic: false, code: false, note: def });
22892
+ else spans.push(...emphasisSpans(m[0]));
22893
+ } else {
22894
+ const anchor = m[2] || m[3];
22895
+ const href = sanitizeHref(m[3].trim()) ?? void 0;
22896
+ const sub = emphasisSpans(anchor);
22897
+ if (href) for (const s of sub) s.href = href;
22898
+ spans.push(...sub);
22899
+ }
22900
+ last = idx + m[0].length;
22901
+ }
22902
+ if (last < text.length) spans.push(...emphasisSpans(text.slice(last)));
22903
+ if (spans.length === 0) spans.push({ text, bold: false, italic: false, code: false });
22904
+ } else {
22905
+ text = text.replace(/\[([^\]]*)\]\(([^)]*)\)/g, (_, t, u) => t || u);
22906
+ spans = emphasisSpans(text);
22907
+ if (spans.length === 0) spans.push({ text, bold: false, italic: false, code: false });
22908
+ }
22909
+ for (const span of spans) {
22910
+ if (!span.text.includes("\0")) continue;
22911
+ span.text = span.text.replace(/\x00(\d+)\x00/g, (_, i) => {
22912
+ const c = literals[+i] ?? "";
22913
+ return span.code ? "\\" + c : c;
22914
+ });
22915
+ }
22916
+ return spans;
22917
+ }
22918
+ function emphasisSpans(text) {
22862
22919
  const spans = [];
22863
22920
  const regex = /(`[^`]+`|\*{3}[^*]+\*{3}|\*{2}[^*]+\*{2}|\*[^*]+\*|(?<![^\s\p{P}\p{S}\x00])(?<!_)_{2}(?=\S)[^_]+(?<=\S)_{2}(?!_)(?![^\s\p{P}\p{S}\x00])|(?<![^\s\p{P}\p{S}\x00])(?<!_)_(?=\S)[^_]+(?<=\S)_(?!_)(?![^\s\p{P}\p{S}\x00]))/gu;
22864
22921
  let lastIdx = 0;
@@ -22882,16 +22939,6 @@ function parseInlineMarkdown(text) {
22882
22939
  if (lastIdx < text.length) {
22883
22940
  spans.push({ text: text.slice(lastIdx), bold: false, italic: false, code: false });
22884
22941
  }
22885
- if (spans.length === 0) {
22886
- spans.push({ text, bold: false, italic: false, code: false });
22887
- }
22888
- for (const span of spans) {
22889
- if (!span.text.includes("\0")) continue;
22890
- span.text = span.text.replace(/\x00(\d+)\x00/g, (_, i) => {
22891
- const c = literals[+i] ?? "";
22892
- return span.code ? "\\" + c : c;
22893
- });
22894
- }
22895
22942
  return spans;
22896
22943
  }
22897
22944
  function spanToCharPrId(span) {
@@ -22901,13 +22948,54 @@ function spanToCharPrId(span) {
22901
22948
  if (span.italic) return CHAR_ITALIC;
22902
22949
  return CHAR_NORMAL;
22903
22950
  }
22951
+ function hyperlinkBeginXml(fid, href) {
22952
+ const cmd = escapeXml(href.replace(/:/g, "\\:"));
22953
+ const path = escapeXml(href);
22954
+ return `<hp:ctrl><hp:fieldBegin id="${fid}" type="HYPERLINK" name="" editable="0" dirty="0" zorder="-1" fieldid="${HYPERLINK_FIELDID}"><hp:parameters cnt="6" name=""><hp:integerParam name="Prop">0</hp:integerParam><hp:stringParam name="Command">${cmd};1;0;0</hp:stringParam><hp:stringParam name="Path">${path}</hp:stringParam><hp:stringParam name="Category">HWPHYPERLINK_TYPE_URL</hp:stringParam><hp:stringParam name="TargetType">HWPHYPERLINK_TARGET_BOOKMARK</hp:stringParam><hp:stringParam name="DocOpenType">HWPHYPERLINK_JUMP_CURRENTTAB</hp:stringParam></hp:parameters></hp:fieldBegin></hp:ctrl>`;
22955
+ }
22956
+ function footnoteXml(note, mapCharId) {
22957
+ const d = inlineDoc;
22958
+ const n = ++d.noteSeq;
22959
+ d.inNote = true;
22960
+ let body;
22961
+ try {
22962
+ body = generateRuns(note, CHAR_NORMAL, mapCharId);
22963
+ } finally {
22964
+ d.inNote = false;
22965
+ }
22966
+ return `<hp:ctrl><hp:footNote number="${n}" suffixChar="41" instId="${FOOTNOTE_INST_BASE + n}"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0"><hp:p paraPrIDRef="0" styleIDRef="0">${body}</hp:p></hp:subList></hp:footNote></hp:ctrl>`;
22967
+ }
22904
22968
  function generateRuns(text, defaultCharPr = CHAR_NORMAL, mapCharId) {
22905
22969
  const spans = parseInlineMarkdown(text);
22906
- return spans.map((span) => {
22907
- let charId = span.code || span.bold || span.italic ? spanToCharPrId(span) : defaultCharPr;
22908
- if (mapCharId) charId = mapCharId(charId);
22909
- return `<hp:run charPrIDRef="${charId}"><hp:t>${escapeXml(span.text)}</hp:t></hp:run>`;
22910
- }).join("");
22970
+ const mapped = (id) => mapCharId ? mapCharId(id) : id;
22971
+ const out = [];
22972
+ let openHref = null;
22973
+ let openFid = 0;
22974
+ const closeField = () => {
22975
+ if (openHref === null) return;
22976
+ out.push(`<hp:run charPrIDRef="${mapped(defaultCharPr)}"><hp:ctrl><hp:fieldEnd beginIDRef="${openFid}" fieldid="${HYPERLINK_FIELDID}"/></hp:ctrl></hp:run>`);
22977
+ openHref = null;
22978
+ };
22979
+ for (const span of spans) {
22980
+ if (span.note !== void 0 && inlineDoc) {
22981
+ closeField();
22982
+ out.push(`<hp:run charPrIDRef="${mapped(defaultCharPr)}">${footnoteXml(span.note, mapCharId)}</hp:run>`);
22983
+ continue;
22984
+ }
22985
+ const href = inlineDoc ? span.href ?? null : null;
22986
+ if (href !== openHref) {
22987
+ closeField();
22988
+ if (href !== null) {
22989
+ openFid = FIELD_ID_BASE + ++inlineDoc.fieldSeq;
22990
+ openHref = href;
22991
+ out.push(`<hp:run charPrIDRef="${mapped(defaultCharPr)}">${hyperlinkBeginXml(openFid, href)}</hp:run>`);
22992
+ }
22993
+ }
22994
+ const charId = span.code || span.bold || span.italic ? spanToCharPrId(span) : defaultCharPr;
22995
+ out.push(`<hp:run charPrIDRef="${mapped(charId)}"><hp:t>${escapeXml(span.text)}</hp:t></hp:run>`);
22996
+ }
22997
+ closeField();
22998
+ return out.join("");
22911
22999
  }
22912
23000
  function generateParagraph(text, paraPrId = PARA_NORMAL, charPrId = CHAR_NORMAL, mapCharId, styleId = 0) {
22913
23001
  if (paraPrId === PARA_CODE) {
@@ -22917,6 +23005,56 @@ function generateParagraph(text, paraPrId = PARA_NORMAL, charPrId = CHAR_NORMAL,
22917
23005
  return `<hp:p paraPrIDRef="${paraPrId}" styleIDRef="${styleId}">${runs}</hp:p>`;
22918
23006
  }
22919
23007
 
23008
+ // src/hwpx/gen-page.ts
23009
+ var PAPER_MM = {
23010
+ A4: [210, 297],
23011
+ A3: [297, 420],
23012
+ B4: [257, 364],
23013
+ B5: [182, 257],
23014
+ Letter: [215.9, 279.4]
23015
+ };
23016
+ function resolvePage(opts) {
23017
+ if (!opts) return null;
23018
+ const { size, orientation, columns, header, footer } = opts;
23019
+ if (size === void 0 && orientation === void 0 && columns === void 0 && header === void 0 && footer === void 0) return null;
23020
+ let wMm = 210, hMm = 297;
23021
+ if (size !== void 0) {
23022
+ if (typeof size === "string") {
23023
+ const preset = PAPER_MM[size];
23024
+ if (!preset) throw new Error(`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC6A9\uC9C0 \uD504\uB9AC\uC14B: ${size} (A4\xB7A3\xB7B4\xB7B5\xB7Letter)`);
23025
+ [wMm, hMm] = preset;
23026
+ } else {
23027
+ if (!(size.widthMm > 0) || !(size.heightMm > 0) || size.widthMm > 1e3 || size.heightMm > 1e3) {
23028
+ throw new Error(`\uC6A9\uC9C0 \uCE58\uC218\uB294 0~1000mm \uBC94\uC704\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${size.widthMm}\xD7${size.heightMm}`);
23029
+ }
23030
+ wMm = size.widthMm;
23031
+ hMm = size.heightMm;
23032
+ }
23033
+ }
23034
+ const cols = columns ?? 1;
23035
+ if (!Number.isInteger(cols) || cols < 1 || cols > 8) {
23036
+ throw new Error(`\uB2E4\uB2E8 \uAC1C\uC218\uB294 1~8 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${columns}`);
23037
+ }
23038
+ const paperHU = (mm) => Math.floor(mm * 7200 / 25.4);
23039
+ return {
23040
+ widthHU: size === void 0 ? A4_W_HU : paperHU(wMm),
23041
+ heightHU: size === void 0 ? A4_H_HU : paperHU(hMm),
23042
+ // 실측: 용지 치수는 방향과 무관하게 유지, 방향은 landscape 속성만 바뀐다
23043
+ landscape: orientation === "landscape" ? "NARROWLY" : "WIDELY",
23044
+ columns: cols,
23045
+ header: header?.trim() ? header.trim() : null,
23046
+ footer: footer?.trim() ? footer.trim() : null
23047
+ };
23048
+ }
23049
+ function columnColPrXml(columns) {
23050
+ const gap = columns > 1 ? 2268 : 0;
23051
+ return `<hp:ctrl><hp:colPr id="" type="NEWSPAPER" layout="LEFT" colCount="${columns}" sameSz="1" sameGap="${gap}"/></hp:ctrl>`;
23052
+ }
23053
+ function headerFooterCtrl(tag, text, id, mapCharId) {
23054
+ const runs = generateRuns(text, void 0, mapCharId);
23055
+ return `<hp:ctrl><hp:${tag} id="${id}" applyPageType="BOTH"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0"><hp:p paraPrIDRef="0" styleIDRef="0">${runs}</hp:p></hp:subList></hp:${tag}></hp:ctrl>`;
23056
+ }
23057
+
22920
23058
  // src/hwpx/gen-header.ts
22921
23059
  function generateContainerXml() {
22922
23060
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
@@ -24507,15 +24645,65 @@ var IMAGE_EXT_MIME = {
24507
24645
  tif: "image/tiff",
24508
24646
  tiff: "image/tiff"
24509
24647
  };
24648
+ function sniffImage(b) {
24649
+ if (b.length >= 8 && b[0] === 137 && b[1] === 80 && b[2] === 78 && b[3] === 71) return { mime: "image/png", ext: "png" };
24650
+ if (b.length >= 3 && b[0] === 255 && b[1] === 216 && b[2] === 255) return { mime: "image/jpeg", ext: "jpg" };
24651
+ if (b.length >= 6 && b[0] === 71 && b[1] === 73 && b[2] === 70) return { mime: "image/gif", ext: "gif" };
24652
+ if (b.length >= 2 && b[0] === 66 && b[1] === 77) return { mime: "image/bmp", ext: "bmp" };
24653
+ return null;
24654
+ }
24655
+ function probeImageSize(b) {
24656
+ const dv = new DataView(b.buffer, b.byteOffset, b.byteLength);
24657
+ try {
24658
+ if (b[0] === 137 && b[1] === 80) {
24659
+ return { w: dv.getUint32(16), h: dv.getUint32(20) };
24660
+ }
24661
+ if (b[0] === 255 && b[1] === 216) {
24662
+ let i = 2;
24663
+ while (i + 9 < b.length) {
24664
+ if (b[i] !== 255) {
24665
+ i++;
24666
+ continue;
24667
+ }
24668
+ const marker = b[i + 1];
24669
+ if (marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204) {
24670
+ return { w: dv.getUint16(i + 7), h: dv.getUint16(i + 5) };
24671
+ }
24672
+ i += 2 + dv.getUint16(i + 2);
24673
+ }
24674
+ return null;
24675
+ }
24676
+ if (b[0] === 71 && b[1] === 73) {
24677
+ return { w: dv.getUint16(6, true), h: dv.getUint16(8, true) };
24678
+ }
24679
+ if (b[0] === 66 && b[1] === 77) {
24680
+ return { w: dv.getUint32(18, true), h: Math.abs(dv.getInt32(22, true)) };
24681
+ }
24682
+ } catch {
24683
+ }
24684
+ return null;
24685
+ }
24686
+ var PX_TO_HU = 75;
24687
+ var MAX_IMG_W_HU = 48189;
24510
24688
  var ImageRegistry = class {
24689
+ /** @param supplied url → 실데이터 바이트 (markdownToHwpx images 옵션) */
24690
+ constructor(supplied) {
24691
+ this.supplied = supplied;
24692
+ }
24511
24693
  byUrl = /* @__PURE__ */ new Map();
24512
24694
  ids = /* @__PURE__ */ new Set();
24513
24695
  parts = [];
24514
24696
  picSeq = 0;
24697
+ binSeq = 0;
24515
24698
  /** url 등록(중복 시 기존 파트) — 수용 불가면 null */
24516
24699
  take(url) {
24517
24700
  const cached = this.byUrl.get(url);
24518
24701
  if (cached !== void 0) return cached;
24702
+ const real = this.takeReal(url);
24703
+ if (real) {
24704
+ this.byUrl.set(url, real);
24705
+ return real;
24706
+ }
24519
24707
  let part = null;
24520
24708
  const m = /^([A-Za-z0-9._-]+)\.([A-Za-z0-9]+)$/.exec(url);
24521
24709
  const mime = m ? IMAGE_EXT_MIME[m[2].toLowerCase()] : void 0;
@@ -24535,6 +24723,41 @@ var ImageRegistry = class {
24535
24723
  this.byUrl.set(url, part);
24536
24724
  return part;
24537
24725
  }
24726
+ /** 실데이터 등록 — images 맵 바이트·data: URI. 포맷 미상(webp 등)은 null → placeholder 폴백 */
24727
+ takeReal(url) {
24728
+ let bytes = this.supplied?.get(url);
24729
+ if (!bytes && url.startsWith("data:")) {
24730
+ const m = /^data:image\/[a-z+]+;base64,([A-Za-z0-9+/=\s]+)$/i.exec(url);
24731
+ if (m) {
24732
+ try {
24733
+ bytes = new Uint8Array(Buffer.from(m[1].replace(/\s+/g, ""), "base64"));
24734
+ } catch {
24735
+ }
24736
+ }
24737
+ }
24738
+ if (!bytes || bytes.length === 0) return null;
24739
+ const sniffed = sniffImage(bytes);
24740
+ if (!sniffed) return null;
24741
+ const safe = /^([A-Za-z0-9._-]+)\.([A-Za-z0-9]+)$/.exec(url);
24742
+ const base = safe && !url.includes("..") ? safe[1] : `image${++this.binSeq}`;
24743
+ let itemId = base.replace(/[^A-Za-z0-9_]/g, "_");
24744
+ let n = 1;
24745
+ while (this.ids.has(itemId)) itemId = `${base.replace(/[^A-Za-z0-9_]/g, "_")}_${n++}`;
24746
+ this.ids.add(itemId);
24747
+ const dim = probeImageSize(bytes);
24748
+ let wHU, hHU;
24749
+ if (dim && dim.w > 0 && dim.h > 0) {
24750
+ wHU = dim.w * PX_TO_HU;
24751
+ hHU = dim.h * PX_TO_HU;
24752
+ if (wHU > MAX_IMG_W_HU) {
24753
+ hHU = Math.round(hHU * (MAX_IMG_W_HU / wHU));
24754
+ wHU = MAX_IMG_W_HU;
24755
+ }
24756
+ }
24757
+ const part = { name: `BinData/${itemId}.${sniffed.ext}`, itemId, mime: sniffed.mime, data: bytes, wHU, hHU };
24758
+ this.parts.push(part);
24759
+ return part;
24760
+ }
24538
24761
  /** manifest <opf:item> 조각들 (실측: isEmbeded="1") */
24539
24762
  manifestItems() {
24540
24763
  return this.parts.map((p) => `<opf:item id="${p.itemId}" href="${p.name}" media-type="${p.mime}" isEmbeded="1"/>`);
@@ -24542,8 +24765,9 @@ var ImageRegistry = class {
24542
24765
  /** 인라인 <hp:pic> XML — 실측 저장본 미러, treatAsChar=1 (셀·문단 안 배치) */
24543
24766
  inlinePicXml(part) {
24544
24767
  const id = PIC_ID_BASE + ++this.picSeq;
24545
- const s = 1130;
24546
- return `<hp:pic id="${id}" zOrder="0" numberingType="PICTURE" textWrap="TOP_AND_BOTTOM" textFlow="BOTH_SIDES" lock="0" dropcapstyle="None" href="" groupLevel="0" instid="${id}" reverse="0" xmlns:hc="http://www.hancom.co.kr/hwpml/2011/core"><hp:offset x="0" y="0"/><hp:orgSz width="${s}" height="${s}"/><hp:curSz width="${s}" height="${s}"/><hp:flip horizontal="0" vertical="0"/><hp:rotationInfo angle="0" centerX="${s / 2}" centerY="${s / 2}" rotateimage="1"/><hp:renderingInfo><hc:transMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/><hc:scaMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/><hc:rotMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/></hp:renderingInfo><hp:imgRect><hc:pt0 x="0" y="0"/><hc:pt1 x="${s}" y="0"/><hc:pt2 x="${s}" y="${s}"/><hc:pt3 x="0" y="${s}"/></hp:imgRect><hp:imgClip left="0" right="${s}" top="0" bottom="${s}"/><hp:inMargin left="0" right="0" top="0" bottom="0"/><hp:imgDim dimwidth="${s}" dimheight="${s}"/><hc:img binaryItemIDRef="${part.itemId}" bright="0" contrast="0" effect="REAL_PIC" alpha="0"/><hp:effects/><hp:sz width="${s}" widthRelTo="ABSOLUTE" height="${s}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="1" allowOverlap="0" holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="PARA" vertAlign="TOP" horzAlign="LEFT" vertOffset="0" horzOffset="0"/><hp:outMargin left="0" right="0" top="0" bottom="0"/></hp:pic>`;
24768
+ const w = part.wHU ?? 1130;
24769
+ const h = part.hHU ?? 1130;
24770
+ return `<hp:pic id="${id}" zOrder="0" numberingType="PICTURE" textWrap="TOP_AND_BOTTOM" textFlow="BOTH_SIDES" lock="0" dropcapstyle="None" href="" groupLevel="0" instid="${id}" reverse="0" xmlns:hc="http://www.hancom.co.kr/hwpml/2011/core"><hp:offset x="0" y="0"/><hp:orgSz width="${w}" height="${h}"/><hp:curSz width="${w}" height="${h}"/><hp:flip horizontal="0" vertical="0"/><hp:rotationInfo angle="0" centerX="${Math.floor(w / 2)}" centerY="${Math.floor(h / 2)}" rotateimage="1"/><hp:renderingInfo><hc:transMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/><hc:scaMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/><hc:rotMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/></hp:renderingInfo><hp:imgRect><hc:pt0 x="0" y="0"/><hc:pt1 x="${w}" y="0"/><hc:pt2 x="${w}" y="${h}"/><hc:pt3 x="0" y="${h}"/></hp:imgRect><hp:imgClip left="0" right="${w}" top="0" bottom="${h}"/><hp:inMargin left="0" right="0" top="0" bottom="0"/><hp:imgDim dimwidth="${w}" dimheight="${h}"/><hc:img binaryItemIDRef="${part.itemId}" bright="0" contrast="0" effect="REAL_PIC" alpha="0"/><hp:effects/><hp:sz width="${w}" widthRelTo="ABSOLUTE" height="${h}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="1" allowOverlap="0" holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="PARA" vertAlign="TOP" horzAlign="LEFT" vertOffset="0" horzOffset="0"/><hp:outMargin left="0" right="0" top="0" bottom="0"/></hp:pic>`;
24547
24771
  }
24548
24772
  };
24549
24773
  var MD_IMAGE_RE = /!\[[^\]]*\]\(([^)\s]+)\)/g;
@@ -25430,7 +25654,7 @@ function generateEquationParagraph(input, zOrder = 0) {
25430
25654
  }
25431
25655
 
25432
25656
  // src/hwpx/gen-section.ts
25433
- function generateSecPr(gongmun) {
25657
+ function generateSecPr(gongmun, page = null) {
25434
25658
  const m = gongmun ? {
25435
25659
  top: mmToHwpunit(gongmun.margins.top),
25436
25660
  bottom: mmToHwpunit(gongmun.margins.bottom),
@@ -25443,13 +25667,15 @@ function generateSecPr(gongmun) {
25443
25667
  m.header = gongmun.headerFooter;
25444
25668
  m.footer = gongmun.headerFooter;
25445
25669
  }
25446
- const secPr = `<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="${A4_W_HU}" height="${A4_H_HU}" 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>`;
25447
- const colPr = `<hp:ctrl><hp:colPr id="" type="NEWSPAPER" layout="LEFT" colCount="1" sameSz="1" sameGap="0"/></hp:ctrl>`;
25448
- return secPr + colPr + (gongmun?.pageNumbers ? pageNumCtrl() : "");
25670
+ const secPr = `<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="${page?.landscape ?? "WIDELY"}" width="${page?.widthHU ?? A4_W_HU}" height="${page?.heightHU ?? A4_H_HU}" 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>`;
25671
+ const colPr = columnColPrXml(page?.columns ?? 1);
25672
+ const hf = (page?.header ? headerFooterCtrl("header", page.header, 1) : "") + (page?.footer ? headerFooterCtrl("footer", page.footer, 2) : "");
25673
+ return secPr + colPr + hf + (gongmun?.pageNumbers ? pageNumCtrl() : "");
25449
25674
  }
25450
25675
  var SectionOpener = class {
25451
- constructor(gongmun) {
25676
+ constructor(gongmun, page = null) {
25452
25677
  this.gongmun = gongmun;
25678
+ this.page = page;
25453
25679
  }
25454
25680
  pending = true;
25455
25681
  /** 아직 secPr를 나를 첫 문단이 안 나왔는가 */
@@ -25461,7 +25687,7 @@ var SectionOpener = class {
25461
25687
  this.pending = false;
25462
25688
  return xml.replace(
25463
25689
  /<hp:run charPrIDRef="(\d+)">/,
25464
- `<hp:run charPrIDRef="$1">${generateSecPr(this.gongmun)}`
25690
+ `<hp:run charPrIDRef="$1">${generateSecPr(this.gongmun, this.page)}`
25465
25691
  );
25466
25692
  }
25467
25693
  /**
@@ -25471,13 +25697,13 @@ var SectionOpener = class {
25471
25697
  emitCarrier(paraXmls) {
25472
25698
  if (!this.pending) return;
25473
25699
  this.pending = false;
25474
- const secRun = `<hp:run charPrIDRef="0">${generateSecPr(this.gongmun)}<hp:t></hp:t></hp:run>`;
25700
+ const secRun = `<hp:run charPrIDRef="0">${generateSecPr(this.gongmun, this.page)}<hp:t></hp:t></hp:run>`;
25475
25701
  paraXmls.push(`<hp:p paraPrIDRef="0" styleIDRef="0">${secRun}</hp:p>`);
25476
25702
  }
25477
25703
  /** 빈 문서 폴백 — secPr를 실은 빈 단락 XML */
25478
25704
  emptyDoc() {
25479
25705
  this.pending = false;
25480
- return `<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="0">${generateSecPr(this.gongmun)}<hp:t></hp:t></hp:run></hp:p>`;
25706
+ return `<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="0">${generateSecPr(this.gongmun, this.page)}<hp:t></hp:t></hp:run></hp:p>`;
25481
25707
  }
25482
25708
  };
25483
25709
  function buildPreamble(blocks, ctx) {
@@ -25718,7 +25944,7 @@ function appendPostamble(blocks, ctx) {
25718
25944
  paraXmls.push(...buildPressContact(gongmun, dfIds, tableStyle.totalWidth, bfReg));
25719
25945
  }
25720
25946
  }
25721
- function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null, bfReg = null, remap = null, dfIds = null, images = null) {
25947
+ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null, bfReg = null, remap = null, dfIds = null, images = null, page = null) {
25722
25948
  resetTableIds();
25723
25949
  resetGjTableIds();
25724
25950
  resetExtraTableIds();
@@ -25757,7 +25983,7 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
25757
25983
  // 개조식 장식표(표지·목차·장헤더·제목박스) 폭 스케일용 본문폭 — margins 오버라이드 대응
25758
25984
  gjBodyW: gongmun ? mmToHwpunit(210 - gongmun.margins.left - gongmun.margins.right) : GAEJOSIK_BASE_WIDTH,
25759
25985
  chamMap: (id) => id === CHAR_BOLD ? GJ_CHAR_CHAM_BOLD : id,
25760
- opener: new SectionOpener(gongmun),
25986
+ opener: new SectionOpener(gongmun, page),
25761
25987
  paraXmls: [],
25762
25988
  // 표 방출 순번 — 생성 성공 여부와 무관하게 '시도' 기준으로 센다. 실패한 표가 이후
25763
25989
  // 표들의 순번을 밀면 앵커 없는 프로필(손편집·구버전)의 table_index 매칭이 어긋난다.
@@ -25842,45 +26068,53 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
25842
26068
  async function markdownToHwpx(markdown, options) {
25843
26069
  const theme = resolveTheme(options?.theme);
25844
26070
  const gongmun = options?.gongmun ? resolveGongmun(options.gongmun) : null;
25845
- const measured = !!gongmun && usesReportFonts(gongmun.preset);
25846
- const richAssets = !!gongmun && needsGaejosikAssets(gongmun);
25847
- const blocks = parseMarkdownToBlocks(markdown);
25848
- const gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null;
25849
- const fit = gongmun && gongmunList ? computeGongmunFitPlan(blocks, gongmun, gongmunList) : null;
25850
- const staticBfEnd = staticBorderFillNext(gongmun);
25851
- const remap = options?.profile ? buildProfileRemap(options.profile, charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4, staticBfEnd, staticFontNext(gongmun)) : null;
25852
- const bfReg = gongmun ? new TableBfRegistry(staticBfEnd + (remap?.borderFillXmls.length ?? 0)) : null;
25853
- const dfActive = !!gongmun && docframeActive(gongmun);
25854
- const dfBase = charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4 + (remap?.charPrXmls.length ?? 0);
25855
- const dfIds = dfActive ? docframeIds(dfBase) : null;
25856
- const chartParts = [];
25857
- const images = new ImageRegistry();
25858
- const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, bfReg, remap, dfIds, images);
25859
- if (remap && remap.tables.length > 0) {
25860
- const unused = remap.tables.filter((t) => !t.used).length;
25861
- if (unused === remap.tables.length) {
25862
- console.warn(`[kordoc] format profile: \uD504\uB85C\uD544 \uD45C ${unused}\uAC1C\uAC00 \uBB38\uC11C \uD45C\uC640 \uB9E4\uCE6D\uB418\uC9C0 \uC54A\uC544 \uBBF8\uC801\uC6A9 (\uD589\xB7\uC5F4/\uCCAB \uC140 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)`);
25863
- }
25864
- }
25865
- const extraBorderFills = [...remap?.borderFillXmls ?? [], ...bfReg?.emit() ?? []];
25866
- const zip = new JSZip8();
25867
- zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
25868
- zip.file("META-INF/container.xml", generateContainerXml());
25869
- zip.file("Contents/content.hpf", generateManifest(chartParts, images.manifestItems(), gongmun ? "gongmun" : "default"));
25870
- for (const part of images.parts) zip.file(part.name, part.data);
25871
- zip.file("Contents/header.xml", generateHeaderXml(
25872
- theme,
25873
- gongmun,
25874
- fit?.variants ?? [],
25875
- extraBorderFills,
25876
- [...remap?.charPrXmls ?? [], ...dfActive ? docframeCharPrXmls(dfBase, richAssets) : []],
25877
- gongmunList?.indentVariants ?? [],
25878
- remap?.fontFaces ?? []
25879
- ));
25880
- zip.file("Contents/section0.xml", sectionXml);
25881
- for (const part of chartParts) zip.file(part.name, part.xml);
25882
- zip.file("Preview/PrvText.txt", buildPrvText(blocks));
25883
- return await zip.generateAsync({ type: "arraybuffer" });
26071
+ const page = resolvePage(options?.page);
26072
+ const { md: md2, defs } = extractFootnoteDefs(markdown);
26073
+ beginInlineDoc(defs);
26074
+ try {
26075
+ const measured = !!gongmun && usesReportFonts(gongmun.preset);
26076
+ const richAssets = !!gongmun && needsGaejosikAssets(gongmun);
26077
+ const blocks = parseMarkdownToBlocks(md2);
26078
+ const gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null;
26079
+ const fit = gongmun && gongmunList ? computeGongmunFitPlan(blocks, gongmun, gongmunList) : null;
26080
+ const staticBfEnd = staticBorderFillNext(gongmun);
26081
+ const remap = options?.profile ? buildProfileRemap(options.profile, charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4, staticBfEnd, staticFontNext(gongmun)) : null;
26082
+ const bfReg = gongmun ? new TableBfRegistry(staticBfEnd + (remap?.borderFillXmls.length ?? 0)) : null;
26083
+ const dfActive = !!gongmun && docframeActive(gongmun);
26084
+ const dfBase = charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4 + (remap?.charPrXmls.length ?? 0);
26085
+ const dfIds = dfActive ? docframeIds(dfBase) : null;
26086
+ const chartParts = [];
26087
+ const supplied = options?.images ? new Map(Object.entries(options.images).map(([k, v]) => [k, v instanceof Uint8Array ? v : new Uint8Array(v)])) : void 0;
26088
+ const images = new ImageRegistry(supplied);
26089
+ const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, bfReg, remap, dfIds, images, page);
26090
+ if (remap && remap.tables.length > 0) {
26091
+ const unused = remap.tables.filter((t) => !t.used).length;
26092
+ if (unused === remap.tables.length) {
26093
+ console.warn(`[kordoc] format profile: \uD504\uB85C\uD544 \uD45C ${unused}\uAC1C\uAC00 \uBB38\uC11C \uD45C\uC640 \uB9E4\uCE6D\uB418\uC9C0 \uC54A\uC544 \uBBF8\uC801\uC6A9 (\uD589\xB7\uC5F4/\uCCAB \uC140 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)`);
26094
+ }
26095
+ }
26096
+ const extraBorderFills = [...remap?.borderFillXmls ?? [], ...bfReg?.emit() ?? []];
26097
+ const zip = new JSZip8();
26098
+ zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
26099
+ zip.file("META-INF/container.xml", generateContainerXml());
26100
+ zip.file("Contents/content.hpf", generateManifest(chartParts, images.manifestItems(), gongmun ? "gongmun" : "default"));
26101
+ for (const part of images.parts) zip.file(part.name, part.data);
26102
+ zip.file("Contents/header.xml", generateHeaderXml(
26103
+ theme,
26104
+ gongmun,
26105
+ fit?.variants ?? [],
26106
+ extraBorderFills,
26107
+ [...remap?.charPrXmls ?? [], ...dfActive ? docframeCharPrXmls(dfBase, richAssets) : []],
26108
+ gongmunList?.indentVariants ?? [],
26109
+ remap?.fontFaces ?? []
26110
+ ));
26111
+ zip.file("Contents/section0.xml", sectionXml);
26112
+ for (const part of chartParts) zip.file(part.name, part.xml);
26113
+ zip.file("Preview/PrvText.txt", buildPrvText(blocks));
26114
+ return await zip.generateAsync({ type: "arraybuffer" });
26115
+ } finally {
26116
+ endInlineDoc();
26117
+ }
25884
26118
  }
25885
26119
 
25886
26120
  // src/diff/compare.ts
@@ -31062,7 +31296,7 @@ async function parse(input, options) {
31062
31296
  }
31063
31297
  async function parseImage(buffer, options) {
31064
31298
  try {
31065
- const { parseImageDocument } = await import("./image-ocr-U2DRRFL3.js");
31299
+ const { parseImageDocument } = await import("./image-ocr-BWQIUUVC.js");
31066
31300
  const { blocks, warnings } = await parseImageDocument(buffer, options);
31067
31301
  return {
31068
31302
  success: true,
@@ -31121,7 +31355,7 @@ async function parseHwp(buffer, options) {
31121
31355
  async function parsePdf(buffer, options) {
31122
31356
  let parsePdfDocument;
31123
31357
  try {
31124
- const mod = await import("./parser-TFPGQWCC.js");
31358
+ const mod = await import("./parser-6OJOFJ64.js");
31125
31359
  parsePdfDocument = mod.parsePdfDocument;
31126
31360
  } catch {
31127
31361
  return {