kordoc 4.0.2 → 4.0.3

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 (78) hide show
  1. package/README.md +792 -768
  2. package/dist/{-XMKVL3NX.js → -QSF64HNK.js} +8 -8
  3. package/dist/{chunk-STMLZDKR.js → chunk-6JSZBSOD.js} +2 -2
  4. package/dist/chunk-6JSZBSOD.js.map +1 -0
  5. package/dist/{chunk-IKBIIEVJ.js → chunk-AUJICYJG.js} +3 -3
  6. package/dist/chunk-AUJICYJG.js.map +1 -0
  7. package/dist/chunk-DCZVOIEO.cjs.map +1 -1
  8. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  9. package/dist/{chunk-AHWRAGXN.js → chunk-K2SETHJ6.js} +162 -75
  10. package/dist/chunk-K2SETHJ6.js.map +1 -0
  11. package/dist/{chunk-5CJGKKMZ.js → chunk-MEPHGCPQ.js} +1 -1
  12. package/dist/chunk-MEPHGCPQ.js.map +1 -0
  13. package/dist/chunk-MOL7MDBG.js +0 -0
  14. package/dist/{chunk-6SD4X5PT.js → chunk-MQLKSRIK.js} +3 -3
  15. package/dist/chunk-MQLKSRIK.js.map +1 -0
  16. package/dist/{chunk-WN7LZHII.cjs → chunk-OVESZY5R.cjs} +2 -2
  17. package/dist/chunk-OVESZY5R.cjs.map +1 -0
  18. package/dist/{chunk-6YIYFWO2.js → chunk-PNQDQ3SM.js} +2 -2
  19. package/dist/chunk-PNQDQ3SM.js.map +1 -0
  20. package/dist/{chunk-67RANGFQ.js → chunk-RO2GVZ3I.js} +3 -3
  21. package/dist/chunk-RO2GVZ3I.js.map +1 -0
  22. package/dist/{chunk-3IYQYBUF.js → chunk-TQYX5E32.js} +2 -2
  23. package/dist/chunk-TQYX5E32.js.map +1 -0
  24. package/dist/cli.js +14 -14
  25. package/dist/cli.js.map +1 -1
  26. package/dist/{detect-PJZMUL2Z.js → detect-RI2MQ33K.js} +2 -2
  27. package/dist/formula-5NKVS2LR.cjs.map +1 -1
  28. package/dist/formula-JCNF43NE.js +0 -0
  29. package/dist/index.cjs +461 -374
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +5 -4
  32. package/dist/index.d.ts +5 -4
  33. package/dist/index.js +157 -70
  34. package/dist/index.js.map +1 -1
  35. package/dist/mcp.js +17 -17
  36. package/dist/mcp.js.map +1 -1
  37. package/dist/page-range-737B4EZW.js +0 -0
  38. package/dist/page-range-P7SDW6LR.cjs.map +1 -1
  39. package/dist/{parser-3HM2VYKK.js → parser-AODAQQLQ.js} +5 -5
  40. package/dist/parser-AODAQQLQ.js.map +1 -0
  41. package/dist/{parser-6AYYGX6J.cjs → parser-FMONFTAN.cjs} +16 -16
  42. package/dist/parser-FMONFTAN.cjs.map +1 -0
  43. package/dist/{parser-2Q2YKEJG.js → parser-J7YREDNS.js} +4 -4
  44. package/dist/parser-J7YREDNS.js.map +1 -0
  45. package/dist/{provider-H4WWSPOV.js → provider-4ZJKV3DC.js} +1 -1
  46. package/dist/provider-4ZJKV3DC.js.map +1 -0
  47. package/dist/{provider-7H4CPZYS.js → provider-AKROB7WQ.js} +1 -1
  48. package/dist/provider-AKROB7WQ.js.map +1 -0
  49. package/dist/{provider-5K7O3Z2O.cjs → provider-G4C2V2PD.cjs} +1 -1
  50. package/dist/provider-G4C2V2PD.cjs.map +1 -0
  51. package/dist/render-JPP7YTV3.js +10 -0
  52. package/dist/seal-MDE4DXZQ.js +10 -0
  53. package/dist/setup-57FB3LSP.js +0 -0
  54. package/dist/{watch-6OHF727O.js → watch-P65Z24AL.js} +8 -8
  55. package/dist/watch-P65Z24AL.js.map +1 -0
  56. package/package.json +4 -4
  57. package/dist/chunk-3IYQYBUF.js.map +0 -1
  58. package/dist/chunk-5CJGKKMZ.js.map +0 -1
  59. package/dist/chunk-67RANGFQ.js.map +0 -1
  60. package/dist/chunk-6SD4X5PT.js.map +0 -1
  61. package/dist/chunk-6YIYFWO2.js.map +0 -1
  62. package/dist/chunk-AHWRAGXN.js.map +0 -1
  63. package/dist/chunk-IKBIIEVJ.js.map +0 -1
  64. package/dist/chunk-STMLZDKR.js.map +0 -1
  65. package/dist/chunk-WN7LZHII.cjs.map +0 -1
  66. package/dist/parser-2Q2YKEJG.js.map +0 -1
  67. package/dist/parser-3HM2VYKK.js.map +0 -1
  68. package/dist/parser-6AYYGX6J.cjs.map +0 -1
  69. package/dist/provider-5K7O3Z2O.cjs.map +0 -1
  70. package/dist/provider-7H4CPZYS.js.map +0 -1
  71. package/dist/provider-H4WWSPOV.js.map +0 -1
  72. package/dist/render-W4VCJE6N.js +0 -10
  73. package/dist/seal-DRPTNHOP.js +0 -10
  74. package/dist/watch-6OHF727O.js.map +0 -1
  75. /package/dist/{-XMKVL3NX.js.map → -QSF64HNK.js.map} +0 -0
  76. /package/dist/{detect-PJZMUL2Z.js.map → detect-RI2MQ33K.js.map} +0 -0
  77. /package/dist/{render-W4VCJE6N.js.map → render-JPP7YTV3.js.map} +0 -0
  78. /package/dist/{seal-DRPTNHOP.js.map → seal-MDE4DXZQ.js.map} +0 -0
@@ -11,13 +11,13 @@ import {
11
11
  dedupeRunningHeaders,
12
12
  flattenLayoutTables,
13
13
  mapPuaText
14
- } from "./chunk-6YIYFWO2.js";
14
+ } from "./chunk-PNQDQ3SM.js";
15
15
  import {
16
16
  detectFormat,
17
17
  detectOle2Format,
18
18
  detectZipFormat,
19
19
  parseLenientCfb
20
- } from "./chunk-5CJGKKMZ.js";
20
+ } from "./chunk-MEPHGCPQ.js";
21
21
  import {
22
22
  parsePageRange
23
23
  } from "./chunk-MOL7MDBG.js";
@@ -32,14 +32,14 @@ import {
32
32
  paraTextPureT,
33
33
  patchZipEntries,
34
34
  scanSectionXml
35
- } from "./chunk-67RANGFQ.js";
35
+ } from "./chunk-RO2GVZ3I.js";
36
36
  import {
37
37
  SPACE_EM_FIXED,
38
38
  charWidthEm1000,
39
39
  fitRatioForFewerLines,
40
40
  measureTextWidth,
41
41
  simulateWrap
42
- } from "./chunk-6SD4X5PT.js";
42
+ } from "./chunk-MQLKSRIK.js";
43
43
  import {
44
44
  MAX_DECOMPRESS_SIZE,
45
45
  MAX_XML_DEPTH,
@@ -50,7 +50,7 @@ import {
50
50
  createXmlParser,
51
51
  extractTextFromNode,
52
52
  findChildByLocalName
53
- } from "./chunk-IKBIIEVJ.js";
53
+ } from "./chunk-AUJICYJG.js";
54
54
  import {
55
55
  KordocError,
56
56
  classifyError,
@@ -61,7 +61,7 @@ import {
61
61
  sanitizeHref,
62
62
  stripDtd,
63
63
  toArrayBuffer
64
- } from "./chunk-STMLZDKR.js";
64
+ } from "./chunk-6JSZBSOD.js";
65
65
 
66
66
  // src/index.ts
67
67
  import { readFile } from "fs/promises";
@@ -199,9 +199,9 @@ async function extractHwpxStyles(zip, decompressed) {
199
199
  const parser = createXmlParser();
200
200
  const doc = parser.parseFromString(stripDtd(xml), "text/xml");
201
201
  if (!doc.documentElement) continue;
202
- parseCharProperties(doc, result.charProperties);
203
- parseStyleElements(doc, result.styles);
204
202
  const domDoc = doc;
203
+ parseCharProperties(domDoc, result.charProperties);
204
+ parseStyleElements(domDoc, result.styles);
205
205
  parseNumberings(domDoc, result.numberings);
206
206
  parseBullets(domDoc, result.bullets);
207
207
  parseParaHeadings(domDoc, result.paraHeadings);
@@ -1069,12 +1069,17 @@ function walkSection(node, blocks, tableCtx, tableStack, ctx, depth = 0) {
1069
1069
  break;
1070
1070
  }
1071
1071
  // 표/도표 캡션 — IRTable.caption으로 보존 (v3.0, 기존 무음 드롭 수정)
1072
- case "caption":
1073
- if (tableCtx) {
1074
- const capText = collectSubListText(el, ctx);
1075
- if (capText) tableCtx.caption = (tableCtx.caption ? tableCtx.caption + "\n" : "") + capText;
1072
+ case "caption": {
1073
+ const capText = collectSubListText(el, ctx);
1074
+ if (capText) {
1075
+ if (tableCtx) {
1076
+ tableCtx.caption = (tableCtx.caption ? tableCtx.caption + "\n" : "") + capText;
1077
+ } else {
1078
+ blocks.push({ type: "paragraph", text: capText, pageNumber: ctx.sectionNum });
1079
+ }
1076
1080
  }
1077
1081
  break;
1082
+ }
1078
1083
  case "tr":
1079
1084
  if (tableCtx) {
1080
1085
  tableCtx.currentRow = [];
@@ -1239,7 +1244,7 @@ function walkParagraphChildren(node, blocks, tableCtx, tableStack, ctx, depth =
1239
1244
  if (depth > MAX_XML_DEPTH) return tableCtx;
1240
1245
  const children = node.childNodes;
1241
1246
  if (!children) return tableCtx;
1242
- const walkChildren = (parent, d) => {
1247
+ const walkChildren = (parent, d, inShape = false) => {
1243
1248
  if (d > MAX_XML_DEPTH) return;
1244
1249
  const kids2 = parent.childNodes;
1245
1250
  if (!kids2) return;
@@ -1253,6 +1258,13 @@ function walkParagraphChildren(node, blocks, tableCtx, tableStack, ctx, depth =
1253
1258
  const newTable = { rows: [], currentRow: [], cell: null };
1254
1259
  walkSection(el, blocks, newTable, tableStack, ctx, d + 1);
1255
1260
  tableCtx = completeTable(newTable, tableStack, blocks, ctx);
1261
+ } else if (localTag === "caption" && !inShape) {
1262
+ const capText = collectSubListText(el, ctx);
1263
+ if (capText) {
1264
+ if (tableCtx?.cell) mergeBlocksIntoCell(tableCtx.cell, [{ type: "paragraph", text: capText, pageNumber: ctx.sectionNum }]);
1265
+ else if (tableCtx) tableCtx.caption = (tableCtx.caption ? tableCtx.caption + "\n" : "") + capText;
1266
+ else blocks.push({ type: "paragraph", text: capText, pageNumber: ctx.sectionNum });
1267
+ }
1256
1268
  } else if (localTag === "pic" || localTag === "shape" || localTag === "drawingObject") {
1257
1269
  if (tableCtx?.cell) {
1258
1270
  const sink = [];
@@ -1269,8 +1281,10 @@ function walkParagraphChildren(node, blocks, tableCtx, tableStack, ctx, depth =
1269
1281
  } else {
1270
1282
  extractDrawTextBlocks(el, blocks, ctx);
1271
1283
  }
1272
- } else if (localTag === "r" || localTag === "run" || localTag === "ctrl" || localTag === "rect" || localTag === "ellipse" || localTag === "polygon" || localTag === "line" || localTag === "arc" || localTag === "curve" || localTag === "connectLine" || localTag === "container") {
1273
- walkChildren(el, d + 1);
1284
+ } else if (localTag === "r" || localTag === "run" || localTag === "ctrl") {
1285
+ walkChildren(el, d + 1, inShape);
1286
+ } else if (localTag === "rect" || localTag === "ellipse" || localTag === "polygon" || localTag === "line" || localTag === "arc" || localTag === "curve" || localTag === "connectLine" || localTag === "container") {
1287
+ walkChildren(el, d + 1, true);
1274
1288
  }
1275
1289
  }
1276
1290
  };
@@ -1406,6 +1420,9 @@ function extractParagraphInfo(para2, styleMap, ctx) {
1406
1420
  case "indexmark":
1407
1421
  case "colPr":
1408
1422
  break;
1423
+ // 캡션 — walkParagraphChildren의 caption 분기가 보존하므로 손실 경고 대상 아님
1424
+ case "caption":
1425
+ break;
1409
1426
  // 미지원 요소 — 텍스트를 가졌으면 무음 손실 대신 경고
1410
1427
  default: {
1411
1428
  if (ctx?.warnings && extractTextFromNode(k)) {
@@ -19860,9 +19877,11 @@ var OFFICIAL_MARGINS = { top: 20, bottom: 15, left: 20, right: 15 };
19860
19877
  var GAEJOSIK_MARGINS = { top: 15, bottom: 15, left: 20, right: 20 };
19861
19878
  var GAEJOSIK_HEADER_FOOTER = 4251;
19862
19879
  var PRESET_DEFAULTS = {
19863
- official: { bodyPt: 15, lineSpacing: 160, numbering: "standard" },
19880
+ // 서울시 실결재 104건 12pt 64건(13pt 30, 15pt 5) — 지배값을 기본으로 사용.
19881
+ official: { bodyPt: 12, lineSpacing: 160, numbering: "standard" },
19864
19882
  report: { bodyPt: 15, lineSpacing: 160, numbering: "report" },
19865
- plan: { bodyPt: 15, lineSpacing: 160, numbering: "standard" },
19883
+ // 실측 추진계획안: * 계층.
19884
+ plan: { bodyPt: 15, lineSpacing: 160, numbering: "report" },
19866
19885
  notice: { bodyPt: 15, lineSpacing: 160, numbering: "standard" },
19867
19886
  minutes: { bodyPt: 14, lineSpacing: 130, numbering: "standard" },
19868
19887
  gaejosik: { bodyPt: 15, lineSpacing: 160, numbering: "gaejosik" },
@@ -19901,7 +19920,46 @@ function normalizeGongmunPreset(preset) {
19901
19920
  function usesReportFonts(preset) {
19902
19921
  return preset === "gaejosik" || preset === "report" || preset === "plan";
19903
19922
  }
19923
+ function usesAsteriskThird(preset) {
19924
+ return preset === "plan" || preset === "press";
19925
+ }
19926
+ function needsGaejosikAssets(gongmun) {
19927
+ return usesReportFonts(gongmun.preset) || gongmun.cover !== null || gongmun.toc;
19928
+ }
19929
+ function assertFiniteRange(name, value, min, max) {
19930
+ if (!Number.isFinite(value) || value < min || value > max) {
19931
+ throw new KordocError(`${name} must be a finite number between ${min} and ${max}`);
19932
+ }
19933
+ }
19934
+ function validateGongmunOptions(opts) {
19935
+ if (opts.bodyPt !== void 0) assertFiniteRange("bodyPt", opts.bodyPt, 6, 40);
19936
+ if (opts.lineSpacing !== void 0) assertFiniteRange("lineSpacing", opts.lineSpacing, 50, 300);
19937
+ if (typeof opts.autoFit === "object" && opts.autoFit.minRatio !== void 0) {
19938
+ assertFiniteRange("autoFit.minRatio", opts.autoFit.minRatio, 50, 99);
19939
+ }
19940
+ if (opts.margins) {
19941
+ for (const side of ["top", "bottom", "left", "right"]) {
19942
+ const value = opts.margins[side];
19943
+ assertFiniteRange(`margins.${side}`, value, 0, 200);
19944
+ }
19945
+ if (opts.margins.left + opts.margins.right >= 210) {
19946
+ throw new KordocError("margins.left + margins.right must be less than 210");
19947
+ }
19948
+ if (opts.margins.top + opts.margins.bottom >= 297) {
19949
+ throw new KordocError("margins.top + margins.bottom must be less than 297");
19950
+ }
19951
+ }
19952
+ if (opts.sizes) {
19953
+ for (const [key, value] of Object.entries(opts.sizes)) {
19954
+ if (value !== void 0) assertFiniteRange(`sizes.${key}`, value, 6, 60);
19955
+ }
19956
+ }
19957
+ if (opts.approval && opts.approval.length > 6) {
19958
+ throw new KordocError("approval must contain at most 6 labels");
19959
+ }
19960
+ }
19904
19961
  function resolveGongmun(opts) {
19962
+ validateGongmunOptions(opts);
19905
19963
  const preset = normalizeGongmunPreset(opts.preset);
19906
19964
  const d = PRESET_DEFAULTS[preset];
19907
19965
  const bodyPt = opts.bodyPt ?? d.bodyPt;
@@ -19919,8 +19977,10 @@ function resolveGongmun(opts) {
19919
19977
  margins: opts.margins ?? (reportFamily ? GAEJOSIK_MARGINS : OFFICIAL_MARGINS),
19920
19978
  centerTitle: opts.centerTitle ?? true,
19921
19979
  autoFitMinRatio,
19922
- cover: coverOn ? { date: coverOpts.date ?? null, org: coverOpts.org ?? "" } : null,
19923
- toc: opts.toc ?? gaejosik,
19980
+ // 보도자료는 머리박스가 1페이지 최상단을 차지하는 서식이라 표지·목차와 양립 불가
19981
+ // 켜면 머리박스가 표지에 얹히고 25pt 제목·부제가 유실된다 (docHead 프리셋 게이팅과 동일 관례)
19982
+ cover: coverOn && preset !== "press" ? { date: coverOpts.date ?? null, org: coverOpts.org ?? "" } : null,
19983
+ toc: preset !== "press" && (opts.toc ?? gaejosik),
19924
19984
  fonts: opts.fonts ?? {},
19925
19985
  sizes: opts.sizes ?? {},
19926
19986
  // 쪽번호 — 보고서 계열 관행(실측: 2_보고서 양식·추진계획·공고문 전부 하단 중앙)
@@ -19936,7 +19996,7 @@ function resolveGongmun(opts) {
19936
19996
  // h2 말머리 — 실측: 보고서 양식 □ 대항목(QA-2), 공고문 아라비아("1. 사업개요", 바이오헬스 실측)
19937
19997
  h2Marker: opts.h2Marker ?? (preset === "report" || preset === "plan" ? "box" : preset === "notice" ? "number" : "none"),
19938
19998
  // 2단계 부호 — 실결재 기안문·공고문 ㅇ 지배(60건 중 ㅇ134:○5), 보고서 양식 계열 ○
19939
- bullet2: opts.bullet2 ?? (preset === "notice" || preset === "press" ? "\u3147" : "\u25CB"),
19999
+ bullet2: opts.bullet2 ?? (preset === "plan" || preset === "notice" || preset === "press" ? "\u3147" : "\u25CB"),
19940
20000
  // 단일 형제 부호 생략 — 규정이지만 부호 없는 계단이 실무 눈에 어색 (실무자 QA)
19941
20001
  suppressSingle: opts.suppressSingle ?? false,
19942
20002
  docHead: preset === "official" && opts.docHead ? opts.docHead : null,
@@ -19962,7 +20022,7 @@ function circledHangul(n) {
19962
20022
  return String.fromCodePoint(12910 + n % 14);
19963
20023
  }
19964
20024
  var REPORT_BULLETS = ["\u25A1", "\u25CB", "-", "\u318D"];
19965
- var PRESS_BULLETS = ["\u25A1", "\u3147", "*", "\u318D"];
20025
+ var ASTERISK_BULLETS = ["\u25A1", "\u25CB", "*", "\u318D"];
19966
20026
  function standardMarker(depth, n) {
19967
20027
  switch (depth) {
19968
20028
  case 0:
@@ -19985,19 +20045,19 @@ function standardMarker(depth, n) {
19985
20045
  return circledHangul(n);
19986
20046
  }
19987
20047
  }
19988
- function reportMarker(depth, bullet2 = "\u25CB", press = false) {
19989
- const bullets = press ? PRESS_BULLETS : REPORT_BULLETS;
20048
+ function reportMarker(depth, bullet2 = "\u25CB", asteriskThird = false) {
20049
+ const bullets = asteriskThird ? ASTERISK_BULLETS : REPORT_BULLETS;
19990
20050
  const m = bullets[Math.min(depth, bullets.length - 1)];
19991
- return depth === 1 && !press ? bullet2 : m;
20051
+ return depth === 1 ? bullet2 : m;
19992
20052
  }
19993
20053
  function markerWidth(marker, bodyHeight) {
19994
20054
  let em = SPACE_EM_FIXED;
19995
20055
  for (const c of marker) em += charWidthEm1000(c.codePointAt(0));
19996
20056
  return Math.round(em / 1e3 * bodyHeight);
19997
20057
  }
19998
- function levelIndent(depth, bodyHeight, numbering, sizes = {}, bullet2 = "\u25CB", press = false) {
20058
+ function levelIndent(depth, bodyHeight, numbering, sizes = {}, bullet2 = "\u25CB", asteriskThird = false) {
19999
20059
  if (numbering === "gaejosik") return gaejosikLevelIndent(depth, bodyHeight, sizes, bullet2);
20000
- const marker = numbering === "report" ? reportMarker(depth, bullet2, press) : standardMarker(depth, 0);
20060
+ const marker = numbering === "report" ? reportMarker(depth, bullet2, asteriskThird) : standardMarker(depth, 0);
20001
20061
  return { left: Math.round(depth * bodyHeight), indent: -markerWidth(marker, bodyHeight) };
20002
20062
  }
20003
20063
  function computeSuppression(depths) {
@@ -20014,10 +20074,10 @@ function computeSuppression(depths) {
20014
20074
  return keys.map((k) => (counts.get(k) ?? 0) <= 1);
20015
20075
  }
20016
20076
  var GongmunNumberer = class {
20017
- constructor(numbering, bullet2 = "\u25CB", press = false) {
20077
+ constructor(numbering, bullet2 = "\u25CB", asteriskThird = false) {
20018
20078
  this.numbering = numbering;
20019
20079
  this.bullet2 = bullet2;
20020
- this.press = press;
20080
+ this.asteriskThird = asteriskThird;
20021
20081
  }
20022
20082
  counts = [];
20023
20083
  /** depth 항목 하나에 대한 마커. suppress=true면 빈 문자열(부호 없음) */
@@ -20027,7 +20087,7 @@ var GongmunNumberer = class {
20027
20087
  this.counts[depth] = n + 1;
20028
20088
  if (suppress) return "";
20029
20089
  if (this.numbering === "gaejosik") return gaejosikMarker(depth, this.bullet2);
20030
- return this.numbering === "report" ? reportMarker(depth, this.bullet2, this.press) : standardMarker(depth, n);
20090
+ return this.numbering === "report" ? reportMarker(depth, this.bullet2, this.asteriskThird) : standardMarker(depth, n);
20031
20091
  }
20032
20092
  reset() {
20033
20093
  this.counts = [];
@@ -20143,13 +20203,16 @@ var GJ_CHAR_TABLE = 22;
20143
20203
  var GJ_CHAR_TABLE_BOLD = 23;
20144
20204
  var GJ_CHAR_BAR = 24;
20145
20205
  var GJ_CHAR_BODY_TITLE = 25;
20146
- var GJ_CHAR_COUNT = 15;
20206
+ var GJ_CHAR_TITLE_BAR = 26;
20207
+ var GJ_CHAR_APPROVAL = 27;
20208
+ var GJ_CHAR_COUNT = 17;
20147
20209
  var GJ_PARA_CHAM = 20;
20148
20210
  var GJ_PARA_COVER = 21;
20149
20211
  var GJ_PARA_TOC_ITEM = 22;
20150
20212
  var GJ_PARA_CHAPTER = 23;
20151
20213
  var GJ_PARA_BAR = 24;
20152
20214
  var GONGMUN_LIST_PLAIN_BASE = 25;
20215
+ var GONGMUN_PARA_APPROVAL = GONGMUN_LIST_PLAIN_BASE + GONGMUN_LIST_LEVELS;
20153
20216
  var GJ_BF_CHAPTER_NUM = 3;
20154
20217
  var GJ_BF_CHAPTER_GAP = 4;
20155
20218
  var GJ_BF_CHAPTER_TITLE = 5;
@@ -20157,8 +20220,8 @@ var GJ_BF_BAR_DARK = 6;
20157
20220
  var GJ_BF_BAR_LIGHT = 7;
20158
20221
  var GJ_BF_TOC_BOX = 8;
20159
20222
  var GJ_BF_TOC_STRIPE = 9;
20160
- function gongmunTableHeaderBf(gaejosik) {
20161
- return gaejosik ? 10 : 3;
20223
+ function gongmunTableHeaderBf(richAssets) {
20224
+ return richAssets ? 10 : 3;
20162
20225
  }
20163
20226
  function borderFillEntry(id, b, fill) {
20164
20227
  const side = (name, v) => v ? ` <hh:${name} type="${v[2] ?? "SOLID"}" width="${v[0]}" color="${v[1]}"/>` : ` <hh:${name} type="NONE" width="0.1 mm" color="#000000"/>`;
@@ -20191,10 +20254,12 @@ function pageHidingCtrl(hideHeader = false) {
20191
20254
  var GONGMUN_TBL_CHAR = 11;
20192
20255
  var GONGMUN_TBL_CHAR_BOLD = 12;
20193
20256
  var GONGMUN_TBL_PT = 1200;
20257
+ var GONGMUN_TITLE_BAR_CHAR = 13;
20258
+ var GONGMUN_APPROVAL_CHAR = 14;
20194
20259
  var CHAR_VARIANT_BASE = 11;
20195
- function charVariantBase(measured, isGongmun = true) {
20260
+ function charVariantBase(richAssets, isGongmun = true) {
20196
20261
  if (!isGongmun) return CHAR_VARIANT_BASE;
20197
- return measured ? 11 + GJ_CHAR_COUNT : 11 + 2;
20262
+ return richAssets ? 11 + GJ_CHAR_COUNT : 11 + 4;
20198
20263
  }
20199
20264
  var GONGMUN_BODY_RATIO = 95;
20200
20265
 
@@ -20443,6 +20508,7 @@ function generateManifest(chartParts = []) {
20443
20508
  }
20444
20509
  function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls = []) {
20445
20510
  const measured = !!gongmun && usesReportFonts(gongmun.preset);
20511
+ const richAssets = !!gongmun && needsGaejosikAssets(gongmun);
20446
20512
  let body = 1e3, code = 900, h1 = 1800, h2 = 1400, h3 = 1200, h4 = 1100;
20447
20513
  if (gongmun) {
20448
20514
  body = gongmun.bodyHeight;
@@ -20450,9 +20516,9 @@ function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls
20450
20516
  h1 = gongmun.preset === "report" || gongmun.preset === "plan" ? 2e3 : 1700;
20451
20517
  h2 = 1600;
20452
20518
  h3 = body;
20453
- h4 = Math.max(body - 100, 1300);
20519
+ h4 = Math.min(h3, Math.max(body - 100, 1300));
20454
20520
  }
20455
- const bodyFont = measured ? 4 : 0;
20521
+ const bodyFont = richAssets ? 4 : 0;
20456
20522
  const hFont = measured ? 3 : 1;
20457
20523
  const hBold = !measured;
20458
20524
  const bodyRatio = gongmun ? GONGMUN_BODY_RATIO : 100;
@@ -20469,13 +20535,15 @@ function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls
20469
20535
  charPr(CHAR_TABLE_HEADER, body, theme.tableHeaderBold, false, bodyFont, theme.tableHeader),
20470
20536
  charPr(CHAR_QUOTE, body, false, true, bodyFont, theme.quote)
20471
20537
  ];
20472
- if (gongmun && !measured) {
20538
+ if (gongmun && !richAssets) {
20473
20539
  rows.push(
20474
20540
  charPr(11, GONGMUN_TBL_PT, false, false, bodyFont, theme.body),
20475
- charPr(12, GONGMUN_TBL_PT, true, false, bodyFont, theme.body)
20541
+ charPr(12, GONGMUN_TBL_PT, true, false, bodyFont, theme.body),
20542
+ charPr(GONGMUN_TITLE_BAR_CHAR, 100, false, false, bodyFont, theme.body),
20543
+ charPr(GONGMUN_APPROVAL_CHAR, 1e3, false, false, bodyFont, theme.body)
20476
20544
  );
20477
20545
  }
20478
- if (measured) {
20546
+ if (richAssets) {
20479
20547
  const sz = gaejosikSizes(body, gongmun.sizes);
20480
20548
  rows.push(
20481
20549
  charPr(11, sz.dae, false, false, 3),
@@ -20506,8 +20574,12 @@ function buildCharProperties(theme, gongmun, ratioVariants = [], extraCharPrXmls
20506
20574
  // 표 셀 bold
20507
20575
  charPr(24, sz.bar, false, false, 4),
20508
20576
  // 표지 바 셀 빈 문단(6pt)
20509
- charPr(25, sz.bodyTitle, false, false, 3)
20577
+ charPr(25, sz.bodyTitle, false, false, 3),
20510
20578
  // 본문 제목박스(HY헤드라인M 22pt, 실측 GT3 표④)
20579
+ charPr(GJ_CHAR_TITLE_BAR, 100, false, false, 4),
20580
+ // 1페이지형 제목박스 바(1pt)
20581
+ charPr(GJ_CHAR_APPROVAL, 1e3, false, false, 7)
20582
+ // 결재란 라벨(맑은 고딕 10pt)
20511
20583
  );
20512
20584
  }
20513
20585
  for (const r of ratioVariants) {
@@ -20553,7 +20625,7 @@ ${base2.join("\n")}
20553
20625
  paraPr(7, { align: "LEFT", lineSpacing: ls, indent: 600, keepWord: true })
20554
20626
  ];
20555
20627
  for (let d = 0; d < GONGMUN_LIST_LEVELS; d++) {
20556
- const { left, indent } = levelIndent(d, gongmun.bodyHeight, gongmun.numbering, gongmun.sizes, gongmun.bullet2, gongmun.preset === "press");
20628
+ const { left, indent } = levelIndent(d, gongmun.bodyHeight, gongmun.numbering, gongmun.sizes, gongmun.bullet2, usesAsteriskThird(gongmun.preset));
20557
20629
  const sectionGap = gongmun.numbering === "gaejosik" || gongmun.numbering === "report" ? gaejosikSpaceBefore(d, gongmun.bodyHeight) : 0;
20558
20630
  const keepNext = (gongmun.numbering === "gaejosik" || gongmun.numbering === "report") && d === 0;
20559
20631
  base.push(paraPr(GONGMUN_LIST_BASE + d, { align: "JUSTIFY", lineSpacing: ls, left, indent, spaceBefore: sectionGap, keepWord: true, keepWithNext: keepNext }));
@@ -20576,10 +20648,11 @@ ${base2.join("\n")}
20576
20648
  );
20577
20649
  }
20578
20650
  for (let d = 0; d < GONGMUN_LIST_LEVELS; d++) {
20579
- const { left } = levelIndent(d, gongmun.bodyHeight, gongmun.numbering, gongmun.sizes, gongmun.bullet2, gongmun.preset === "press");
20651
+ const { left } = levelIndent(d, gongmun.bodyHeight, gongmun.numbering, gongmun.sizes, gongmun.bullet2, usesAsteriskThird(gongmun.preset));
20580
20652
  const sectionGap = gongmun.numbering === "gaejosik" || gongmun.numbering === "report" ? gaejosikSpaceBefore(d, gongmun.bodyHeight) : 0;
20581
20653
  base.push(paraPr(GONGMUN_LIST_PLAIN_BASE + d, { align: "JUSTIFY", lineSpacing: ls, left, indent: 0, spaceBefore: sectionGap, keepWord: true }));
20582
20654
  }
20655
+ base.push(paraPr(GONGMUN_PARA_APPROVAL, { align: "CENTER", lineSpacing: 100, keepWord: true }));
20583
20656
  return `<hh:paraProperties itemCnt="${base.length}">
20584
20657
  ${base.join("\n")}
20585
20658
  </hh:paraProperties>`;
@@ -20596,14 +20669,14 @@ ${heads}
20596
20669
  </hh:numberings>`;
20597
20670
  }
20598
20671
  function fontEntry(id, face, weight = 6) {
20599
- return ` <hh:font id="${id}" face="${face}" type="TTF" isEmbedded="0">
20672
+ return ` <hh:font id="${id}" face="${escapeXml(face)}" type="TTF" isEmbedded="0">
20600
20673
  <hh:typeInfo familyType="FCAT_GOTHIC" weight="${weight}" proportion="4" contrast="0" strokeVariation="1" armStyle="1" letterform="1" midline="1" xHeight="1"/>
20601
20674
  </hh:font>`;
20602
20675
  }
20603
20676
  function buildFontFaces(gongmun, bodyFace) {
20604
- if (gongmun && usesReportFonts(gongmun.preset)) {
20677
+ if (gongmun && needsGaejosikAssets(gongmun)) {
20605
20678
  const ov = gongmun.fonts;
20606
- const bodyDefault = gongmun.preset !== "gaejosik" && gongmun.bodyFont === "gothic" ? "\uB9D1\uC740 \uACE0\uB515" : "\uD734\uBA3C\uBA85\uC870";
20679
+ const bodyDefault = usesReportFonts(gongmun.preset) ? gongmun.preset !== "gaejosik" && gongmun.bodyFont === "gothic" ? "\uB9D1\uC740 \uACE0\uB515" : "\uD734\uBA3C\uBA85\uC870" : bodyFace;
20607
20680
  const faces = [
20608
20681
  "\uD568\uCD08\uB86C\uBC14\uD0D5",
20609
20682
  "\uD568\uCD08\uB86C\uB3CB\uC6C0",
@@ -20662,7 +20735,7 @@ function buildBorderFills(gongmun, extra = []) {
20662
20735
  borderFillEntry(1, {}),
20663
20736
  borderFillEntry(2, { l: thin, r: thin, t: thin, b: thin })
20664
20737
  ];
20665
- if (gongmun?.preset === "gaejosik") {
20738
+ if (gongmun && needsGaejosikAssets(gongmun)) {
20666
20739
  const c = GAEJOSIK_COLORS;
20667
20740
  const edge = ["0.12 mm", c.border];
20668
20741
  const grayLine = ["0.1 mm", c.titleLine];
@@ -20959,7 +21032,7 @@ function computeGongmunFitPlan(blocks, gongmun, gongmunList) {
20959
21032
  if (gongmun.numbering === "gaejosik" && (depth === 0 || (block.text || "").trimStart().startsWith("\u203B"))) continue;
20960
21033
  const content = plainRenderText(block.text || "");
20961
21034
  text = marker ? `${marker} ${content}` : content;
20962
- const li = levelIndent(depth, gongmun.bodyHeight, gongmun.numbering, gongmun.sizes, gongmun.bullet2, gongmun.preset === "press");
21035
+ const li = levelIndent(depth, gongmun.bodyHeight, gongmun.numbering, gongmun.sizes, gongmun.bullet2, usesAsteriskThird(gongmun.preset));
20963
21036
  const left = li.left;
20964
21037
  const indent = marker ? li.indent : 0;
20965
21038
  firstW = pageW - left - Math.max(indent, 0);
@@ -21017,7 +21090,7 @@ function precomputeGongmunList(blocks, gongmun) {
21017
21090
  }
21018
21091
  const depths = run.map((bi) => Math.min(Math.max((blocks[bi].indent || 0) + depthOffset, 0), GONGMUN_LIST_LEVELS - 1));
21019
21092
  const suppress = gongmun.suppressSingle && gongmun.numbering === "standard" ? computeSuppression(depths) : depths.map(() => false);
21020
- const numberer = new GongmunNumberer(gongmun.numbering, gongmun.bullet2, gongmun.preset === "press");
21093
+ const numberer = new GongmunNumberer(gongmun.numbering, gongmun.bullet2, usesAsteriskThird(gongmun.preset));
21021
21094
  run.forEach((bi, k) => {
21022
21095
  const marker = numberer.next(depths[k], suppress[k]);
21023
21096
  result.set(bi, { marker, depth: depths[k] });
@@ -21906,6 +21979,7 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
21906
21979
  const reg = style?.bfRegistry ?? null;
21907
21980
  let htmlHeaderRows = 0;
21908
21981
  while (htmlHeaderRows < rows.length && rows[htmlHeaderRows].tag === "th") htmlHeaderRows++;
21982
+ const tableRowHeights = Array(rowCnt).fill(cellH);
21909
21983
  const tcXmls = placed.map((cell2, i) => {
21910
21984
  const k = `${cell2.r},${cell2.c}`;
21911
21985
  const isHeader = cell2.isHeader;
@@ -21933,6 +22007,10 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
21933
22007
  }
21934
22008
  const contentH = Math.max(cellH * cell2.rowSpan, Math.max(lines.length, 1) * (style ? Math.round(measureH * 1.6) : 800) + nestedH);
21935
22009
  const cellHeight = Math.max(prof?.cellH.get(k) ?? 0, contentH);
22010
+ const perRow = Math.ceil(cellHeight / cell2.rowSpan);
22011
+ for (let r = cell2.r; r < Math.min(cell2.r + cell2.rowSpan, rowCnt); r++) {
22012
+ tableRowHeights[r] = Math.max(tableRowHeights[r], perRow);
22013
+ }
21936
22014
  const bf = prof?.cellBf.get(k) ?? (reg ? reg.get(dataCellSpec({
21937
22015
  row: cell2.r,
21938
22016
  rowEnd: cell2.r + cell2.rowSpan - 1,
@@ -21950,7 +22028,8 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, style = null, r
21950
22028
  const rowTcs = tcXmls.filter((_, i) => placed[i].r === r);
21951
22029
  trXmls.push(`<hp:tr>${rowTcs.join("")}</hp:tr>`);
21952
22030
  }
21953
- return `<hp:tbl id="${tblId}" zOrder="0" numberingType="TABLE" pageBreak="CELL" repeatHeader="${style ? 1 : 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>`;
22031
+ const tableH = tableRowHeights.reduce((sum, height) => sum + height, 0);
22032
+ return `<hp:tbl id="${tblId}" zOrder="0" numberingType="TABLE" pageBreak="CELL" repeatHeader="${style ? 1 : 0}" rowCnt="${rowCnt}" colCnt="${colCnt}" cellSpacing="0" borderFillIDRef="2" noShading="0"><hp:sz width="${tblW}" widthRelTo="ABSOLUTE" height="${tableH}" 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>`;
21954
22033
  }
21955
22034
 
21956
22035
  // src/hwpx/gen-gongmun-extra.ts
@@ -21965,9 +22044,9 @@ function para(text, paraPrId, charPrId) {
21965
22044
  return `<hp:p paraPrIDRef="${paraPrId}" styleIDRef="0"><hp:run charPrIDRef="${charPrId}"><hp:t>${escapeXml(text)}</hp:t></hp:run></hp:p>`;
21966
22045
  }
21967
22046
  var APPROVAL_COL_W = 7085;
21968
- var APPROVAL_LABEL_H = 1100;
22047
+ var APPROVAL_LABEL_H = 1300;
21969
22048
  var APPROVAL_SIGN_H = 4200;
21970
- function buildApprovalTable(labels, gongmun, reg) {
22049
+ function buildApprovalTable(labels, reg, approvalCharPr) {
21971
22050
  const n = labels.length;
21972
22051
  const w = APPROVAL_COL_W * n;
21973
22052
  const bfAt = (row, col) => reg.get({
@@ -21977,10 +22056,10 @@ function buildApprovalTable(labels, gongmun, reg) {
21977
22056
  r: col === n - 1 ? "thick" : "thin"
21978
22057
  });
21979
22058
  const labelRow = labels.map(
21980
- (label, c) => tc({ bf: bfAt(0, c), row: 0, col: c, w: APPROVAL_COL_W, h: APPROVAL_LABEL_H, paras: para(label, GONGMUN_TBL_CENTER, CHAR_NORMAL) })
22059
+ (label, c) => tc({ bf: bfAt(0, c), row: 0, col: c, w: APPROVAL_COL_W, h: APPROVAL_LABEL_H, paras: para(label, GONGMUN_PARA_APPROVAL, approvalCharPr) })
21981
22060
  ).join("");
21982
22061
  const signRow = labels.map(
21983
- (_, c) => tc({ bf: bfAt(1, c), row: 1, col: c, w: APPROVAL_COL_W, h: APPROVAL_SIGN_H, paras: para("", GONGMUN_TBL_CENTER, CHAR_NORMAL) })
22062
+ (_, c) => tc({ bf: bfAt(1, c), row: 1, col: c, w: APPROVAL_COL_W, h: APPROVAL_SIGN_H, paras: para("", GONGMUN_PARA_APPROVAL, approvalCharPr) })
21984
22063
  ).join("");
21985
22064
  const table2 = tbl([labelRow, signRow], w, APPROVAL_LABEL_H + APPROVAL_SIGN_H, n);
21986
22065
  return `<hp:p paraPrIDRef="${GONGMUN_RIGHT}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}">${table2}</hp:run></hp:p>`;
@@ -21992,13 +22071,13 @@ function buildEndMark() {
21992
22071
  return para(" \uB05D.", PARA_NORMAL, CHAR_NORMAL);
21993
22072
  }
21994
22073
  var TITLE_BOX = { barH: 382, titleH: 2850, color: "#0080C0", gradient: ["#0080C0", "#3CBFFF"] };
21995
- function buildTitleBox(title, titleCharPr, bodyWidth, reg) {
22074
+ function buildTitleBox(title, titleCharPr, barCharPr, bodyWidth, reg) {
21996
22075
  const w = bodyWidth - 280;
21997
22076
  const outer = { t: "thin", b: "thin", l: "thin", r: "thin" };
21998
22077
  const barTop = reg.get({ ...outer, fill: TITLE_BOX.color });
21999
22078
  const barBottom = reg.get({ ...outer, fill: { gradient: TITLE_BOX.gradient } });
22000
22079
  const mid = reg.get(outer);
22001
- const barPara = `<hp:p paraPrIDRef="${GONGMUN_TBL_CENTER}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}"><hp:t></hp:t></hp:run></hp:p>`;
22080
+ const barPara = para("", GJ_PARA_BAR, barCharPr);
22002
22081
  const rows = [
22003
22082
  tc({ bf: barTop, row: 0, col: 0, w, h: TITLE_BOX.barH, paras: barPara }),
22004
22083
  tc({ bf: mid, row: 1, col: 0, w, h: TITLE_BOX.titleH, paras: para(title, GONGMUN_TBL_CENTER, titleCharPr) }),
@@ -22015,8 +22094,8 @@ function docframeIds(base) {
22015
22094
  function docframeActive(g) {
22016
22095
  return !!(g.docHead || g.docFoot || g.reportInfo || g.noticeHead || g.press);
22017
22096
  }
22018
- function docframeCharPrXmls(base, measured) {
22019
- const body = measured ? 4 : 0;
22097
+ function docframeCharPrXmls(base, richAssets) {
22098
+ const body = richAssets ? 4 : 0;
22020
22099
  const ids = docframeIds(base);
22021
22100
  return [
22022
22101
  charPr(ids.org, 1800, true, false, body),
@@ -22423,15 +22502,16 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22423
22502
  let prevWasOrdered = false;
22424
22503
  const gaejosik = gongmun?.preset === "gaejosik";
22425
22504
  const measured = !!gongmun && usesReportFonts(gongmun.preset);
22426
- const vBase = charVariantBase(measured, !!gongmun);
22505
+ const richAssets = !!gongmun && needsGaejosikAssets(gongmun);
22506
+ const vBase = charVariantBase(richAssets, !!gongmun);
22427
22507
  const tableStyle = gongmun ? {
22428
22508
  totalWidth: mmToHwpunit(210 - gongmun.margins.left - gongmun.margins.right),
22429
22509
  // 표 셀 크기 — 실측: 실측 프리셋 맑은 고딕 12pt(22·23), 비실측도 12pt(11·12,
22430
22510
  // 실결재 지배값 — 본문 크기 셀은 열폭 부족으로 서술 열 세로 신장, v4.0.2 QA)
22431
- charPr: measured ? GJ_CHAR_TABLE : GONGMUN_TBL_CHAR,
22432
- boldCharPr: measured ? GJ_CHAR_TABLE_BOLD : GONGMUN_TBL_CHAR_BOLD,
22433
- charHeight: measured ? gaejosikSizes(gongmun.bodyHeight, gongmun.sizes).table : GONGMUN_TBL_PT,
22434
- headerBf: gongmunTableHeaderBf(gaejosik),
22511
+ charPr: richAssets ? GJ_CHAR_TABLE : GONGMUN_TBL_CHAR,
22512
+ boldCharPr: richAssets ? GJ_CHAR_TABLE_BOLD : GONGMUN_TBL_CHAR_BOLD,
22513
+ charHeight: richAssets ? gaejosikSizes(gongmun.bodyHeight, gongmun.sizes).table : GONGMUN_TBL_PT,
22514
+ headerBf: gongmunTableHeaderBf(richAssets),
22435
22515
  centerParaPr: GONGMUN_CENTER,
22436
22516
  tblCenterParaPr: GONGMUN_TBL_CENTER,
22437
22517
  tblLeftParaPr: GONGMUN_TBL_LEFT,
@@ -22452,7 +22532,7 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22452
22532
  preamble.push(buildReportInfo(gongmun, dfIds));
22453
22533
  }
22454
22534
  if (gongmun?.approval && bfReg) {
22455
- preamble.push(buildApprovalTable(gongmun.approval, gongmun, bfReg));
22535
+ preamble.push(buildApprovalTable(gongmun.approval, bfReg, richAssets ? GJ_CHAR_APPROVAL : GONGMUN_APPROVAL_CHAR));
22456
22536
  }
22457
22537
  if (gongmun?.docHead && dfIds) {
22458
22538
  preamble.push(...buildDocHead(gongmun, dfIds));
@@ -22463,7 +22543,7 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22463
22543
  if (gongmun?.press && dfIds && bfReg && tableStyle) {
22464
22544
  preamble.push(...buildPressHead(gongmun, dfIds, tableStyle.totalWidth, bfReg));
22465
22545
  }
22466
- if (gaejosik && gongmun) {
22546
+ if (gongmun && (gongmun.cover || gongmun.toc)) {
22467
22547
  const h1Idx = blocks.findIndex((b) => b.type === "heading" && (b.level ?? 1) === 1);
22468
22548
  const chapters = blocks.filter((b) => b.type === "heading" && b.level === 2).map((b) => stripChapterNumber(b.text || ""));
22469
22549
  let coverTitle = "";
@@ -22485,9 +22565,10 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22485
22565
  if (gongmun.bodyTitleBox && coverTitle && hasFrontPages) {
22486
22566
  preamble.push(buildGaejosikBodyTitle(coverTitle, gongmun).replace(/^<hp:p /, `<hp:p pageBreak="1" `));
22487
22567
  }
22488
- } else if (gongmun && !gaejosik && bfReg && (gongmun.preset === "report" || gongmun.preset === "plan" || gongmun.preset === "notice")) {
22568
+ }
22569
+ if (gongmun && !gaejosik && coverH1Idx < 0 && bfReg && (gongmun.preset === "report" || gongmun.preset === "plan" || gongmun.preset === "notice")) {
22489
22570
  titleBoxH1Idx = blocks.findIndex((b) => b.type === "heading" && (b.level ?? 1) === 1);
22490
- } else if (gongmun?.press && dfIds) {
22571
+ } else if (gongmun?.press && coverH1Idx < 0 && dfIds) {
22491
22572
  pressH1Idx = blocks.findIndex((b) => b.type === "heading" && (b.level ?? 1) === 1);
22492
22573
  }
22493
22574
  if (preamble.length > 0) {
@@ -22508,6 +22589,7 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22508
22589
  }
22509
22590
  switch (block.type) {
22510
22591
  case "heading": {
22592
+ if (gongmun && blockIdx === coverH1Idx) break;
22511
22593
  if (gongmun && blockIdx === pressH1Idx && dfIds) {
22512
22594
  const parts = [generateParagraph((block.text || "").trim(), GONGMUN_CENTER, dfIds.pressTitle)];
22513
22595
  for (const s of gongmun.press?.sub ?? []) {
@@ -22517,12 +22599,17 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22517
22599
  break;
22518
22600
  }
22519
22601
  if (gongmun && blockIdx === titleBoxH1Idx && tableStyle && bfReg) {
22520
- xml = buildTitleBox((block.text || "").trim(), measured ? GJ_CHAR_BODY_TITLE : CHAR_H1, tableStyle.totalWidth, bfReg);
22602
+ xml = buildTitleBox(
22603
+ (block.text || "").trim(),
22604
+ measured ? GJ_CHAR_BODY_TITLE : CHAR_H1,
22605
+ richAssets ? GJ_CHAR_TITLE_BAR : GONGMUN_TITLE_BAR_CHAR,
22606
+ tableStyle.totalWidth,
22607
+ bfReg
22608
+ );
22521
22609
  break;
22522
22610
  }
22523
22611
  if (gaejosik) {
22524
22612
  const lvl = block.level || 1;
22525
- if (blockIdx === coverH1Idx) break;
22526
22613
  if (lvl <= 2) {
22527
22614
  chapterNo++;
22528
22615
  xml = buildGaejosikChapter(chapterNo, stripChapterNumber(block.text || ""), gongmun);
@@ -22737,16 +22824,16 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
22737
22824
  async function markdownToHwpx(markdown, options) {
22738
22825
  const theme = resolveTheme(options?.theme);
22739
22826
  const gongmun = options?.gongmun ? resolveGongmun(options.gongmun) : null;
22740
- const gaejosik = gongmun?.preset === "gaejosik";
22741
22827
  const measured = !!gongmun && usesReportFonts(gongmun.preset);
22828
+ const richAssets = !!gongmun && needsGaejosikAssets(gongmun);
22742
22829
  const blocks = parseMarkdownToBlocks(markdown);
22743
22830
  const gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null;
22744
22831
  const fit = gongmun && gongmunList ? computeGongmunFitPlan(blocks, gongmun, gongmunList) : null;
22745
- const staticBfEnd = gongmun ? gaejosik ? 11 : 4 : 3;
22746
- const remap = options?.profile ? buildProfileRemap(options.profile, charVariantBase(measured, !!gongmun) + (fit?.variants?.length ?? 0) * 4, staticBfEnd) : null;
22832
+ const staticBfEnd = gongmun ? richAssets ? 11 : 4 : 3;
22833
+ const remap = options?.profile ? buildProfileRemap(options.profile, charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4, staticBfEnd) : null;
22747
22834
  const bfReg = gongmun ? new TableBfRegistry(staticBfEnd + (remap?.borderFillXmls.length ?? 0)) : null;
22748
22835
  const dfActive = !!gongmun && docframeActive(gongmun);
22749
- const dfBase = charVariantBase(measured, !!gongmun) + (fit?.variants?.length ?? 0) * 4 + (remap?.charPrXmls.length ?? 0);
22836
+ const dfBase = charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4 + (remap?.charPrXmls.length ?? 0);
22750
22837
  const dfIds = dfActive ? docframeIds(dfBase) : null;
22751
22838
  const chartParts = [];
22752
22839
  const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, bfReg, remap, dfIds);
@@ -22766,7 +22853,7 @@ async function markdownToHwpx(markdown, options) {
22766
22853
  gongmun,
22767
22854
  fit?.variants ?? [],
22768
22855
  extraBorderFills,
22769
- [...remap?.charPrXmls ?? [], ...dfActive ? docframeCharPrXmls(dfBase, measured) : []]
22856
+ [...remap?.charPrXmls ?? [], ...dfActive ? docframeCharPrXmls(dfBase, richAssets) : []]
22770
22857
  ));
22771
22858
  zip.file("Contents/section0.xml", sectionXml);
22772
22859
  for (const part of chartParts) zip.file(part.name, part.xml);
@@ -26120,7 +26207,7 @@ async function parseHwp(buffer, options) {
26120
26207
  async function parsePdf(buffer, options) {
26121
26208
  let parsePdfDocument;
26122
26209
  try {
26123
- const mod = await import("./parser-3HM2VYKK.js");
26210
+ const mod = await import("./parser-AODAQQLQ.js");
26124
26211
  parsePdfDocument = mod.parsePdfDocument;
26125
26212
  } catch {
26126
26213
  return {
@@ -26252,4 +26339,4 @@ export {
26252
26339
  parseHwpml,
26253
26340
  fillForm
26254
26341
  };
26255
- //# sourceMappingURL=chunk-AHWRAGXN.js.map
26342
+ //# sourceMappingURL=chunk-K2SETHJ6.js.map