kordoc 3.8.4 → 3.10.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 (38) hide show
  1. package/README.md +39 -0
  2. package/dist/{-ZAIG6FWT.js → -3B5FDXW2.js} +18 -12
  3. package/dist/{chunk-2UDAEQPW.js → chunk-5DL6VCIJ.js} +4 -120
  4. package/dist/chunk-5DL6VCIJ.js.map +1 -0
  5. package/dist/{chunk-6EDNKPXQ.js → chunk-5TK4X4JQ.js} +373 -315
  6. package/dist/chunk-5TK4X4JQ.js.map +1 -0
  7. package/dist/chunk-FU25KFFZ.js +938 -0
  8. package/dist/chunk-FU25KFFZ.js.map +1 -0
  9. package/dist/chunk-MZA7AXHN.js +124 -0
  10. package/dist/chunk-MZA7AXHN.js.map +1 -0
  11. package/dist/{chunk-T4SGNVVS.js → chunk-PNXOUDS7.js} +2 -2
  12. package/dist/{chunk-T4SGNVVS.js.map → chunk-PNXOUDS7.js.map} +1 -1
  13. package/dist/{chunk-Z3O36LBJ.cjs → chunk-ZQOGTAT5.cjs} +2 -2
  14. package/dist/{chunk-Z3O36LBJ.cjs.map → chunk-ZQOGTAT5.cjs.map} +1 -1
  15. package/dist/cli.js +33 -6
  16. package/dist/cli.js.map +1 -1
  17. package/dist/index.cjs +1136 -173
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +40 -1
  20. package/dist/index.d.ts +40 -1
  21. package/dist/index.js +1018 -55
  22. package/dist/index.js.map +1 -1
  23. package/dist/mcp.js +8 -5
  24. package/dist/mcp.js.map +1 -1
  25. package/dist/{parser-ZVKCFXR3.cjs → parser-6B7BUSX3.cjs} +14 -14
  26. package/dist/{parser-ZVKCFXR3.cjs.map → parser-6B7BUSX3.cjs.map} +1 -1
  27. package/dist/{parser-2THIF623.js → parser-DKIA66MN.js} +2 -2
  28. package/dist/{parser-PR7CPMM4.js → parser-VCJTQVAH.js} +8 -6
  29. package/dist/{parser-PR7CPMM4.js.map → parser-VCJTQVAH.js.map} +1 -1
  30. package/dist/render-4I72JOAR.js +9 -0
  31. package/dist/render-4I72JOAR.js.map +1 -0
  32. package/dist/{watch-2HYPNMOB.js → watch-MQTMNUSB.js} +6 -4
  33. package/dist/{watch-2HYPNMOB.js.map → watch-MQTMNUSB.js.map} +1 -1
  34. package/package.json +2 -2
  35. package/dist/chunk-2UDAEQPW.js.map +0 -1
  36. package/dist/chunk-6EDNKPXQ.js.map +0 -1
  37. /package/dist/{-ZAIG6FWT.js.map → -3B5FDXW2.js.map} +0 -0
  38. /package/dist/{parser-2THIF623.js.map → parser-DKIA66MN.js.map} +0 -0
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  sanitizeHref,
20
20
  stripDtd,
21
21
  toArrayBuffer
22
- } from "./chunk-T4SGNVVS.js";
22
+ } from "./chunk-PNXOUDS7.js";
23
23
  import {
24
24
  parsePageRange
25
25
  } from "./chunk-GE43BE46.js";
@@ -478,9 +478,9 @@ async function extractHwpxStyles(zip, decompressed) {
478
478
  function parseCharProperties(doc, map) {
479
479
  const tagNames = ["hh:charPr", "charPr", "hp:charPr"];
480
480
  for (const tagName of tagNames) {
481
- const elements = doc.getElementsByTagName(tagName);
482
- for (let i = 0; i < elements.length; i++) {
483
- const el = elements[i];
481
+ const elements2 = doc.getElementsByTagName(tagName);
482
+ for (let i = 0; i < elements2.length; i++) {
483
+ const el = elements2[i];
484
484
  const id = el.getAttribute("id") || el.getAttribute("IDRef") || "";
485
485
  if (!id) continue;
486
486
  const prop = {};
@@ -514,9 +514,9 @@ function parseCharProperties(doc, map) {
514
514
  function parseStyleElements(doc, map) {
515
515
  const tagNames = ["hh:style", "style", "hp:style"];
516
516
  for (const tagName of tagNames) {
517
- const elements = doc.getElementsByTagName(tagName);
518
- for (let i = 0; i < elements.length; i++) {
519
- const el = elements[i];
517
+ const elements2 = doc.getElementsByTagName(tagName);
518
+ for (let i = 0; i < elements2.length; i++) {
519
+ const el = elements2[i];
520
520
  const id = el.getAttribute("id") || el.getAttribute("IDRef") || String(i);
521
521
  const name = el.getAttribute("name") || el.getAttribute("engName") || "";
522
522
  const charPrId = el.getAttribute("charPrIDRef") || void 0;
@@ -528,9 +528,9 @@ function parseStyleElements(doc, map) {
528
528
  function parseNumberings(doc, map) {
529
529
  const tagNames = ["hh:numbering", "numbering"];
530
530
  for (const tagName of tagNames) {
531
- const elements = doc.getElementsByTagName(tagName);
532
- for (let i = 0; i < elements.length; i++) {
533
- const el = elements[i];
531
+ const elements2 = doc.getElementsByTagName(tagName);
532
+ for (let i = 0; i < elements2.length; i++) {
533
+ const el = elements2[i];
534
534
  const id = el.getAttribute("id") || "";
535
535
  if (!id) continue;
536
536
  const def = { heads: /* @__PURE__ */ new Map() };
@@ -557,9 +557,9 @@ function parseNumberings(doc, map) {
557
557
  function parseBullets(doc, map) {
558
558
  const tagNames = ["hh:bullet", "bullet"];
559
559
  for (const tagName of tagNames) {
560
- const elements = doc.getElementsByTagName(tagName);
561
- for (let i = 0; i < elements.length; i++) {
562
- const el = elements[i];
560
+ const elements2 = doc.getElementsByTagName(tagName);
561
+ for (let i = 0; i < elements2.length; i++) {
562
+ const el = elements2[i];
563
563
  const id = el.getAttribute("id") || "";
564
564
  const char = el.getAttribute("char") || "";
565
565
  if (id && char) map.set(id, char);
@@ -570,9 +570,9 @@ function parseBullets(doc, map) {
570
570
  function parseParaHeadings(doc, map) {
571
571
  const tagNames = ["hh:paraPr", "paraPr"];
572
572
  for (const tagName of tagNames) {
573
- const elements = doc.getElementsByTagName(tagName);
574
- for (let i = 0; i < elements.length; i++) {
575
- const el = elements[i];
573
+ const elements2 = doc.getElementsByTagName(tagName);
574
+ for (let i = 0; i < elements2.length; i++) {
575
+ const el = elements2[i];
576
576
  const id = el.getAttribute("id") || "";
577
577
  if (!id) continue;
578
578
  const heading = findChildByLocalName(el, "heading");
@@ -664,8 +664,10 @@ var CONVERT_MAP = {
664
664
  SUCC: "\\succ",
665
665
  UPLUS: "\\uplus",
666
666
  "\xB1": "\\pm",
667
+ "+-": "\\pm",
667
668
  "-+": "\\mp",
668
669
  "\xF7": "\\div",
670
+ cdot: "\\cdot",
669
671
  CIRC: "\\circ",
670
672
  BULLET: "\\bullet",
671
673
  DEG: " ^\\circ",
@@ -1054,6 +1056,10 @@ function hmlToLatex(hmlEqStr) {
1054
1056
  const t = tokens[i];
1055
1057
  if (t in CONVERT_MAP) tokens[i] = CONVERT_MAP[t];
1056
1058
  else if (t in MIDDLE_CONVERT_MAP) tokens[i] = MIDDLE_CONVERT_MAP[t];
1059
+ else {
1060
+ const quoted = /^"(.+)"$/.exec(t);
1061
+ if (quoted) tokens[i] = `\\text{${quoted[1]}}`;
1062
+ }
1057
1063
  }
1058
1064
  tokens = tokens.filter((tok) => tok.length !== 0);
1059
1065
  tokens = replaceBracket(tokens);
@@ -2499,11 +2505,11 @@ function formatRoman(n, upper) {
2499
2505
  const values = [1e3, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
2500
2506
  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"];
2501
2507
  let result = "";
2502
- let num = n;
2508
+ let num2 = n;
2503
2509
  for (let i = 0; i < values.length; i++) {
2504
- while (num >= values[i]) {
2510
+ while (num2 >= values[i]) {
2505
2511
  result += symbols[i];
2506
- num -= values[i];
2512
+ num2 -= values[i];
2507
2513
  }
2508
2514
  }
2509
2515
  return result;
@@ -2511,11 +2517,11 @@ function formatRoman(n, upper) {
2511
2517
  function formatLatin(n, upper) {
2512
2518
  if (n <= 0) return "";
2513
2519
  let result = "";
2514
- let num = n;
2515
- while (num > 0) {
2516
- num--;
2517
- result = String.fromCharCode((upper ? 65 : 97) + num % 26) + result;
2518
- num = Math.floor(num / 26);
2520
+ let num2 = n;
2521
+ while (num2 > 0) {
2522
+ num2--;
2523
+ result = String.fromCharCode((upper ? 65 : 97) + num2 % 26) + result;
2524
+ num2 = Math.floor(num2 / 26);
2519
2525
  }
2520
2526
  return result;
2521
2527
  }
@@ -2523,15 +2529,15 @@ function formatEastAsianNumber(n, digits, units, zero) {
2523
2529
  if (n === 0) return zero;
2524
2530
  if (n < 0 || n > 99999) return String(n);
2525
2531
  let result = "";
2526
- let num = n;
2532
+ let num2 = n;
2527
2533
  let unit = 0;
2528
- while (num > 0) {
2529
- const d = num % 10;
2534
+ while (num2 > 0) {
2535
+ const d = num2 % 10;
2530
2536
  if (d > 0) {
2531
2537
  const digitStr = d === 1 && unit > 0 ? "" : digits[d];
2532
2538
  result = digitStr + units[unit] + result;
2533
2539
  }
2534
- num = Math.floor(num / 10);
2540
+ num2 = Math.floor(num2 / 10);
2535
2541
  unit++;
2536
2542
  }
2537
2543
  return result;
@@ -2578,8 +2584,8 @@ function expandNumberingFormat(formatStr, counters, numbering) {
2578
2584
  const idx = levelRef - 1;
2579
2585
  const counterVal = counters[idx] ?? 0;
2580
2586
  const start = numbering.startNumbers[idx] ?? 1;
2581
- const num = counterVal > 0 ? start - 1 + counterVal : start;
2582
- result += formatNumber(num, headFormatToNumFmt(numbering.numberFormats[idx] ?? 0));
2587
+ const num2 = counterVal > 0 ? start - 1 + counterVal : start;
2588
+ result += formatNumber(num2, headFormatToNumFmt(numbering.numberFormats[idx] ?? 0));
2583
2589
  i += 2;
2584
2590
  continue;
2585
2591
  }
@@ -4147,11 +4153,11 @@ function applyCtrlEffect(ctrl, records, ctx) {
4147
4153
  const attr = ctrl.data.readUInt32LE(4);
4148
4154
  const type = attr & 15;
4149
4155
  const format = attr >>> 4 & 255;
4150
- const num = ctx.doc.autoCounters.get(type) ?? 1;
4151
- ctx.doc.autoCounters.set(type, num + 1);
4156
+ const num2 = ctx.doc.autoCounters.get(type) ?? 1;
4157
+ ctx.doc.autoCounters.set(type, num2 + 1);
4152
4158
  const prefix = ctrl.data.length >= 14 ? wcharAt(ctrl.data, 12) : "";
4153
4159
  const suffix = ctrl.data.length >= 16 ? wcharAt(ctrl.data, 14) : "";
4154
- ctrl.inlineText = `${prefix}${formatNumber(num, shapeFormatToNumFmt(format))}${suffix}`;
4160
+ ctrl.inlineText = `${prefix}${formatNumber(num2, shapeFormatToNumFmt(format))}${suffix}`;
4155
4161
  }
4156
4162
  return;
4157
4163
  }
@@ -4159,8 +4165,8 @@ function applyCtrlEffect(ctrl, records, ctx) {
4159
4165
  if (ctrl.data.length >= 10) {
4160
4166
  const attr = ctrl.data.readUInt32LE(4);
4161
4167
  const type = attr & 15;
4162
- const num = ctrl.data.readUInt16LE(8);
4163
- if (num > 0) ctx.doc.autoCounters.set(type, num);
4168
+ const num2 = ctrl.data.readUInt16LE(8);
4169
+ if (num2 > 0) ctx.doc.autoCounters.set(type, num2);
4164
4170
  }
4165
4171
  return;
4166
4172
  }
@@ -4222,7 +4228,7 @@ function blocksPlainText(blocks, sep) {
4222
4228
  return parts.join(sep).trim();
4223
4229
  }
4224
4230
  function applyNoteEffect(ctrl, records, ctx, autoType) {
4225
- const num = ctx.doc.autoCounters.get(autoType) ?? 1;
4231
+ const num2 = ctx.doc.autoCounters.get(autoType) ?? 1;
4226
4232
  let before = "";
4227
4233
  let after = "";
4228
4234
  let shape = 0;
@@ -4233,11 +4239,11 @@ function applyNoteEffect(ctrl, records, ctx, autoType) {
4233
4239
  if (ctrl.data.length >= 16) {
4234
4240
  shape = ctrl.data.readUInt32LE(12) & 255;
4235
4241
  }
4236
- const formatted = formatNumber(num, shapeFormatToNumFmt(shape));
4242
+ const formatted = formatNumber(num2, shapeFormatToNumFmt(shape));
4237
4243
  const marker = before || after ? `${before}${formatted}${after}` : `${formatted})`;
4238
4244
  const content = blocksPlainText(parseListHeaderParagraphs(ctrl, records, ctx), " ");
4239
- if ((ctx.doc.autoCounters.get(autoType) ?? 1) <= num) {
4240
- ctx.doc.autoCounters.set(autoType, num + 1);
4245
+ if ((ctx.doc.autoCounters.get(autoType) ?? 1) <= num2) {
4246
+ ctx.doc.autoCounters.set(autoType, num2 + 1);
4241
4247
  }
4242
4248
  ctrl.inlineText = marker;
4243
4249
  if (content) ctrl.footnote = content.startsWith(marker) ? content : `${marker} ${content}`;
@@ -16775,9 +16781,9 @@ var MAX_ROWS2 = 1e4;
16775
16781
  var MAX_COLS2 = 200;
16776
16782
  function cleanNumericValue(raw) {
16777
16783
  if (!/^-?\d+\.\d+$/.test(raw)) return raw;
16778
- const num = parseFloat(raw);
16779
- if (!isFinite(num)) return raw;
16780
- const cleaned = parseFloat(num.toPrecision(15)).toString();
16784
+ const num2 = parseFloat(raw);
16785
+ if (!isFinite(num2)) return raw;
16786
+ const cleaned = parseFloat(num2.toPrecision(15)).toString();
16781
16787
  return cleaned;
16782
16788
  }
16783
16789
  function parseCellRef(ref) {
@@ -17120,17 +17126,17 @@ function decodeRk(rk) {
17120
17126
  const fDiv100 = (rk & 1) !== 0;
17121
17127
  const fInt = (rk & 2) !== 0;
17122
17128
  const val30 = rk >> 2;
17123
- let num;
17129
+ let num2;
17124
17130
  if (fInt) {
17125
- num = val30;
17131
+ num2 = val30;
17126
17132
  } else {
17127
17133
  const high32 = (rk & 4294967292) >>> 0;
17128
17134
  const buf = Buffer.alloc(8);
17129
17135
  buf.writeUInt32LE(0, 0);
17130
17136
  buf.writeUInt32LE(high32, 4);
17131
- num = buf.readDoubleLE(0);
17137
+ num2 = buf.readDoubleLE(0);
17132
17138
  }
17133
- return fDiv100 ? num / 100 : num;
17139
+ return fDiv100 ? num2 / 100 : num2;
17134
17140
  }
17135
17141
  function decodeMulRk(data) {
17136
17142
  if (data.length < 6) return null;
@@ -17830,9 +17836,9 @@ function nodeToLatex(el) {
17830
17836
  case "f": {
17831
17837
  const n = firstKid(el, "num");
17832
17838
  const d = firstKid(el, "den");
17833
- const num = n ? childrenToLatex(n) : "";
17839
+ const num2 = n ? childrenToLatex(n) : "";
17834
17840
  const den = d ? childrenToLatex(d) : "";
17835
- return "\\frac" + grp(num) + grp(den);
17841
+ return "\\frac" + grp(num2) + grp(den);
17836
17842
  }
17837
17843
  // 첨자
17838
17844
  case "sSup": {
@@ -20473,10 +20479,10 @@ function simulateWrap(text, firstWidth, contWidth, height, ratioPct, mode = "kee
20473
20479
  const spacing = opts?.spacingPct ?? 0;
20474
20480
  const k = height * ratioPct / 100 / 1e3;
20475
20481
  const cwCp = (cp) => (cp === 32 ? spaceEm : charWidthEm1000(cp)) * (1 + spacing / 100) * k;
20476
- const charW = (ch) => cwCp(ch.codePointAt(0));
20482
+ const charW2 = (ch) => cwCp(ch.codePointAt(0));
20477
20483
  const rangeW = (from, to) => {
20478
20484
  let w = 0;
20479
- for (const ch of text.slice(from, to)) w += charW(ch);
20485
+ for (const ch of text.slice(from, to)) w += charW2(ch);
20480
20486
  return w;
20481
20487
  };
20482
20488
  const units = text.match(mode === "keep" ? / +|[^ ]+/g : / +|[^ ]/g) ?? [];
@@ -20497,7 +20503,7 @@ function simulateWrap(text, firstWidth, contWidth, height, ratioPct, mode = "kee
20497
20503
  };
20498
20504
  for (const u of units) {
20499
20505
  if (u[0] === " ") {
20500
- lineW += charW(" ") * u.length;
20506
+ lineW += charW2(" ") * u.length;
20501
20507
  pos += u.length;
20502
20508
  continue;
20503
20509
  }
@@ -20510,7 +20516,7 @@ function simulateWrap(text, firstWidth, contWidth, height, ratioPct, mode = "kee
20510
20516
  if (lineW === 0 || w > contWidth + EPS) {
20511
20517
  let sub = 0;
20512
20518
  for (const ch of u) {
20513
- const c = charW(ch);
20519
+ const c = charW2(ch);
20514
20520
  if (lineW + c > avail + EPS && lineW > 0) breakBefore(pos + sub, 0);
20515
20521
  lineW += c;
20516
20522
  sub += ch.length;
@@ -20770,6 +20776,16 @@ function buildPrvText(blocks) {
20770
20776
  }
20771
20777
  return lines.join("\n").slice(0, 1024);
20772
20778
  }
20779
+ function findMathDelim(s, from) {
20780
+ let i = s.indexOf("$$", from);
20781
+ while (i > 0) {
20782
+ let backslashes = 0;
20783
+ for (let j = i - 1; j >= 0 && s[j] === "\\"; j--) backslashes++;
20784
+ if (backslashes % 2 === 0) break;
20785
+ i = s.indexOf("$$", i + 1);
20786
+ }
20787
+ return i;
20788
+ }
20773
20789
  function parseMarkdownToBlocks(md2) {
20774
20790
  const lines = md2.split("\n");
20775
20791
  const blocks = [];
@@ -20780,6 +20796,45 @@ function parseMarkdownToBlocks(md2) {
20780
20796
  i++;
20781
20797
  continue;
20782
20798
  }
20799
+ const mathOpen = /^\s*\$\$/.exec(line);
20800
+ if (mathOpen) {
20801
+ const afterOpen = line.slice(mathOpen[0].length);
20802
+ const closeSame = findMathDelim(afterOpen, 0);
20803
+ if (closeSame >= 0) {
20804
+ const inner = afterOpen.slice(0, closeSame).trim();
20805
+ const trailing2 = afterOpen.slice(closeSame + 2).trim();
20806
+ if (inner) blocks.push({ type: "equation", text: inner });
20807
+ if (trailing2) blocks.push({ type: "paragraph", text: trailing2 });
20808
+ i++;
20809
+ continue;
20810
+ }
20811
+ const mathLines = [];
20812
+ if (afterOpen.trim()) mathLines.push(afterOpen);
20813
+ let closed = false;
20814
+ let trailing = "";
20815
+ let j = i + 1;
20816
+ for (; j < lines.length; j++) {
20817
+ const l = lines[j];
20818
+ if (!l.trim() || /^\s*(`{3,}|~{3,})/.test(l)) break;
20819
+ const end = findMathDelim(l, 0);
20820
+ if (end >= 0) {
20821
+ const before = l.slice(0, end);
20822
+ if (before.trim()) mathLines.push(before);
20823
+ trailing = l.slice(end + 2).trim();
20824
+ closed = true;
20825
+ j++;
20826
+ break;
20827
+ }
20828
+ mathLines.push(l);
20829
+ }
20830
+ if (closed) {
20831
+ const text = mathLines.join("\n").trim();
20832
+ if (text) blocks.push({ type: "equation", text });
20833
+ if (trailing) blocks.push({ type: "paragraph", text: trailing });
20834
+ i = j;
20835
+ continue;
20836
+ }
20837
+ }
20783
20838
  const fenceMatch = line.match(/^(`{3,}|~{3,})(.*)$/);
20784
20839
  if (fenceMatch) {
20785
20840
  const fence = fenceMatch[1];
@@ -21172,6 +21227,7 @@ function precomputeGongmunList(blocks, gongmun) {
21172
21227
  i++;
21173
21228
  continue;
21174
21229
  }
21230
+ const passThrough = (t) => t === "table" || t === "html_table" || t === "equation";
21175
21231
  const run = [];
21176
21232
  while (i < blocks.length) {
21177
21233
  const t = blocks[i].type;
@@ -21180,9 +21236,9 @@ function precomputeGongmunList(blocks, gongmun) {
21180
21236
  i++;
21181
21237
  continue;
21182
21238
  }
21183
- if (t === "table" || t === "html_table") {
21239
+ if (passThrough(t)) {
21184
21240
  let j = i + 1;
21185
- while (j < blocks.length && (blocks[j].type === "table" || blocks[j].type === "html_table")) j++;
21241
+ while (j < blocks.length && passThrough(blocks[j].type)) j++;
21186
21242
  if (j < blocks.length && blocks[j].type === "list_item") {
21187
21243
  i = j;
21188
21244
  continue;
@@ -21708,6 +21764,280 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3) {
21708
21764
  return `<hp:tbl id="${tblId}" zOrder="0" numberingType="TABLE" pageBreak="CELL" repeatHeader="0" rowCnt="${rowCnt}" colCnt="${colCnt}" cellSpacing="0" borderFillIDRef="2" noShading="0"><hp:sz width="${tblW}" widthRelTo="ABSOLUTE" height="${cellH * rowCnt}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="0" 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:inMargin left="510" right="510" top="141" bottom="141"/>` + trXmls.join("") + `</hp:tbl>`;
21709
21765
  }
21710
21766
 
21767
+ // src/hwpx/equation-generate.ts
21768
+ var MAX_EQUATION_SOURCE = 1e4;
21769
+ var MAX_GROUP_DEPTH = 64;
21770
+ var COMMAND_MAP = {
21771
+ alpha: "alpha",
21772
+ beta: "beta",
21773
+ gamma: "gamma",
21774
+ delta: "delta",
21775
+ epsilon: "epsilon",
21776
+ zeta: "zeta",
21777
+ eta: "eta",
21778
+ theta: "theta",
21779
+ iota: "iota",
21780
+ kappa: "kappa",
21781
+ lambda: "lambda",
21782
+ mu: "mu",
21783
+ nu: "nu",
21784
+ xi: "xi",
21785
+ pi: "pi",
21786
+ rho: "rho",
21787
+ sigma: "sigma",
21788
+ tau: "tau",
21789
+ upsilon: "upsilon",
21790
+ phi: "phi",
21791
+ chi: "chi",
21792
+ psi: "psi",
21793
+ omega: "omega",
21794
+ Gamma: "GAMMA",
21795
+ Delta: "DELTA",
21796
+ Theta: "THETA",
21797
+ Lambda: "LAMBDA",
21798
+ Xi: "XI",
21799
+ Pi: "PI",
21800
+ Sigma: "SIGMA",
21801
+ Upsilon: "UPSILON",
21802
+ Phi: "PHI",
21803
+ Psi: "PSI",
21804
+ Omega: "OMEGA",
21805
+ le: "LEQ",
21806
+ leq: "LEQ",
21807
+ ge: "GEQ",
21808
+ geq: "GEQ",
21809
+ ne: "!=",
21810
+ neq: "!=",
21811
+ pm: "+-",
21812
+ mp: "-+",
21813
+ times: "TIMES",
21814
+ cdot: "cdot",
21815
+ ast: "AST",
21816
+ circ: "CIRC",
21817
+ bullet: "BULLET",
21818
+ in: "IN",
21819
+ notin: "NOTIN",
21820
+ subset: "SUBSET",
21821
+ subseteq: "SUBSETEQ",
21822
+ supset: "SUPERSET",
21823
+ supseteq: "SUPSETEQ",
21824
+ cup: "CUP",
21825
+ cap: "SMALLINTER",
21826
+ emptyset: "EMPTYSET",
21827
+ forall: "FORALL",
21828
+ exists: "EXIST",
21829
+ infinity: "INF",
21830
+ infty: "INF",
21831
+ partial: "Partial",
21832
+ nabla: "NABLA",
21833
+ int: "int",
21834
+ iint: "dint",
21835
+ iiint: "tint",
21836
+ oint: "oint",
21837
+ sum: "sum",
21838
+ prod: "prod",
21839
+ lim: "lim",
21840
+ to: "->",
21841
+ rightarrow: "->",
21842
+ leftarrow: "larrow",
21843
+ leftrightarrow: "<->",
21844
+ Rightarrow: "RARROW",
21845
+ Leftarrow: "LARROW",
21846
+ Leftrightarrow: "LRARROW",
21847
+ cdots: "CDOTS",
21848
+ ldots: "LDOTS",
21849
+ vdots: "VDOTS",
21850
+ ddots: "DDOTS"
21851
+ };
21852
+ var ACCENT_COMMANDS = {
21853
+ bar: "bar",
21854
+ overline: "bar",
21855
+ vec: "vec",
21856
+ overrightarrow: "vec",
21857
+ hat: "hat",
21858
+ widehat: "hat",
21859
+ tilde: "tilde",
21860
+ widetilde: "tilde",
21861
+ dot: "dot",
21862
+ ddot: "ddot",
21863
+ underline: "under"
21864
+ };
21865
+ var RESERVED_WORDS = new Set(
21866
+ [...Object.keys(CONVERT_MAP), ...Object.keys(MIDDLE_CONVERT_MAP), "over", "root", "of"].filter((w) => /^[A-Za-z]+$/.test(w))
21867
+ );
21868
+ function skipSpaces(input, idx) {
21869
+ while (idx < input.length && /\s/.test(input[idx])) idx++;
21870
+ return idx;
21871
+ }
21872
+ function normalizeEqEdit(input) {
21873
+ return input.replace(/\s+/g, " ").trim();
21874
+ }
21875
+ function stripMathDelimiters(input) {
21876
+ let s = input.trim();
21877
+ if (s.startsWith("$$") && s.endsWith("$$")) s = s.slice(2, -2).trim();
21878
+ if (s.startsWith("\\[") && s.endsWith("\\]")) s = s.slice(2, -2).trim();
21879
+ return s;
21880
+ }
21881
+ function readBalanced(input, idx, open, close) {
21882
+ let depth = 1;
21883
+ let cursor = idx + 1;
21884
+ while (cursor < input.length) {
21885
+ const ch = input[cursor];
21886
+ if (ch === "\\") {
21887
+ cursor += 2;
21888
+ continue;
21889
+ }
21890
+ if (ch === open) depth++;
21891
+ else if (ch === close) depth--;
21892
+ if (depth === 0) {
21893
+ return { value: input.slice(idx + 1, cursor), next: cursor + 1 };
21894
+ }
21895
+ cursor++;
21896
+ }
21897
+ return { value: input.slice(idx + 1), next: input.length };
21898
+ }
21899
+ function readGroupOrToken(input, idx, depth) {
21900
+ const start = skipSpaces(input, idx);
21901
+ if (depth > MAX_GROUP_DEPTH) return { value: input.slice(start), next: input.length };
21902
+ if (input[start] === "{") {
21903
+ const group = readBalanced(input, start, "{", "}");
21904
+ return { value: convertLatexFragment(group.value, depth + 1), next: group.next };
21905
+ }
21906
+ if (input[start] === "\\") {
21907
+ const cmd = readCommand(input, start, depth + 1);
21908
+ return { value: cmd.value, next: cmd.next };
21909
+ }
21910
+ return { value: input[start] ?? "", next: Math.min(start + 1, input.length) };
21911
+ }
21912
+ function readCommandName(input, idx) {
21913
+ if (input[idx + 1] === "\\") return { value: "\\", next: idx + 2 };
21914
+ const match = /^[A-Za-z]+/.exec(input.slice(idx + 1));
21915
+ if (match) return { value: match[0], next: idx + 1 + match[0].length };
21916
+ return { value: input[idx + 1] ?? "", next: Math.min(idx + 2, input.length) };
21917
+ }
21918
+ function readCommand(input, idx, depth) {
21919
+ const name = readCommandName(input, idx);
21920
+ const command = name.value;
21921
+ if (command === "\\") return { value: "#", next: name.next };
21922
+ if (command === "frac") {
21923
+ const num2 = readGroupOrToken(input, name.next, depth);
21924
+ const den = readGroupOrToken(input, num2.next, depth);
21925
+ return { value: `{${num2.value}} over {${den.value}}`, next: den.next };
21926
+ }
21927
+ if (command === "sqrt") {
21928
+ let cursor = skipSpaces(input, name.next);
21929
+ let root = null;
21930
+ if (input[cursor] === "[") {
21931
+ const opt = readBalanced(input, cursor, "[", "]");
21932
+ root = { value: convertLatexFragment(opt.value, depth + 1), next: opt.next };
21933
+ cursor = opt.next;
21934
+ }
21935
+ const body = readGroupOrToken(input, cursor, depth);
21936
+ if (root) return { value: `root {${root.value}} of {${body.value}}`, next: body.next };
21937
+ return { value: `sqrt{${body.value}}`, next: body.next };
21938
+ }
21939
+ if (command === "begin") {
21940
+ const env = readGroupOrToken(input, name.next, depth);
21941
+ const endTag = `\\end{${env.value}}`;
21942
+ const endIdx = input.indexOf(endTag, env.next);
21943
+ if (endIdx === -1) return { value: env.value, next: env.next };
21944
+ const body = convertLatexFragment(input.slice(env.next, endIdx), depth + 1);
21945
+ if (env.value === "matrix" || env.value === "pmatrix" || env.value === "bmatrix") {
21946
+ return { value: `{${env.value}{${body}}}`, next: endIdx + endTag.length };
21947
+ }
21948
+ return { value: body, next: endIdx + endTag.length };
21949
+ }
21950
+ if (command === "left" || command === "right") {
21951
+ const kw = command === "left" ? "LEFT" : "RIGHT";
21952
+ const cursor = skipSpaces(input, name.next);
21953
+ let delimiter = input[cursor] ?? "";
21954
+ let next = delimiter ? cursor + 1 : cursor;
21955
+ if (delimiter === "\\") {
21956
+ const escaped = readCommandName(input, cursor);
21957
+ delimiter = escaped.value === "\\" ? "\\" : COMMAND_MAP[escaped.value] ?? escaped.value;
21958
+ next = escaped.next;
21959
+ }
21960
+ return { value: delimiter ? `${kw} ${delimiter}` : kw, next };
21961
+ }
21962
+ if (command in ACCENT_COMMANDS) {
21963
+ const body = readGroupOrToken(input, name.next, depth);
21964
+ return { value: `${ACCENT_COMMANDS[command]}{${body.value}}`, next: body.next };
21965
+ }
21966
+ if (command === "mathrm" || command === "text") {
21967
+ const start = skipSpaces(input, name.next);
21968
+ if (input[start] === "{") {
21969
+ const group = readBalanced(input, start, "{", "}");
21970
+ return { value: `"${group.value}"`, next: group.next };
21971
+ }
21972
+ const tok = readGroupOrToken(input, start, depth);
21973
+ return { value: `"${tok.value}"`, next: tok.next };
21974
+ }
21975
+ return { value: COMMAND_MAP[command] ?? command, next: name.next };
21976
+ }
21977
+ function convertLatexFragment(input, depth) {
21978
+ if (depth > MAX_GROUP_DEPTH) return normalizeEqEdit(input);
21979
+ let out = "";
21980
+ let idx = 0;
21981
+ while (idx < input.length) {
21982
+ const ch = input[idx];
21983
+ if (ch === "\\") {
21984
+ const cmd = readCommand(input, idx, depth + 1);
21985
+ out += ` ${cmd.value} `;
21986
+ idx = cmd.next;
21987
+ continue;
21988
+ }
21989
+ if (ch === "{") {
21990
+ const group = readBalanced(input, idx, "{", "}");
21991
+ out += `{${convertLatexFragment(group.value, depth + 1)}}`;
21992
+ idx = group.next;
21993
+ continue;
21994
+ }
21995
+ if (ch === "_" || ch === "^") {
21996
+ const script = readGroupOrToken(input, idx + 1, depth);
21997
+ out += ` ${ch}{${script.value}}`;
21998
+ idx = script.next;
21999
+ continue;
22000
+ }
22001
+ if (ch === "&") {
22002
+ out += " & ";
22003
+ idx++;
22004
+ continue;
22005
+ }
22006
+ out += ch;
22007
+ idx++;
22008
+ }
22009
+ return normalizeEqEdit(out);
22010
+ }
22011
+ function quoteReservedKeywords(latex) {
22012
+ return latex.replace(/([_^])\s*\{\s*([A-Za-z]+)\s*\}/g, (match, op, word) => RESERVED_WORDS.has(word) ? `${op}{"${word}"}` : match);
22013
+ }
22014
+ function latexLikeToEqEdit(input) {
22015
+ const src = stripMathDelimiters(input);
22016
+ if (src.length > MAX_EQUATION_SOURCE) return normalizeEqEdit(src);
22017
+ return convertLatexFragment(quoteReservedKeywords(src), 0);
22018
+ }
22019
+ function estimateEquationMetrics(script) {
22020
+ const cleaned = script.replace(/[{}\\^_]/g, "").replace(/\s+/g, " ").trim();
22021
+ const width = Math.min(Math.max(cleaned.length, 5) * 700 + 2e3, 4e4);
22022
+ const rowCount = Math.max(1, (script.match(/#/g) ?? []).length + 1);
22023
+ if (/\bmatrix\b|#/.test(script)) {
22024
+ if (rowCount >= 4) return { width, height: 5500, baseline: 55 };
22025
+ if (rowCount === 3) return { width, height: 4500, baseline: 60 };
22026
+ return { width, height: 3260, baseline: 63 };
22027
+ }
22028
+ if (/\bover\b|\broot\b|\bsqrt\b/.test(script)) return { width, height: 3010, baseline: 69 };
22029
+ return { width, height: 1450, baseline: 71 };
22030
+ }
22031
+ function generateEquationXml(script, zOrder = 0) {
22032
+ const { width, height, baseline } = estimateEquationMetrics(script);
22033
+ const eqId = 2000000001 + zOrder;
22034
+ return `<hp:equation id="${eqId}" zOrder="${zOrder}" numberingType="EQUATION" textWrap="TOP_AND_BOTTOM" textFlow="BOTH_SIDES" lock="0" dropcapstyle="None" version="Equation Version 60" baseLine="${baseline}" textColor="#000000" baseUnit="1200" lineMode="CHAR" font="HYhwpEQ"><hp:sz width="${width}" widthRelTo="ABSOLUTE" height="${height}" 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="56" right="56" top="0" bottom="0"/><hp:shapeComment>\uC218\uC2DD\uC785\uB2C8\uB2E4.</hp:shapeComment><hp:script>${escapeXml(script)}</hp:script></hp:equation>`;
22035
+ }
22036
+ function generateEquationParagraph(input, zOrder = 0) {
22037
+ const script = latexLikeToEqEdit(input);
22038
+ return `<hp:p paraPrIDRef="${PARA_NORMAL}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}">${generateEquationXml(script, zOrder)}</hp:run></hp:p>`;
22039
+ }
22040
+
21711
22041
  // src/hwpx/gen-section.ts
21712
22042
  function generateSecPr(gongmun) {
21713
22043
  const m = gongmun ? {
@@ -21755,6 +22085,15 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
21755
22085
  xml = codeLines.map((line) => generateParagraph(line || " ", PARA_CODE)).join("\n ");
21756
22086
  break;
21757
22087
  }
22088
+ case "equation": {
22089
+ if (isFirst) {
22090
+ const secRun = `<hp:run charPrIDRef="0">${generateSecPr(gongmun)}<hp:t></hp:t></hp:run>`;
22091
+ paraXmls.push(`<hp:p paraPrIDRef="0" styleIDRef="0">${secRun}</hp:p>`);
22092
+ isFirst = false;
22093
+ }
22094
+ xml = generateEquationParagraph(block.text || "", blockIdx);
22095
+ break;
22096
+ }
21758
22097
  case "blockquote":
21759
22098
  xml = generateParagraph(
21760
22099
  block.text || "",
@@ -24499,6 +24838,629 @@ async function blocksToPdf(blocks, options) {
24499
24838
  return markdownToPdf(markdown, options);
24500
24839
  }
24501
24840
 
24841
+ // src/render/svg-render.ts
24842
+ import JSZip10 from "jszip";
24843
+
24844
+ // src/render/layout.ts
24845
+ function toInt32(v, fallback = 0) {
24846
+ if (v == null || v === "") return fallback;
24847
+ const n = Number(v);
24848
+ if (!Number.isFinite(n)) return fallback;
24849
+ return n > 2147483647 ? n - 4294967296 : n;
24850
+ }
24851
+ function solveBoundaries(constraints, count, total) {
24852
+ const x = new Array(count + 1).fill(void 0);
24853
+ x[0] = 0;
24854
+ if (total != null && total > 0) x[count] = total;
24855
+ let changed = true;
24856
+ let guard = 0;
24857
+ while (changed && guard++ < count + 8) {
24858
+ changed = false;
24859
+ for (const c of constraints) {
24860
+ if (c.a < 0 || c.b > count || c.a >= c.b) continue;
24861
+ const xa = x[c.a];
24862
+ const xb = x[c.b];
24863
+ if (xa != null && xb == null) {
24864
+ x[c.b] = xa + c.size;
24865
+ changed = true;
24866
+ } else if (xb != null && xa == null) {
24867
+ x[c.a] = xb - c.size;
24868
+ changed = true;
24869
+ }
24870
+ }
24871
+ }
24872
+ let i = 0;
24873
+ while (i <= count) {
24874
+ if (x[i] != null) {
24875
+ i++;
24876
+ continue;
24877
+ }
24878
+ let lo = i - 1;
24879
+ let hi = i;
24880
+ while (hi <= count && x[hi] == null) hi++;
24881
+ const loV = x[lo];
24882
+ const hiV = hi <= count ? x[hi] : loV + (hi - lo) * 1e3;
24883
+ const n = hi - lo;
24884
+ for (let k = 1; k < n; k++) x[lo + k] = loV + (hiV - loV) * k / n;
24885
+ if (hi > count) x[count] = hiV;
24886
+ i = hi;
24887
+ }
24888
+ const out = x;
24889
+ for (let k = 1; k <= count; k++) if (out[k] < out[k - 1]) out[k] = out[k - 1];
24890
+ return out;
24891
+ }
24892
+ function solveRowHeights(cells, rowCount) {
24893
+ const h = new Array(rowCount).fill(0);
24894
+ for (const c of cells) {
24895
+ if (c.rowSpan === 1 && c.rowAddr >= 0 && c.rowAddr < rowCount) {
24896
+ h[c.rowAddr] = Math.max(h[c.rowAddr], c.height);
24897
+ }
24898
+ }
24899
+ for (const c of cells) {
24900
+ if (c.rowSpan <= 1) continue;
24901
+ const rows = [];
24902
+ for (let r = c.rowAddr; r < Math.min(c.rowAddr + c.rowSpan, rowCount); r++) rows.push(r);
24903
+ const known = rows.reduce((s, r) => s + h[r], 0);
24904
+ const missing = rows.filter((r) => h[r] === 0);
24905
+ if (missing.length > 0 && c.height > known) {
24906
+ const each = (c.height - known) / missing.length;
24907
+ for (const r of missing) h[r] = each;
24908
+ }
24909
+ }
24910
+ for (const c of cells) {
24911
+ if (c.rowSpan === 1 && c.contentH != null && c.rowAddr >= 0 && c.rowAddr < rowCount) {
24912
+ if (c.contentH > h[c.rowAddr]) h[c.rowAddr] = c.contentH;
24913
+ }
24914
+ }
24915
+ return h;
24916
+ }
24917
+
24918
+ // src/render/head-styles.ts
24919
+ var DEFAULT_CHAR = { height: 1e3, bold: false, italic: false, underline: false, ratio: 100, spacing: 0 };
24920
+ function borderWidthPt(v) {
24921
+ const n = parseFloat(v ?? "");
24922
+ if (!Number.isFinite(n)) return 0.34;
24923
+ return n * 2.834645;
24924
+ }
24925
+ function parseEdge(el) {
24926
+ if (!el) return void 0;
24927
+ const type = el.getAttribute("type") ?? "NONE";
24928
+ if (type === "NONE") return void 0;
24929
+ return { type, widthPt: borderWidthPt(el.getAttribute("width")), color: el.getAttribute("color") ?? "#000000" };
24930
+ }
24931
+ function parseRenderStyles(headXml) {
24932
+ const styles = { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
24933
+ const doc = createXmlParser().parseFromString(headXml, "text/xml");
24934
+ const root = doc.documentElement;
24935
+ if (!root) return styles;
24936
+ const walk = (el) => {
24937
+ const tag = (el.tagName || "").replace(/^[^:]+:/, "");
24938
+ if (tag === "charPr") {
24939
+ const id = el.getAttribute("id");
24940
+ if (id != null) {
24941
+ const ratioEl = findChildByLocalName(el, "ratio");
24942
+ const spacingEl = findChildByLocalName(el, "spacing");
24943
+ const underlineEl = findChildByLocalName(el, "underline");
24944
+ const textColor = el.getAttribute("textColor");
24945
+ styles.charPr.set(id, {
24946
+ height: Number(el.getAttribute("height")) || 1e3,
24947
+ bold: findChildByLocalName(el, "bold") != null,
24948
+ italic: findChildByLocalName(el, "italic") != null,
24949
+ underline: underlineEl != null && (underlineEl.getAttribute("type") ?? "NONE") !== "NONE",
24950
+ color: textColor && textColor !== "#000000" && textColor.toLowerCase() !== "none" ? textColor : void 0,
24951
+ ratio: Number(ratioEl?.getAttribute("hangul")) || 100,
24952
+ spacing: Number(spacingEl?.getAttribute("hangul")) || 0
24953
+ });
24954
+ }
24955
+ } else if (tag === "paraPr") {
24956
+ const id = el.getAttribute("id");
24957
+ if (id != null) {
24958
+ const align = findChildByLocalName(el, "align");
24959
+ styles.paraAlign.set(id, align?.getAttribute("horizontal") || "JUSTIFY");
24960
+ }
24961
+ } else if (tag === "borderFill") {
24962
+ const id = el.getAttribute("id");
24963
+ if (id != null) {
24964
+ const bf = {
24965
+ left: parseEdge(findChildByLocalName(el, "leftBorder")),
24966
+ right: parseEdge(findChildByLocalName(el, "rightBorder")),
24967
+ top: parseEdge(findChildByLocalName(el, "topBorder")),
24968
+ bottom: parseEdge(findChildByLocalName(el, "bottomBorder"))
24969
+ };
24970
+ const fillBrush = findChildByLocalName(el, "fillBrush");
24971
+ const winBrush = fillBrush ? findChildByLocalName(fillBrush, "winBrush") : null;
24972
+ const face = winBrush?.getAttribute("faceColor");
24973
+ if (face && face.toLowerCase() !== "none") bf.fill = face;
24974
+ styles.borderFill.set(id, bf);
24975
+ }
24976
+ }
24977
+ const children = el.childNodes;
24978
+ for (let i = 0; i < children.length; i++) {
24979
+ const ch = children[i];
24980
+ if (ch.nodeType === 1) walk(ch);
24981
+ }
24982
+ };
24983
+ walk(root);
24984
+ return styles;
24985
+ }
24986
+
24987
+ // src/render/svg-render.ts
24988
+ function ln(el) {
24989
+ return (el.tagName || "").replace(/^[^:]+:/, "");
24990
+ }
24991
+ function elements(el) {
24992
+ const out = [];
24993
+ const children = el.childNodes;
24994
+ if (!children) return out;
24995
+ for (let i = 0; i < children.length; i++) {
24996
+ if (children[i].nodeType === 1) out.push(children[i]);
24997
+ }
24998
+ return out;
24999
+ }
25000
+ function num(el, attr, fallback = 0) {
25001
+ return el ? toInt32(el.getAttribute(attr) ?? void 0, fallback) : fallback;
25002
+ }
25003
+ function findFirst(el, name, depth = 0) {
25004
+ if (depth > 64) return null;
25005
+ for (const ch of elements(el)) {
25006
+ if (ln(ch) === name) return ch;
25007
+ const found = findFirst(ch, name, depth + 1);
25008
+ if (found) return found;
25009
+ }
25010
+ return null;
25011
+ }
25012
+ function escapeXml3(s) {
25013
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
25014
+ }
25015
+ var OBJ_TAGS = /* @__PURE__ */ new Set(["tbl", "pic", "container", "equation", "rect", "ellipse", "polygon", "curv", "line", "arc", "ole", "textart"]);
25016
+ var pt = (u) => String(Math.round(u) / 100);
25017
+ function warnOnce(ctx, key, msg2) {
25018
+ if (ctx.warned.has(key)) return;
25019
+ ctx.warned.add(key);
25020
+ ctx.warnings.push(msg2);
25021
+ }
25022
+ function textOfT(t) {
25023
+ let s = "";
25024
+ const walk = (n, d) => {
25025
+ if (d > 32) return;
25026
+ const kids2 = n.childNodes;
25027
+ if (!kids2) return;
25028
+ for (let i = 0; i < kids2.length; i++) {
25029
+ const c = kids2[i];
25030
+ if (c.nodeType === 3) s += c.textContent ?? "";
25031
+ else if (c.nodeType === 1) walk(c, d + 1);
25032
+ }
25033
+ };
25034
+ walk(t, 0);
25035
+ return s;
25036
+ }
25037
+ function buildPara(p) {
25038
+ const chars = [];
25039
+ const objs = [];
25040
+ let segs = [];
25041
+ for (const runEl of elements(p)) {
25042
+ const tag = ln(runEl);
25043
+ if (tag === "run") {
25044
+ const prId = runEl.getAttribute("charPrIDRef");
25045
+ for (const ch of elements(runEl)) {
25046
+ const cn = ln(ch);
25047
+ if (cn === "t") {
25048
+ for (const c of textOfT(ch)) chars.push({ ch: c, prId });
25049
+ } else if (OBJ_TAGS.has(cn)) {
25050
+ const sz = findChildByLocalName(ch, "sz");
25051
+ const pos = findChildByLocalName(ch, "pos");
25052
+ objs.push({
25053
+ el: ch,
25054
+ tag: cn,
25055
+ index: chars.length,
25056
+ inline: pos?.getAttribute("treatAsChar") === "1",
25057
+ width: num(sz, "width"),
25058
+ height: num(sz, "height")
25059
+ });
25060
+ }
25061
+ }
25062
+ } else if (tag === "linesegarray") {
25063
+ segs = elements(runEl).filter((s) => ln(s) === "lineseg").map((s) => ({
25064
+ textpos: num(s, "textpos"),
25065
+ vertpos: num(s, "vertpos"),
25066
+ horzpos: num(s, "horzpos"),
25067
+ horzsize: num(s, "horzsize"),
25068
+ textheight: num(s, "textheight", 1e3),
25069
+ baseline: num(s, "baseline", 850)
25070
+ }));
25071
+ }
25072
+ }
25073
+ return { chars, segs, objs, paraPrId: p.getAttribute("paraPrIDRef") };
25074
+ }
25075
+ function charW(c, styles) {
25076
+ const st = (c.prId != null ? styles.charPr.get(c.prId) : void 0) ?? DEFAULT_CHAR;
25077
+ return measureTextWidth(c.ch, st.height, st.ratio, { spacingPct: st.spacing });
25078
+ }
25079
+ function lineNaturalWidth(m, styles, start, end) {
25080
+ let text = 0;
25081
+ for (let i = start; i < end && i < m.chars.length; i++) text += charW(m.chars[i], styles);
25082
+ let obj = 0;
25083
+ for (const o of m.objs) if (o.inline && o.index >= start && o.index < end) obj += o.width;
25084
+ return { text, obj };
25085
+ }
25086
+ function planLines(m, styles) {
25087
+ const align = (m.paraPrId != null ? styles.paraAlign.get(m.paraPrId) : void 0) ?? "JUSTIFY";
25088
+ const plans = [];
25089
+ for (let i = 0; i < m.segs.length; i++) {
25090
+ const seg = m.segs[i];
25091
+ const start = seg.textpos;
25092
+ const end = i + 1 < m.segs.length ? m.segs[i + 1].textpos : Math.max(m.chars.length, start);
25093
+ const nat = lineNaturalWidth(m, styles, start, end);
25094
+ const isLast = i === m.segs.length - 1;
25095
+ let xoff = 0;
25096
+ let scale = 1;
25097
+ const avail = seg.horzsize - nat.obj;
25098
+ if (nat.text > 0 && (!isLast || align === "DISTRIBUTE" || align === "DISTRIBUTE_SPACE")) {
25099
+ scale = avail > 0 ? avail / nat.text : 1;
25100
+ } else if (nat.text + nat.obj > 0 && isLast) {
25101
+ const w = nat.text + nat.obj;
25102
+ if (align === "CENTER") xoff = Math.max(0, (seg.horzsize - w) / 2);
25103
+ else if (align === "RIGHT") xoff = Math.max(0, seg.horzsize - w);
25104
+ }
25105
+ if (!Number.isFinite(scale) || scale <= 0) scale = 1;
25106
+ scale = Math.min(4, Math.max(0.25, scale));
25107
+ plans.push({ seg, xoff, scale, start, end });
25108
+ }
25109
+ return plans;
25110
+ }
25111
+ function advanceTo(m, styles, plan, upto) {
25112
+ let x = 0;
25113
+ for (let i = plan.start; i < upto && i < m.chars.length; i++) x += charW(m.chars[i], styles) * plan.scale;
25114
+ for (const o of m.objs) if (o.inline && o.index >= plan.start && o.index < upto) x += o.width;
25115
+ return x;
25116
+ }
25117
+ function drawPara(p, ox, oy, areaW, ctx, depth) {
25118
+ if (depth > 16) {
25119
+ warnOnce(ctx, "depth", "\uC911\uCCA9 \uAE4A\uC774 16 \uCD08\uACFC \u2014 \uC774\uD558 \uC0DD\uB7B5");
25120
+ return;
25121
+ }
25122
+ const m = buildPara(p);
25123
+ if (m.segs.length === 0) {
25124
+ for (const o of m.objs) drawObject(o, ox, oy, 0, areaW, ctx, depth);
25125
+ return;
25126
+ }
25127
+ const plans = planLines(m, ctx.styles);
25128
+ const baseV = m.segs[0].vertpos;
25129
+ for (const plan of plans) {
25130
+ const { seg } = plan;
25131
+ let i = plan.start;
25132
+ let cursor = ox + seg.horzpos + plan.xoff;
25133
+ const y = oy + seg.vertpos + seg.baseline;
25134
+ while (i < plan.end && i < m.chars.length) {
25135
+ const prId = m.chars[i].prId;
25136
+ let j = i;
25137
+ let piece = "";
25138
+ while (j < plan.end && j < m.chars.length && m.chars[j].prId === prId) {
25139
+ piece += m.chars[j].ch;
25140
+ j++;
25141
+ }
25142
+ for (const o of m.objs) {
25143
+ if (o.inline && o.index > i && o.index < j) {
25144
+ piece = piece.slice(0, o.index - i);
25145
+ j = o.index;
25146
+ break;
25147
+ }
25148
+ }
25149
+ {
25150
+ const cut = piece.search(/ {2,}/);
25151
+ if (cut > 0) {
25152
+ piece = piece.slice(0, cut);
25153
+ j = i + cut;
25154
+ } else if (cut === 0) {
25155
+ const runEnd = piece.match(/^ +/)[0].length;
25156
+ piece = piece.slice(0, runEnd);
25157
+ j = i + runEnd;
25158
+ }
25159
+ }
25160
+ const st = (prId != null ? ctx.styles.charPr.get(prId) : void 0) ?? DEFAULT_CHAR;
25161
+ const w = measureTextWidth(piece, st.height, st.ratio, { spacingPct: st.spacing }) * plan.scale;
25162
+ if (piece.trim().length > 0) {
25163
+ const attrs = [`x="${pt(cursor)}"`, `y="${pt(y)}"`, `font-size="${pt(st.height)}"`];
25164
+ if ([...piece].length > 1 && w > 50) {
25165
+ attrs.push(`textLength="${pt(w)}"`, `lengthAdjust="${plan.scale < 1 ? "spacingAndGlyphs" : "spacing"}"`);
25166
+ }
25167
+ if (st.bold) attrs.push(`font-weight="bold"`);
25168
+ if (st.italic) attrs.push(`font-style="italic"`);
25169
+ if (st.underline) attrs.push(`text-decoration="underline"`);
25170
+ if (st.color) attrs.push(`fill="${escapeXml3(st.color)}"`);
25171
+ ctx.svg.push(`<text ${attrs.join(" ")}>${escapeXml3(piece)}</text>`);
25172
+ ctx.stats.texts++;
25173
+ }
25174
+ cursor += w;
25175
+ for (const o of m.objs) if (o.inline && o.index === j) cursor += o.width;
25176
+ i = j;
25177
+ }
25178
+ }
25179
+ for (const o of m.objs) {
25180
+ if (o.inline) {
25181
+ let plan = plans[0];
25182
+ for (const pl of plans) if (pl.start <= o.index && (o.index < pl.end || pl === plans[plans.length - 1])) plan = pl;
25183
+ const x = ox + plan.seg.horzpos + plan.xoff + advanceTo(m, ctx.styles, plan, o.index);
25184
+ const yTop = oy + plan.seg.vertpos + Math.max(0, plan.seg.baseline - o.height);
25185
+ drawObject(o, x, yTop, baseV, areaW, ctx, depth);
25186
+ } else {
25187
+ const { x, y } = anchorObject(o, ox, oy, baseV, areaW, ctx);
25188
+ drawObject(o, x, y, baseV, areaW, ctx, depth);
25189
+ }
25190
+ }
25191
+ }
25192
+ function anchorObject(o, ox, oy, baseV, areaW, ctx) {
25193
+ const { PW, PH, ML, MT, BODY_W, BODY_H } = ctx.geom;
25194
+ const pos = findChildByLocalName(o.el, "pos");
25195
+ const om = findChildByLocalName(o.el, "outMargin");
25196
+ const omT = num(om, "top"), omB = num(om, "bottom");
25197
+ const w = o.width, h = o.height;
25198
+ if (!pos) return { x: ox, y: oy + baseV };
25199
+ const vo = num(pos, "vertOffset");
25200
+ const ho = num(pos, "horzOffset");
25201
+ const vrel = pos.getAttribute("vertRelTo") ?? "PARA";
25202
+ const hrel = pos.getAttribute("horzRelTo") ?? "PARA";
25203
+ const va = pos.getAttribute("vertAlign") ?? "TOP";
25204
+ const ha = pos.getAttribute("horzAlign") ?? "LEFT";
25205
+ const wrap = o.el.getAttribute("textWrap") ?? "TOP_AND_BOTTOM";
25206
+ let y;
25207
+ if (vrel === "PAPER") {
25208
+ y = va === "BOTTOM" ? PH - h - vo : va === "CENTER" ? (PH - h) / 2 + vo : vo;
25209
+ } else if (vrel === "PAGE") {
25210
+ y = va === "BOTTOM" ? MT + BODY_H - h - vo : va === "CENTER" ? MT + (BODY_H - h) / 2 + vo : MT + vo;
25211
+ } else if (wrap === "TOP_AND_BOTTOM") {
25212
+ const pushed = baseV - (omT + h + omB);
25213
+ const anchor = pushed >= -100 ? pushed : baseV;
25214
+ y = oy + anchor + omT + vo;
25215
+ } else {
25216
+ y = oy + baseV + vo;
25217
+ }
25218
+ let x;
25219
+ if (hrel === "PAGE") {
25220
+ x = ha === "RIGHT" ? ML + BODY_W - w - ho : ha === "CENTER" ? ML + (BODY_W - w) / 2 + ho : ML + ho;
25221
+ } else if (hrel === "PAPER") {
25222
+ x = ha === "RIGHT" ? PW - w - ho : ha === "CENTER" ? (PW - w) / 2 + ho : ho;
25223
+ } else {
25224
+ x = ha === "RIGHT" ? ox + areaW - w - ho : ha === "CENTER" ? ox + (areaW - w) / 2 + ho : ox + ho;
25225
+ }
25226
+ return { x, y };
25227
+ }
25228
+ function drawObject(o, x, y, baseV, areaW, ctx, depth) {
25229
+ if (o.tag === "tbl") drawTable(o.el, x, y, ctx, depth + 1);
25230
+ else if (o.tag === "pic") drawPic(o.el, x, y, ctx);
25231
+ else if (o.tag === "container") {
25232
+ for (const ch of elements(o.el)) {
25233
+ const tag = ln(ch);
25234
+ if (!OBJ_TAGS.has(tag)) continue;
25235
+ const sz = findChildByLocalName(ch, "sz");
25236
+ const off = findChildByLocalName(ch, "offset");
25237
+ const sub = { el: ch, tag, index: 0, inline: true, width: num(sz, "width"), height: num(sz, "height") };
25238
+ drawObject(sub, x + num(off, "x"), y + num(off, "y"), baseV, areaW, ctx, depth + 1);
25239
+ }
25240
+ } else if (o.tag === "equation") {
25241
+ warnOnce(ctx, "equation", "\uC218\uC2DD \uAC1C\uCCB4\uB294 \uB80C\uB354 \uBBF8\uC9C0\uC6D0 \u2014 \uC0DD\uB7B5");
25242
+ } else {
25243
+ warnOnce(ctx, `shape:${o.tag}`, `\uB3C4\uD615 \uAC1C\uCCB4(${o.tag}) \uB80C\uB354 \uBBF8\uC9C0\uC6D0 \u2014 \uC0DD\uB7B5`);
25244
+ }
25245
+ }
25246
+ function cellContentExtent(cell, ctx) {
25247
+ if (!cell.sub) return 0;
25248
+ let ext = 0;
25249
+ for (const p of elements(cell.sub)) {
25250
+ if (ln(p) !== "p") continue;
25251
+ const m = buildPara(p);
25252
+ for (const s of m.segs) ext = Math.max(ext, s.vertpos + s.textheight);
25253
+ const baseV = m.segs[0]?.vertpos ?? 0;
25254
+ for (const o of m.objs) {
25255
+ if (o.inline) continue;
25256
+ const pos = findChildByLocalName(o.el, "pos");
25257
+ if ((pos?.getAttribute("vertRelTo") ?? "PARA") !== "PARA") continue;
25258
+ const om = findChildByLocalName(o.el, "outMargin");
25259
+ const pushed = baseV - (num(om, "top") + o.height + num(om, "bottom"));
25260
+ const anchor = pushed >= -100 ? pushed : baseV;
25261
+ ext = Math.max(ext, anchor + num(om, "top") + num(pos, "vertOffset") + o.height);
25262
+ }
25263
+ }
25264
+ return ext;
25265
+ }
25266
+ function edgeLine(x1, y1, x2, y2, e) {
25267
+ const dash = /DASH|DOT/.test(e.type) ? ` stroke-dasharray="${e.type.includes("DOT") ? "1,1.5" : "3,1.5"}"` : "";
25268
+ return `<line x1="${pt(x1)}" y1="${pt(y1)}" x2="${pt(x2)}" y2="${pt(y2)}" stroke="${escapeXml3(e.color)}" stroke-width="${e.widthPt.toFixed(2)}"${dash}/>`;
25269
+ }
25270
+ function drawTable(tbl, tx, ty, ctx, depth) {
25271
+ if (depth > 16) {
25272
+ warnOnce(ctx, "depth", "\uC911\uCCA9 \uAE4A\uC774 16 \uCD08\uACFC \u2014 \uC774\uD558 \uC0DD\uB7B5");
25273
+ return;
25274
+ }
25275
+ ctx.stats.tables++;
25276
+ const tblSz = findChildByLocalName(tbl, "sz");
25277
+ const inMargin = findChildByLocalName(tbl, "inMargin");
25278
+ const defL = num(inMargin, "left", 141), defR = num(inMargin, "right", 141);
25279
+ const defT = num(inMargin, "top", 141), defB = num(inMargin, "bottom", 141);
25280
+ const cells = [];
25281
+ for (const tr of elements(tbl)) {
25282
+ if (ln(tr) !== "tr") continue;
25283
+ for (const tc of elements(tr)) {
25284
+ if (ln(tc) !== "tc") continue;
25285
+ const addr = findChildByLocalName(tc, "cellAddr");
25286
+ const span = findChildByLocalName(tc, "cellSpan");
25287
+ const csz = findChildByLocalName(tc, "cellSz");
25288
+ const cm = findChildByLocalName(tc, "cellMargin");
25289
+ if (!addr || !csz) continue;
25290
+ cells.push({
25291
+ el: tc,
25292
+ ca: num(addr, "colAddr"),
25293
+ ra: num(addr, "rowAddr"),
25294
+ cs: Math.max(1, num(span, "colSpan", 1)),
25295
+ rs: Math.max(1, num(span, "rowSpan", 1)),
25296
+ w: num(csz, "width"),
25297
+ h: num(csz, "height"),
25298
+ bfId: tc.getAttribute("borderFillIDRef"),
25299
+ sub: findChildByLocalName(tc, "subList"),
25300
+ marginL: cm ? num(cm, "left", defL) : defL,
25301
+ marginR: cm ? num(cm, "right", defR) : defR,
25302
+ marginT: cm ? num(cm, "top", defT) : defT,
25303
+ marginB: cm ? num(cm, "bottom", defB) : defB
25304
+ });
25305
+ }
25306
+ }
25307
+ if (cells.length === 0 || cells.length > 4096) return;
25308
+ const nCols = Math.max(...cells.map((c) => c.ca + c.cs));
25309
+ const nRows = Math.max(...cells.map((c) => c.ra + c.rs));
25310
+ const colCons = cells.map((c) => ({ a: c.ca, b: c.ca + c.cs, size: c.w }));
25311
+ const colX = solveBoundaries(colCons, nCols, num(tblSz, "width") || void 0);
25312
+ const rowH = solveRowHeights(
25313
+ cells.map((c) => ({ rowAddr: c.ra, rowSpan: c.rs, height: c.h, contentH: c.rs === 1 ? cellContentExtent(c, ctx) : void 0 })),
25314
+ nRows
25315
+ );
25316
+ const rowY = [0];
25317
+ for (let r = 0; r < nRows; r++) rowY.push(rowY[r] + rowH[r]);
25318
+ const geom = cells.map((c) => ({
25319
+ c,
25320
+ x: tx + colX[c.ca],
25321
+ y: ty + rowY[c.ra],
25322
+ w: colX[Math.min(c.ca + c.cs, nCols)] - colX[c.ca],
25323
+ h: rowY[Math.min(c.ra + c.rs, nRows)] - rowY[c.ra]
25324
+ }));
25325
+ for (const g of geom) {
25326
+ const bf = g.c.bfId != null ? ctx.styles.borderFill.get(g.c.bfId) : void 0;
25327
+ if (bf?.fill) ctx.svg.push(`<rect x="${pt(g.x)}" y="${pt(g.y)}" width="${pt(g.w)}" height="${pt(g.h)}" fill="${escapeXml3(bf.fill)}"/>`);
25328
+ }
25329
+ for (const g of geom) {
25330
+ const { c } = g;
25331
+ if (!c.sub) continue;
25332
+ const innerH = g.h - c.marginT - c.marginB;
25333
+ const extent = cellContentExtent(c, ctx);
25334
+ const va = c.sub.getAttribute("vertAlign") ?? "TOP";
25335
+ let yoff = 0;
25336
+ if (va === "CENTER") yoff = Math.max(0, (innerH - extent) / 2);
25337
+ else if (va === "BOTTOM") yoff = Math.max(0, innerH - extent);
25338
+ for (const p of elements(c.sub)) {
25339
+ if (ln(p) !== "p") continue;
25340
+ drawPara(p, g.x + c.marginL, g.y + c.marginT + yoff, g.w - c.marginL - c.marginR, ctx, depth + 1);
25341
+ }
25342
+ }
25343
+ for (const g of geom) {
25344
+ const bf = g.c.bfId != null ? ctx.styles.borderFill.get(g.c.bfId) : void 0;
25345
+ if (!bf) continue;
25346
+ if (bf.top) ctx.svg.push(edgeLine(g.x, g.y, g.x + g.w, g.y, bf.top));
25347
+ if (bf.bottom) ctx.svg.push(edgeLine(g.x, g.y + g.h, g.x + g.w, g.y + g.h, bf.bottom));
25348
+ if (bf.left) ctx.svg.push(edgeLine(g.x, g.y, g.x, g.y + g.h, bf.left));
25349
+ if (bf.right) ctx.svg.push(edgeLine(g.x + g.w, g.y, g.x + g.w, g.y + g.h, bf.right));
25350
+ }
25351
+ }
25352
+ function drawPic(pic, x, y, ctx) {
25353
+ const sz = findChildByLocalName(pic, "sz");
25354
+ const w = num(sz, "width", 5669), h = num(sz, "height", 5669);
25355
+ const img = findFirst(pic, "img");
25356
+ const ref = img?.getAttribute("binaryItemIDRef");
25357
+ const loaded = ref != null ? ctx.images.get(ref) : void 0;
25358
+ if (!loaded) {
25359
+ ctx.svg.push(`<rect x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" fill="#eee" stroke="#c00" stroke-width="0.5"/>`);
25360
+ warnOnce(ctx, `img:${ref}`, `\uC774\uBBF8\uC9C0 \uBC14\uC774\uB108\uB9AC \uB204\uB77D: ${ref ?? "(ref \uC5C6\uC74C)"}`);
25361
+ return;
25362
+ }
25363
+ ctx.stats.images++;
25364
+ const orgSz = findChildByLocalName(pic, "orgSz");
25365
+ const clip = findChildByLocalName(pic, "imgClip");
25366
+ const orgW = num(orgSz, "width"), orgH = num(orgSz, "height");
25367
+ const cl = num(clip, "left"), ct = num(clip, "top");
25368
+ const cr = num(clip, "right", orgW), cb = num(clip, "bottom", orgH);
25369
+ const cropped = orgW > 0 && orgH > 0 && clip != null && (cl > 0 || ct > 0 || cr < orgW || cb < orgH) && cr > cl && cb > ct;
25370
+ if (cropped) {
25371
+ ctx.svg.push(
25372
+ `<svg x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" viewBox="${pt(cl)} ${pt(ct)} ${pt(cr - cl)} ${pt(cb - ct)}" preserveAspectRatio="none"><image x="0" y="0" width="${pt(orgW)}" height="${pt(orgH)}" preserveAspectRatio="none" href="${loaded.dataUri}"/></svg>`
25373
+ );
25374
+ } else {
25375
+ ctx.svg.push(`<image x="${pt(x)}" y="${pt(y)}" width="${pt(w)}" height="${pt(h)}" preserveAspectRatio="none" href="${loaded.dataUri}"/>`);
25376
+ }
25377
+ }
25378
+ function sniffMime(name, bytes) {
25379
+ const lower = name.toLowerCase();
25380
+ if (lower.endsWith(".png") || bytes.length > 4 && bytes[0] === 137 && bytes[1] === 80) return "image/png";
25381
+ if (lower.endsWith(".bmp") || bytes.length > 2 && bytes[0] === 66 && bytes[1] === 77) return "image/bmp";
25382
+ if (lower.endsWith(".gif")) return "image/gif";
25383
+ if (lower.endsWith(".svg")) return "image/svg+xml";
25384
+ return "image/jpeg";
25385
+ }
25386
+ async function renderHwpxToSvg(input, options) {
25387
+ const maxImg = options?.maxImageBytes ?? 40 * 1024 * 1024;
25388
+ let zip;
25389
+ try {
25390
+ zip = await JSZip10.loadAsync(input);
25391
+ } catch {
25392
+ throw new KordocError("HWPX(ZIP) \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4 \u2014 \uB80C\uB354\uB294 HWPX\uB9CC \uC9C0\uC6D0");
25393
+ }
25394
+ const secFile = zip.file("Contents/section0.xml") ?? zip.file(/Contents\/section\d+\.xml$/i).sort((a, b) => a.name.localeCompare(b.name))[0];
25395
+ if (!secFile) throw new KordocError("Contents/section0.xml \uC5C6\uC74C \u2014 HWPX\uAC00 \uC544\uB2C8\uAC70\uB098 \uC190\uC0C1\uB428");
25396
+ const secXml = await secFile.async("string");
25397
+ if (secXml.length > MAX_DECOMPRESS_SIZE) throw new KordocError("\uC139\uC158 XML\uC774 \uD5C8\uC6A9 \uD06C\uAE30\uB97C \uCD08\uACFC");
25398
+ if (!secXml.includes("linesegarray")) {
25399
+ throw new KordocError("\uC870\uD310 \uCE90\uC2DC(linesegarray) \uC5C6\uC74C \u2014 \uD55C\uCEF4\uC5D0\uC11C \uC800\uC7A5\uD55C HWPX\uB9CC \uB80C\uB354 \uAC00\uB2A5");
25400
+ }
25401
+ const warnings = [];
25402
+ const headFile = zip.file("Contents/header.xml") ?? zip.file("Contents/head.xml");
25403
+ const styles = headFile ? parseRenderStyles(await headFile.async("string")) : { charPr: /* @__PURE__ */ new Map(), paraAlign: /* @__PURE__ */ new Map(), borderFill: /* @__PURE__ */ new Map() };
25404
+ if (!headFile) warnings.push("header.xml \uC5C6\uC74C \u2014 \uAE30\uBCF8 \uC2A4\uD0C0\uC77C\uB85C \uB80C\uB354");
25405
+ const binmap = /* @__PURE__ */ new Map();
25406
+ const hpf = zip.file(/content\.hpf$/i)[0];
25407
+ if (hpf) {
25408
+ const man = await hpf.async("string");
25409
+ for (const m of man.matchAll(/<[^>]*\bid="([^"]+)"[^>]*\bhref="(BinData\/[^"]+)"[^>]*>/g)) binmap.set(m[1], m[2]);
25410
+ for (const m of man.matchAll(/<[^>]*\bhref="(BinData\/[^"]+)"[^>]*\bid="([^"]+)"[^>]*>/g)) binmap.set(m[2], m[1]);
25411
+ }
25412
+ const images = /* @__PURE__ */ new Map();
25413
+ const refs = /* @__PURE__ */ new Set();
25414
+ for (const m of secXml.matchAll(/binaryItemIDRef="([^"]+)"/g)) refs.add(m[1]);
25415
+ for (const ref of refs) {
25416
+ let href = binmap.get(ref);
25417
+ if (!href) {
25418
+ const cand = zip.file(new RegExp(`BinData/.*${ref.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i"))[0];
25419
+ href = cand?.name;
25420
+ }
25421
+ if (!href) continue;
25422
+ const f = zip.file(href) ?? zip.file("Contents/" + href);
25423
+ if (!f) continue;
25424
+ const bytes = await f.async("uint8array");
25425
+ if (bytes.length > maxImg) {
25426
+ warnings.push(`\uC774\uBBF8\uC9C0 ${href} ${(bytes.length / 1048576).toFixed(1)}MB \u2014 \uD55C\uB3C4 \uCD08\uACFC\uB85C \uC0DD\uB7B5`);
25427
+ continue;
25428
+ }
25429
+ images.set(ref, { dataUri: `data:${sniffMime(href, bytes)};base64,${Buffer.from(bytes).toString("base64")}` });
25430
+ }
25431
+ const doc = createXmlParser().parseFromString(secXml, "text/xml");
25432
+ const root = doc.documentElement;
25433
+ if (!root) throw new KordocError("\uC139\uC158 XML \uD30C\uC2F1 \uC2E4\uD328");
25434
+ const pagePr = findFirst(root, "pagePr");
25435
+ const margin = pagePr ? findChildByLocalName(pagePr, "margin") : null;
25436
+ const PW = num(pagePr, "width", 59528), PH = num(pagePr, "height", 84188);
25437
+ const ML = num(margin, "left", 8504);
25438
+ const MT = num(margin, "top", 5668) + num(margin, "header", 0);
25439
+ const BODY_H = PH - MT - num(margin, "bottom", 4252) - num(margin, "footer", 0);
25440
+ const BODY_W = PW - ML - num(margin, "right", 8504);
25441
+ const ctx = {
25442
+ svg: [],
25443
+ geom: { PW, PH, ML, MT, BODY_W, BODY_H },
25444
+ styles,
25445
+ images,
25446
+ warnings,
25447
+ warned: /* @__PURE__ */ new Set(),
25448
+ stats: { texts: 0, images: 0, tables: 0 }
25449
+ };
25450
+ for (const p of elements(root)) {
25451
+ if (ln(p) !== "p") continue;
25452
+ const segs = findChildByLocalName(p, "linesegarray");
25453
+ const first = segs ? elements(segs)[0] : null;
25454
+ if (first && num(first, "vertpos") > BODY_H) continue;
25455
+ drawPara(p, ML, MT, BODY_W, ctx, 0);
25456
+ }
25457
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${pt(PW)} ${pt(PH)}" width="${pt(PW)}" height="${pt(PH)}" font-family="'HCR Batang','\uD568\uCD08\uB86C\uBC14\uD0D5','Hancom Batang',AppleMyungjo,'Noto Serif CJK KR',serif" xml:space="preserve">
25458
+ <rect width="100%" height="100%" fill="white"/>
25459
+ ${ctx.svg.join("\n")}
25460
+ </svg>`;
25461
+ return { svg, width: Math.round(PW) / 100, height: Math.round(PH) / 100, warnings, stats: ctx.stats };
25462
+ }
25463
+
24502
25464
  // src/index.ts
24503
25465
  async function parse(input, options) {
24504
25466
  let buffer;
@@ -24586,7 +25548,7 @@ async function parseHwp(buffer, options) {
24586
25548
  async function parsePdf(buffer, options) {
24587
25549
  let parsePdfDocument;
24588
25550
  try {
24589
- const mod = await import("./parser-2THIF623.js");
25551
+ const mod = await import("./parser-DKIA66MN.js");
24590
25552
  parsePdfDocument = mod.parsePdfDocument;
24591
25553
  } catch {
24592
25554
  return {
@@ -24723,6 +25685,7 @@ export {
24723
25685
  patchHwpx,
24724
25686
  patchHwpxBlocks,
24725
25687
  renderHtml,
25688
+ renderHwpxToSvg,
24726
25689
  scanSectionXml,
24727
25690
  simulateWrap,
24728
25691
  simulateWrapKeepWord