kordoc 4.18.3 → 4.18.4

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 (145) hide show
  1. package/dist/{-WOKB25R2.js → -DDAVBMHD.js} +11 -11
  2. package/dist/{chunk-BGOR5GCF.js → chunk-274ZPMHK.js} +2 -2
  3. package/dist/{chunk-2ZBLQVAS.cjs → chunk-3WLZOJIE.cjs} +6 -6
  4. package/dist/chunk-3WLZOJIE.cjs.map +1 -0
  5. package/dist/{chunk-SHRRD2TD.cjs → chunk-3XSP7V5P.cjs} +2 -2
  6. package/dist/chunk-3XSP7V5P.cjs.map +1 -0
  7. package/dist/{chunk-6GLTGOP6.js → chunk-4IBY5LTJ.js} +2 -2
  8. package/dist/chunk-6H25SXDI.js +11 -0
  9. package/dist/chunk-6H25SXDI.js.map +1 -0
  10. package/dist/{chunk-CAN5P6N6.js → chunk-7GR2GCJF.js} +2 -2
  11. package/dist/{chunk-HZV52V2X.cjs → chunk-AVIZ55NQ.cjs} +3 -3
  12. package/dist/chunk-AVIZ55NQ.cjs.map +1 -0
  13. package/dist/chunk-DC6CTQTK.js +9 -0
  14. package/dist/chunk-DC6CTQTK.js.map +1 -0
  15. package/dist/{chunk-NES5U4JK.js → chunk-DUV7Y6IQ.js} +3 -3
  16. package/dist/{chunk-WN5YLP7H.cjs → chunk-E2644XCO.cjs} +693 -187
  17. package/dist/chunk-E2644XCO.cjs.map +1 -0
  18. package/dist/{chunk-3FZGL3IL.js → chunk-ELOPDQES.js} +2 -2
  19. package/dist/{chunk-2I2RTJJ5.js → chunk-F2GDLA45.js} +25 -35
  20. package/dist/chunk-F2GDLA45.js.map +1 -0
  21. package/dist/{chunk-VGDTONTB.js → chunk-F5YVCJVF.js} +2 -2
  22. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  23. package/dist/{chunk-RDBTOE5X.js → chunk-HRJJDNRD.js} +2 -2
  24. package/dist/{chunk-KSJ7GKNQ.js → chunk-IAXGGQGD.js} +2 -2
  25. package/dist/{chunk-IXX3WHIE.js → chunk-IBQCK4F3.js} +7 -3
  26. package/dist/chunk-IBQCK4F3.js.map +1 -0
  27. package/dist/chunk-J55UQC5H.cjs.map +1 -1
  28. package/dist/{chunk-J2A46VCA.js → chunk-KUUSP6OS.js} +576 -70
  29. package/dist/chunk-KUUSP6OS.js.map +1 -0
  30. package/dist/{chunk-RSDUH4XF.js → chunk-LGF2IO66.js} +2 -2
  31. package/dist/{chunk-BJ6RYYXV.js → chunk-MXA6YW2W.js} +577 -71
  32. package/dist/chunk-MXA6YW2W.js.map +1 -0
  33. package/dist/{chunk-ZD5WNQNC.cjs → chunk-OIUSF2VA.cjs} +16 -12
  34. package/dist/chunk-OIUSF2VA.cjs.map +1 -0
  35. package/dist/{chunk-AZQWESRH.js → chunk-QVCHFCT2.js} +2 -2
  36. package/dist/{chunk-W7P4GPOV.js → chunk-RCI7LY4N.js} +8 -4
  37. package/dist/chunk-RCI7LY4N.js.map +1 -0
  38. package/dist/{chunk-V4BKT65D.cjs → chunk-SVNBZEL6.cjs} +3 -3
  39. package/dist/chunk-SVNBZEL6.cjs.map +1 -0
  40. package/dist/{chunk-OOX2GZZ4.js → chunk-T2BJPT6D.js} +3 -3
  41. package/dist/{chunk-OOX2GZZ4.js.map → chunk-T2BJPT6D.js.map} +1 -1
  42. package/dist/chunk-TK3FDAEE.cjs +9 -0
  43. package/dist/chunk-TK3FDAEE.cjs.map +1 -0
  44. package/dist/{chunk-UVUKT3IQ.js → chunk-TMJVD6FW.js} +2 -2
  45. package/dist/{chunk-ZN3LHNJG.js → chunk-V5X4LLVM.js} +28 -27
  46. package/dist/chunk-V5X4LLVM.js.map +1 -0
  47. package/dist/{chunk-W3RADOLO.js → chunk-VTVK2JMI.js} +2 -2
  48. package/dist/{chunk-PSJLB3SZ.js → chunk-XG4SYOZL.js} +2 -2
  49. package/dist/{chunk-RRURZDEK.js → chunk-YCY2R4FM.js} +2 -2
  50. package/dist/{chunk-5X7XWYR2.js → chunk-Z2PPDQK2.js} +2 -2
  51. package/dist/chunks-5QTTAT5T.js +10 -0
  52. package/dist/cli.js +154 -115
  53. package/dist/cli.js.map +1 -1
  54. package/dist/{formula-QZAOKPBX.js → formula-7ZOZ5QJ6.js} +8 -4
  55. package/dist/{formula-QZAOKPBX.js.map → formula-7ZOZ5QJ6.js.map} +1 -1
  56. package/dist/{formula-GPCOJJXN.js → formula-HQFZEXFF.js} +7 -3
  57. package/dist/{formula-GPCOJJXN.js.map → formula-HQFZEXFF.js.map} +1 -1
  58. package/dist/{formula-BQ5RW5XD.cjs → formula-YYJQBKEN.cjs} +13 -9
  59. package/dist/formula-YYJQBKEN.cjs.map +1 -0
  60. package/dist/{image-ocr-POCME5I4.js → image-ocr-4BGX2EJJ.js} +7 -6
  61. package/dist/{image-ocr-POCME5I4.js.map → image-ocr-4BGX2EJJ.js.map} +1 -1
  62. package/dist/{image-ocr-VKIUBLBX.cjs → image-ocr-CC26Q5KG.cjs} +16 -15
  63. package/dist/image-ocr-CC26Q5KG.cjs.map +1 -0
  64. package/dist/{image-ocr-TWNNVTZS.js → image-ocr-RK3HJVCI.js} +10 -9
  65. package/dist/{image-ocr-TWNNVTZS.js.map → image-ocr-RK3HJVCI.js.map} +1 -1
  66. package/dist/index.cjs +338 -347
  67. package/dist/index.cjs.map +1 -1
  68. package/dist/index.js +42 -51
  69. package/dist/index.js.map +1 -1
  70. package/dist/mcp.js +22 -22
  71. package/dist/{model-bundle-THYUL7GG.js → model-bundle-VHRXG63R.js} +5 -5
  72. package/dist/{models-U22N4RXX.js → models-G3WA24SY.js} +5 -5
  73. package/dist/page-range-QHHFTL7X.cjs.map +1 -1
  74. package/dist/{parser-JOMFOZLH.cjs → parser-BGORCLIU.cjs} +449 -244
  75. package/dist/parser-BGORCLIU.cjs.map +1 -0
  76. package/dist/{parser-SCXRLOW7.js → parser-GFDGAVLV.js} +242 -37
  77. package/dist/parser-GFDGAVLV.js.map +1 -0
  78. package/dist/{parser-NKP2NCSV.js → parser-SOWTUOMK.js} +245 -40
  79. package/dist/parser-SOWTUOMK.js.map +1 -0
  80. package/dist/pdf-ocr-7IOOVR2I.js +20 -0
  81. package/dist/pdf-ocr-EJ2HNZN6.cjs +17 -0
  82. package/dist/pdf-ocr-EJ2HNZN6.cjs.map +1 -0
  83. package/dist/pdf-ocr-RACAZU3N.js +16 -0
  84. package/dist/{profile-io-UI3TZBYH.js → profile-io-Q2T47RVH.js} +3 -3
  85. package/dist/{rasterize-XMBV5H2I.js → rasterize-OAVMUTE6.js} +3 -3
  86. package/dist/{redact-doc-7ZZMHDBO.js → redact-doc-ECFOVR4X.js} +11 -11
  87. package/dist/{render-SWRTUDAV.js → render-NSKWZVTD.js} +7 -7
  88. package/dist/seal-A4MG7MPQ.js +10 -0
  89. package/dist/{setup-43JJEEU7.js → setup-REH2KZP2.js} +3 -3
  90. package/dist/visual-B56WQAGW.js +20 -0
  91. package/dist/{watch-NRATQ472.js → watch-JXDUZYBY.js} +12 -12
  92. package/package.json +1 -1
  93. package/dist/chunk-2I2RTJJ5.js.map +0 -1
  94. package/dist/chunk-2ZBLQVAS.cjs.map +0 -1
  95. package/dist/chunk-BJ6RYYXV.js.map +0 -1
  96. package/dist/chunk-HZV52V2X.cjs.map +0 -1
  97. package/dist/chunk-IXX3WHIE.js.map +0 -1
  98. package/dist/chunk-J2A46VCA.js.map +0 -1
  99. package/dist/chunk-SHRRD2TD.cjs.map +0 -1
  100. package/dist/chunk-V4BKT65D.cjs.map +0 -1
  101. package/dist/chunk-W7P4GPOV.js.map +0 -1
  102. package/dist/chunk-WN5YLP7H.cjs.map +0 -1
  103. package/dist/chunk-ZD5WNQNC.cjs.map +0 -1
  104. package/dist/chunk-ZN3LHNJG.js.map +0 -1
  105. package/dist/chunks-OQDRDICD.js +0 -10
  106. package/dist/formula-BQ5RW5XD.cjs.map +0 -1
  107. package/dist/image-ocr-VKIUBLBX.cjs.map +0 -1
  108. package/dist/parser-JOMFOZLH.cjs.map +0 -1
  109. package/dist/parser-NKP2NCSV.js.map +0 -1
  110. package/dist/parser-SCXRLOW7.js.map +0 -1
  111. package/dist/pdf-ocr-NF4AY5MI.cjs +0 -16
  112. package/dist/pdf-ocr-NF4AY5MI.cjs.map +0 -1
  113. package/dist/pdf-ocr-OLII3WAG.js +0 -15
  114. package/dist/pdf-ocr-VJL7ON2Q.js +0 -19
  115. package/dist/seal-UKKJZHKE.js +0 -10
  116. package/dist/visual-D2563HCJ.js +0 -20
  117. /package/dist/{-WOKB25R2.js.map → -DDAVBMHD.js.map} +0 -0
  118. /package/dist/{chunk-BGOR5GCF.js.map → chunk-274ZPMHK.js.map} +0 -0
  119. /package/dist/{chunk-6GLTGOP6.js.map → chunk-4IBY5LTJ.js.map} +0 -0
  120. /package/dist/{chunk-CAN5P6N6.js.map → chunk-7GR2GCJF.js.map} +0 -0
  121. /package/dist/{chunk-NES5U4JK.js.map → chunk-DUV7Y6IQ.js.map} +0 -0
  122. /package/dist/{chunk-3FZGL3IL.js.map → chunk-ELOPDQES.js.map} +0 -0
  123. /package/dist/{chunk-VGDTONTB.js.map → chunk-F5YVCJVF.js.map} +0 -0
  124. /package/dist/{chunk-RDBTOE5X.js.map → chunk-HRJJDNRD.js.map} +0 -0
  125. /package/dist/{chunk-KSJ7GKNQ.js.map → chunk-IAXGGQGD.js.map} +0 -0
  126. /package/dist/{chunk-RSDUH4XF.js.map → chunk-LGF2IO66.js.map} +0 -0
  127. /package/dist/{chunk-AZQWESRH.js.map → chunk-QVCHFCT2.js.map} +0 -0
  128. /package/dist/{chunk-UVUKT3IQ.js.map → chunk-TMJVD6FW.js.map} +0 -0
  129. /package/dist/{chunk-W3RADOLO.js.map → chunk-VTVK2JMI.js.map} +0 -0
  130. /package/dist/{chunk-PSJLB3SZ.js.map → chunk-XG4SYOZL.js.map} +0 -0
  131. /package/dist/{chunk-RRURZDEK.js.map → chunk-YCY2R4FM.js.map} +0 -0
  132. /package/dist/{chunk-5X7XWYR2.js.map → chunk-Z2PPDQK2.js.map} +0 -0
  133. /package/dist/{chunks-OQDRDICD.js.map → chunks-5QTTAT5T.js.map} +0 -0
  134. /package/dist/{model-bundle-THYUL7GG.js.map → model-bundle-VHRXG63R.js.map} +0 -0
  135. /package/dist/{models-U22N4RXX.js.map → models-G3WA24SY.js.map} +0 -0
  136. /package/dist/{pdf-ocr-OLII3WAG.js.map → pdf-ocr-7IOOVR2I.js.map} +0 -0
  137. /package/dist/{pdf-ocr-VJL7ON2Q.js.map → pdf-ocr-RACAZU3N.js.map} +0 -0
  138. /package/dist/{profile-io-UI3TZBYH.js.map → profile-io-Q2T47RVH.js.map} +0 -0
  139. /package/dist/{rasterize-XMBV5H2I.js.map → rasterize-OAVMUTE6.js.map} +0 -0
  140. /package/dist/{redact-doc-7ZZMHDBO.js.map → redact-doc-ECFOVR4X.js.map} +0 -0
  141. /package/dist/{render-SWRTUDAV.js.map → render-NSKWZVTD.js.map} +0 -0
  142. /package/dist/{seal-UKKJZHKE.js.map → seal-A4MG7MPQ.js.map} +0 -0
  143. /package/dist/{setup-43JJEEU7.js.map → setup-REH2KZP2.js.map} +0 -0
  144. /package/dist/{visual-D2563HCJ.js.map → visual-B56WQAGW.js.map} +0 -0
  145. /package/dist/{watch-NRATQ472.js.map → watch-JXDUZYBY.js.map} +0 -0
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  parseFormatProfileJson
4
- } from "./chunk-OOX2GZZ4.js";
4
+ } from "./chunk-T2BJPT6D.js";
5
5
  import {
6
6
  BODY_FONTS,
7
7
  BULLET2_CHARS,
@@ -33,24 +33,24 @@ import {
33
33
  toPlainMarkdown,
34
34
  unknownFontWarnings,
35
35
  usesGaejosikMunche
36
- } from "./chunk-2I2RTJJ5.js";
37
- import "./chunk-6GLTGOP6.js";
38
- import "./chunk-NES5U4JK.js";
36
+ } from "./chunk-F2GDLA45.js";
37
+ import "./chunk-4IBY5LTJ.js";
38
+ import "./chunk-DUV7Y6IQ.js";
39
39
  import "./chunk-3WSNLH4B.js";
40
- import "./chunk-RRURZDEK.js";
40
+ import "./chunk-YCY2R4FM.js";
41
41
  import {
42
42
  detectFormat,
43
43
  detectImageMime,
44
44
  detectZipFormat
45
- } from "./chunk-ZN3LHNJG.js";
45
+ } from "./chunk-V5X4LLVM.js";
46
46
  import "./chunk-7FCNOKOR.js";
47
- import "./chunk-UVUKT3IQ.js";
47
+ import "./chunk-TMJVD6FW.js";
48
48
  import "./chunk-VQFA55IC.js";
49
- import "./chunk-RSDUH4XF.js";
49
+ import "./chunk-LGF2IO66.js";
50
50
  import {
51
51
  blocksToMarkdown
52
- } from "./chunk-W3RADOLO.js";
53
- import "./chunk-KSJ7GKNQ.js";
52
+ } from "./chunk-VTVK2JMI.js";
53
+ import "./chunk-IAXGGQGD.js";
54
54
  import {
55
55
  KordocError,
56
56
  VERSION,
@@ -58,26 +58,57 @@ import {
58
58
  routeConsoleToStderr,
59
59
  sanitizeError,
60
60
  toArrayBuffer
61
- } from "./chunk-VGDTONTB.js";
61
+ } from "./chunk-F5YVCJVF.js";
62
62
 
63
63
  // src/cli.ts
64
64
  import { Command } from "commander";
65
65
 
66
66
  // src/cli/convert.ts
67
- import { readFileSync, writeFileSync, mkdirSync, statSync } from "fs";
67
+ import { readFileSync, writeFileSync, mkdirSync, statSync as statSync2 } from "fs";
68
+ import { basename as basename2, resolve as resolve2 } from "path";
69
+
70
+ // src/cli/output-path.ts
71
+ import { statSync } from "fs";
68
72
  import { basename, resolve } from "path";
73
+ function createOutputGuard(inputs) {
74
+ const paths = new Map(inputs.map((input) => [resolve(input), basename(input)]));
75
+ const identities = /* @__PURE__ */ new Map();
76
+ for (const [input, name] of paths) {
77
+ try {
78
+ const stat = statSync(input, { bigint: true });
79
+ identities.set(`${stat.dev}:${stat.ino}`, name);
80
+ } catch {
81
+ }
82
+ }
83
+ return (outputs) => {
84
+ for (const output of outputs) {
85
+ let input = paths.get(resolve(output));
86
+ if (!input) {
87
+ try {
88
+ const stat = statSync(output, { bigint: true });
89
+ input = identities.get(`${stat.dev}:${stat.ino}`);
90
+ } catch (err) {
91
+ if (err.code !== "ENOENT" && err.code !== "ENOTDIR") throw err;
92
+ }
93
+ }
94
+ if (input) throw new Error(`\uCD9C\uB825 \uACBD\uB85C\uAC00 \uC785\uB825 \uD30C\uC77C\uACFC \uAC19\uC2B5\uB2C8\uB2E4: ${input}`);
95
+ }
96
+ };
97
+ }
98
+
99
+ // src/cli/convert.ts
69
100
  async function convertFiles(files, opts, writeOutput = (text) => {
70
101
  process.stdout.write(text);
71
- }) {
102
+ }, assertSafeOutputs = createOutputGuard(files)) {
72
103
  let failed = false;
73
104
  for (let fi = 0; fi < files.length; fi++) {
74
105
  const filePath = files[fi];
75
- const absPath = resolve(filePath);
76
- const fileName = basename(absPath);
106
+ const absPath = resolve2(filePath);
107
+ const fileName = basename2(absPath);
77
108
  const filePrefix = files.length > 1 ? `[${fi + 1}/${files.length}] ` : "";
78
109
  let detectedFormat = "unknown";
79
110
  try {
80
- const fileSize = statSync(absPath).size;
111
+ const fileSize = statSync2(absPath).size;
81
112
  if (fileSize > 500 * 1024 * 1024) {
82
113
  process.stderr.write(`
83
114
  [kordoc] SKIP: ${fileName} \u2014 \uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${(fileSize / 1024 / 1024).toFixed(1)}MB)
@@ -131,7 +162,7 @@ async function convertFiles(files, opts, writeOutput = (text) => {
131
162
  let markdown = result.markdown;
132
163
  const imagesInlined = opts.inlineImages && result.fileType === "hwp";
133
164
  const savesImageFiles = Boolean(opts.outDir || opts.output && files.length === 1);
134
- const docStem = (opts.output && files.length === 1 ? basename(opts.output) : fileName).replace(/\.[^.]+$/, "");
165
+ const docStem = (opts.output && files.length === 1 ? basename2(opts.output) : fileName).replace(/\.[^.]+$/, "");
135
166
  const imgLink = `images/${docStem.replace(/[ ()]/g, (ch) => encodeURIComponent(ch))}/`;
136
167
  const linkImages = (text) => savesImageFiles && result.images?.length && !imagesInlined ? text.replace(/!\[image\]\(image_/g, `![image](${imgLink}image_`).replace(/(<img\b[^>]*\bsrc=")image_/g, `$1${imgLink}image_`) : text;
137
168
  markdown = linkImages(markdown);
@@ -155,7 +186,7 @@ async function convertFiles(files, opts, writeOutput = (text) => {
155
186
  `);
156
187
  }
157
188
  } else if (opts.format === "chunks") {
158
- const { blocksToChunks } = await import("./chunks-OQDRDICD.js");
189
+ const { blocksToChunks } = await import("./chunks-5QTTAT5T.js");
159
190
  const chunks = blocksToChunks(result.blocks).map((c) => {
160
191
  let text = c.text;
161
192
  if (opts.plain) text = toPlainMarkdown(text);
@@ -168,10 +199,10 @@ async function convertFiles(files, opts, writeOutput = (text) => {
168
199
  }
169
200
  const saveImages = (dir) => {
170
201
  if (!result.images?.length || imagesInlined) return;
171
- const imgDir = resolve(dir, "images", docStem);
202
+ const imgDir = resolve2(dir, "images", docStem);
172
203
  mkdirSync(imgDir, { recursive: true });
173
204
  for (const img of result.images) {
174
- writeFileSync(resolve(imgDir, img.filename), img.data);
205
+ writeFileSync(resolve2(imgDir, img.filename), img.data);
175
206
  }
176
207
  const manifest = result.images.map((img) => ({
177
208
  name: img.filename,
@@ -179,21 +210,25 @@ async function convertFiles(files, opts, writeOutput = (text) => {
179
210
  bytes: img.data.length,
180
211
  ...img.source ? { source: img.source } : {}
181
212
  }));
182
- writeFileSync(resolve(imgDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
213
+ writeFileSync(resolve2(imgDir, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
183
214
  if (!opts.silent) process.stderr.write(` \u2192 ${result.images.length}\uAC1C \uC774\uBBF8\uC9C0 \u2192 ${imgDir} (manifest.json \uD3EC\uD568)
184
215
  `);
185
216
  };
217
+ const assertSafeDestination = (output2, dir) => {
218
+ const imageOutputs = result.images?.length && !imagesInlined ? [...result.images.map((img) => resolve2(dir, "images", docStem, img.filename)), resolve2(dir, "images", docStem, "manifest.json")] : [];
219
+ assertSafeOutputs([output2, ...imageOutputs]);
220
+ };
186
221
  if (opts.output && files.length === 1) {
187
- if (resolve(opts.output) === absPath) throw new Error(`\uCD9C\uB825 \uACBD\uB85C\uAC00 \uC785\uB825 \uD30C\uC77C\uACFC \uAC19\uC2B5\uB2C8\uB2E4: ${fileName}`);
222
+ assertSafeDestination(opts.output, resolve2(opts.output, ".."));
188
223
  writeFileSync(opts.output, output, "utf-8");
189
224
  if (!opts.silent) process.stderr.write(` \u2192 ${opts.output}
190
225
  `);
191
- saveImages(resolve(opts.output, ".."));
226
+ saveImages(resolve2(opts.output, ".."));
192
227
  } else if (opts.outDir) {
193
228
  mkdirSync(opts.outDir, { recursive: true });
194
229
  const outExt = opts.format === "json" ? ".json" : opts.format === "chunks" ? ".chunks.json" : ".md";
195
- const outPath = resolve(opts.outDir, fileName.replace(/\.[^.]+$/, "") + outExt);
196
- if (outPath === absPath) throw new Error(`\uCD9C\uB825 \uACBD\uB85C\uAC00 \uC785\uB825 \uD30C\uC77C\uACFC \uAC19\uC2B5\uB2C8\uB2E4: ${fileName}`);
230
+ const outPath = resolve2(opts.outDir, fileName.replace(/\.[^.]+$/, "") + outExt);
231
+ assertSafeDestination(outPath, opts.outDir);
197
232
  writeFileSync(outPath, output, "utf-8");
198
233
  if (!opts.silent) process.stderr.write(` \u2192 ${outPath}
199
234
  `);
@@ -222,16 +257,18 @@ async function convertFiles(files, opts, writeOutput = (text) => {
222
257
 
223
258
  // src/cli/batch.ts
224
259
  import { fork } from "child_process";
225
- import { basename as basename2 } from "path";
260
+ import { basename as basename3 } from "path";
226
261
  function registerBatchWorker(program2) {
227
262
  program2.command("__convert-worker", { hidden: true }).action(() => {
228
263
  if (!process.send) program2.error("Internal command requires an IPC channel");
229
264
  process.on("disconnect", () => process.exit(0));
230
- process.on("message", async ({ file, opts }) => {
265
+ let assertSafeOutputs;
266
+ process.on("message", async ({ file, opts, inputs }) => {
231
267
  const output = [];
268
+ assertSafeOutputs ??= createOutputGuard(inputs ?? [file]);
232
269
  const ok = await convertFiles([file], opts, (text) => {
233
270
  output.push(text);
234
- });
271
+ }, assertSafeOutputs);
235
272
  process.send({ ok, output });
236
273
  });
237
274
  });
@@ -239,8 +276,8 @@ function registerBatchWorker(program2) {
239
276
  function assertDistinctStems(files) {
240
277
  const stems = /* @__PURE__ */ new Set();
241
278
  for (const file of files) {
242
- const stem = basename2(file).replace(/\.[^.]+$/, "").normalize("NFC").toLowerCase();
243
- if (stems.has(stem)) throw new KordocError(`Output name collision: ${basename2(file)}; use distinct file stems`);
279
+ const stem = basename3(file).replace(/\.[^.]+$/, "").normalize("NFC").toLowerCase();
280
+ if (stems.has(stem)) throw new KordocError(`Output name collision: ${basename3(file)}; use distinct file stems`);
244
281
  stems.add(stem);
245
282
  }
246
283
  }
@@ -263,33 +300,35 @@ async function convertParallel(files, opts, jobs) {
263
300
  process.once("SIGINT", onSigint);
264
301
  process.once("SIGTERM", onSigterm);
265
302
  try {
266
- await Promise.all(Array.from({ length: Math.min(jobs, files.length) }, () => new Promise((resolve6, reject) => {
303
+ await Promise.all(Array.from({ length: Math.min(jobs, files.length) }, () => new Promise((resolve7, reject) => {
267
304
  const worker = fork(process.argv[1], ["__convert-worker"], { stdio: ["ignore", "ignore", "inherit", "ipc"] });
268
305
  workers.push(worker);
269
306
  let current;
270
307
  let finished = false;
308
+ let firstJob = true;
271
309
  worker.on("error", reject);
272
310
  worker.on("exit", (code, signal) => {
273
- if (!finished) reject(new KordocError(`Conversion worker exited (${signal ?? code}) while processing ${basename2(current ?? "unknown")}`));
311
+ if (!finished) reject(new KordocError(`Conversion worker exited (${signal ?? code}) while processing ${basename3(current ?? "unknown")}`));
274
312
  });
275
313
  const dispatch = () => {
276
314
  if (next === files.length) {
277
315
  finished = true;
278
316
  worker.disconnect();
279
- resolve6();
317
+ resolve7();
280
318
  return;
281
319
  }
282
320
  current = files[next++];
283
- if (!opts.silent) process.stderr.write(`[kordoc] [${next}/${files.length}] ${basename2(current)} ...
321
+ if (!opts.silent) process.stderr.write(`[kordoc] [${next}/${files.length}] ${basename3(current)} ...
284
322
  `);
285
- worker.send({ file: current, opts: { ...opts, output: void 0, silent: true } }, (err) => {
323
+ worker.send({ file: current, opts: { ...opts, output: void 0, silent: true }, ...firstJob ? { inputs: files } : {} }, (err) => {
286
324
  if (err) reject(err);
287
325
  });
326
+ firstJob = false;
288
327
  };
289
328
  worker.on("message", ({ ok, output }) => {
290
329
  if (!ok) failed = true;
291
330
  for (const text of output) process.stdout.write(text);
292
- if (!opts.silent) process.stderr.write(`[kordoc] ${basename2(current)} ${ok ? "OK" : "FAIL"}
331
+ if (!opts.silent) process.stderr.write(`[kordoc] ${basename3(current)} ${ok ? "OK" : "FAIL"}
293
332
  `);
294
333
  dispatch();
295
334
  });
@@ -304,8 +343,8 @@ async function convertParallel(files, opts, jobs) {
304
343
  }
305
344
 
306
345
  // src/cli/commands-docs.ts
307
- import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, statSync as statSync2 } from "fs";
308
- import { basename as basename3, dirname, resolve as resolve2, extname } from "path";
346
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, statSync as statSync3 } from "fs";
347
+ import { basename as basename4, dirname, resolve as resolve3, extname } from "path";
309
348
  function registerDocCommands(program2) {
310
349
  program2.command("watch <dir>").description("\uB514\uB809\uD1A0\uB9AC \uAC10\uC2DC \u2014 \uC0C8 \uBB38\uC11C \uC790\uB3D9 \uBCC0\uD658").option("--webhook <url>", "\uACB0\uACFC \uC804\uC1A1 \uC6F9\uD6C5 URL").option("-d, --out-dir <dir>", "\uBCC0\uD658 \uACB0\uACFC \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC").option("-p, --pages <range>", "\uD398\uC774\uC9C0/\uC139\uC158 \uBC94\uC704").option("--format <type>", "\uCD9C\uB825 \uD615\uC2DD: markdown \uB610\uB294 json", "markdown").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (dir, opts, command) => {
311
350
  const rootOpts = program2.opts();
@@ -315,7 +354,7 @@ function registerDocCommands(program2) {
315
354
  if (command.getOptionValueSource("format") === "default" && program2.getOptionValueSource("format") === "cli") {
316
355
  opts.format = rootOpts.format;
317
356
  }
318
- const { watchDirectory } = await import("./watch-NRATQ472.js");
357
+ const { watchDirectory } = await import("./watch-JXDUZYBY.js");
319
358
  await watchDirectory({
320
359
  dir,
321
360
  outDir: opts.outDir,
@@ -355,15 +394,15 @@ function registerDocCommands(program2) {
355
394
  arrayBuffer = readBuiltinTemplate(t);
356
395
  inputName = t.file;
357
396
  } else if (file) {
358
- const absPath = resolve2(file);
359
- const fileSize = statSync2(absPath).size;
397
+ const absPath = resolve3(file);
398
+ const fileSize = statSync3(absPath).size;
360
399
  if (fileSize > 500 * 1024 * 1024) {
361
400
  process.stderr.write(`[kordoc] \uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${(fileSize / 1024 / 1024).toFixed(1)}MB)
362
401
  `);
363
402
  process.exit(1);
364
403
  }
365
404
  arrayBuffer = toArrayBuffer(readFileSync2(absPath));
366
- inputName = basename3(absPath);
405
+ inputName = basename4(absPath);
367
406
  } else {
368
407
  process.stderr.write(`[kordoc] \uC11C\uC2DD \uD30C\uC77C \uACBD\uB85C \uB610\uB294 --template \uC744 \uC9C0\uC815\uD574\uC8FC\uC138\uC694 (\uBAA9\uB85D: kordoc fill --list-templates)
369
408
  `);
@@ -395,8 +434,8 @@ function registerDocCommands(program2) {
395
434
  }
396
435
  let values = {};
397
436
  if (opts.json) {
398
- const jsonPath = resolve2(opts.json);
399
- const jsonContent = readFileSync2(jsonPath, "utf-8");
437
+ const jsonPath = resolve3(opts.json);
438
+ const jsonContent = readFileSync2(jsonPath, "utf-8").replace(/^/, "");
400
439
  values = JSON.parse(jsonContent);
401
440
  } else if (opts.fields) {
402
441
  const fieldsStr = opts.fields;
@@ -471,9 +510,9 @@ function registerDocCommands(program2) {
471
510
  }
472
511
  }
473
512
  if (opts.output) {
474
- mkdirSync2(dirname(resolve2(opts.output)), { recursive: true });
475
- writeFileSync2(resolve2(opts.output), Buffer.from(hwpxResult.buffer));
476
- if (!opts.silent) process.stderr.write(`[kordoc] \u2192 ${resolve2(opts.output)}
513
+ mkdirSync2(dirname(resolve3(opts.output)), { recursive: true });
514
+ writeFileSync2(resolve3(opts.output), Buffer.from(hwpxResult.buffer));
515
+ if (!opts.silent) process.stderr.write(`[kordoc] \u2192 ${resolve3(opts.output)}
477
516
  `);
478
517
  } else {
479
518
  process.stdout.write(Buffer.from(hwpxResult.buffer));
@@ -509,18 +548,18 @@ function registerDocCommands(program2) {
509
548
  if (outputFormat === "hwpx") {
510
549
  const hwpxBuffer = await markdownToHwpx(markdown);
511
550
  if (opts.output) {
512
- mkdirSync2(dirname(resolve2(opts.output)), { recursive: true });
513
- writeFileSync2(resolve2(opts.output), Buffer.from(hwpxBuffer));
514
- if (!opts.silent) process.stderr.write(`[kordoc] \u2192 ${resolve2(opts.output)}
551
+ mkdirSync2(dirname(resolve3(opts.output)), { recursive: true });
552
+ writeFileSync2(resolve3(opts.output), Buffer.from(hwpxBuffer));
553
+ if (!opts.silent) process.stderr.write(`[kordoc] \u2192 ${resolve3(opts.output)}
515
554
  `);
516
555
  } else {
517
556
  process.stdout.write(Buffer.from(hwpxBuffer));
518
557
  }
519
558
  } else {
520
559
  if (opts.output) {
521
- mkdirSync2(dirname(resolve2(opts.output)), { recursive: true });
522
- writeFileSync2(resolve2(opts.output), markdown, "utf-8");
523
- if (!opts.silent) process.stderr.write(`[kordoc] \u2192 ${resolve2(opts.output)}
560
+ mkdirSync2(dirname(resolve3(opts.output)), { recursive: true });
561
+ writeFileSync2(resolve3(opts.output), markdown, "utf-8");
562
+ if (!opts.silent) process.stderr.write(`[kordoc] \u2192 ${resolve3(opts.output)}
524
563
  `);
525
564
  } else if (opts.mask) {
526
565
  process.stdout.write(`\u26A0\uFE0F --mask \uD65C\uC131 \u2014 \uAC1C\uC778\uC815\uBCF4 \uB178\uCD9C \uBC29\uC9C0\uB97C \uC704\uD574 \uBCF8\uBB38\uC744 \uCD9C\uB825\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. -o \uB85C \uD30C\uC77C \uC800\uC7A5 \uD6C4 \uD655\uC778\uD558\uC138\uC694.
@@ -537,7 +576,7 @@ function registerDocCommands(program2) {
537
576
  });
538
577
  program2.command("seal <file>").description('\uB3C4\uC7A5/\uC11C\uBA85 \uC774\uBBF8\uC9C0\uB97C \uC575\uCEE4 \uBB38\uAD6C \uC704\uC5D0 \uBD80\uC720 \uBC30\uCE58 (\uD45C/\uD398\uC774\uC9C0 \uBD88\uD655\uC7A5) \u2014 kordoc seal \uC2E0\uCCAD\uC11C.hwpx --image \uB3C4\uC7A5.png --anchor "(\uC778)" -o \uACB0\uACFC.hwpx').requiredOption("--image <path>", "\uB3C4\uC7A5/\uC11C\uBA85 \uC774\uBBF8\uC9C0 (\uD22C\uBA85 \uBC30\uACBD PNG \uAD8C\uC7A5)").option("--anchor <text>", "\uC575\uCEE4 \uBB38\uAD6C", "(\uC778)").option("-n, --occurrence <num>", "\uAC19\uC740 \uC575\uCEE4\uAC00 \uC5EC\uB7FF\uC77C \uB54C 0-based \uC120\uD0DD", "0").option("--size-mm <num>", "\uB3C4\uC7A5 \uD55C \uBCC0 \uD06C\uAE30 mm (\uAE30\uBCF8: \uC904\uB192\uC774\xD71.6, 7~18 \uD074\uB7A8\uD504)").option("--mode <mode>", "overlap(\uBB38\uAD6C \uC704 \uACB9\uCE68) | right(\uC624\uB978\uCABD \uC606) | auto", "auto").option("--dx <mm>", "x \uBBF8\uC138\uC870\uC815 mm", "0").option("--dy <mm>", "y \uBBF8\uC138\uC870\uC815 mm", "0").option("-o, --output <path>", "\uCD9C\uB825 \uACBD\uB85C (\uAE30\uBCF8: <\uC785\uB825>.sealed.hwpx)").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (file, opts) => {
539
578
  try {
540
- const { placeSealHwpx, detectFormat: detectFormat2 } = await import("./-WOKB25R2.js");
579
+ const { placeSealHwpx, detectFormat: detectFormat2 } = await import("./-DDAVBMHD.js");
541
580
  const rootOpts = program2.opts();
542
581
  const output = opts.output ?? rootOpts.output;
543
582
  const silent = opts.silent ?? rootOpts.silent;
@@ -547,14 +586,14 @@ function registerDocCommands(program2) {
547
586
  `);
548
587
  process.exit(1);
549
588
  }
550
- const buf = new Uint8Array(readFileSync2(resolve2(file)));
589
+ const buf = new Uint8Array(readFileSync2(resolve3(file)));
551
590
  if (detectFormat2(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)) !== "hwpx") {
552
591
  process.stderr.write(`[kordoc] seal \uC740 HWPX \uC804\uC6A9\uC785\uB2C8\uB2E4 (HWP 5.x \uBC14\uC774\uB108\uB9AC\uB294 \uBBF8\uC9C0\uC6D0)
553
592
  `);
554
593
  process.exit(1);
555
594
  }
556
- const imgPath = resolve2(opts.image);
557
- const imgSize = statSync2(imgPath).size;
595
+ const imgPath = resolve3(opts.image);
596
+ const imgSize = statSync3(imgPath).size;
558
597
  if (imgSize > 500 * 1024 * 1024) {
559
598
  process.stderr.write(`[kordoc] \uB3C4\uC7A5 \uC774\uBBF8\uC9C0\uAC00 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${(imgSize / 1024 / 1024).toFixed(0)}MB)
560
599
  `);
@@ -594,7 +633,7 @@ function registerDocCommands(program2) {
594
633
  dyMm: parseNum("--dy", opts.dy, { allowNeg: true })
595
634
  }]
596
635
  );
597
- const outPath = resolve2(output ?? file.replace(/\.hwpx$/i, "") + ".sealed.hwpx");
636
+ const outPath = resolve3(output ?? file.replace(/\.hwpx$/i, "") + ".sealed.hwpx");
598
637
  mkdirSync2(dirname(outPath), { recursive: true });
599
638
  writeFileSync2(outPath, Buffer.from(result.buffer));
600
639
  if (!silent) {
@@ -615,12 +654,12 @@ function registerDocCommands(program2) {
615
654
  });
616
655
  program2.command("patch <original> <edited>").description("\uC11C\uC2DD \uBCF4\uC874 \uB77C\uC6B4\uB4DC\uD2B8\uB9BD \uD328\uCE58 \u2014 \uD3B8\uC9D1\uB41C \uB9C8\uD06C\uB2E4\uC6B4\uC744 \uC6D0\uBCF8 HWPX/HWP\uC5D0 in-place \uBC18\uC601 (kordoc patch \uC6D0\uBCF8.hwpx \uD3B8\uC9D1.md -o \uCD9C\uB825.hwpx). \uBBF8\uC801\uC6A9(skip) \uD3B8\uC9D1\uC774 \uC788\uC73C\uBA74 exit 2").option("-o, --output <path>", "\uCD9C\uB825 \uACBD\uB85C (\uAE30\uBCF8: <\uC6D0\uBCF8>.patched.hwpx|.hwp)").option("--no-verify", "\uD328\uCE58 \uD6C4 \uC7AC\uD30C\uC2F1 \uC790\uB3D9 \uAC80\uC99D \uC0DD\uB7B5").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (original, edited, opts) => {
617
656
  try {
618
- const { patchHwpx, patchHwp, detectFormat: detectFormat2 } = await import("./-WOKB25R2.js");
657
+ const { patchHwpx, patchHwp, detectFormat: detectFormat2 } = await import("./-DDAVBMHD.js");
619
658
  const rootOpts = program2.opts();
620
659
  const output = opts.output ?? rootOpts.output;
621
660
  const silent = opts.silent ?? rootOpts.silent;
622
- const originalBuf = new Uint8Array(readFileSync2(resolve2(original)));
623
- const editedMarkdown = readFileSync2(resolve2(edited), "utf-8");
661
+ const originalBuf = new Uint8Array(readFileSync2(resolve3(original)));
662
+ const editedMarkdown = readFileSync2(resolve3(edited), "utf-8");
624
663
  const format = detectFormat2(originalBuf.buffer);
625
664
  const result = format === "hwp" ? await patchHwp(originalBuf, editedMarkdown, { verify: opts.verify !== false }) : await patchHwpx(originalBuf, editedMarkdown, { verify: opts.verify !== false });
626
665
  if (!result.success || !result.data) {
@@ -629,7 +668,7 @@ function registerDocCommands(program2) {
629
668
  process.exit(1);
630
669
  }
631
670
  const ext = format === "hwp" ? ".hwp" : ".hwpx";
632
- const outPath = resolve2(output ?? original.replace(/\.hwpx?$/i, "") + ".patched" + ext);
671
+ const outPath = resolve3(output ?? original.replace(/\.hwpx?$/i, "") + ".patched" + ext);
633
672
  mkdirSync2(dirname(outPath), { recursive: true });
634
673
  writeFileSync2(outPath, result.data);
635
674
  if (!silent) {
@@ -656,8 +695,8 @@ function registerDocCommands(program2) {
656
695
  });
657
696
  program2.command("validate <file>").description("HWPX \uAD6C\uC870 \uAC80\uC99D \u2014 ZIP\xB7mimetype\xB7\uD544\uC218 \uD30C\uC77C\xB7XML \uC6F0\uD3FC\uB4DC\xB7secCnt\xB7manifest \uCC38\uC870 (\uD55C\uCEF4\uB3C5\uC2A4 \uAC70\uBD80 \uC694\uC778 \uC0AC\uC804 \uCC28\uB2E8)").option("--json", "\uACB0\uACFC\uB97C JSON\uC73C\uB85C stdout\uC5D0 \uCD9C\uB825").action(async (file, opts) => {
658
697
  try {
659
- const { validateHwpx } = await import("./-WOKB25R2.js");
660
- const buf = new Uint8Array(readFileSync2(resolve2(file)));
698
+ const { validateHwpx } = await import("./-DDAVBMHD.js");
699
+ const buf = new Uint8Array(readFileSync2(resolve3(file)));
661
700
  const result = await validateHwpx(buf);
662
701
  if (opts.json) {
663
702
  process.stdout.write(JSON.stringify(result, null, 2) + "\n");
@@ -682,8 +721,8 @@ function registerDocCommands(program2) {
682
721
  }
683
722
 
684
723
  // src/cli/commands-generate.ts
685
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, statSync as statSync3 } from "fs";
686
- import { basename as basename4, dirname as dirname2, resolve as resolve3 } from "path";
724
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, statSync as statSync4 } from "fs";
725
+ import { basename as basename5, dirname as dirname2, resolve as resolve4 } from "path";
687
726
  function registerGenerateCommands(program2) {
688
727
  program2.command("generate <markdown>").alias("gen").description("\uB9C8\uD06C\uB2E4\uC6B4 \u2192 \uACF5\uBB38\uC11C HWPX \uC0DD\uC131 \u2014 kordoc generate \uBCF4\uACE0\uC11C.md -o \uBCF4\uACE0\uC11C.hwpx --preset \uBCF4\uACE0\uC11C (markdown\uC5D0 '-' \uC9C0\uC815 \uC2DC stdin)").option("-o, --output <path>", "\uCD9C\uB825 HWPX \uACBD\uB85C (\uAE30\uBCF8: <\uC785\uB825>.hwpx)").option("--preset <name>", "\uACF5\uBB38\uC11C \uD504\uB9AC\uC14B: \uAE30\uC548\uBB38(official)\xB7\uBCF4\uACE0\uC11C(report)\xB7\uACC4\uD68D\uC11C(plan)\xB7\uD1B5\uC9C0(notice)\xB7\uD68C\uC758\uB85D(minutes)\xB7\uAC1C\uC870\uC2DD(gaejosik \u2014 \uD45C\uC9C0\xB7\uBAA9\uCC28\xB7\uC7A5\uD5E4\uB354 \uC790\uB3D9)\xB7\uC5C5\uBB34\uBCF4\uACE0(ministry \u2014 \uC911\uC559\uBD80\uCC98 \uC5C5\uBB34\uBCF4\uACE0: \uC7A5 \uB760\xB7\uC808 \uC22B\uC790\uCE78\xB7\uC18C\uC81C\uBAA9 \uBC15\uC2A4\xB7\u2460 \uD56D\uBAA9 \uB760\xB7\uC131\uACFC \uC694\uC57D\uBC15\uC2A4\xB7\uBCC4\uCCA8 \uB760)\xB7\uC11C\uC6B8\uBC29\uCE68(bangchim \u2014 \uC11C\uC6B8\uC2DC \uBC29\uCE68\uC11C: \uC81C\uBAA9\uD45C\xB7\uD30C\uB791 \uBD80\uC81C\xB7\uC694\uC57D\uBC15\uC2A4\xB7[\u2160] \uC7A5 \uC0C1\uC790\xB7\uC808 \uB760\xB7\u2776 \uACFC\uC81C)\xB7\uBCF4\uB3C4\uC790\uB8CC(press)", "\uAE30\uC548\uBB38").option("--font <type>", "\uBCF8\uBB38 \uAE00\uAF34: myeongjo(\uD568\uCD08\uB86C\uBC14\uD0D5) \uB610\uB294 gothic(\uB9D1\uC740 \uACE0\uB515)").option("--pt <size>", "\uBCF8\uBB38 \uAE00\uC790 \uD06C\uAE30(pt)").option("--line-spacing <percent>", "\uBCF8\uBB38 \uC904\uAC04\uACA9(%)").option("--profile <path>", "\uC11C\uC2DD \uD504\uB85C\uD544 JSON (kordoc profile\uB85C \uCD94\uCD9C) \u2014 \uCC38\uC870 \uBB38\uC11C\uC758 \uD45C \uD14C\uB450\uB9AC\xB7\uC74C\uC601\xB7\uC5F4\uD3ED\xB7\uC140 \uAE00\uAF34 \uC7AC\uD604").option("--org <name>", "\uD45C\uC9C0 \uAE30\uAD00\uBA85 (\uD45C\uC9C0\uB97C \uCF1C\uB294 \uD504\uB9AC\uC14B \uACF5\uD1B5)").option("--date <date>", "\uD45C\uC9C0 \uB0A0\uC9DC (\uAE30\uBCF8 \uC624\uB298 \u2014 'YYYY. M. D.')").option("--toc", "\uBAA9\uCC28 \uD398\uC774\uC9C0 \uAC15\uC81C \uCF1C\uAE30 (\uAC1C\uC870\uC2DD \uC678 \uD504\uB9AC\uC14B\uC5D0\uC11C\uB3C4 h2 \uBAA9\uB85D\uC73C\uB85C \uC0DD\uC131)").option("--no-toc", "\uBAA9\uCC28 \uD398\uC774\uC9C0 \uB044\uAE30 (\uAC1C\uC870\uC2DD \uD504\uB9AC\uC14B \uAE30\uBCF8 \uCF1C\uC9D0)").option("--cover", "\uD45C\uC9C0 \uD398\uC774\uC9C0 \uAC15\uC81C \uCF1C\uAE30 (\uAC1C\uC870\uC2DD \uC678 \uD504\uB9AC\uC14B\uC5D0\uC11C\uB3C4 \uCCAB h1\uC744 \uD45C\uC9C0\uB85C)").option("--no-cover", "\uD45C\uC9C0 \uD398\uC774\uC9C0 \uB044\uAE30 (\uAC1C\uC870\uC2DD \uD504\uB9AC\uC14B \uAE30\uBCF8 \uCF1C\uC9D0)").option("--approval <labels>", "\uACB0\uC7AC\uB780 \uC9C1\uC704 \uB77C\uBCA8 (\uC27C\uD45C \uAD6C\uBD84, \uC608: \uB2F4\uB2F9,\uD300\uC7A5,\uACFC\uC7A5) \u2014 \uBB38\uC11C \uCD5C\uC0C1\uB2E8 \uC6B0\uCE21").option("--page-numbers", "\uCABD\uBC88\uD638 \uAC15\uC81C \uCF1C\uAE30 (\uD558\uB2E8 \uC911\uC559 '- 1 -')").option("--no-page-numbers", "\uCABD\uBC88\uD638 \uB044\uAE30 (\uAC1C\uC870\uC2DD\xB7\uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C \uAE30\uBCF8 \uCF1C\uC9D0)").option("--end-mark", "\uBCF8\uBB38 \uB05D '\uB05D.' \uD45C\uC2DC \uAC15\uC81C \uCF1C\uAE30").option("--no-end-mark", "'\uB05D.' \uD45C\uC2DC \uB044\uAE30 (\uAE30\uC548\uBB38 \uAE30\uBCF8 \uCF1C\uC9D0)").option("--no-body-title-box", "\uBCF8\uBB38 \uCCAB \uD398\uC774\uC9C0 \uC81C\uBAA9 \uBC18\uBCF5 \uBC15\uC2A4 \uB044\uAE30 (\uAC1C\uC870\uC2DD+\uD45C\uC9C0 \uAE30\uBCF8 \uCF1C\uC9D0)").option("--chapter-fit", "\uAC1C\uC870\uC2DD \uC7A5 \uD5E4\uB354 \uC81C\uBAA9 \uCE78\uC744 \uAE00\uC790 \uD3ED\uC5D0 \uB9DE\uCDA4 (\uAE30\uBCF8: \uBCF8\uBB38 \uD3ED\uAE4C\uC9C0)").option("--h2-marker <type>", "h2 \uC7A5 \uC81C\uBAA9 \uD45C\uAE30: band(\uB85C\uB9C8\uC790 \uCC44\uC6C0 \uCE78 + \uC81C\uBAA9 \uB760 \uD45C \u2014 \uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C \uAE30\uBCF8)\xB7roman(\u2160. \uD14D\uC2A4\uD2B8)\xB7number(1. \u2014 \uD1B5\uC9C0 \uAE30\uBCF8)\xB7box(\uC7A5 \uC5C6\uC774 \u25A1 \uB300\uD56D\uBAA9)\xB7none").option("--band-color <hex>", "\uB760 \uC81C\uBAA9 \uBC88\uD638\uCE78 \uCC44\uC6C0\uC0C9 #RRGGBB (\uAE30\uBCF8 #003366 \u2014 \uC2E4\uCE21 \uCD5C\uB2E4. \uAD50\uC721\uCCAD\uD615 \uBC1D\uC740 \uB760: #DFE6F7)").option("--band-text-color <hex>", "\uB760 \uC81C\uBAA9 \uBC88\uD638 \uAE00\uC790\uC0C9 #RRGGBB (\uAE30\uBCF8 #FFFFFF \u2014 \uBC1D\uC740 \uB760\uBA74 #000000)").option("--summary <text>", "\uBCF4\uACE0\uC11C \uC694\uC57D \uBC15\uC2A4 (\uC81C\uBAA9\uD45C \uC544\uB798 \uC74C\uC601 \uC0C1\uC790 \u2014 \uB9C8\uD06C\uB2E4\uC6B4 \uC81C\uBAA9 \uC9C1\uD6C4 \uC778\uC6A9\uBB38(>)\uC73C\uB85C\uB3C4 \uC9C0\uC815)").option("--doc-info <spec>", "\uBCF4\uACE0\uC11C \uD45C\uC9C0 \uBB38\uC11C\uC815\uBCF4\uD45C: docNum=\uC2A4\uB9C8\uD2B8\uB3C4\uC2DC\uACFC-123,date=2026. 9. 6.,disclosure=\uACF5\uAC1C,policyNo= (--cover\uC640 \uD568\uAED8)").option("--dept <name>", "\uD45C\uC9C0 \uBD80\uC11C\uBA85 (\uAE30\uAD00\uBA85 \uC544\uB798 \uAD04\uD638)").option("--checklist [na]", "\uC11C\uC6B8 \uC0AC\uC804 \uAC80\uD1A0\uD56D\uBAA9 \uC810\uAC80\uD45C(\uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C\xB7\uC11C\uC6B8\uBC29\uCE68) \u2014 \uAC12 \uC5C6\uC73C\uBA74 \uBE48 \uC11C\uC2DD, \uD574\uB2F9\uC5C6\uC74C \uBB38\uD56D \uBC88\uD638\uB97C \uC8FC\uBA74(6,7,8) \uB098\uBA38\uC9C0\uB294 \uAC80\uD1A0\uC644\uB8CC").option("--cover-label <text>", "\uD45C\uC9C0 \uC6B0\uC0C1\uB2E8 \uCDE8\uAE09 \uD45C\uC2DC \u2014 '\uB300\uC678\uC8FC\uC758'\xB7'\uBE44\uACF5\uAC1C' \uBE68\uAC04 \uD14C\uB450\uB9AC \uBC15\uC2A4 (\uC5C5\uBB34\uBCF4\uACE0 \uD504\uB9AC\uC14B \uC2E4\uCE21)").option("--fonts <spec>", "\uC694\uC18C\uBCC4 \uAE00\uAF34 \uC624\uBC84\uB77C\uC774\uB4DC: body=\uB098\uB214\uBA85\uC870,heading=\uB098\uB214\uACE0\uB515,ref=\uD55C\uC591\uC911\uACE0\uB515,table=\uB9D1\uC740 \uACE0\uB515").option("--sizes <spec>", "\uAC1C\uC870\uC2DD \uC694\uC18C\uBCC4 \uD06C\uAE30(pt): dae=16,cham=13,table=12,coverTitle=30 \u2026").option("--levels <spec>", "\uD56D\uBAA9\uBD80\uD638 \uB2E8\uACC4\uBCC4 \uC704\uACC4 \uD0C0\uC774\uD3EC: 0=HY\uACAC\uACE0\uB515/17/bold,1=\uD55C\uCEF4\uB3CB\uC6C0/15/bold,2=\uD734\uBA3C\uBA85\uC870/14 (depth 0~7, \uC22B\uC790=pt\xB7bold\xB7plain\xB7\uAE00\uAF34\uBA85)").option("--bullet2 <char>", "2\uB2E8\uACC4 \uD56D\uBAA9\uBD80\uD638: \u3147(\uC774\uC751 \u2014 \uAE30\uC548\uBB38\xB7\uACF5\uACE0\uBB38 \uC2E4\uCE21 \uC9C0\uBC30) \uB610\uB294 \u25CB(\uC6D0 \u2014 \uBCF4\uACE0\uC11C \uC591\uC2DD)").option("--suppress-single", "\uB2E8\uC77C \uD615\uC81C \uD56D\uBAA9 \uBD80\uD638 \uC0DD\uB7B5 (\uD3B8\uB78C \uADDC\uC815 \u2014 \uAE30\uBCF8\uC740 \uD558\uB098\uC5EC\uB3C4 \uBD80\uD638 \uBD80\uC5EC)").option("--doc-head <spec>", "\uAE30\uC548\uBB38 \uB450\uBB38\uD45C: org=\uAE30\uAD00\uBA85,slogan=\uC6D0\uD6C8,to=\uC218\uC2E0\uCC98,title=\uC81C\uBAA9 (\uBCC4\uC9C0 \uC81C1\uD638\uC11C\uC2DD\xB7\uC11C\uC6B8 \uC2E4\uACB0\uC7AC 6\uD589 \uD45C)").option("--doc-foot <spec>", "\uAE30\uC548\uBB38 \uACB0\uBB38\uD45C: sender=\uBC1C\uC2E0\uBA85\uC758,drafter=\uC8FC\uBB34\uAD00 \uD64D\uAE38\uB3D9,reviewer=\uACFC\uC7A5 \uAE40\uCCA0\uC218,approver=\uAD6D\uC7A5 \uBC15\uC601\uD76C,cooperator=\uD611\uC870\uC790,docNum=\uC2DC\uD589(\uACFC-\uBC88\uD638 (\uB0A0\uC9DC)),receive=\uC811\uC218,zip=\uC6B0\uD3B8\uBC88\uD638,address=\uC8FC\uC18C,site=\uD648\uD398\uC774\uC9C0,phone=\uC804\uD654,fax=\uC804\uC1A1,email=\uBA54\uC77C,disclosure=\uACF5\uAC1C\uAD6C\uBD84").option("--report-info <text>", "\uBCF4\uACE0\uC11C \uB2F4\uB2F9\uC790 \uD589(\uC81C\uBAA9\uD45C \uC544\uB798) / \uAE30\uC548\uBB38 \uC6B0\uC0C1\uB2E8 \uBCF4\uACE0\uC815\uBCF4 \uD589 \u2014 \uC608: '(2026. 7. 11., \uACFC\uC7A5 \uD64D\uAE38\uB3D9, \u260E02-120)'").option("--notice-head <spec>", "\uACF5\uACE0\uBB38 \uB450\uBB38\xB7\uACB0\uBB38: no=\uACF5\uACE0 \uC81C2026-1\uD638,date=2026\uB144 7\uC6D4 11\uC77C,sender=\uD589\uC815\uC548\uC804\uBD80\uC7A5\uAD00").option("--press-head <spec>", "\uBCF4\uB3C4\uC790\uB8CC \uBA38\uB9AC: release=\uBCF4\uB3C4\uC2DC\uC810,distribute=\uBC30\uD3EC\uC77C,dept=\uB2F4\uB2F9\uBD80\uC11C,manager=\uB2F4\uB2F9\uC790,phone=\uC5F0\uB77D\uCC98").option("--press-sub <items>", "\uBCF4\uB3C4\uC790\uB8CC \uBD80\uC81C (\uC138\uBBF8\uCF5C\uB860 \uAD6C\uBD84, \uC81C\uBAA9 \uC544\uB798 '- \u2026 -')").option("--plain", "\uACF5\uBB38\uC11C \uBAA8\uB4DC \uB044\uAE30 (\uBC94\uC6A9 \uB9C8\uD06C\uB2E4\uC6B4 \uBCC0\uD658)").option("--paper <size>", "\uC6A9\uC9C0: A4\xB7A3\xB7B4\xB7B5\xB7Letter \uB610\uB294 '210x297'(mm)").option("--landscape", "\uC6A9\uC9C0 \uAC00\uB85C \uBC29\uD5A5").option("--columns <n>", "\uB2E4\uB2E8 \uAC1C\uC218 (1~8)").option("--header <text>", "\uBA38\uB9AC\uB9D0 \uD14D\uC2A4\uD2B8 (\uBAA8\uB4E0 \uCABD, \uC778\uB77C\uC778 \uB9C8\uD06C\uB2E4\uC6B4 \uD5C8\uC6A9)").option("--footer <text>", "\uAF2C\uB9AC\uB9D0 \uD14D\uC2A4\uD2B8").option("--image-dir <dir>", "\uB9C8\uD06C\uB2E4\uC6B4 \uC774\uBBF8\uC9C0 \uCC38\uC870(![](x.png))\uB97C \uC774 \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uC77D\uC5B4 \uC2E4\uB370\uC774\uD130 \uC784\uBCA0\uB4DC").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (markdown, opts) => {
689
728
  try {
@@ -695,9 +734,9 @@ function registerGenerateCommands(program2) {
695
734
  if (markdown === "-") {
696
735
  md = readFileSync3(0, "utf-8");
697
736
  } else {
698
- const inPath = resolve3(markdown);
737
+ const inPath = resolve4(markdown);
699
738
  md = readFileSync3(inPath, "utf-8");
700
- baseName = basename4(inPath).replace(/\.(md|markdown|txt)$/i, "");
739
+ baseName = basename5(inPath).replace(/\.(md|markdown|txt)$/i, "");
701
740
  }
702
741
  let gongmun;
703
742
  if (!opts.plain) {
@@ -798,7 +837,7 @@ function registerGenerateCommands(program2) {
798
837
  }
799
838
  let profile;
800
839
  if (opts.profile) {
801
- profile = parseFormatProfileJson(readFileSync3(resolve3(String(opts.profile)), "utf-8"));
840
+ profile = parseFormatProfileJson(readFileSync3(resolve4(String(opts.profile)), "utf-8"));
802
841
  if (!silent) process.stderr.write(`[kordoc] \uC11C\uC2DD \uD504\uB85C\uD544 \uC801\uC6A9: \uD45C ${profile.tables.length}\uAC1C (${opts.profile})
803
842
  `);
804
843
  }
@@ -819,7 +858,7 @@ function registerGenerateCommands(program2) {
819
858
  }
820
859
  let imageBytes;
821
860
  if (opts.imageDir) {
822
- const dir = resolve3(String(opts.imageDir));
861
+ const dir = resolve4(String(opts.imageDir));
823
862
  const loaded = await loadGenerationImages(md, dir);
824
863
  imageBytes = loaded.images;
825
864
  if (!silent) {
@@ -839,7 +878,7 @@ function registerGenerateCommands(program2) {
839
878
  } : void 0);
840
879
  if (!silent) for (const w of genWarnings) process.stderr.write(`[kordoc] \u26A0 ${w}
841
880
  `);
842
- const outPath = resolve3(output ?? (markdown === "-" ? `${baseName}.hwpx` : markdown.replace(/\.(md|markdown|txt)$/i, "") + ".hwpx"));
881
+ const outPath = resolve4(output ?? (markdown === "-" ? `${baseName}.hwpx` : markdown.replace(/\.(md|markdown|txt)$/i, "") + ".hwpx"));
843
882
  mkdirSync3(dirname2(outPath), { recursive: true });
844
883
  writeFileSync3(outPath, Buffer.from(buf));
845
884
  if (!silent) {
@@ -858,9 +897,9 @@ function registerGenerateCommands(program2) {
858
897
  const rootOpts = program2.opts();
859
898
  const output = opts.output ?? rootOpts.output;
860
899
  const silent = opts.silent ?? rootOpts.silent;
861
- const absPath = resolve3(file);
900
+ const absPath = resolve4(file);
862
901
  const profile = await hwpxToProfile(readFileSync3(absPath));
863
- const outPath = resolve3(output ?? absPath.replace(/\.hwpx$/i, "") + ".profile.json");
902
+ const outPath = resolve4(output ?? absPath.replace(/\.hwpx$/i, "") + ".profile.json");
864
903
  mkdirSync3(dirname2(outPath), { recursive: true });
865
904
  writeFileSync3(outPath, JSON.stringify(profile, null, 2));
866
905
  if (!silent) process.stderr.write(`[kordoc] \uC11C\uC2DD \uD504\uB85C\uD544 \uCD94\uCD9C: \uD45C ${profile.tables.length}\uAC1C \u2192 ${outPath}
@@ -873,7 +912,7 @@ function registerGenerateCommands(program2) {
873
912
  });
874
913
  program2.command("lint <file>").description("\uACF5\uBB38\uC11C \uD45C\uAE30\uBC95 \uAC80\uC218 \u2014 \uB0A0\uC9DC\xB7\uC2DC\uAC04\xB7\uAE08\uC561\xB7\uBD99\uC784 \uB4F1 \uD589\uC815\uC5C5\uBB34\uC6B4\uC601 \uD3B8\uB78C \uD45C\uAE30\uBC95 (md/txt, '-'=stdin). error \uC788\uC73C\uBA74 exit 1").option("--json", "JSON \uCD9C\uB825").option("--munche", "\uAC1C\uC870\uC2DD \uBB38\uCCB4 \uAC80\uC218 \uBCD1\uD589 \u2014 \uC11C\uC220\uD615 \uC885\uACB0\xB7\uB2F9\uC704\xB7\uC218\uC0AC\xB7\uD56D\uBAA9 \uAE38\uC774 (\uBCF4\uACE0\uC11C\xB7\uACC4\uD68D\uC11C \uC6D0\uACE0\uC6A9)").action((file, opts) => {
875
914
  try {
876
- const raw = file === "-" ? readFileSync3(0) : readFileSync3(resolve3(file));
915
+ const raw = file === "-" ? readFileSync3(0) : readFileSync3(resolve4(file));
877
916
  const kind = detectFormat(
878
917
  raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength)
879
918
  );
@@ -922,7 +961,7 @@ function registerGenerateCommands(program2) {
922
961
  });
923
962
  program2.command("redact <files...>").description("\uAC1C\uC778\uC815\uBCF4 \uC11C\uC2DD \uBCF4\uC874 \uB9C8\uC2A4\uD0B9 \u2014 \uC8FC\uBBFC\xB7\uC678\uAD6D\uC778\uB4F1\uB85D\uBC88\uD638\xB7\uC804\uD654\xB7\uC774\uBA54\uC77C\xB7\uCE74\uB4DC\xB7\uACC4\uC88C\xB7\uC0AC\uC5C5\uC790\uB4F1\uB85D\uBC88\uD638\xB7\uC5EC\uAD8C\xB7\uC6B4\uC804\uBA74\uD5C8(--rules \uB85C \uC778\uBA85\xB7\uC8FC\uC18C opt-in)\uB97C \uD0D0\uC9C0\uD574 HWPX/HWP\uB294 \uC6D0\uBCF8 \uC11C\uC2DD \uADF8\uB300\uB85C \uAC19\uC740 \uAE38\uC774\uB85C \uAC00\uB9B0 \uD30C\uC77C(\uBCF8\uBB38\xB7\uD45C\xB7\uBA38\uB9AC\uB9D0/\uAF2C\uB9AC\uB9D0\xB7\uAC01\uC8FC\xB7\uAE00\uC0C1\uC790\xB7\uBBF8\uB9AC\uBCF4\uAE30\xB7\uBA54\uD0C0\uB370\uC774\uD130 \uD3EC\uD568), \uADF8 \uC678 \uD3EC\uB9F7(PDF \uB4F1)\uC740 \uC6D0\uBCF8\uC744 \uAC74\uB4DC\uB9AC\uC9C0 \uC54A\uACE0 \uB9C8\uC2A4\uD0B9\uB41C \uB9C8\uD06C\uB2E4\uC6B4\uB9CC \uCD9C\uB825. \uC790\uB3D9 \uAC80\uCD9C \uBCF4\uC870 \uB3C4\uAD6C\uC774\uBBC0\uB85C \uACB0\uACFC\uB294 \uBC18\uB4DC\uC2DC \uC0AC\uB78C\uC774 \uCD5C\uC885 \uD655\uC778\uD558\uC138\uC694 (\uC774\uBBF8\uC9C0 \uC18D \uAE00\uC790\uB294 \uD0D0\uC9C0 \uBD88\uAC00)").option("--rules <csv>", "\uC801\uC6A9 \uB8F0 (\uAE30\uBCF8: rrn,phone,email,card,account,brn,passport,driver \u2014 crn(\uBC95\uC778\uB4F1\uB85D\uBC88\uD638),ip,name(\uC778\uBA85),address(\uC8FC\uC18C)\uB294 opt-in)").option("--mask-char <ch>", "\uB9C8\uC2A4\uD06C \uBB38\uC790 1\uAE00\uC790 (\uAE30\uBCF8: \u25CF)").option("-o, --output <path>", "\uCD9C\uB825 \uACBD\uB85C (\uB2E8\uC77C \uD30C\uC77C \uC2DC)").option("-d, --out-dir <dir>", "\uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC (\uB2E4\uC911 \uD30C\uC77C \uC2DC)").option("--dry-run", "\uD0D0\uC9C0 \uB9AC\uD3EC\uD2B8\uB9CC \uCD9C\uB825, \uD30C\uC77C \uBBF8\uC0DD\uC131").option("--json", "\uB9AC\uD3EC\uD2B8\uB97C JSON\uC73C\uB85C stdout \uCD9C\uB825").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (files, opts) => {
924
963
  const { ALL_REDACT_RULES, DEFAULT_REDACT_RULES, redactText } = await import("./redact-NV2QCDGE.js");
925
- const { redactDocument } = await import("./redact-doc-7ZZMHDBO.js");
964
+ const { redactDocument } = await import("./redact-doc-ECFOVR4X.js");
926
965
  const rootOpts = program2.opts();
927
966
  const output = opts.output ?? rootOpts.output;
928
967
  const outDir = opts.outDir ?? rootOpts.outDir;
@@ -956,12 +995,12 @@ function registerGenerateCommands(program2) {
956
995
  }
957
996
  return out.join("");
958
997
  };
959
- const shown = (p) => resolve3(dirname2(p), maskName(basename4(p)));
960
- const inputs = files.map((f) => resolve3(f));
998
+ const shown = (p) => resolve4(dirname2(p), maskName(basename5(p)));
999
+ const inputs = files.map((f) => resolve4(f));
961
1000
  const sameFile = (a, b) => {
962
1001
  if (a === b) return true;
963
1002
  try {
964
- const sa = statSync3(a), sb = statSync3(b);
1003
+ const sa = statSync4(a), sb = statSync4(b);
965
1004
  return sa.ino === sb.ino && sa.dev === sb.dev;
966
1005
  } catch {
967
1006
  return false;
@@ -969,18 +1008,18 @@ function registerGenerateCommands(program2) {
969
1008
  };
970
1009
  const written = /* @__PURE__ */ new Set();
971
1010
  const defaultOut = (absPath, ext) => {
972
- const stem = maskName(basename4(absPath)).replace(/\.[^.]+$/, "");
973
- const dir = resolve3(outDir ?? dirname2(absPath));
1011
+ const stem = maskName(basename5(absPath)).replace(/\.[^.]+$/, "");
1012
+ const dir = resolve4(outDir ?? dirname2(absPath));
974
1013
  for (let n = 1; ; n++) {
975
- const p = resolve3(dir, `${stem}${n > 1 ? `-${n}` : ""}.redacted${ext}`);
1014
+ const p = resolve4(dir, `${stem}${n > 1 ? `-${n}` : ""}.redacted${ext}`);
976
1015
  if (!written.has(p) && !inputs.some((i) => sameFile(i, p))) return p;
977
1016
  }
978
1017
  };
979
1018
  const MAX_LINES = 200;
980
1019
  const jsonReports = [];
981
1020
  for (const absPath of inputs) {
982
- const fileName = maskName(basename4(absPath));
983
- if (output && files.length === 1 && !opts.dryRun && sameFile(absPath, resolve3(output))) {
1021
+ const fileName = maskName(basename5(absPath));
1022
+ if (output && files.length === 1 && !opts.dryRun && sameFile(absPath, resolve4(output))) {
984
1023
  process.stderr.write(`[kordoc] ERROR: ${fileName} \u2014 \uCD9C\uB825 \uACBD\uB85C\uAC00 \uC785\uB825 \uD30C\uC77C\uACFC \uAC19\uC2B5\uB2C8\uB2E4. \uC6D0\uBCF8\uC744 \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2014 \uB2E4\uB978 -o \uACBD\uB85C\uB97C \uC9C0\uC815\uD558\uC138\uC694
985
1024
  `);
986
1025
  process.exitCode = 1;
@@ -1004,7 +1043,7 @@ function registerGenerateCommands(program2) {
1004
1043
  const save = r.data ? r.changed : r.markdownHits.length > 0;
1005
1044
  if (!opts.dryRun && save) {
1006
1045
  const ext = r.data ? r.format === "hwp" ? ".hwp" : ".hwpx" : ".md";
1007
- outPath = output && files.length === 1 ? resolve3(output) : defaultOut(absPath, ext);
1046
+ outPath = output && files.length === 1 ? resolve4(output) : defaultOut(absPath, ext);
1008
1047
  mkdirSync3(dirname2(outPath), { recursive: true });
1009
1048
  if (r.data) writeFileSync3(outPath, r.data);
1010
1049
  else {
@@ -1069,7 +1108,7 @@ function registerGenerateCommands(program2) {
1069
1108
 
1070
1109
  // src/cli/commands-render.ts
1071
1110
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4 } from "fs";
1072
- import { dirname as dirname3, resolve as resolve4 } from "path";
1111
+ import { dirname as dirname3, resolve as resolve5 } from "path";
1073
1112
  function registerRenderCommands(program2) {
1074
1113
  program2.command("render <file>").description("\uB808\uC774\uC544\uC6C3 \uBCF4\uC874 \uB80C\uB354 \u2014 HWPX\xB7HWP(5.x)\uB97C SVG(\uAE30\uBCF8, HWPX \uB294 \uC804\uCCB4 \uD398\uC774\uC9C0 \uC138\uB85C \uC2A4\uD0DD)\xB7HTML\xB7PNG\xB7JPEG\xB7PDF\uB85C. \uD55C\uCEF4 \uC800\uC7A5\uBCF8\uC740 \uC870\uD310 \uCE90\uC2DC \uADF8\uB300\uB85C, \uCE90\uC2DC \uC5C6\uB294 \uC0DD\uC131\uBCF8\xB7\uD3B8\uC9D1\uBCF8\uC740 \uC21C\uC218 TS \uC870\uD310(reflow, \uAE30\uBCF8 \uCF2C) \u2014 kordoc render \uBB38\uC11C.hwpx -o \uBB38\uC11C.svg / --format png --pages 2-4 -d ./pages / --format pdf -o \uBB38\uC11C.pdf").option("-o, --output <path>", "\uCD9C\uB825 \uACBD\uB85C (\uB2E8\uC77C \uC0B0\uCD9C: svg \uC2A4\uD0DD\xB7html\xB7pdf\xB7\uD55C \uCABD png/jpeg. \uAE30\uBCF8: <\uC785\uB825>.<\uD655\uC7A5\uC790>)").option("-d, --out-dir <dir>", "\uD398\uC774\uC9C0\uBCC4 \uC0B0\uCD9C \uB514\uB809\uD1A0\uB9AC (svg/png/jpeg \uC5EC\uB7EC \uCABD \u2192 page_001.png \u2026)").option("--format <fmt>", "svg(\uAE30\uBCF8) | html | png | jpeg | pdf").option("--pages <range>", "\uB80C\uB354\uD560 \uD398\uC774\uC9C0 (1-based: 3 / 1-3 / 1,3,7-9)").option("--max-width <px>", "\uB798\uC2A4\uD130 \uCD5C\uB300 \uD3ED px (\uAE30\uBCF8 1400)").option("--title <text>", "HTML/PDF \uBB38\uC11C \uC81C\uBAA9").option("--browser <path>", "PDF \uC6A9 Chromium \uC2E4\uD589 \uD30C\uC77C (\uAE30\uBCF8: PUPPETEER_EXECUTABLE_PATH \uB610\uB294 \uC790\uB3D9 \uD0D0\uC9C0)").option("--highlight <terms>", "\uAC80\uC0C9\uC5B4 \uD615\uAD11\uD39C (\uC27C\uD45C \uAD6C\uBD84)").option("--no-reflow", "\uC21C\uC218 TS \uC870\uD310 \uB044\uAE30 (\uC870\uD310 \uCE90\uC2DC \uC5C6\uB294 \uBB38\uC11C\uAC00 \uBE48 \uD398\uC774\uC9C0\uB85C \uB098\uC62C \uC218 \uC788\uC74C)").option("--reflow", "\uC21C\uC218 TS \uC870\uD310 \uCF1C\uAE30 \u2014 \uAE30\uBCF8\uAC12\uACFC \uAC19\uB2E4 (\uC61B \uC548\uB0B4 \uD638\uD658, #97)").option("--reflow-mode <mode>", "reflow \uC904\uBC14\uAFC8 \uBAA8\uB4DC: keep(\uC5B4\uC808) | charAll(\uAE00\uC790)", "keep").option("--silent", "\uC9C4\uD589 \uBA54\uC2DC\uC9C0 \uC228\uAE30\uAE30").action(async (file, opts) => {
1075
1114
  try {
@@ -1081,13 +1120,13 @@ function registerRenderCommands(program2) {
1081
1120
  const pages = opts.pages ?? rootOpts.pages;
1082
1121
  if (!["svg", "html", "png", "jpeg", "pdf"].includes(fmt)) throw new KordocError(`--format \uC740 svg|html|png|jpeg|pdf \uC911 \uD558\uB098: ${fmt}`);
1083
1122
  const highlights = opts.highlight ? String(opts.highlight).split(",") : void 0;
1084
- const absPath = resolve4(file);
1123
+ const absPath = resolve5(file);
1085
1124
  const stem = file.replace(/\.hwpx?$/i, "");
1086
1125
  if (fmt === "svg" && !outDir && !pages && !/\.hwp$/i.test(absPath)) {
1087
- const { renderHwpxToSvg } = await import("./render-SWRTUDAV.js");
1126
+ const { renderHwpxToSvg } = await import("./render-NSKWZVTD.js");
1088
1127
  const buffer = readFileSync4(absPath);
1089
1128
  const result = await renderHwpxToSvg(toArrayBuffer(buffer), { highlights, reflow: opts.reflow, reflowMode: opts.reflowMode });
1090
- const outPath = resolve4(output ?? stem + ".svg");
1129
+ const outPath = resolve5(output ?? stem + ".svg");
1091
1130
  mkdirSync4(dirname3(outPath), { recursive: true });
1092
1131
  writeFileSync4(outPath, result.svg, "utf-8");
1093
1132
  if (!silent) {
@@ -1098,7 +1137,7 @@ function registerRenderCommands(program2) {
1098
1137
  }
1099
1138
  return;
1100
1139
  }
1101
- const { renderDocument } = await import("./render-SWRTUDAV.js");
1140
+ const { renderDocument } = await import("./render-NSKWZVTD.js");
1102
1141
  const { scene, assets } = await renderDocument(absPath, {
1103
1142
  format: fmt,
1104
1143
  pages,
@@ -1112,21 +1151,21 @@ function registerRenderCommands(program2) {
1112
1151
  const ext = fmt === "jpeg" ? "jpg" : fmt;
1113
1152
  const written = [];
1114
1153
  if (fmt === "html" || fmt === "pdf" || assets.length === 1 && !outDir) {
1115
- const outPath = resolve4(output ?? stem + "." + ext);
1154
+ const outPath = resolve5(output ?? stem + "." + ext);
1116
1155
  mkdirSync4(dirname3(outPath), { recursive: true });
1117
1156
  writeFileSync4(outPath, assets[0].data);
1118
1157
  written.push(outPath);
1119
1158
  } else {
1120
1159
  if (!outDir) throw new KordocError(`\uD398\uC774\uC9C0 ${assets.length}\uC7A5 \uC0B0\uCD9C\uC740 --out-dir \uC774 \uD544\uC694\uD569\uB2C8\uB2E4 (\uD55C \uCABD\uB9CC \uB0B4\uB824\uBA74 --pages \uB85C \uC120\uD0DD)`);
1121
- mkdirSync4(resolve4(outDir), { recursive: true });
1160
+ mkdirSync4(resolve5(outDir), { recursive: true });
1122
1161
  for (const a of assets) {
1123
- const outPath = resolve4(outDir, `page_${String(a.page).padStart(3, "0")}.${ext}`);
1162
+ const outPath = resolve5(outDir, `page_${String(a.page).padStart(3, "0")}.${ext}`);
1124
1163
  writeFileSync4(outPath, a.data);
1125
1164
  written.push(outPath);
1126
1165
  }
1127
1166
  }
1128
1167
  if (!silent) {
1129
- process.stderr.write(`[kordoc] \uB80C\uB354 ${fmt} (${scene.pages.length}\uD398\uC774\uC9C0 \uC911 ${assets.length}\uAC74, \uD14D\uC2A4\uD2B8 ${scene.stats.texts}\xB7\uC774\uBBF8\uC9C0 ${scene.stats.images}\xB7\uD45C ${scene.stats.tables}\xB7\uB3C4\uD615 ${scene.stats.shapes}) \u2192 ${written.length === 1 ? written[0] : resolve4(outDir)}
1168
+ process.stderr.write(`[kordoc] \uB80C\uB354 ${fmt} (${scene.pages.length}\uD398\uC774\uC9C0 \uC911 ${assets.length}\uAC74, \uD14D\uC2A4\uD2B8 ${scene.stats.texts}\xB7\uC774\uBBF8\uC9C0 ${scene.stats.images}\xB7\uD45C ${scene.stats.tables}\xB7\uB3C4\uD615 ${scene.stats.shapes}) \u2192 ${written.length === 1 ? written[0] : resolve5(outDir)}
1130
1169
  `);
1131
1170
  for (const w of scene.warnings) process.stderr.write(`[kordoc] \u26A0\uFE0F ${w}
1132
1171
  `);
@@ -1148,8 +1187,8 @@ function registerRenderCommands(program2) {
1148
1187
  if (!outDir) throw new KordocError("--out-dir \uC774 \uD544\uC694\uD569\uB2C8\uB2E4 (crop \uC740 \uD30C\uC77C \uC5EC\uB7EC \uAC1C\uB97C \uB0C5\uB2C8\uB2E4)");
1149
1188
  const types = String(opts.target).split(",").map((t) => t.trim()).filter(Boolean);
1150
1189
  for (const t of types) if (!["table", "image", "paragraph", "shape"].includes(t)) throw new KordocError(`--target \uC720\uD615 \uC624\uB958: ${t}`);
1151
- const { extractRenderedRegions } = await import("./render-SWRTUDAV.js");
1152
- const regions = await extractRenderedRegions(resolve4(file), {
1190
+ const { extractRenderedRegions } = await import("./render-NSKWZVTD.js");
1191
+ const regions = await extractRenderedRegions(resolve5(file), {
1153
1192
  types,
1154
1193
  format: fmt,
1155
1194
  pages,
@@ -1158,15 +1197,15 @@ function registerRenderCommands(program2) {
1158
1197
  reflow: opts.reflow,
1159
1198
  reflowMode: opts.reflowMode
1160
1199
  });
1161
- const dir = resolve4(outDir);
1200
+ const dir = resolve5(outDir);
1162
1201
  mkdirSync4(dir, { recursive: true });
1163
1202
  const ext = fmt === "jpeg" ? "jpg" : "png";
1164
1203
  const manifest = regions.map((r) => {
1165
1204
  const name = `${r.region.id.replace("-", "_")}_page_${String(r.page).padStart(3, "0")}.${ext}`;
1166
- writeFileSync4(resolve4(dir, name), r.data);
1205
+ writeFileSync4(resolve5(dir, name), r.data);
1167
1206
  return { file: name, id: r.region.id, type: r.region.type, sourceId: r.region.sourceId, parentId: r.region.parentId, page: r.page, bbox: r.bbox, widthPx: r.widthPx, heightPx: r.heightPx };
1168
1207
  });
1169
- writeFileSync4(resolve4(dir, "regions.json"), JSON.stringify(manifest, null, 2));
1208
+ writeFileSync4(resolve5(dir, "regions.json"), JSON.stringify(manifest, null, 2));
1170
1209
  if (!silent) process.stderr.write(`[kordoc] crop ${regions.length}\uAC74 (${types.join(",")}) \u2192 ${dir}
1171
1210
  `);
1172
1211
  } catch (err) {
@@ -1186,15 +1225,15 @@ function registerRenderCommands(program2) {
1186
1225
  if (policy !== "none" && !outDir) throw new KordocError("--visual \uC740 crop \uD30C\uC77C\uC744 \uB0B4\uBBC0\uB85C --out-dir \uC774 \uD544\uC694\uD569\uB2C8\uB2E4");
1187
1226
  const cropFmt = String(opts.cropFormat);
1188
1227
  if (!["png", "jpeg"].includes(cropFmt)) throw new KordocError(`--crop-format \uC740 png|jpeg: ${cropFmt}`);
1189
- const { extractTables } = await import("./visual-D2563HCJ.js");
1190
- const tables = await extractTables(resolve4(file), { policy, format: cropFmt, paddingPt: Number(opts.padding) || 0 });
1191
- const dir = outDir ? resolve4(outDir) : void 0;
1228
+ const { extractTables } = await import("./visual-B56WQAGW.js");
1229
+ const tables = await extractTables(resolve5(file), { policy, format: cropFmt, paddingPt: Number(opts.padding) || 0 });
1230
+ const dir = outDir ? resolve5(outDir) : void 0;
1192
1231
  if (dir) mkdirSync4(dir, { recursive: true });
1193
1232
  const ext = cropFmt === "jpeg" ? "jpg" : "png";
1194
1233
  const report = tables.map((t) => {
1195
1234
  const crops = t.crops.map((c) => {
1196
1235
  const name = `${t.id.replace(/[^\w.-]/g, "_")}_page_${String(c.page).padStart(3, "0")}.${ext}`;
1197
- if (dir) writeFileSync4(resolve4(dir, name), c.data);
1236
+ if (dir) writeFileSync4(resolve5(dir, name), c.data);
1198
1237
  return { file: dir ? name : void 0, page: c.page, bbox: c.bbox };
1199
1238
  });
1200
1239
  return {
@@ -1209,7 +1248,7 @@ function registerRenderCommands(program2) {
1209
1248
  };
1210
1249
  });
1211
1250
  const json = JSON.stringify(report, null, 2);
1212
- const jsonPath = output ? resolve4(output) : dir ? resolve4(dir, "tables.json") : void 0;
1251
+ const jsonPath = output ? resolve5(output) : dir ? resolve5(dir, "tables.json") : void 0;
1213
1252
  if (jsonPath) {
1214
1253
  mkdirSync4(dirname3(jsonPath), { recursive: true });
1215
1254
  writeFileSync4(jsonPath, json + "\n");
@@ -1230,7 +1269,7 @@ function registerRenderCommands(program2) {
1230
1269
  });
1231
1270
  program2.command("render-worker").description("persistent \uB80C\uB354 \uC6CC\uCEE4 \u2014 stdin NDJSON \uC694\uCCAD \u2192 \uC870\uD310 SVG \uD30C\uC77C \uCD9C\uB825 (\uD504\uB85C\uC138\uC2A4 \uC720\uC9C0, \uCF5C\uB4DC\uC2A4\uD0C0\uD2B8 \uC81C\uAC70)").action(async () => {
1232
1271
  const { createInterface } = await import("readline");
1233
- const { renderHwpxToSvg } = await import("./render-SWRTUDAV.js");
1272
+ const { renderHwpxToSvg } = await import("./render-NSKWZVTD.js");
1234
1273
  const rl = createInterface({ input: process.stdin });
1235
1274
  const write = (o) => void process.stdout.write(JSON.stringify(o) + "\n");
1236
1275
  write({ ready: true, version: VERSION });
@@ -1255,13 +1294,13 @@ function registerRenderCommands(program2) {
1255
1294
  const id = req.id;
1256
1295
  try {
1257
1296
  if (!req.file || !req.out) throw new Error("file\xB7out \uD544\uC218");
1258
- const buffer = readFileSync4(resolve4(req.file));
1297
+ const buffer = readFileSync4(resolve5(req.file));
1259
1298
  const result = await renderHwpxToSvg(toArrayBuffer(buffer), {
1260
1299
  highlights: req.highlight,
1261
1300
  reflow: req.reflow,
1262
1301
  reflowMode: req.reflowMode
1263
1302
  });
1264
- const outPath = resolve4(req.out);
1303
+ const outPath = resolve5(req.out);
1265
1304
  mkdirSync4(dirname3(outPath), { recursive: true });
1266
1305
  writeFileSync4(outPath, result.svg, "utf-8");
1267
1306
  write({ id, ok: true, out: outPath, width: result.width, height: result.height, pageCount: result.pageCount, stats: result.stats, warnings: result.warnings });
@@ -1279,12 +1318,12 @@ function registerSystemCommands(program2) {
1279
1318
  await startMcpServer();
1280
1319
  });
1281
1320
  program2.command("setup").description("\uB300\uD654\uD615 \uC124\uCE58 \uB9C8\uBC95\uC0AC \u2014 AI \uD074\uB77C\uC774\uC5B8\uD2B8 \uC790\uB3D9 \uB4F1\uB85D (Mac/Win/Linux)").action(async () => {
1282
- const { runSetup } = await import("./setup-43JJEEU7.js");
1321
+ const { runSetup } = await import("./setup-REH2KZP2.js");
1283
1322
  await runSetup();
1284
1323
  });
1285
1324
  program2.command("check-formula-models").description("PDF \uC218\uC2DD OCR \uBAA8\uB378(MFD + MFR + tokenizer, ~155MB) \uC0C1\uD0DC \uD655\uC778 \u2014 \uC5C6\uAC70\uB098 SHA \uBD88\uC77C\uCE58\uBA74 \uB2E4\uC6B4\uB85C\uB4DC").option("--status-only", "\uC0C1\uD0DC\uB9CC JSON \uC73C\uB85C \uCD9C\uB825 (\uB2E4\uC6B4\uB85C\uB4DC \uC548 \uD568)").action(async (opts) => {
1286
1325
  try {
1287
- const { getFormulaModelStatus, ensureFormulaModels, getFormulaModelsDir } = await import("./formula-QZAOKPBX.js");
1326
+ const { getFormulaModelStatus, ensureFormulaModels, getFormulaModelsDir } = await import("./formula-7ZOZ5QJ6.js");
1288
1327
  const dir = getFormulaModelsDir();
1289
1328
  if (opts.statusOnly) {
1290
1329
  const status = await getFormulaModelStatus();
@@ -1338,7 +1377,7 @@ function registerSystemCommands(program2) {
1338
1377
  });
1339
1378
  program2.command("check-ocr-models").description("\uD14D\uC2A4\uD2B8 OCR \uBAA8\uB378(PP-OCRv5 korean det+rec, ~18MB) \uC0C1\uD0DC \uD655\uC778 \u2014 \uC5C6\uAC70\uB098 SHA \uBD88\uC77C\uCE58\uBA74 \uB2E4\uC6B4\uB85C\uB4DC").option("--status-only", "\uC0C1\uD0DC\uB9CC JSON \uC73C\uB85C \uCD9C\uB825 (\uB2E4\uC6B4\uB85C\uB4DC \uC548 \uD568)").action(async (opts) => {
1340
1379
  try {
1341
- const { getOcrModelStatus, ensureOcrModels, getOcrModelsDir } = await import("./models-U22N4RXX.js");
1380
+ const { getOcrModelStatus, ensureOcrModels, getOcrModelsDir } = await import("./models-G3WA24SY.js");
1342
1381
  const dir = getOcrModelsDir();
1343
1382
  if (opts.statusOnly) {
1344
1383
  const status = await getOcrModelStatus();
@@ -1392,7 +1431,7 @@ function registerSystemCommands(program2) {
1392
1431
  });
1393
1432
  program2.command("models").description("OCR/\uC218\uC2DD \uBAA8\uB378 \uC624\uD504\uB77C\uC778 \uC0AC\uC774\uB4DC\uB85C\uB4DC \u2014 \uD3D0\uC1C4\uB9DD \uBC18\uC785\uC6A9 \uB0B4\uBCF4\uB0B4\uAE30/\uAC00\uC838\uC624\uAE30 (SHA-256 \uAC80\uC99D)").option("--status", "\uCE90\uC2DC\uC5D0 \uC124\uCE58\uB41C \uBAA8\uB378 \uC0C1\uD0DC\uB97C JSON \uC73C\uB85C \uCD9C\uB825").option("--export <dir>", "\uB85C\uCEEC \uCE90\uC2DC \u2192 \uBC88\uB4E4 \uB514\uB809\uD1A0\uB9AC\uB85C \uB0B4\uBCF4\uB0B4\uAE30 (\uC628\uB77C\uC778 PC\uC5D0\uC11C \uC2E4\uD589)").option("--import <dir>", "\uBC88\uB4E4 \uB514\uB809\uD1A0\uB9AC \u2192 \uB85C\uCEEC \uCE90\uC2DC\uB85C \uC124\uCE58 (\uB0B4\uBD80\uB9DD PC\uC5D0\uC11C \uC2E4\uD589)").action(async (opts) => {
1394
1433
  try {
1395
- const { exportModels, importModels, modelCacheStatus } = await import("./model-bundle-THYUL7GG.js");
1434
+ const { exportModels, importModels, modelCacheStatus } = await import("./model-bundle-VHRXG63R.js");
1396
1435
  if (opts.status) {
1397
1436
  process.stdout.write(JSON.stringify(await modelCacheStatus(), null, 2) + "\n");
1398
1437
  return;
@@ -1429,15 +1468,15 @@ function registerSystemCommands(program2) {
1429
1468
  }
1430
1469
 
1431
1470
  // src/cli/commands-worker.ts
1432
- import { readFileSync as readFileSync5, statSync as statSync4 } from "fs";
1433
- import { resolve as resolve5 } from "path";
1471
+ import { readFileSync as readFileSync5, statSync as statSync5 } from "fs";
1472
+ import { resolve as resolve6 } from "path";
1434
1473
  var PARSE_WORKER_PROTOCOL = 1;
1435
1474
  var MAX_FILE_BYTES = 500 * 1024 * 1024;
1436
1475
  var bytesToBase64 = (_key, value) => value instanceof Uint8Array ? Buffer.from(value).toString("base64") : value;
1437
1476
  async function parseOne(req) {
1438
- const absPath = resolve5(req.file);
1477
+ const absPath = resolve6(req.file);
1439
1478
  try {
1440
- const size = statSync4(absPath).size;
1479
+ const size = statSync5(absPath).size;
1441
1480
  if (size > MAX_FILE_BYTES) {
1442
1481
  return { success: false, fileType: "unknown", error: `\uD30C\uC77C\uC774 \uB108\uBB34 \uD07D\uB2C8\uB2E4 (${(size / 1024 / 1024).toFixed(1)}MB)`, code: "PARSE_ERROR" };
1443
1482
  }
@@ -1536,5 +1575,5 @@ registerBatchWorker(program);
1536
1575
  program.hook("preAction", (_program, action) => {
1537
1576
  if (action.name() !== "setup") routeConsoleToStderr();
1538
1577
  });
1539
- program.parse();
1578
+ program.parse(process.argv, { from: "node" });
1540
1579
  //# sourceMappingURL=cli.js.map