kordoc 4.21.15 → 4.21.17

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 (129) hide show
  1. package/README.md +7 -5
  2. package/dist/{-HYTPLFLG.js → -GS6LEDZ6.js} +11 -11
  3. package/dist/{chunk-ZCGVIGG5.js → chunk-3PYAUHWY.js} +2 -2
  4. package/dist/{chunk-HIXDQ43L.js → chunk-6F6L63RG.js} +31 -26
  5. package/dist/chunk-6F6L63RG.js.map +1 -0
  6. package/dist/{chunk-7JCSAOTM.js → chunk-7ASI3XKM.js} +3 -3
  7. package/dist/{chunk-IJK4VDEU.js → chunk-7NXHIM2I.js} +2 -2
  8. package/dist/{chunk-NUUFPRNE.js → chunk-AJJLT6QJ.js} +2 -2
  9. package/dist/{chunk-TJQ7ME2Z.js → chunk-BTMFVKL7.js} +2 -2
  10. package/dist/{chunk-SQFCH4AY.js → chunk-FMUBLLIZ.js} +6 -6
  11. package/dist/{chunk-ER3N3QPL.js → chunk-FWQHYJZ2.js} +2 -2
  12. package/dist/{chunk-W6TVVTVX.js → chunk-GTSEPXAH.js} +4 -4
  13. package/dist/{chunk-CHQLIGVR.cjs → chunk-I43ZKTUM.cjs} +28 -25
  14. package/dist/chunk-I43ZKTUM.cjs.map +1 -0
  15. package/dist/{chunk-VOSAGXM6.js → chunk-I7TWFW4X.js} +9 -6
  16. package/dist/chunk-I7TWFW4X.js.map +1 -0
  17. package/dist/{chunk-6CVYB634.js → chunk-J2FMAYNJ.js} +2 -2
  18. package/dist/{chunk-B5WKFVQN.cjs → chunk-L3U6MKGV.cjs} +3 -3
  19. package/dist/{chunk-B5WKFVQN.cjs.map → chunk-L3U6MKGV.cjs.map} +1 -1
  20. package/dist/{chunk-VFGH2R4P.js → chunk-L3VCBSFW.js} +2 -2
  21. package/dist/{chunk-5B5LMAUW.js → chunk-ORNPI5YF.js} +2 -2
  22. package/dist/{chunk-YE3LPTBT.js → chunk-OZW5RYGF.js} +2 -2
  23. package/dist/{chunk-NHMRAR3I.js → chunk-PEQ5K2JO.js} +2 -2
  24. package/dist/{chunk-OUBHY6W3.js → chunk-Q4GXF444.js} +2 -2
  25. package/dist/{chunk-65GJ2MMG.js → chunk-QLL7VG6L.js} +2 -2
  26. package/dist/{chunk-AFDLKT76.cjs → chunk-QMQCFVTC.cjs} +3 -3
  27. package/dist/{chunk-AFDLKT76.cjs.map → chunk-QMQCFVTC.cjs.map} +1 -1
  28. package/dist/{chunk-CRDBLQU5.js → chunk-S27YQEPA.js} +10 -7
  29. package/dist/chunk-S27YQEPA.js.map +1 -0
  30. package/dist/{chunk-FGC3EEQD.js → chunk-TUSREHO3.js} +2 -2
  31. package/dist/{chunk-M4LXFLAV.js → chunk-TZU7PXV2.js} +2 -2
  32. package/dist/{chunk-ZTEBJBJK.js → chunk-UEI7A4N5.js} +2 -2
  33. package/dist/{chunk-Y64SVE5C.js → chunk-VOMOC7YF.js} +3 -3
  34. package/dist/{chunk-QA5KN5IT.cjs → chunk-VVFNVMFM.cjs} +6 -6
  35. package/dist/{chunk-QA5KN5IT.cjs.map → chunk-VVFNVMFM.cjs.map} +1 -1
  36. package/dist/{chunk-LYWRIUZY.js → chunk-XBQ554QP.js} +3 -3
  37. package/dist/{chunk-Q2BKBY3O.cjs → chunk-Y4TO3GBF.cjs} +2 -2
  38. package/dist/{chunk-Q2BKBY3O.cjs.map → chunk-Y4TO3GBF.cjs.map} +1 -1
  39. package/dist/{chunk-SJJQ47DB.cjs → chunk-Z3OHMNYF.cjs} +13 -13
  40. package/dist/{chunk-SJJQ47DB.cjs.map → chunk-Z3OHMNYF.cjs.map} +1 -1
  41. package/dist/chunks-RRV5535L.js +10 -0
  42. package/dist/cli.js +30 -30
  43. package/dist/{formula-H7CXHNLU.cjs → formula-BCCH3T3Y.cjs} +9 -9
  44. package/dist/{formula-H7CXHNLU.cjs.map → formula-BCCH3T3Y.cjs.map} +1 -1
  45. package/dist/{formula-NC3C6E3I.js → formula-CJ5DGNGC.js} +3 -3
  46. package/dist/{formula-Q4OWMNYI.js → formula-JZXPEDK3.js} +4 -4
  47. package/dist/{image-ocr-BGNLPWT6.js → image-ocr-2POAP5GL.js} +6 -6
  48. package/dist/{image-ocr-LEOMPCGS.cjs → image-ocr-5TZMNEGR.cjs} +15 -15
  49. package/dist/{image-ocr-LEOMPCGS.cjs.map → image-ocr-5TZMNEGR.cjs.map} +1 -1
  50. package/dist/{image-ocr-DV5NNNZW.js → image-ocr-HLEL6TED.js} +9 -9
  51. package/dist/index.cjs +297 -292
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.cts +3 -0
  54. package/dist/index.d.ts +3 -0
  55. package/dist/index.js +26 -21
  56. package/dist/index.js.map +1 -1
  57. package/dist/mcp.js +22 -22
  58. package/dist/{model-bundle-VW3V7DPG.js → model-bundle-7Z5HLNGX.js} +5 -5
  59. package/dist/{models-YYIPIE24.js → models-IGPCMPQQ.js} +5 -5
  60. package/dist/{parse-worker-v2-3LIIZE2T.js → parse-worker-v2-TS2JTIS2.js} +12 -12
  61. package/dist/{parser-4LF556NR.cjs → parser-KANGHQU4.cjs} +147 -139
  62. package/dist/parser-KANGHQU4.cjs.map +1 -0
  63. package/dist/{parser-2RDVYJPK.js → parser-VHZ2PZXG.js} +21 -13
  64. package/dist/{parser-2RDVYJPK.js.map → parser-VHZ2PZXG.js.map} +1 -1
  65. package/dist/{parser-FSHPAFTU.js → parser-WR6UBRI4.js} +24 -16
  66. package/dist/{parser-FSHPAFTU.js.map → parser-WR6UBRI4.js.map} +1 -1
  67. package/dist/pdf-ocr-BLT45T3Z.js +22 -0
  68. package/dist/pdf-ocr-DKYP5EKK.js +18 -0
  69. package/dist/pdf-ocr-SCLTCB2B.cjs +19 -0
  70. package/dist/{pdf-ocr-BEZS6VHS.cjs.map → pdf-ocr-SCLTCB2B.cjs.map} +1 -1
  71. package/dist/{profile-io-C376OP4V.js → profile-io-KHEXVGDJ.js} +3 -3
  72. package/dist/{rasterize-SCFDD6GF.js → rasterize-KHGMOS2F.js} +3 -3
  73. package/dist/{redact-doc-3XDM4LNR.js → redact-doc-DYWNTB2J.js} +11 -11
  74. package/dist/{render-FILMNF4B.js → render-JNMZ5ULA.js} +7 -7
  75. package/dist/seal-FDHX37MP.js +10 -0
  76. package/dist/{setup-KWXKE26M.js → setup-OQZS6I7X.js} +3 -3
  77. package/dist/visual-VZTQMICM.js +20 -0
  78. package/dist/{watch-D4GFLFAR.js → watch-DPNIOMTV.js} +12 -12
  79. package/package.json +1 -1
  80. package/dist/chunk-CHQLIGVR.cjs.map +0 -1
  81. package/dist/chunk-CRDBLQU5.js.map +0 -1
  82. package/dist/chunk-HIXDQ43L.js.map +0 -1
  83. package/dist/chunk-VOSAGXM6.js.map +0 -1
  84. package/dist/chunks-JUOKYHXK.js +0 -10
  85. package/dist/parser-4LF556NR.cjs.map +0 -1
  86. package/dist/pdf-ocr-BEZS6VHS.cjs +0 -19
  87. package/dist/pdf-ocr-LCVFTHGX.js +0 -18
  88. package/dist/pdf-ocr-WSPAXWEX.js +0 -22
  89. package/dist/seal-JJP72252.js +0 -10
  90. package/dist/visual-ESQJOYNZ.js +0 -20
  91. /package/dist/{-HYTPLFLG.js.map → -GS6LEDZ6.js.map} +0 -0
  92. /package/dist/{chunk-ZCGVIGG5.js.map → chunk-3PYAUHWY.js.map} +0 -0
  93. /package/dist/{chunk-7JCSAOTM.js.map → chunk-7ASI3XKM.js.map} +0 -0
  94. /package/dist/{chunk-IJK4VDEU.js.map → chunk-7NXHIM2I.js.map} +0 -0
  95. /package/dist/{chunk-NUUFPRNE.js.map → chunk-AJJLT6QJ.js.map} +0 -0
  96. /package/dist/{chunk-TJQ7ME2Z.js.map → chunk-BTMFVKL7.js.map} +0 -0
  97. /package/dist/{chunk-SQFCH4AY.js.map → chunk-FMUBLLIZ.js.map} +0 -0
  98. /package/dist/{chunk-ER3N3QPL.js.map → chunk-FWQHYJZ2.js.map} +0 -0
  99. /package/dist/{chunk-W6TVVTVX.js.map → chunk-GTSEPXAH.js.map} +0 -0
  100. /package/dist/{chunk-6CVYB634.js.map → chunk-J2FMAYNJ.js.map} +0 -0
  101. /package/dist/{chunk-VFGH2R4P.js.map → chunk-L3VCBSFW.js.map} +0 -0
  102. /package/dist/{chunk-5B5LMAUW.js.map → chunk-ORNPI5YF.js.map} +0 -0
  103. /package/dist/{chunk-YE3LPTBT.js.map → chunk-OZW5RYGF.js.map} +0 -0
  104. /package/dist/{chunk-NHMRAR3I.js.map → chunk-PEQ5K2JO.js.map} +0 -0
  105. /package/dist/{chunk-OUBHY6W3.js.map → chunk-Q4GXF444.js.map} +0 -0
  106. /package/dist/{chunk-65GJ2MMG.js.map → chunk-QLL7VG6L.js.map} +0 -0
  107. /package/dist/{chunk-FGC3EEQD.js.map → chunk-TUSREHO3.js.map} +0 -0
  108. /package/dist/{chunk-M4LXFLAV.js.map → chunk-TZU7PXV2.js.map} +0 -0
  109. /package/dist/{chunk-ZTEBJBJK.js.map → chunk-UEI7A4N5.js.map} +0 -0
  110. /package/dist/{chunk-Y64SVE5C.js.map → chunk-VOMOC7YF.js.map} +0 -0
  111. /package/dist/{chunk-LYWRIUZY.js.map → chunk-XBQ554QP.js.map} +0 -0
  112. /package/dist/{chunks-JUOKYHXK.js.map → chunks-RRV5535L.js.map} +0 -0
  113. /package/dist/{formula-NC3C6E3I.js.map → formula-CJ5DGNGC.js.map} +0 -0
  114. /package/dist/{formula-Q4OWMNYI.js.map → formula-JZXPEDK3.js.map} +0 -0
  115. /package/dist/{image-ocr-BGNLPWT6.js.map → image-ocr-2POAP5GL.js.map} +0 -0
  116. /package/dist/{image-ocr-DV5NNNZW.js.map → image-ocr-HLEL6TED.js.map} +0 -0
  117. /package/dist/{model-bundle-VW3V7DPG.js.map → model-bundle-7Z5HLNGX.js.map} +0 -0
  118. /package/dist/{models-YYIPIE24.js.map → models-IGPCMPQQ.js.map} +0 -0
  119. /package/dist/{parse-worker-v2-3LIIZE2T.js.map → parse-worker-v2-TS2JTIS2.js.map} +0 -0
  120. /package/dist/{pdf-ocr-LCVFTHGX.js.map → pdf-ocr-BLT45T3Z.js.map} +0 -0
  121. /package/dist/{pdf-ocr-WSPAXWEX.js.map → pdf-ocr-DKYP5EKK.js.map} +0 -0
  122. /package/dist/{profile-io-C376OP4V.js.map → profile-io-KHEXVGDJ.js.map} +0 -0
  123. /package/dist/{rasterize-SCFDD6GF.js.map → rasterize-KHGMOS2F.js.map} +0 -0
  124. /package/dist/{redact-doc-3XDM4LNR.js.map → redact-doc-DYWNTB2J.js.map} +0 -0
  125. /package/dist/{render-FILMNF4B.js.map → render-JNMZ5ULA.js.map} +0 -0
  126. /package/dist/{seal-JJP72252.js.map → seal-FDHX37MP.js.map} +0 -0
  127. /package/dist/{setup-KWXKE26M.js.map → setup-OQZS6I7X.js.map} +0 -0
  128. /package/dist/{visual-ESQJOYNZ.js.map → visual-VZTQMICM.js.map} +0 -0
  129. /package/dist/{watch-D4GFLFAR.js.map → watch-DPNIOMTV.js.map} +0 -0
package/README.md CHANGED
@@ -12,7 +12,7 @@ HWP 3.x·5.x, HWPX, HWPML, PDF, XLS·XLSX, DOCX, PPTX, PNG·JPG·WebP를 Markdow
12
12
  [English](README-EN.md) · [상세 사용법](docs/usage.md) · [벤치마크](docs/benchmarks.md) · [변경 이력](CHANGELOG.md)
13
13
 
14
14
  - 📊 **PDF 공개 벤치 종합 0.963** — opendataloader-bench 200문서. 공개 12개 파서 비교 1위(2026-09-29 기록). [측정 조건](docs/benchmarks.md)
15
- - 🇰🇷 **한국 공문서 표 구조 100%** — 원본 HWPX 2,424문서의 보이는 표 **10,342개 전부 구조 일치**. [4.21.15 검증](docs/benchmarks.md)
15
+ - 🇰🇷 **한국 공문서 표 구조 100%** — 원본 HWPX 2,424문서의 보이는 표 **10,342개 전부 구조 일치**. [4.21.17 검증](docs/benchmarks.md)
16
16
 
17
17
  쓸모 있었다면 GitHub ⭐ 하나 눌러주세요. 다른 사람이 이 도구를 찾는 데 도움이 됩니다.
18
18
 
@@ -100,27 +100,29 @@ await writeFile("보고서.hwpx", Buffer.from(hwpx))
100
100
 
101
101
  ## 검증 결과
102
102
 
103
- **4.21.15 · 2026-10-10 배포 검증**. 고정 코퍼스와 참조 기준으로 측정한 결과입니다.
103
+ **4.21.17 · 2026-10-11 배포 검증**. 고정 코퍼스와 참조 기준으로 측정한 결과입니다.
104
104
 
105
105
  | 대상 | 규모 | 결과 |
106
106
  | --- | --- | --- |
107
107
  | HWPX | 2,424문서 · 10,342표 | 표 구조 일치 **10,342/10,342 · 100%** |
108
108
  | HWP 5.x ↔ HWPX | 1,130쌍 · 4,315표 | 짝 문서의 표 구조 일치 **100%** |
109
- | PDF 글 | 744쌍 | 글자 재현율 **99.84%** · 정확도 **99.64%** · 읽기 순서 **99.16%** · 어절 F1 **98.98%** |
109
+ | PDF 글 | 744쌍 | 글자 재현율 **99.84%** · 정확도 **99.64%** · 읽기 순서 **99.16%** · 어절 F1 **98.99%** |
110
110
  | PDF 표 | 708쌍 · 2,331표 | 표 탐지 **99.83%** · 구조 일치 **97.98%** · 칸 F1 **0.991** |
111
111
  | PDF 전체 | 1,911문서 중 1,729건 채점 | 글 커버리지 **99.80%** |
112
112
  | OCR | 53문서 · 102쪽 | CER **0.0412** · 글자 재현율 **99.02%** |
113
113
 
114
114
  표 구조 점수와 셀 내용·화면 재현은 별도 지표입니다. 채점 범위·제외 기준·전 벤치 문서별 비교는 [벤치마크 상세](docs/benchmarks.md)에 있습니다.
115
115
 
116
- 외부 PDF 벤치 **opendataloader-bench 200문서**는 4.21.15 배포 측정에서 기본값 종합 **0.963**, OCR 끔 **0.939**입니다. [옵션별 결과와 재현 방법](docs/benchmarks.md#pdf--markdown--opendataloader-bench)
116
+ 외부 PDF 벤치 **opendataloader-bench 200문서**는 4.21.17 배포 측정에서 기본값 종합 **0.963**, OCR 끔 **0.939**입니다. [옵션별 결과와 재현 방법](docs/benchmarks.md#pdf--markdown--opendataloader-bench)
117
117
 
118
118
  ## 최근 업데이트
119
119
 
120
- 최신 배포: **[4.21.15](https://github.com/chrisryugj/kordoc/releases/tag/v4.21.15)** · 2026-10-10
120
+ 최신 배포: **[4.21.17](https://github.com/chrisryugj/kordoc/releases/tag/v4.21.17)** · 2026-10-11
121
121
 
122
122
  | 버전 | 주요 변경 |
123
123
  | --- | --- |
124
+ | 4.21.17 | PDF 공백 없는 꽉 찬 줄 끝 + 영문 괄호 — "공적개발원조⏎(ODA)"·"하네스⏎(safety …)" 를 붙여 씀 (PDF 어절 F1 98.98 → 98.99%) |
125
+ | 4.21.16 | PDF 표 쪽 넘김 갈린 행의 수량 이어짐 — 머리 칸 "30%" / 다음 쪽 "미만" 을 한 칸으로; 공문서 autoFit.safety(다른 조판기용 한 줄 판정 여유) (법령 별표 PDF 표 97.40 → 97.69%) |
124
126
  | 4.21.15 | PDF 줄 끝 공백 글리프로 어절 경계 꺾임 가르기 — 원문이 띄운 줄 꺾임("이루어⏎진다면")을 붙이던 것 (PDF 어절 F1 98.89 → 98.98%) |
125
127
  | 4.21.14 | 한컴 PDF 유니코드 없는 기호 되살리기 — 자동 글머리표·괄호(U+F000)를 글꼴 윤곽 모양으로 "▸"·"□"·"《》"·"↓" 등으로; 텍스트층 커버리지 채점 기준 변경 (PDF 어절 F1 98.87 → 98.89%·글 재현율 99.83 → 99.84%) |
126
128
  | 4.21.13 | PDF 법령 별표 쪽 넘김 행 — 번호 열이 다음 차례면 새 행, "가)" 항목도 다음 항목 머리로, 쪽을 넘는 긴 칸은 두 행을 덮는 한 칸으로; parse-worker 가 닫힌 stdout 에서 조용히 끝남(#142) (법령 별표 PDF 표 구조 일치 96.82 → 97.40%, 문서별 하락 0) |
@@ -54,17 +54,17 @@ import {
54
54
  unknownFontWarnings,
55
55
  usesGaejosikMunche,
56
56
  validateHwpx
57
- } from "./chunk-HIXDQ43L.js";
57
+ } from "./chunk-6F6L63RG.js";
58
58
  import {
59
59
  blocksToPages
60
- } from "./chunk-VFGH2R4P.js";
60
+ } from "./chunk-L3VCBSFW.js";
61
61
  import {
62
62
  applySplices,
63
63
  buildParagraphSplices,
64
64
  buildRangeSplices,
65
65
  placeSealHwpx,
66
66
  scanSectionXml
67
- } from "./chunk-7JCSAOTM.js";
67
+ } from "./chunk-7ASI3XKM.js";
68
68
  import {
69
69
  DEFAULT_REDACT_RULES,
70
70
  redactMarkdown,
@@ -72,7 +72,7 @@ import {
72
72
  } from "./chunk-3WSNLH4B.js";
73
73
  import {
74
74
  blocksToChunks
75
- } from "./chunk-ER3N3QPL.js";
75
+ } from "./chunk-FWQHYJZ2.js";
76
76
  import {
77
77
  SPACE_EM_FIXED,
78
78
  SPACE_EM_FONT,
@@ -97,20 +97,20 @@ import {
97
97
  renderSceneToHtml,
98
98
  simulateWrap,
99
99
  simulateWrapKeepWord
100
- } from "./chunk-SQFCH4AY.js";
100
+ } from "./chunk-FMUBLLIZ.js";
101
101
  import "./chunk-7FCNOKOR.js";
102
- import "./chunk-M4LXFLAV.js";
102
+ import "./chunk-TZU7PXV2.js";
103
103
  import "./chunk-VQFA55IC.js";
104
- import "./chunk-OUBHY6W3.js";
104
+ import "./chunk-Q4GXF444.js";
105
105
  import {
106
106
  blocksToMarkdown,
107
107
  flattenLayoutTables,
108
108
  hasStructuredCellContent
109
- } from "./chunk-65GJ2MMG.js";
110
- import "./chunk-FGC3EEQD.js";
109
+ } from "./chunk-QLL7VG6L.js";
110
+ import "./chunk-TUSREHO3.js";
111
111
  import {
112
112
  VERSION
113
- } from "./chunk-NHMRAR3I.js";
113
+ } from "./chunk-PEQ5K2JO.js";
114
114
  export {
115
115
  AGENCY_COMMON_NAME,
116
116
  BUILTIN_TEMPLATES,
@@ -204,4 +204,4 @@ export {
204
204
  usesGaejosikMunche,
205
205
  validateHwpx
206
206
  };
207
- //# sourceMappingURL=-HYTPLFLG.js.map
207
+ //# sourceMappingURL=-GS6LEDZ6.js.map
@@ -3,7 +3,7 @@ import {
3
3
  ensureModelsIn,
4
4
  getModelStatusIn,
5
5
  getModelsDir
6
- } from "./chunk-6CVYB634.js";
6
+ } from "./chunk-J2FMAYNJ.js";
7
7
 
8
8
  // src/ocr/models.ts
9
9
  import { join } from "path";
@@ -93,4 +93,4 @@ export {
93
93
  parseCharacterDict,
94
94
  ocrModelPath
95
95
  };
96
- //# sourceMappingURL=chunk-ZCGVIGG5.js.map
96
+ //# sourceMappingURL=chunk-3PYAUHWY.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  blocksToPages
4
- } from "./chunk-VFGH2R4P.js";
4
+ } from "./chunk-L3VCBSFW.js";
5
5
  import {
6
6
  allLinesegRemovalSplices,
7
7
  applySplices,
@@ -16,7 +16,7 @@ import {
16
16
  patchZipEntries,
17
17
  readZipEntries,
18
18
  scanSectionXml
19
- } from "./chunk-7JCSAOTM.js";
19
+ } from "./chunk-7ASI3XKM.js";
20
20
  import {
21
21
  CONVERT_MAP,
22
22
  FLAG_COMPRESSED,
@@ -67,7 +67,7 @@ import {
67
67
  romanNumeral,
68
68
  simulateWrap,
69
69
  takeTocLeaders
70
- } from "./chunk-SQFCH4AY.js";
70
+ } from "./chunk-FMUBLLIZ.js";
71
71
  import {
72
72
  inlineImagesIntoMarkdown
73
73
  } from "./chunk-7FCNOKOR.js";
@@ -82,7 +82,7 @@ import {
82
82
  tidyScriptTags,
83
83
  unframeLayoutTables,
84
84
  wrapScript
85
- } from "./chunk-M4LXFLAV.js";
85
+ } from "./chunk-TZU7PXV2.js";
86
86
  import {
87
87
  parsePageRange
88
88
  } from "./chunk-VQFA55IC.js";
@@ -102,7 +102,7 @@ import {
102
102
  localName,
103
103
  rawTextContent,
104
104
  readZipEntry
105
- } from "./chunk-OUBHY6W3.js";
105
+ } from "./chunk-Q4GXF444.js";
106
106
  import {
107
107
  MAX_COLS,
108
108
  MAX_ROWS,
@@ -117,7 +117,7 @@ import {
117
117
  hasStructuredCellContent,
118
118
  mapPuaText,
119
119
  noteSuffix
120
- } from "./chunk-65GJ2MMG.js";
120
+ } from "./chunk-QLL7VG6L.js";
121
121
  import {
122
122
  KordocError,
123
123
  classifyError,
@@ -133,7 +133,7 @@ import {
133
133
  toArrayBuffer,
134
134
  unescapeHtml,
135
135
  unzipLimitBytes
136
- } from "./chunk-NHMRAR3I.js";
136
+ } from "./chunk-PEQ5K2JO.js";
137
137
 
138
138
  // src/table/visual.ts
139
139
  import { readFile as readFile2 } from "fs/promises";
@@ -20517,12 +20517,13 @@ function buildTitleBox(title, titleCharPr, barCharPr, bodyWidth, reg) {
20517
20517
  // src/hwpx/fit-line.ts
20518
20518
  var RATIOS = [100, 97, 95, 92, 90, 87, 85];
20519
20519
  var SPACINGS = [0, -3, -5];
20520
- function safety(faceClass, approx) {
20521
- return faceClass.startsWith("font:") ? 0.98 : approx;
20520
+ function safety(faceClass, approx, limit) {
20521
+ const k = faceClass.startsWith("font:") ? 0.98 : approx;
20522
+ return limit === void 0 ? k : Math.min(k, limit);
20522
20523
  }
20523
- function fitOneLine(text, font, pt, availHu, minPt = Math.max(pt - 3, 10), minRatio = 85) {
20524
+ function fitOneLine(text, font, pt, availHu, minPt = Math.max(pt - 3, 10), minRatio = 85, safetyLimit) {
20524
20525
  const faceClass = faceClassForGen(font);
20525
- const avail = availHu * safety(faceClass, 0.98);
20526
+ const avail = availHu * safety(faceClass, 0.98, safetyLimit);
20526
20527
  const fits = (p, r, s) => measureTextWidth(text, p * 100, r, { spacingPct: s, faceClass }) <= avail;
20527
20528
  if (fits(pt, 100, 0)) return { pt, ratio: 100, spacing: 0, overflow: false };
20528
20529
  const ratios = RATIOS.filter((r) => r >= minRatio);
@@ -20557,10 +20558,10 @@ function worstLooseness(text, starts, firstW, contW, h, ratio, spacing, faceClas
20557
20558
  }
20558
20559
  return worst;
20559
20560
  }
20560
- function fitParagraph(text, font, pt, firstW, contW, minRatio = 88, orphanRatio = ORPHAN_RATIO) {
20561
+ function fitParagraph(text, font, pt, firstW, contW, minRatio = 88, orphanRatio = ORPHAN_RATIO, safetyLimit) {
20561
20562
  const faceClass = faceClassForGen(font);
20562
20563
  const h = pt * 100;
20563
- const k = safety(faceClass, 0.95);
20564
+ const k = safety(faceClass, 0.95, safetyLimit);
20564
20565
  const f = firstW * k, c = contW * k;
20565
20566
  const ladder = [[100, 0], ...SQUEEZE.filter(([r]) => r >= minRatio)];
20566
20567
  const base = simulateWrap(text, f, c, h, 100, "keep", { faceClass });
@@ -20614,10 +20615,10 @@ function fitParagraph(text, font, pt, firstW, contW, minRatio = 88, orphanRatio
20614
20615
  return best && (best.r !== 100 || best.sp !== 0) ? { ratio: best.r, spacing: best.sp } : null;
20615
20616
  }
20616
20617
  var LIST_BREAK = /* @__PURE__ */ new Set([..."\xB7,\u3001/"]);
20617
- function fitCharBreaks(text, font, pt, firstW, contW, minRatio = 88) {
20618
+ function fitCharBreaks(text, font, pt, firstW, contW, minRatio = 88, safetyLimit) {
20618
20619
  const faceClass = faceClassForGen(font);
20619
20620
  const h = pt * 100;
20620
- const k = safety(faceClass, 0.95);
20621
+ const k = safety(faceClass, 0.95, safetyLimit);
20621
20622
  if (!text.split(/ +/).some((w) => measureTextWidth(w, h, 100, { faceClass }) > contW * k)) return null;
20622
20623
  const prepared = prepareWrap(text, "charAll", { faceClass });
20623
20624
  let best = null;
@@ -21270,6 +21271,9 @@ function validateGongmunOptions(opts) {
21270
21271
  if (typeof opts.autoFit === "object" && opts.autoFit.minRatio !== void 0) {
21271
21272
  assertFiniteRange("autoFit.minRatio", opts.autoFit.minRatio, 50, 99);
21272
21273
  }
21274
+ if (typeof opts.autoFit === "object" && opts.autoFit.safety !== void 0) {
21275
+ assertFiniteRange("autoFit.safety", opts.autoFit.safety, 0.8, 1);
21276
+ }
21273
21277
  if (opts.margins) {
21274
21278
  for (const side of ["top", "bottom", "left", "right"]) {
21275
21279
  const value = opts.margins[side];
@@ -21387,6 +21391,7 @@ function resolveGongmun(input) {
21387
21391
  margins: opts.margins ?? (ministry ? MINISTRY_MARGINS : preset === "report" || preset === "plan" || preset === "bangchim" ? SEOUL_REPORT_MARGINS : reportFamily ? GAEJOSIK_MARGINS : OFFICIAL_MARGINS),
21388
21392
  centerTitle: opts.centerTitle ?? true,
21389
21393
  autoFitMinRatio,
21394
+ ...typeof opts.autoFit === "object" && opts.autoFit.safety !== void 0 ? { autoFitSafety: opts.autoFit.safety } : {},
21390
21395
  // 보도자료는 머리박스가 1페이지 최상단을 차지하는 서식이라 표지·목차와 양립 불가 —
21391
21396
  // 켜면 머리박스가 표지에 얹히고 25pt 제목·부제가 유실된다 (docHead 프리셋 게이팅과 동일 관례)
21392
21397
  cover: coverOn && preset !== "press" ? { date: coverOpts.date ?? null, org: coverOpts.org ?? "", ...coverOpts.dept ? { dept: coverOpts.dept } : {}, ...coverOpts.label ? { label: coverOpts.label } : {} } : null,
@@ -26104,7 +26109,7 @@ function buildGongmunSectionV5(blocks, gongmun, deps, theme) {
26104
26109
  const textW2 = W2 - lay.left - lay.hang;
26105
26110
  let ratio = 100, spacing = 0, charBreaks = false;
26106
26111
  if (st.oneLine) {
26107
- const fit = fitOneLine(plain2(node.text), st.font, st.pt, textW2, st.pt, 90);
26112
+ const fit = fitOneLine(plain2(node.text), st.font, st.pt, textW2, st.pt, 90, g.autoFitSafety);
26108
26113
  if (fit.overflow) warnings.push(`\u25A1 \uD56D\uBAA9\uC774 \uD55C \uC904\uC5D0 \uB2F4\uAE30\uC9C0 \uC54A\uC544 \uB450 \uC904\uB85C \uAEBE\uC785\uB2C8\uB2E4 \u2014 \uBB38\uC7A5\uC744 \uC904\uC774\uC138\uC694(\uC7A5\uD3C9 90%\xB7\uC790\uAC04 -5 \uB85C\uB3C4 \uCD08\uACFC): "${node.text.slice(0, 30)}\u2026"`);
26109
26114
  else {
26110
26115
  ratio = fit.ratio;
@@ -26112,8 +26117,8 @@ function buildGongmunSectionV5(blocks, gongmun, deps, theme) {
26112
26117
  }
26113
26118
  } else {
26114
26119
  const t = plain2(node.text);
26115
- const cb = fitCharBreaks(t, st.font, st.pt, textW2, textW2, g.autoFitMinRatio ?? 101);
26116
- const f = cb ?? (g.autoFitMinRatio !== null ? fitParagraph(t, st.font, st.pt, textW2, textW2, g.autoFitMinRatio) : null);
26120
+ const cb = fitCharBreaks(t, st.font, st.pt, textW2, textW2, g.autoFitMinRatio ?? 101, g.autoFitSafety);
26121
+ const f = cb ?? (g.autoFitMinRatio !== null ? fitParagraph(t, st.font, st.pt, textW2, textW2, g.autoFitMinRatio, void 0, g.autoFitSafety) : null);
26117
26122
  if (f) {
26118
26123
  ratio = f.ratio;
26119
26124
  spacing = f.spacing;
@@ -26142,8 +26147,8 @@ function buildGongmunSectionV5(blocks, gongmun, deps, theme) {
26142
26147
  const left = isMinistry ? st.leadTa * taHu(st.pt) : leadLeft(node.depth, st.pt);
26143
26148
  const textW2 = W2 - left - lay.hang;
26144
26149
  const t = plain2(node.text);
26145
- const cb = fitCharBreaks(t, st.font, st.pt, textW2, textW2, g.autoFitMinRatio ?? 101);
26146
- const f = cb ?? (g.autoFitMinRatio !== null ? fitParagraph(t, st.font, st.pt, textW2, textW2, g.autoFitMinRatio) : null);
26150
+ const cb = fitCharBreaks(t, st.font, st.pt, textW2, textW2, g.autoFitMinRatio ?? 101, g.autoFitSafety);
26151
+ const f = cb ?? (g.autoFitMinRatio !== null ? fitParagraph(t, st.font, st.pt, textW2, textW2, g.autoFitMinRatio, void 0, g.autoFitSafety) : null);
26147
26152
  const base = { font: st.font, pt: st.pt, bold: st.bold, ratio: f?.ratio ?? 100, spacing: f?.spacing ?? 0 };
26148
26153
  const paraId = reg.para({ align: st.align ?? "JUSTIFY", left, indent: -lay.hang, after: isMinistry ? 400 : 0, lineSp: isMinistry ? 130 : st.lineSp ?? scheme.lineSp, keepWord: !cb, autoTab: true, widowOrphan: true });
26149
26154
  const markerRun = markerRunXml(marker, reg.char({ font: st.font, pt: st.pt, bold: st.bold }), lay);
@@ -26172,8 +26177,8 @@ function buildGongmunSectionV5(blocks, gongmun, deps, theme) {
26172
26177
  let ratio = 100, spacing = 0, charBreaks = false;
26173
26178
  if (!node.align) {
26174
26179
  const t = plain2(node.text);
26175
- const cb = fitCharBreaks(t, st.font, st.pt, W2, W2, g.autoFitMinRatio ?? 101);
26176
- const f = cb ?? (g.autoFitMinRatio !== null ? fitParagraph(t, st.font, st.pt, W2, W2, g.autoFitMinRatio) : null);
26180
+ const cb = fitCharBreaks(t, st.font, st.pt, W2, W2, g.autoFitMinRatio ?? 101, g.autoFitSafety);
26181
+ const f = cb ?? (g.autoFitMinRatio !== null ? fitParagraph(t, st.font, st.pt, W2, W2, g.autoFitMinRatio, void 0, g.autoFitSafety) : null);
26177
26182
  if (f) {
26178
26183
  ratio = f.ratio;
26179
26184
  spacing = f.spacing;
@@ -26215,7 +26220,7 @@ function buildGongmunSectionV5(blocks, gongmun, deps, theme) {
26215
26220
  }
26216
26221
  const label = chapterStyle === "none" ? "" : chapterLabel(node.index, chapterStyle === "number" ? "number" : "roman");
26217
26222
  const text = label ? `${label} ${node.text}` : node.text;
26218
- const fit = fitOneLine(plain2(text), st.font, st.pt, W2, st.pt - 2);
26223
+ const fit = fitOneLine(plain2(text), st.font, st.pt, W2, st.pt - 2, void 0, g.autoFitSafety);
26219
26224
  const base = { font: st.font, pt: fit.pt, bold: st.bold, ratio: fit.ratio, spacing: fit.spacing };
26220
26225
  const before = prevKind === "start" || prevKind === "title" || prevKind === "summary" ? 0 : lineHu(scheme.body);
26221
26226
  const paraId = reg.para({ align: "LEFT", before, after: Math.round(lineHu(scheme.body) * 0.3), lineSp: st.lineSp ?? scheme.lineSp, keepWithNext: true });
@@ -30754,7 +30759,7 @@ function scriptsOff(r, off) {
30754
30759
  }
30755
30760
  async function parseImage(buffer, options) {
30756
30761
  try {
30757
- const { parseImageDocument } = await import("./image-ocr-DV5NNNZW.js");
30762
+ const { parseImageDocument } = await import("./image-ocr-HLEL6TED.js");
30758
30763
  const { blocks, warnings } = await parseImageDocument(buffer, options);
30759
30764
  stripScriptTags({ blocks });
30760
30765
  return {
@@ -30814,7 +30819,7 @@ async function parseHwp(buffer, options) {
30814
30819
  async function parsePdf(buffer, options) {
30815
30820
  let parsePdfDocument;
30816
30821
  try {
30817
- const mod = await import("./parser-FSHPAFTU.js");
30822
+ const mod = await import("./parser-WR6UBRI4.js");
30818
30823
  parsePdfDocument = mod.parsePdfDocument;
30819
30824
  } catch {
30820
30825
  return {
@@ -31044,4 +31049,4 @@ export {
31044
31049
  parseHwpml,
31045
31050
  fillForm
31046
31051
  };
31047
- //# sourceMappingURL=chunk-HIXDQ43L.js.map
31052
+ //# sourceMappingURL=chunk-6F6L63RG.js.map