for-humanity 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/LICENSE +21 -0
  3. package/README.md +118 -0
  4. package/dist/cli.css +962 -0
  5. package/dist/cli.js +1241 -0
  6. package/dist/client.js +5 -0
  7. package/package.json +92 -0
  8. package/src/app.tsx +57 -0
  9. package/src/asset/favicon.svg +5 -0
  10. package/src/asset/font/architects-daughter/LICENSE.txt +93 -0
  11. package/src/asset/font/architects-daughter/architects-daughter-latin-400-normal.woff2 +0 -0
  12. package/src/asset/font/architects-daughter/architects-daughter.css +10 -0
  13. package/src/asset/font/jetbrains-mono/LICENSE +93 -0
  14. package/src/asset/font/jetbrains-mono/jetbrains-mono-latin-wght-normal.woff2 +0 -0
  15. package/src/asset/font/jetbrains-mono/jetbrains-mono.css +11 -0
  16. package/src/asset/font/pretendard/LICENSE.txt +94 -0
  17. package/src/asset/font/pretendard/pretendardvariable-dynamic-subset.css +1008 -0
  18. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.0.woff2 +0 -0
  19. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.1.woff2 +0 -0
  20. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.10.woff2 +0 -0
  21. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.11.woff2 +0 -0
  22. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.12.woff2 +0 -0
  23. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.13.woff2 +0 -0
  24. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.14.woff2 +0 -0
  25. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.15.woff2 +0 -0
  26. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.16.woff2 +0 -0
  27. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.17.woff2 +0 -0
  28. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.18.woff2 +0 -0
  29. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.19.woff2 +0 -0
  30. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.2.woff2 +0 -0
  31. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.20.woff2 +0 -0
  32. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.21.woff2 +0 -0
  33. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.22.woff2 +0 -0
  34. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.23.woff2 +0 -0
  35. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.24.woff2 +0 -0
  36. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.25.woff2 +0 -0
  37. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.26.woff2 +0 -0
  38. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.27.woff2 +0 -0
  39. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.28.woff2 +0 -0
  40. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.29.woff2 +0 -0
  41. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.3.woff2 +0 -0
  42. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.30.woff2 +0 -0
  43. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.31.woff2 +0 -0
  44. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.32.woff2 +0 -0
  45. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.33.woff2 +0 -0
  46. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.34.woff2 +0 -0
  47. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.35.woff2 +0 -0
  48. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.36.woff2 +0 -0
  49. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.37.woff2 +0 -0
  50. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.38.woff2 +0 -0
  51. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.39.woff2 +0 -0
  52. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.4.woff2 +0 -0
  53. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.40.woff2 +0 -0
  54. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.41.woff2 +0 -0
  55. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.42.woff2 +0 -0
  56. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.43.woff2 +0 -0
  57. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.44.woff2 +0 -0
  58. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.45.woff2 +0 -0
  59. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.46.woff2 +0 -0
  60. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.47.woff2 +0 -0
  61. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.48.woff2 +0 -0
  62. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.49.woff2 +0 -0
  63. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.5.woff2 +0 -0
  64. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.50.woff2 +0 -0
  65. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.51.woff2 +0 -0
  66. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.52.woff2 +0 -0
  67. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.53.woff2 +0 -0
  68. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.54.woff2 +0 -0
  69. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.55.woff2 +0 -0
  70. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.56.woff2 +0 -0
  71. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.57.woff2 +0 -0
  72. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.58.woff2 +0 -0
  73. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.59.woff2 +0 -0
  74. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.6.woff2 +0 -0
  75. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.60.woff2 +0 -0
  76. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.61.woff2 +0 -0
  77. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.62.woff2 +0 -0
  78. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.63.woff2 +0 -0
  79. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.64.woff2 +0 -0
  80. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.65.woff2 +0 -0
  81. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.66.woff2 +0 -0
  82. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.67.woff2 +0 -0
  83. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.68.woff2 +0 -0
  84. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.69.woff2 +0 -0
  85. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.7.woff2 +0 -0
  86. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.70.woff2 +0 -0
  87. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.71.woff2 +0 -0
  88. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.72.woff2 +0 -0
  89. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.73.woff2 +0 -0
  90. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.74.woff2 +0 -0
  91. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.75.woff2 +0 -0
  92. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.76.woff2 +0 -0
  93. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.77.woff2 +0 -0
  94. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.78.woff2 +0 -0
  95. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.79.woff2 +0 -0
  96. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.8.woff2 +0 -0
  97. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.80.woff2 +0 -0
  98. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.81.woff2 +0 -0
  99. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.82.woff2 +0 -0
  100. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.83.woff2 +0 -0
  101. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.84.woff2 +0 -0
  102. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.85.woff2 +0 -0
  103. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.86.woff2 +0 -0
  104. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.87.woff2 +0 -0
  105. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.88.woff2 +0 -0
  106. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.89.woff2 +0 -0
  107. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.9.woff2 +0 -0
  108. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.90.woff2 +0 -0
  109. package/src/asset/font/pretendard/woff2-dynamic-subset/PretendardVariable.subset.91.woff2 +0 -0
  110. package/src/cli.ts +162 -0
  111. package/src/client.ts +322 -0
  112. package/src/component/widget/prose/_constant/heading-highlight.ts +4 -0
  113. package/src/component/widget/prose/_constant/section.ts +7 -0
  114. package/src/component/widget/prose/_constant/status.ts +9 -0
  115. package/src/component/widget/prose/_function/has-block-content.ts +30 -0
  116. package/src/component/widget/prose/_function/rehype-head.ts +31 -0
  117. package/src/component/widget/prose/_function/rehype-sections/_to-section-headings.ts +20 -0
  118. package/src/component/widget/prose/_function/rehype-sections/rehype-sections.ts +21 -0
  119. package/src/component/widget/prose/_function/rehype-tables.ts +22 -0
  120. package/src/component/widget/prose/_function/remark-blocks.ts +112 -0
  121. package/src/component/widget/prose/_function/remark-flow.ts +26 -0
  122. package/src/component/widget/prose/_function/remark-links.ts +33 -0
  123. package/src/component/widget/prose/_function/remark-parts.ts +26 -0
  124. package/src/component/widget/prose/_function/remark-status.ts +59 -0
  125. package/src/component/widget/prose/_function/remark-swatch.ts +16 -0
  126. package/src/component/widget/prose/_function/remark-unknown-directives.ts +25 -0
  127. package/src/component/widget/prose/_type/doc-section.ts +9 -0
  128. package/src/component/widget/prose/wg-prose.css +381 -0
  129. package/src/component/widget/prose/wg-prose.tsx +43 -0
  130. package/src/component/widget/shell/_constant/cursor-face.ts +9 -0
  131. package/src/component/widget/shell/_constant/navigation.ts +4 -0
  132. package/src/component/widget/shell/_constant/reading-line.ts +4 -0
  133. package/src/component/widget/shell/_function/bind-mobile-navigation.ts +140 -0
  134. package/src/component/widget/shell/_function/to-toc-groups.ts +38 -0
  135. package/src/component/widget/shell/_type/doc-outline.ts +16 -0
  136. package/src/component/widget/shell/_type/toc-group.ts +39 -0
  137. package/src/component/widget/shell/_wg-shell-nav.css +134 -0
  138. package/src/component/widget/shell/_wg-shell-nav.tsx +75 -0
  139. package/src/component/widget/shell/_wg-shell-toc.css +268 -0
  140. package/src/component/widget/shell/_wg-shell-toc.tsx +57 -0
  141. package/src/component/widget/shell/wg-shell.css +261 -0
  142. package/src/component/widget/shell/wg-shell.tsx +147 -0
  143. package/src/constant/asset.ts +48 -0
  144. package/src/constant/cli.ts +19 -0
  145. package/src/constant/copy.ts +108 -0
  146. package/src/constant/doc.ts +13 -0
  147. package/src/constant/font.ts +39 -0
  148. package/src/constant/locale.ts +9 -0
  149. package/src/constant/site.ts +9 -0
  150. package/src/constant/status.ts +15 -0
  151. package/src/content/create-processor.ts +59 -0
  152. package/src/content/read-docs.test.ts +242 -0
  153. package/src/content/read-docs.ts +75 -0
  154. package/src/content/read-home.ts +32 -0
  155. package/src/content/rehype-heading-ids.ts +34 -0
  156. package/src/content/remark-report.ts +15 -0
  157. package/src/content/to-doc-groups.ts +18 -0
  158. package/src/dev.ts +79 -0
  159. package/src/env.d.ts +6 -0
  160. package/src/page/doc/pg-doc.tsx +35 -0
  161. package/src/page/home/pg-home.tsx +40 -0
  162. package/src/style/base.css +28 -0
  163. package/src/style/token.css +162 -0
  164. package/src/type/doc-content.ts +15 -0
  165. package/src/type/doc-data.ts +33 -0
  166. package/src/type/doc-file-data.ts +21 -0
  167. package/src/type/doc-heading.ts +17 -0
  168. package/src/type/doc.ts +16 -0
  169. package/src/type/site-assets.ts +17 -0
  170. package/src/type/site-config.ts +55 -0
  171. package/src/type/vfile-data.d.ts +10 -0
  172. package/src/util/dom/find-hash-target.ts +18 -0
  173. package/src/util/dom/reveal-hash-target.ts +15 -0
  174. package/src/util/error/to-error-message.ts +10 -0
  175. package/src/util/font/to-font-css.test.ts +41 -0
  176. package/src/util/font/to-font-css.ts +28 -0
  177. package/src/util/mermaid/render-flow.js +321 -0
package/dist/cli.js ADDED
@@ -0,0 +1,1241 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli.ts
4
+ import { EventEmitter } from "node:events";
5
+ import { existsSync as existsSync2, watch } from "node:fs";
6
+ import { copyFile, mkdir, rm, writeFile } from "node:fs/promises";
7
+ import { basename as basename2, dirname as dirname3, join as join4, relative as relative3, resolve as resolve2 } from "node:path";
8
+ import { fileURLToPath, pathToFileURL } from "node:url";
9
+ import { serve } from "@hono/node-server";
10
+ import { serveStatic } from "@hono/node-server/serve-static";
11
+ import { Hono as Hono3 } from "hono";
12
+ import { toSSG } from "hono/ssg";
13
+
14
+ // src/app.tsx
15
+ import { Hono } from "hono";
16
+ import { ssgParams } from "hono/ssg";
17
+ import { renderToStaticMarkup } from "react-dom/server";
18
+
19
+ // src/component/widget/prose/wg-prose.tsx
20
+ import clsx from "clsx";
21
+ import { jsx, jsxs } from "react/jsx-runtime";
22
+ var WgProse = (props) => {
23
+ if (props.html !== void 0) {
24
+ return /* @__PURE__ */ jsx("article", { className: clsx("wg_prose__root"), dangerouslySetInnerHTML: { __html: props.html } });
25
+ }
26
+ return /* @__PURE__ */ jsx("article", { className: clsx("wg_prose__root"), children: props.head !== void 0 && /* @__PURE__ */ jsxs("header", { className: clsx("wg_prose__head"), children: [
27
+ /* @__PURE__ */ jsx("h1", { children: props.head.title }),
28
+ props.head.lead !== void 0 && /* @__PURE__ */ jsx("p", { children: props.head.lead })
29
+ ] }) });
30
+ };
31
+
32
+ // src/component/widget/shell/wg-shell.tsx
33
+ import clsx4 from "clsx";
34
+
35
+ // src/component/widget/shell/_function/to-toc-groups.ts
36
+ import { takeWhile } from "es-toolkit/array";
37
+
38
+ // src/component/widget/prose/_constant/section.ts
39
+ var section_heading_depth = {
40
+ section: 2,
41
+ sub: 3
42
+ };
43
+
44
+ // src/component/widget/shell/_function/to-toc-groups.ts
45
+ var toTocGroups = (outline) => {
46
+ const entries = outline.headings.filter((heading) => heading.depth === section_heading_depth.section || heading.depth === section_heading_depth.sub).map((heading, index) => ({ heading, section: outline.sections[index] }));
47
+ const sections = entries.flatMap(
48
+ (entry, index) => entry.heading.depth === section_heading_depth.section ? [
49
+ {
50
+ heading: entry.heading,
51
+ part: entry.section.part,
52
+ subs: takeWhile(entries.slice(index + 1), (sub) => sub.heading.depth !== section_heading_depth.section).map((sub) => ({
53
+ heading: sub.heading
54
+ }))
55
+ }
56
+ ] : []
57
+ );
58
+ return sections.flatMap(
59
+ (section, index) => index === 0 || section.part !== void 0 ? [
60
+ {
61
+ part: section.part,
62
+ sections: [section, ...takeWhile(sections.slice(index + 1), (next) => next.part === void 0)]
63
+ }
64
+ ] : []
65
+ );
66
+ };
67
+
68
+ // src/component/widget/shell/_wg-shell-nav.tsx
69
+ import clsx2 from "clsx";
70
+
71
+ // src/constant/copy.ts
72
+ var copy_site_title_default = "for humanity";
73
+ var copy_nav_aria_label = "Document navigation";
74
+ var copy_nav_open = "Open navigation";
75
+ var copy_nav_close = "Close navigation";
76
+ var copy_nav_title = "Navigation";
77
+ var copy_home_missing = "\uBB38\uC11C \uD3F4\uB354\uC5D0 README.md\uB97C \uCD94\uAC00\uD558\uBA74 \uC774\uACF3\uC5D0 \uD648 \uD654\uBA74\uC73C\uB85C \uD45C\uC2DC\uB429\uB2C8\uB2E4.";
78
+ var copy_nav_toc_label = "Contents";
79
+ var copy_error_home_clash = "\uD648 README\uAC00 \uACB9\uCE5C\uB2E4";
80
+ var copy_error_prefix = "for-humanity";
81
+ var copy_error_font_preload = "Missing bundled font for preload";
82
+ var copy_error_unknown_command = "\uBAA8\uB974\uB294 \uBA85\uB839\uC774\uB2E4";
83
+ var copy_error_config = "\uC124\uC815\uC774 \uD2C0\uB838\uB2E4";
84
+ var copy_error_frontmatter = "frontmatter\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4";
85
+ var copy_error_navigation_clash = "navigation\uC758 \uBB36\uC74C\uC774 \uACB9\uCE5C\uB2E4";
86
+ var copy_error_doc_id = "\uBB38\uC11C id\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uB294 \uACBD\uB85C";
87
+ var copy_error_doc_id_clash = "\uBB38\uC11C id\uAC00 \uACB9\uCE5C\uB2E4";
88
+ var copy_error_flow = "\uD750\uB984\uB3C4\uB97C \uADF8\uB9AC\uC9C0 \uBABB\uD588\uB2E4";
89
+ var copy_error_unknown_directive = "\uBAA8\uB974\uB294 \uBD80\uD488\uC774\uB2E4";
90
+ var copy_error_directive_syntax = "\uBD80\uD488 \uBB38\uBC95\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uB2E4";
91
+ var copy_warn_broken_link = "\uC5C6\uB294 \uBB38\uC11C\uB85C \uAC74 \uB9C1\uD06C\uB2E4";
92
+ var copy_warn_unknown_status = "\uC124\uC815\uC5D0 \uC5C6\uB294 \uC0C1\uD0DC \uBB38\uAD6C\uB2E4";
93
+
94
+ // src/constant/locale.ts
95
+ var locale_doc_name = "en";
96
+ var locale_doc_group = "ko";
97
+
98
+ // src/content/to-doc-groups.ts
99
+ var toDocGroups = (options) => {
100
+ const positions = new Map(options.navigation.map((name, index) => [name, index]));
101
+ return [...Map.groupBy(options.docs, (doc) => doc.data.group)].toSorted((a, b) => (positions.get(a[0]) ?? options.navigation.length) - (positions.get(b[0]) ?? options.navigation.length) || a[0].localeCompare(b[0], locale_doc_group)).map(([name, docs]) => ({
102
+ name,
103
+ docs: docs.toSorted((a, b) => a.data.order - b.data.order || a.data.name.localeCompare(b.data.name, locale_doc_name) || a.id.localeCompare(b.id, locale_doc_name))
104
+ }));
105
+ };
106
+
107
+ // src/component/widget/shell/_wg-shell-nav.tsx
108
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
109
+ var WgShellNav = (props) => {
110
+ const docGroups = toDocGroups({ docs: props.docs, navigation: props.site.navigation });
111
+ return /* @__PURE__ */ jsx2("nav", { className: clsx2("wg_shellNav__root"), "aria-label": copy_nav_aria_label, children: /* @__PURE__ */ jsx2("div", { className: clsx2("wg_shellNav__docs"), children: docGroups.map((group) => {
112
+ const currentIndex = group.docs.findIndex((doc) => doc.id === props.current);
113
+ return /* @__PURE__ */ jsxs2("section", { className: clsx2("wg_shellNav__docGroup"), "aria-label": group.name, children: [
114
+ /* @__PURE__ */ jsx2("div", { className: clsx2("wg_shellNav__group"), children: group.name }),
115
+ /* @__PURE__ */ jsx2("ul", { className: clsx2("wg_shellNav__list"), children: group.docs.map((doc, index) => /* @__PURE__ */ jsx2(
116
+ "li",
117
+ {
118
+ className: clsx2("wg_shellNav__item", {
119
+ "wg_shellNav__item--trail": index < currentIndex,
120
+ "wg_shellNav__item--current": index === currentIndex
121
+ }),
122
+ children: /* @__PURE__ */ jsx2(
123
+ "a",
124
+ {
125
+ className: clsx2("wg_shellNav__link", {
126
+ "wg_shellNav__link--active": index === currentIndex
127
+ }),
128
+ href: `/${doc.id}/`,
129
+ title: doc.data.label,
130
+ "aria-current": index === currentIndex ? "page" : void 0,
131
+ children: doc.data.name
132
+ }
133
+ )
134
+ },
135
+ doc.id
136
+ )) })
137
+ ] }, group.name);
138
+ }) }) });
139
+ };
140
+
141
+ // src/component/widget/shell/_wg-shell-toc.tsx
142
+ import clsx3 from "clsx";
143
+ import { Fragment } from "react";
144
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
145
+ var WgShellToc = (props) => {
146
+ return /* @__PURE__ */ jsxs3("nav", { className: clsx3("wg_shellToc__root"), "aria-label": copy_nav_toc_label, children: [
147
+ /* @__PURE__ */ jsx3("div", { className: clsx3("wg_shellToc__label"), children: copy_nav_toc_label }),
148
+ props.groups.map((group) => /* @__PURE__ */ jsxs3(Fragment, { children: [
149
+ group.part !== void 0 && /* @__PURE__ */ jsx3("div", { className: clsx3("wg_shellToc__group"), children: group.part }),
150
+ /* @__PURE__ */ jsx3("ul", { className: clsx3("wg_shellToc__list"), children: group.sections.map((section) => /* @__PURE__ */ jsxs3("li", { className: clsx3("wg_shellToc__item"), children: [
151
+ /* @__PURE__ */ jsx3("a", { className: clsx3("wg_shellToc__link"), href: `#${section.heading.slug}`, "data-toc-link": "", children: section.heading.text }),
152
+ section.subs.length > 0 && /* @__PURE__ */ jsx3("ul", { className: clsx3("wg_shellToc__sub"), children: section.subs.map((sub) => /* @__PURE__ */ jsx3("li", { className: clsx3("wg_shellToc__subItem"), children: /* @__PURE__ */ jsx3("a", { className: clsx3("wg_shellToc__subLink"), href: `#${sub.heading.slug}`, "data-toc-sub-link": "", children: sub.heading.text }) }, sub.heading.slug)) })
153
+ ] }, section.heading.slug)) })
154
+ ] }, group.sections[0].heading.slug))
155
+ ] });
156
+ };
157
+
158
+ // src/constant/asset.ts
159
+ var asset_dir = "_fh";
160
+ var asset_style_path = `/${asset_dir}/style.css`;
161
+ var asset_client_path = `/${asset_dir}/client.js`;
162
+ var asset_font_dir = `/${asset_dir}/fonts`;
163
+ var asset_reload_path = `/${asset_dir}/reload`;
164
+ var asset_favicon_path = "/favicon.svg";
165
+ var asset_content_types = {
166
+ ".css": "text/css; charset=utf-8",
167
+ ".js": "text/javascript; charset=utf-8",
168
+ ".woff2": "font/woff2",
169
+ ".svg": "image/svg+xml"
170
+ };
171
+ var asset_content_type_default = "application/octet-stream";
172
+
173
+ // src/component/widget/shell/wg-shell.tsx
174
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
175
+ var reloadScript = `new EventSource(${JSON.stringify(asset_reload_path)}).onmessage=function(){location.reload()}`;
176
+ var WgShell = (props) => {
177
+ const tocGroups = props.outline === void 0 ? [] : toTocGroups(props.outline);
178
+ return /* @__PURE__ */ jsxs4("html", { lang: "ko", children: [
179
+ /* @__PURE__ */ jsxs4("head", { children: [
180
+ /* @__PURE__ */ jsx4("meta", { charSet: "utf-8" }),
181
+ /* @__PURE__ */ jsx4("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }),
182
+ props.site.description !== void 0 && /* @__PURE__ */ jsx4("meta", { name: "description", content: props.site.description }),
183
+ /* @__PURE__ */ jsx4("title", { children: props.title === void 0 ? props.site.title : `${props.title} \xB7 ${props.site.title}` }),
184
+ /* @__PURE__ */ jsx4("link", { rel: "icon", href: asset_favicon_path, type: "image/svg+xml" }),
185
+ /* @__PURE__ */ jsx4("style", { dangerouslySetInnerHTML: { __html: props.assets.fontCss } }),
186
+ props.assets.preload.map((href) => /* @__PURE__ */ jsx4("link", { rel: "preload", href, as: "font", type: "font/woff2", crossOrigin: "" }, href)),
187
+ /* @__PURE__ */ jsx4("script", { dangerouslySetInnerHTML: { __html: 'document.documentElement.style.scrollBehavior="auto"' } }),
188
+ /* @__PURE__ */ jsx4("link", { rel: "stylesheet", href: asset_style_path }),
189
+ props.assets.reload && /* @__PURE__ */ jsx4("script", { dangerouslySetInnerHTML: { __html: reloadScript } })
190
+ ] }),
191
+ /* @__PURE__ */ jsxs4("body", { className: clsx4("wg_shell__root"), children: [
192
+ /* @__PURE__ */ jsxs4("div", { className: clsx4("wg_shell__sidebar"), children: [
193
+ /* @__PURE__ */ jsxs4("div", { className: clsx4("wg_shell__brandRow"), children: [
194
+ /* @__PURE__ */ jsx4("a", { className: clsx4("wg_shell__brand"), href: "/", "aria-current": props.current === void 0 ? "page" : void 0, children: props.site.title }),
195
+ /* @__PURE__ */ jsx4(
196
+ "button",
197
+ {
198
+ className: clsx4("wg_shell__menuToggle"),
199
+ type: "button",
200
+ "aria-label": copy_nav_open,
201
+ "aria-controls": "fh-navigation-drawer",
202
+ "aria-expanded": "false",
203
+ "data-navigation-open": "",
204
+ children: /* @__PURE__ */ jsx4("svg", { className: clsx4("wg_shell__menuIcon"), viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx4("path", { d: "M4 6h16M4 12h16M4 18h16" }) })
205
+ }
206
+ )
207
+ ] }),
208
+ /* @__PURE__ */ jsxs4("div", { className: clsx4("wg_shell__navigation"), "data-navigation": "", children: [
209
+ /* @__PURE__ */ jsx4(WgShellNav, { site: props.site, docs: props.docs, current: props.current }),
210
+ tocGroups.length > 0 && /* @__PURE__ */ jsx4(WgShellToc, { groups: tocGroups })
211
+ ] })
212
+ ] }),
213
+ /* @__PURE__ */ jsx4("main", { className: clsx4("wg_shell__main"), children: props.children }),
214
+ /* @__PURE__ */ jsxs4("dialog", { className: clsx4("wg_shell__drawer"), id: "fh-navigation-drawer", "aria-labelledby": "fh-navigation-title", "data-navigation-drawer": "", children: [
215
+ /* @__PURE__ */ jsxs4("div", { className: clsx4("wg_shell__drawerHeader"), children: [
216
+ /* @__PURE__ */ jsx4("h2", { className: clsx4("wg_shell__drawerTitle"), id: "fh-navigation-title", children: copy_nav_title }),
217
+ /* @__PURE__ */ jsx4("button", { className: clsx4("wg_shell__drawerClose"), type: "button", "aria-label": copy_nav_close, "data-navigation-close": "", children: /* @__PURE__ */ jsx4("svg", { className: clsx4("wg_shell__menuIcon"), viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: /* @__PURE__ */ jsx4("path", { d: "m6 6 12 12M18 6 6 18" }) }) })
218
+ ] }),
219
+ /* @__PURE__ */ jsx4("div", { className: clsx4("wg_shell__drawerContent"), "data-navigation-content": "" })
220
+ ] }),
221
+ /* @__PURE__ */ jsx4("img", { className: clsx4("wg_shell__cursorFace"), src: asset_favicon_path, width: "24", height: "24", alt: "", "aria-hidden": "true", draggable: false, "data-cursor-face": "" }),
222
+ /* @__PURE__ */ jsx4("script", { type: "module", src: asset_client_path })
223
+ ] })
224
+ ] });
225
+ };
226
+
227
+ // src/page/doc/pg-doc.tsx
228
+ import { jsx as jsx5 } from "react/jsx-runtime";
229
+ var PgDoc = (props) => {
230
+ return /* @__PURE__ */ jsx5(WgShell, { site: props.site, docs: props.docs, assets: props.assets, title: props.doc.data.name, current: props.doc.id, outline: props.doc.outline, children: /* @__PURE__ */ jsx5(WgProse, { html: props.doc.html }) });
231
+ };
232
+
233
+ // src/page/home/pg-home.tsx
234
+ import { jsx as jsx6 } from "react/jsx-runtime";
235
+ var PgHome = (props) => {
236
+ return /* @__PURE__ */ jsx6(WgShell, { site: props.site, docs: props.docs, assets: props.assets, outline: props.home?.outline, children: props.home === void 0 ? /* @__PURE__ */ jsx6(WgProse, { head: { title: props.site.title, lead: copy_home_missing } }) : /* @__PURE__ */ jsx6(WgProse, { html: props.home.html }) });
237
+ };
238
+
239
+ // src/app.tsx
240
+ import { jsx as jsx7 } from "react/jsx-runtime";
241
+ var toHtml = (page) => {
242
+ return `<!DOCTYPE html>${renderToStaticMarkup(page)}`;
243
+ };
244
+ var createApp = (options) => {
245
+ const app = new Hono();
246
+ app.get("/", (c) => c.html(toHtml(/* @__PURE__ */ jsx7(PgHome, { site: options.site, docs: options.store.docs, assets: options.assets, home: options.store.home }))));
247
+ app.get(
248
+ "/:slug{.+}/",
249
+ ssgParams(() => options.store.docs.map((doc) => ({ slug: doc.id }))),
250
+ (c) => {
251
+ const doc = options.store.docs.find((entry) => entry.id === c.req.param("slug"));
252
+ return doc === void 0 ? c.notFound() : c.html(toHtml(/* @__PURE__ */ jsx7(PgDoc, { site: options.site, docs: options.store.docs, assets: options.assets, doc })));
253
+ }
254
+ );
255
+ return app;
256
+ };
257
+
258
+ // src/constant/cli.ts
259
+ var cli_default_command = "dev";
260
+ var cli_default_docs_dir = ".";
261
+ var cli_config_file_name = "for-humanity.config.mjs";
262
+ var cli_dev_port = 4321;
263
+
264
+ // src/constant/font.ts
265
+ var font_sans_css = "src/asset/font/pretendard/pretendardvariable-dynamic-subset.css";
266
+ var font_mono_css = "src/asset/font/jetbrains-mono/jetbrains-mono.css";
267
+ var font_brand_css = "src/asset/font/architects-daughter/architects-daughter.css";
268
+ var font_sans_preload_file = "PretendardVariable.subset.91.woff2";
269
+ var font_display_strategy = "optional";
270
+ var font_hash_length = 12;
271
+ var font_cache_control = "public, max-age=31536000, immutable";
272
+
273
+ // src/constant/site.ts
274
+ var site_config_absent = {};
275
+ var site_navigation_default = [];
276
+
277
+ // src/content/create-processor.ts
278
+ import rehypeShiki from "@shikijs/rehype";
279
+ import rehypeRaw from "rehype-raw";
280
+ import rehypeStringify from "rehype-stringify";
281
+ import remarkDirective from "remark-directive";
282
+ import remarkFrontmatter from "remark-frontmatter";
283
+ import remarkGfm from "remark-gfm";
284
+ import remarkParse from "remark-parse";
285
+ import remarkRehype from "remark-rehype";
286
+ import remarkSmartypants from "remark-smartypants";
287
+ import { createCssVariablesTheme } from "shiki";
288
+ import { unified } from "unified";
289
+
290
+ // src/component/widget/prose/_function/rehype-head.ts
291
+ var rehypeHead = () => (tree, file) => {
292
+ const frontmatter = file.data.fh?.frontmatter;
293
+ const firstSection = tree.children.findIndex((node) => node.type === "element" && node.tagName === `h${section_heading_depth.section}`);
294
+ const leadEnd = firstSection === -1 ? tree.children.length : firstSection;
295
+ if (frontmatter === void 0 && leadEnd === 0) {
296
+ return;
297
+ }
298
+ tree.children = [
299
+ {
300
+ type: "element",
301
+ tagName: "header",
302
+ properties: { className: ["wg_prose__head"] },
303
+ children: [...tree.children.slice(0, leadEnd).filter((node) => node.type !== "doctype")]
304
+ },
305
+ ...tree.children.slice(leadEnd)
306
+ ];
307
+ if (frontmatter !== void 0 && tree.children[0].type === "element") {
308
+ tree.children[0].children.unshift({ type: "element", tagName: "h1", properties: {}, children: [{ type: "text", value: frontmatter.name }] });
309
+ }
310
+ };
311
+
312
+ // src/component/widget/prose/_function/rehype-sections/_to-section-headings.ts
313
+ var toSectionHeadings = (node) => {
314
+ return node.children.flatMap((child) => {
315
+ if (child.type !== "element") {
316
+ return [];
317
+ }
318
+ if (child.tagName === `h${section_heading_depth.section}` || child.tagName === `h${section_heading_depth.sub}`) {
319
+ return [child];
320
+ }
321
+ return toSectionHeadings(child);
322
+ });
323
+ };
324
+
325
+ // src/component/widget/prose/_function/rehype-sections/rehype-sections.ts
326
+ var rehypeSections = () => (tree, file) => {
327
+ if (file.data.fh === void 0) {
328
+ return;
329
+ }
330
+ file.data.fh.sections = toSectionHeadings(tree).map(
331
+ (heading) => ({
332
+ part: typeof heading.properties.dataPart === "string" ? heading.properties.dataPart : void 0
333
+ })
334
+ );
335
+ };
336
+
337
+ // src/component/widget/prose/_function/rehype-tables.ts
338
+ import { SKIP, visit } from "unist-util-visit";
339
+ var rehypeTables = () => (tree) => {
340
+ visit(tree, "element", (node, index, parent) => {
341
+ if (node.tagName !== "table" || parent === void 0 || index === void 0) {
342
+ return;
343
+ }
344
+ parent.children[index] = {
345
+ type: "element",
346
+ tagName: "div",
347
+ properties: { className: ["wg_prose__table"] },
348
+ children: [node]
349
+ };
350
+ return [SKIP, index + 1];
351
+ });
352
+ };
353
+
354
+ // src/component/widget/prose/_function/remark-blocks.ts
355
+ import { toString as toPlainText } from "mdast-util-to-string";
356
+ import { visit as visit2 } from "unist-util-visit";
357
+
358
+ // src/component/widget/prose/_function/has-block-content.ts
359
+ var hasBlockContent = (node) => {
360
+ if (node.type === "definition") {
361
+ return false;
362
+ }
363
+ if (node.type === "html") {
364
+ return node.value.replace(/<!--(?:>|->|[\s\S]*?(?:--!?>|$))/g, "").trim() !== "";
365
+ }
366
+ if ("value" in node) {
367
+ return node.value.trim() !== "";
368
+ }
369
+ if (node.type === "table" || node.type === "textDirective") {
370
+ return true;
371
+ }
372
+ if ("children" in node) {
373
+ return node.children.some(hasBlockContent);
374
+ }
375
+ return true;
376
+ };
377
+
378
+ // src/component/widget/prose/_function/remark-blocks.ts
379
+ var remarkBlocks = () => (tree, file) => {
380
+ const source = String(file.value);
381
+ visit2(tree, (node, _index, parent) => {
382
+ if (node.type === "leafDirective" && node.name === "part" && parent?.type !== "root") {
383
+ file.fail(`${copy_error_directive_syntax}: part \xB7 \uBB38\uC11C \uCD5C\uC0C1\uC704\uC5D0 \uC791\uC131`, node);
384
+ }
385
+ if (node.type !== "containerDirective" && node.type !== "leafDirective" && node.type !== "textDirective") {
386
+ return;
387
+ }
388
+ if (node.name !== "note" && node.name !== "details") {
389
+ return;
390
+ }
391
+ if (node.type !== "containerDirective") {
392
+ file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 ::: \uBE14\uB85D\uC73C\uB85C \uC791\uC131`, node);
393
+ }
394
+ const label = node.children.at(0);
395
+ if (label?.type !== "paragraph" || label.data?.directiveLabel !== true || label.children.some((child) => child.type !== "text")) {
396
+ file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uC77C\uBC18 \uD14D\uC2A4\uD2B8 \uC81C\uBAA9 \uD544\uC218`, node);
397
+ }
398
+ const title = toPlainText(label).trim();
399
+ if (title === "") {
400
+ file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uBE44\uC5B4 \uC788\uC9C0 \uC54A\uC740 \uC81C\uBAA9 \uD544\uC218`, node);
401
+ }
402
+ if (!node.children.slice(1).some(hasBlockContent)) {
403
+ file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uBCF8\uBB38 \uD544\uC218`, node);
404
+ }
405
+ const unsupported = node.attributes ? Object.keys(node.attributes).find((key) => node.name !== "details" || key !== "open") : void 0;
406
+ if (unsupported !== void 0) {
407
+ file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uBBF8\uC9C0\uC6D0 \uC18D\uC131 ${unsupported}`, node);
408
+ }
409
+ const open = node.attributes?.open;
410
+ const attributeSource = source.slice(label.position?.end.offset, node.position?.end.offset).split(/\r?\n/, 1)[0].trim();
411
+ if (attributeSource !== "" && (node.name !== "details" || !/^\{[ \t]*open[ \t]*\}$/.test(attributeSource))) {
412
+ file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uD5C8\uC6A9 \uC18D\uC131\uC740 Details\uC758 {open}, \uB098\uBA38\uC9C0\uB294 \uC0DD\uB7B5`, node);
413
+ }
414
+ const original = source.slice(node.position?.start.offset, node.position?.end.offset);
415
+ const opening = /^(:{3,})/.exec(original);
416
+ const closing = /(?:^|\n)[ \t>]*(:{3,})[ \t]*\r?$/.exec(original);
417
+ if (opening === null || closing === null || closing.index + closing[0].length !== original.length || closing[1].length < opening[1].length || node.position?.end.offset === node.children.at(-1)?.position?.end.offset) {
418
+ file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uBE14\uB85D\uC744 \uB2EB\uB294 fence \uD544\uC218`, node);
419
+ }
420
+ visit2(node, "heading", (heading) => {
421
+ if (heading.depth <= section_heading_depth.section) {
422
+ file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 #\xB7## \uC81C\uBAA9\uC740 \uBD80\uD488 \uBC16\uC5D0 \uC791\uC131`, heading);
423
+ }
424
+ });
425
+ visit2(node, "code", (code) => {
426
+ const originalCode = source.slice(code.position?.start.offset, code.position?.end.offset);
427
+ const codeOpening = /^ {0,3}(`{3,}|~{3,})/.exec(originalCode);
428
+ const codeClosing = /(?:^|\n)[ \t>]*(`{3,}|~{3,})[ \t]*\r?$/.exec(originalCode);
429
+ if (codeOpening !== null && (codeClosing === null || codeClosing.index + codeClosing[0].length !== originalCode.length || codeClosing[1][0] !== codeOpening[1][0] || codeClosing[1].length < codeOpening[1].length)) {
430
+ file.fail(`${copy_error_directive_syntax}: ${node.name} \xB7 \uCF54\uB4DC fence\uB97C \uB2EB\uACE0, \uCF54\uB4DC \uC548\uC758 :\uBCF4\uB2E4 \uAE34 \uBC14\uAE65 fence \uC0AC\uC6A9`, code);
431
+ }
432
+ });
433
+ label.children = [{ type: "text", value: title }];
434
+ label.data = {
435
+ ...label.data,
436
+ hName: node.name === "note" ? "strong" : "summary",
437
+ hProperties: { className: [node.name === "note" ? "wg_prose__noteTitle" : "wg_prose__detailsSummary"] }
438
+ };
439
+ node.data = {
440
+ ...node.data,
441
+ hName: node.name === "note" ? "aside" : "details",
442
+ hProperties: node.name === "note" ? { className: ["wg_prose__note"], ariaLabel: title } : { className: ["wg_prose__details"], open: open === "" }
443
+ };
444
+ });
445
+ };
446
+
447
+ // src/component/widget/prose/_function/remark-flow.ts
448
+ import { visit as visit3 } from "unist-util-visit";
449
+
450
+ // src/util/mermaid/render-flow.js
451
+ import { renderMermaidASCII } from "beautiful-mermaid";
452
+ var esc = (s) => String(s == null ? "" : s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
453
+ var ASCII_OPT = { paddingX: 3, paddingY: 2, boxBorderPadding: 1, colorMode: "none" };
454
+ var WIDE = /[ᄀ-ᇿ -〿㄰-㆏가-힯一-鿿぀-ヿ＀-⦆]/;
455
+ var ZW = "\u200B";
456
+ var widenCjk = (src) => src.replace(new RegExp(WIDE.source, "g"), (c) => c + ZW);
457
+ var LINES = {
458
+ "\u2500": "LR",
459
+ "\u2502": "UD",
460
+ "\u250C": "RD",
461
+ "\u2510": "LD",
462
+ "\u2514": "RU",
463
+ "\u2518": "LU",
464
+ "\u251C": "UDR",
465
+ "\u2524": "UDL",
466
+ "\u252C": "LRD",
467
+ "\u2534": "LRU",
468
+ "\u253C": "LRUD",
469
+ "\u256D": "RDr",
470
+ "\u256E": "LDr",
471
+ "\u2570": "RUr",
472
+ "\u256F": "LUr",
473
+ "\u2550": "LRb",
474
+ "\u2551": "UDb",
475
+ "\u2554": "RDb",
476
+ "\u2557": "LDb",
477
+ "\u255A": "RUb",
478
+ "\u255D": "LUb",
479
+ "\u255F": "UDRb",
480
+ "\u2562": "UDLb",
481
+ "\u254C": "LRd",
482
+ "\u254E": "UDd"
483
+ };
484
+ var ARROWS = { "\u25BA": "R", "\u25C4": "L", "\u25BC": "D", "\u25B2": "U", "\u25B6": "R", "\u25C0": "L" };
485
+ var isWall = (chr) => chr === "\u2502" || chr === "\u25C7" || chr === "\u251C" || chr === "\u2524";
486
+ var isHBorder = (chr) => chr !== void 0 && chr !== " " && chr !== ZW && (LINES[chr] !== void 0 || chr === "\u25C7");
487
+ function widenLabelGaps(rows) {
488
+ const width = Math.max.apply(null, rows.map((r) => r.length));
489
+ let grid = rows.map((r) => r.padEnd(width));
490
+ const H = new Set("\u2500\u252C\u2534\u251C\u2524\u253C\u25C7\u250C\u2510\u2514\u2518\u256D\u256E\u2570\u256F\u2550\u254C\u25BA\u25C4\u25B6\u25C0\u2554\u2557\u255A\u255D\u255F\u2562".split(""));
491
+ const ANCHOR = new Set("\u251C\u2524\u252C\u2534\u253C\u2514\u2518\u250C\u2510\u256D\u256E\u2570\u256F".split(""));
492
+ const END = new Set("\u25BA\u25B6\u25C4\u25C0\u2524\u251C\u252C\u2534\u253C\u2510\u2518\u250C\u2514\u256E\u256F\u256D\u2570\u2502".split(""));
493
+ const isTxt = (chr) => chr !== void 0 && chr !== " " && chr !== ZW && chr !== "\u2502" && !H.has(chr);
494
+ const txtish = (chr) => isTxt(chr) || chr === ZW;
495
+ const splittable = (col) => grid.every((r) => !(txtish(r[col - 1]) && txtish(r[col])));
496
+ const filler = (r, col) => {
497
+ const l = r[col - 1], rt = r[col];
498
+ if (l === void 0 || rt === void 0) return " ";
499
+ if ((H.has(l) || txtish(l)) && (H.has(rt) || rt === "\u2502" || txtish(rt)) && !(txtish(l) && txtish(rt))) {
500
+ if (!(H.has(l) || H.has(rt))) return " ";
501
+ return l === "\u254C" || rt === "\u254C" ? "\u254C" : "\u2500";
502
+ }
503
+ return " ";
504
+ };
505
+ const runs = (row) => {
506
+ const out = [];
507
+ for (const m of row.matchAll(/(─*)((?:[가-힣A-Za-z0-9]​?)+)(─*)/g)) {
508
+ if (m[2].length === 0) continue;
509
+ const before = row[m.index - 1], after = row[m.index + m[0].length];
510
+ const leftOk = m[1].length > 0 || ANCHOR.has(before);
511
+ const rightOk = m[3].length > 0 || END.has(after);
512
+ if (leftOk && rightOk && (m[1].length + m[3].length > 0 || ANCHOR.has(before) && END.has(after))) {
513
+ out.push({ start: m.index, label: m[2], left: m[1].length, right: m[3].length, end: m.index + m[0].length });
514
+ }
515
+ }
516
+ return out;
517
+ };
518
+ const want = 6;
519
+ const inserts = [];
520
+ grid.forEach((row) => {
521
+ for (const run of runs(row)) {
522
+ const missing = want - (run.left + run.right);
523
+ if (missing > 0) inserts.push({ at: run.end, alt: run.start + run.left, n: missing });
524
+ }
525
+ });
526
+ inserts.sort((x, y) => y.at - x.at);
527
+ for (const ins of inserts) {
528
+ const candidates = [ins.at, ins.at + 1, ins.at + 2, ins.alt, ins.alt - 1];
529
+ const col = candidates.find((c) => c > 0 && c < width + 40 && splittable(c));
530
+ if (col === void 0) continue;
531
+ grid = grid.map((r) => r.slice(0, col) + filler(r, col).repeat(ins.n) + r.slice(col));
532
+ }
533
+ return grid.map((row) => {
534
+ let out = row;
535
+ for (const run of runs(row).reverse()) {
536
+ const total = run.left + run.right, l = Math.floor(total / 2), rgt = total - l;
537
+ out = out.slice(0, run.start) + "\u2500".repeat(l) + run.label + "\u2500".repeat(rgt) + out.slice(run.end);
538
+ }
539
+ return out;
540
+ });
541
+ }
542
+ function gridToSvg(ascii) {
543
+ const cw = 7.2, ch = 17, fs = 12;
544
+ const rows = widenLabelGaps(ascii.replace(/\s+$/, "").split("\n"));
545
+ const cols = Math.max.apply(null, rows.map((r) => r.length));
546
+ const f = (n) => n.toFixed(1);
547
+ let path = "", bold = "", dashed = "", arcs = "", tris = "", marks = "", dots = "", texts = "";
548
+ const isText = (chr) => chr !== void 0 && chr !== " " && chr !== ZW && LINES[chr] === void 0 && ARROWS[chr] === void 0 && chr !== "\u25C7";
549
+ const center = (c) => c * cw + cw / 2;
550
+ const textWidth = (chars) => chars.reduce((w, chr) => w + (WIDE.test(chr) ? fs : cw), 0);
551
+ rows.forEach((row, r) => {
552
+ const cy = r * ch + ch / 2, y0 = r * ch, y1 = y0 + ch;
553
+ let run = null;
554
+ const skip = /* @__PURE__ */ new Set();
555
+ for (let c = 0; c < row.length; c++) {
556
+ if (!isText(row[c]) || skip.has(c)) continue;
557
+ let e = c;
558
+ while (e < row.length && (isText(row[e]) || row[e] === ZW || row[e] === " " && isText(row[e + 1]))) e++;
559
+ if (row[c - 1] === "\u2500" && row[e] === "\u2500") {
560
+ const below = rows[r + 1] || "", above = rows[r - 1] || "";
561
+ let exit = null;
562
+ for (let k = c - 2; k < e + 2 && exit === null; k++) {
563
+ if (below[k] === "\u2502" || below[k] === "\u25BC") exit = { k, dir: 1 };
564
+ else if (above[k] === "\u2502" || above[k] === "\u25B2") exit = { k, dir: -1 };
565
+ }
566
+ if (exit) {
567
+ const kx = center(exit.k), chars2 = row.slice(c, e).split("").filter((chr) => chr !== ZW);
568
+ path += "M" + f(c * cw) + " " + f(cy) + "H" + f(e * cw) + " ";
569
+ path += "M" + f(kx) + " " + f(cy) + "V" + f(exit.dir > 0 ? y1 : y0) + " ";
570
+ texts += '<text x="' + f(kx + cw * 0.8 + textWidth(chars2) / 2) + '" y="' + f(cy + exit.dir * ch + fs * 0.35) + '">' + esc(chars2.join("")) + "</text>";
571
+ for (let k = c; k < e; k++) skip.add(k);
572
+ c = e - 1;
573
+ continue;
574
+ }
575
+ }
576
+ let l = c - 1, rr = e;
577
+ while (l >= 0 && row[l] === " ") l--;
578
+ while (rr < row.length && row[rr] === " ") rr++;
579
+ const onLine = (row[l] === "\u2500" || row[l] === "\u251C") && (row[rr] === "\u2500" || ARROWS[row[rr]] !== void 0 || row[rr] === "\u2524");
580
+ if (!onLine) {
581
+ c = e - 1;
582
+ continue;
583
+ }
584
+ let L = l;
585
+ while (L - 1 >= 0 && row[L - 1] === "\u2500") L--;
586
+ let segStart = L * cw, drawStart = L * cw;
587
+ if (row[L] === "\u251C" || row[L - 1] === "\u251C") {
588
+ const j = row[L] === "\u251C" ? L : L - 1;
589
+ const above = rows[r - 1] ? rows[r - 1][j] : " ", below = rows[r + 1] ? rows[r + 1][j] : " ";
590
+ const junction = above !== void 0 && LINES[above] !== void 0 && /[UD]/.test(LINES[above]) || below !== void 0 && LINES[below] !== void 0 && /[UD]/.test(LINES[below]);
591
+ if (junction) {
592
+ segStart = center(j);
593
+ drawStart = center(j);
594
+ for (let m = j + 1; m < L; m++) skip.add(m);
595
+ } else {
596
+ let k = j - 1;
597
+ while (k >= 0 && row[k] === " ") k--;
598
+ segStart = isWall(row[k]) ? center(k) : center(j);
599
+ drawStart = segStart;
600
+ for (let m = j; m < L; m++) skip.add(m);
601
+ }
602
+ } else if (LINES[row[L - 1]] !== void 0 || isWall(row[L - 1])) {
603
+ segStart = center(L - 1);
604
+ }
605
+ let R = rr;
606
+ while (R + 1 < row.length && row[R + 1] === "\u2500") R++;
607
+ let segEnd = (R + 1) * cw, drawEnd = (R + 1) * cw;
608
+ if (ARROWS[row[R]] !== void 0) {
609
+ drawEnd = R * cw;
610
+ segEnd = isWall(row[R + 1]) ? center(R + 1) : center(R) + cw * 0.45;
611
+ R--;
612
+ } else if (ARROWS[row[R + 1]] !== void 0) {
613
+ drawEnd = (R + 1) * cw;
614
+ segEnd = isWall(row[R + 2]) ? center(R + 2) : center(R + 1) + cw * 0.45;
615
+ } else if (LINES[row[R + 1]] !== void 0 || isWall(row[R + 1])) {
616
+ segEnd = center(R + 1);
617
+ }
618
+ const chars = row.slice(c, e).split("").filter((chr) => chr !== ZW);
619
+ const mid = (segStart + segEnd) / 2, half = textWidth(chars) / 2 + 5;
620
+ path += "M" + f(drawStart) + " " + f(cy) + "H" + f(mid - half) + " ";
621
+ path += "M" + f(mid + half) + " " + f(cy) + "H" + f(drawEnd) + " ";
622
+ texts += '<text x="' + f(mid) + '" y="' + f(cy + fs * 0.35) + '">' + esc(chars.join("")) + "</text>";
623
+ for (let k = L; k <= R; k++) skip.add(k);
624
+ c = e - 1;
625
+ }
626
+ const wall = (chr) => chr === "\u2502" || chr === "\u25C7" || chr === "\u251C" || chr === "\u2524";
627
+ const walls = (from, to) => {
628
+ let l = from - 1, rgt = to;
629
+ while (l >= 0 && (row[l] === " " || row[l] === ZW)) l--;
630
+ while (rgt < row.length && (row[rgt] === " " || row[rgt] === ZW)) rgt++;
631
+ return wall(row[l] || "") && wall(row[rgt] || "") ? [l, rgt] : null;
632
+ };
633
+ const lift = (box) => {
634
+ const col = run.start;
635
+ let top = r - 1, bottom = r + 1;
636
+ while (top >= 0 && !isHBorder((rows[top] || "")[col])) top--;
637
+ while (bottom < rows.length && !isHBorder((rows[bottom] || "")[col])) bottom++;
638
+ const corner = (chr) => chr !== void 0 && chr !== "\u2500" && chr !== "\u2550" && chr !== "\u254C" && (LINES[chr] !== void 0 || chr === "\u25C7");
639
+ if (top < 0 || bottom >= rows.length || !corner((rows[top] || "")[box[0]]) || !corner((rows[bottom] || "")[box[0]])) return 0;
640
+ let labelRows = 0;
641
+ for (let k = top + 1; k < bottom; k++) {
642
+ const inner = (rows[k] || "").slice(box[0] + 1, box[1]).split(ZW).join("").trim();
643
+ if (inner.length > 0) labelRows++;
644
+ }
645
+ return (bottom - top - 1 - labelRows) % 2 === 1 ? -ch / 2 : 0;
646
+ };
647
+ const flush = () => {
648
+ if (!run) return;
649
+ const box = walls(run.start, run.end);
650
+ const y = f(cy + fs * 0.35 + (box ? lift(box) : 0));
651
+ const x = box ? f(((box[0] + 1) * cw + box[1] * cw) / 2) : run.wide ? f((run.start * cw + run.end * cw) / 2) : run.xs.join(" ");
652
+ texts += '<text x="' + x + '" y="' + y + '">' + esc(run.chars.join("")) + "</text>";
653
+ run = null;
654
+ };
655
+ for (let c = 0; c < row.length; c++) {
656
+ const chr = row[c];
657
+ const cx = c * cw + cw / 2, x0 = c * cw, x1 = x0 + cw;
658
+ if (skip.has(c)) {
659
+ flush();
660
+ continue;
661
+ }
662
+ if (chr === ZW) {
663
+ if (run) run.end = c + 1;
664
+ continue;
665
+ }
666
+ if (chr === " ") {
667
+ const next = row[c + 1];
668
+ const joins = run && next !== void 0 && next !== " " && next !== ZW && !LINES[next] && !ARROWS[next] && next !== "\u25C7";
669
+ if (!joins) {
670
+ flush();
671
+ continue;
672
+ }
673
+ }
674
+ const above = rows[r - 1] ? rows[r - 1][c] : " ", below = rows[r + 1] ? rows[r + 1][c] : " ";
675
+ const vertical = (v) => v !== void 0 && LINES[v] !== void 0 && /[UD]/.test(LINES[v]) || v === "\u25C7";
676
+ if ((chr === "\u251C" || chr === "\u2524") && !vertical(above) && !vertical(below)) {
677
+ flush();
678
+ let l = c - 1, rgt = c + 1;
679
+ while (l >= 0 && row[l] === " ") l--;
680
+ while (rgt < row.length && row[rgt] === " ") rgt++;
681
+ const gapL = isWall(row[l]) ? l * cw + cw / 2 : x0;
682
+ const gapR = isWall(row[rgt]) ? rgt * cw + cw / 2 : x1;
683
+ path += "M" + f(gapL) + " " + f(cy) + "H" + f(gapR) + " ";
684
+ continue;
685
+ }
686
+ const ln = LINES[chr];
687
+ if (ln) {
688
+ flush();
689
+ if (ln.indexOf("r") >= 0) {
690
+ const ax = ln.indexOf("L") >= 0 ? x0 : x1, by = ln.indexOf("U") >= 0 ? y0 : y1;
691
+ arcs += "M" + f(ax) + " " + f(cy) + "Q" + f(cx) + " " + f(cy) + " " + f(cx) + " " + f(by) + " ";
692
+ } else {
693
+ let seg = "";
694
+ if (ln.indexOf("L") >= 0) seg += "M" + f(isWall(row[c - 1]) ? x0 - cw / 2 : x0) + " " + f(cy) + "H" + f(cx) + " ";
695
+ if (ln.indexOf("R") >= 0) seg += "M" + f(cx) + " " + f(cy) + "H" + f(isWall(row[c + 1]) ? x1 + cw / 2 : x1) + " ";
696
+ if (ln.indexOf("U") >= 0) seg += "M" + f(cx) + " " + f(y0) + "V" + f(cy) + " ";
697
+ if (ln.indexOf("D") >= 0) seg += "M" + f(cx) + " " + f(cy) + "V" + f(y1) + " ";
698
+ if (ln.indexOf("b") >= 0) bold += seg;
699
+ else if (ln.indexOf("d") >= 0) dashed += seg;
700
+ else path += seg;
701
+ }
702
+ continue;
703
+ }
704
+ const ar = ARROWS[chr];
705
+ if (ar) {
706
+ flush();
707
+ const w = cw * 0.9, h = ch * 0.42;
708
+ const tipR = isWall(row[c + 1]) ? x1 + cw / 2 : cx + w / 2, tipL = isWall(row[c - 1]) ? x0 - cw / 2 : cx - w / 2;
709
+ const tipD = isHBorder(below) ? y1 + ch / 2 : cy + h / 2, tipU = isHBorder(above) ? y0 - ch / 2 : cy - h / 2;
710
+ if (ar === "R") {
711
+ path += "M" + f(x0) + " " + f(cy) + "H" + f(tipR - w) + " ";
712
+ tris += "M" + f(tipR - w) + " " + f(cy - h / 2) + "L" + f(tipR) + " " + f(cy) + "L" + f(tipR - w) + " " + f(cy + h / 2) + "Z ";
713
+ }
714
+ if (ar === "L") {
715
+ path += "M" + f(tipL + w) + " " + f(cy) + "H" + f(x1) + " ";
716
+ tris += "M" + f(tipL + w) + " " + f(cy - h / 2) + "L" + f(tipL) + " " + f(cy) + "L" + f(tipL + w) + " " + f(cy + h / 2) + "Z ";
717
+ }
718
+ if (ar === "D") {
719
+ path += "M" + f(cx) + " " + f(y0) + "V" + f(tipD - h) + " ";
720
+ tris += "M" + f(cx - w / 2) + " " + f(tipD - h) + "L" + f(cx + w / 2) + " " + f(tipD - h) + "L" + f(cx) + " " + f(tipD) + "Z ";
721
+ }
722
+ if (ar === "U") {
723
+ path += "M" + f(cx) + " " + f(tipU + h) + "V" + f(y1) + " ";
724
+ tris += "M" + f(cx - w / 2) + " " + f(tipU + h) + "L" + f(cx + w / 2) + " " + f(tipU + h) + "L" + f(cx) + " " + f(tipU) + "Z ";
725
+ }
726
+ continue;
727
+ }
728
+ if (chr === "\u25C7") {
729
+ flush();
730
+ const w = cw * 0.8, h = ch * 0.4;
731
+ marks += "M" + f(cx) + " " + f(cy - h / 2) + "L" + f(cx + w / 2) + " " + f(cy) + "L" + f(cx) + " " + f(cy + h / 2) + "L" + f(cx - w / 2) + " " + f(cy) + "Z ";
732
+ continue;
733
+ }
734
+ if (chr === "\u25CF") {
735
+ flush();
736
+ const rr = cw * 0.45;
737
+ dots += "M" + f(cx - rr) + " " + f(cy) + "a" + f(rr) + " " + f(rr) + " 0 1 0 " + f(rr * 2) + " 0a" + f(rr) + " " + f(rr) + " 0 1 0 " + f(-rr * 2) + " 0Z ";
738
+ continue;
739
+ }
740
+ if (chr === "\u25B3") {
741
+ flush();
742
+ const w = cw * 0.9, h = ch * 0.42;
743
+ marks += "M" + f(cx) + " " + f(cy - h / 2) + "L" + f(cx + w / 2) + " " + f(cy + h / 2) + "L" + f(cx - w / 2) + " " + f(cy + h / 2) + "Z ";
744
+ path += "M" + f(cx) + " " + f(cy + h / 2) + "V" + f(y1) + " ";
745
+ continue;
746
+ }
747
+ if (!run) run = { start: c, end: c + 1, xs: [], chars: [], wide: false };
748
+ run.end = c + 1;
749
+ run.xs.push(f(cx));
750
+ run.chars.push(chr);
751
+ if (WIDE.test(chr)) run.wide = true;
752
+ }
753
+ flush();
754
+ });
755
+ const W = f(cols * cw), H = f(rows.length * ch);
756
+ return '<svg xmlns="http://www.w3.org/2000/svg" class="ascii-flow" viewBox="0 0 ' + W + " " + H + '" width="' + W + '" height="' + H + '"><path d="' + path + '" fill="none" stroke="var(--app-color-text-muted)" stroke-width="1"/><path d="' + bold + '" fill="none" stroke="var(--app-color-text-muted)" stroke-width="2"/><path d="' + dashed + '" fill="none" stroke="var(--app-color-text-muted)" stroke-width="1" stroke-dasharray="3 3"/><path d="' + arcs + '" fill="none" stroke="var(--app-color-text-muted)" stroke-width="1"/><path d="' + tris + '" fill="var(--app-color-text-muted)"/><path d="' + dots + '" fill="var(--app-color-text-muted)"/><path d="' + marks + '" fill="var(--app-color-surface)" stroke="var(--app-color-text-muted)" stroke-width="1"/><g font-family="var(--app-font-mono)" font-size="' + fs + '" text-anchor="middle" fill="var(--app-color-text)">' + texts + "</g></svg>";
757
+ }
758
+ var renderFlow = (source) => gridToSvg(renderMermaidASCII(widenCjk(source), ASCII_OPT));
759
+
760
+ // src/component/widget/prose/_function/remark-flow.ts
761
+ var remarkFlow = () => (tree, file) => {
762
+ visit3(tree, "code", (node, index, parent) => {
763
+ if (node.lang !== "mermaid" || parent === void 0 || index === void 0) {
764
+ return;
765
+ }
766
+ try {
767
+ parent.children[index] = {
768
+ type: "html",
769
+ value: `<div class="wg_prose__flow">${renderFlow(node.value)}</div>`
770
+ };
771
+ } catch (error) {
772
+ file.fail(`${copy_error_flow}: ${error instanceof Error ? error.message : String(error)}`, node);
773
+ }
774
+ });
775
+ };
776
+
777
+ // src/component/widget/prose/_function/remark-links.ts
778
+ import { existsSync } from "node:fs";
779
+ import { dirname, posix, relative, resolve } from "node:path";
780
+ import { visit as visit4 } from "unist-util-visit";
781
+ var remarkLinks = (options) => (tree, file) => {
782
+ const here = dirname(relative(options.root, file.path));
783
+ visit4(tree, (node) => {
784
+ if (node.type !== "link" && node.type !== "definition") {
785
+ return;
786
+ }
787
+ const match = /^(?![a-z]+:|\/|#)([^#?]+)(\.mdx?)([?#].*|)$/i.exec(node.url);
788
+ if (match) {
789
+ if (!existsSync(resolve(dirname(file.path), `${match[1]}${match[2]}`))) {
790
+ file.message(`${copy_warn_broken_link}: ${node.url}`, node);
791
+ }
792
+ const target = posix.join(here, `${match[1]}${match[2]}`).toLowerCase();
793
+ node.url = target === "readme.md" ? `/${match[3]}` : `/${posix.join(here, match[1]).toLowerCase()}/${match[3]}`;
794
+ }
795
+ });
796
+ };
797
+
798
+ // src/component/widget/prose/_function/remark-parts.ts
799
+ import { toString as toPlainText2 } from "mdast-util-to-string";
800
+ var remarkParts = () => (tree) => {
801
+ for (const [index, node] of tree.children.entries()) {
802
+ if (node.type !== "leafDirective" || node.name !== "part") {
803
+ continue;
804
+ }
805
+ const section = tree.children.slice(index + 1).find((next) => next.type === "heading" && next.depth === section_heading_depth.section);
806
+ node.data = { hName: "div", hProperties: { className: ["wg_prose__part"] } };
807
+ if (section) {
808
+ section.data = {
809
+ ...section.data,
810
+ hProperties: { ...section.data?.hProperties, dataPart: toPlainText2(node).trim() }
811
+ };
812
+ }
813
+ }
814
+ };
815
+
816
+ // src/component/widget/prose/_function/remark-status.ts
817
+ import { escape as escapeHtml, escapeRegExp } from "es-toolkit/string";
818
+ import { findAndReplace } from "mdast-util-find-and-replace";
819
+
820
+ // src/component/widget/prose/_constant/status.ts
821
+ var status_date_pattern = String.raw`\d{4}-\d{2}-\d{2}`;
822
+ var status_candidate_pattern = new RegExp(String.raw`\([^()\n]*${status_date_pattern}\)`, "g");
823
+
824
+ // src/component/widget/prose/_function/remark-status.ts
825
+ var remarkStatus = (options) => {
826
+ const statuses = options.status.toSorted((a, b) => b.phrase.length - a.phrase.length);
827
+ const phrases = statuses.map((item) => [escapeRegExp(item.phrase), ...item.date ? [`(?: ${status_date_pattern})?`] : []].join("")).join("|");
828
+ const pattern = new RegExp(String.raw`\((${phrases})\)|(${phrases})`, "g");
829
+ const ignore = ["link", "linkReference", "heading"];
830
+ return (tree, file) => {
831
+ findAndReplace(
832
+ tree,
833
+ [
834
+ pattern,
835
+ (_match, inParens, bare) => {
836
+ const text = inParens ?? bare;
837
+ const item = statuses.find((status) => text?.startsWith(status.phrase));
838
+ if (text === void 0 || item === void 0) {
839
+ return false;
840
+ }
841
+ return {
842
+ type: "html",
843
+ value: `<span class="wg_prose__pill wg_prose__pill--${item.kind}">${escapeHtml(text)}</span>`
844
+ };
845
+ }
846
+ ],
847
+ { ignore }
848
+ );
849
+ findAndReplace(
850
+ tree,
851
+ [
852
+ status_candidate_pattern,
853
+ (match, info) => {
854
+ file.message(
855
+ `${copy_warn_unknown_status}: ${match}`,
856
+ info.stack.findLast((node) => node.position !== void 0)
857
+ );
858
+ return false;
859
+ }
860
+ ],
861
+ { ignore }
862
+ );
863
+ };
864
+ };
865
+
866
+ // src/component/widget/prose/_function/remark-swatch.ts
867
+ import { visit as visit5 } from "unist-util-visit";
868
+ var remarkSwatch = () => (tree) => {
869
+ visit5(tree, "inlineCode", (node) => {
870
+ if (/^#[0-9a-f]{3,8}$/i.test(node.value.trim())) {
871
+ node.data = {
872
+ hProperties: { className: ["wg_prose__color"], style: `--wg-prose-chip-color: ${node.value.trim()}` }
873
+ };
874
+ }
875
+ });
876
+ };
877
+
878
+ // src/component/widget/prose/_function/remark-unknown-directives.ts
879
+ import { SKIP as SKIP2, visit as visit6 } from "unist-util-visit";
880
+ var remarkUnknownDirectives = () => (tree, file) => {
881
+ visit6(tree, (node, index, parent) => {
882
+ if (node.type === "textDirective" && parent !== void 0 && index !== void 0) {
883
+ parent.children[index] = {
884
+ type: "text",
885
+ value: String(file.value).slice(node.position?.start.offset, node.position?.end.offset)
886
+ };
887
+ return SKIP2;
888
+ }
889
+ if ((node.type === "leafDirective" || node.type === "containerDirective") && node.data?.hName === void 0) {
890
+ file.fail(`${copy_error_unknown_directive}: ${node.name}`, node);
891
+ }
892
+ });
893
+ };
894
+
895
+ // src/content/rehype-heading-ids.ts
896
+ import Slugger from "github-slugger";
897
+ import { toString as toPlainText3 } from "hast-util-to-string";
898
+ import { visit as visit7 } from "unist-util-visit";
899
+ var rehypeHeadingIds = () => (tree, file) => {
900
+ const slugger = new Slugger();
901
+ const headings = [];
902
+ visit7(tree, "element", (node) => {
903
+ const depth = /^h([1-6])$/.exec(node.tagName)?.[1];
904
+ if (depth === void 0) {
905
+ return;
906
+ }
907
+ const text = toPlainText3(node);
908
+ node.properties.id = typeof node.properties.id === "string" ? node.properties.id : slugger.slug(text);
909
+ headings.push({ depth: Number(depth), slug: node.properties.id, text });
910
+ node.children = [{ type: "element", tagName: "span", properties: { className: ["wg_prose__headingText"] }, children: node.children }];
911
+ });
912
+ if (file.data.fh) {
913
+ file.data.fh.headings = headings;
914
+ }
915
+ };
916
+
917
+ // src/content/remark-report.ts
918
+ import { relative as relative2 } from "node:path";
919
+ var remarkReport = (options) => (_tree, file) => {
920
+ const path = relative2(options.root, file.path);
921
+ for (const message of file.messages) {
922
+ console.warn(`${message.line === void 0 ? path : `${path}:${message.line}`} ${message.reason}`);
923
+ }
924
+ };
925
+
926
+ // src/content/create-processor.ts
927
+ var createProcessor = (options) => {
928
+ return unified().use(remarkParse).use(remarkFrontmatter, ["yaml"]).use(remarkGfm).use(remarkSmartypants).use(remarkDirective).use(remarkBlocks).use(remarkParts).use(remarkFlow).use(remarkStatus, { status: options.site.status }).use(remarkSwatch).use(remarkLinks, { root: options.root }).use(remarkUnknownDirectives).use(remarkReport, { root: options.root }).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeShiki, { theme: createCssVariablesTheme({ name: "for-humanity", variablePrefix: "--app-code-" }) }).use(rehypeHead).use(rehypeHeadingIds).use(rehypeSections).use(rehypeTables).use(rehypeRaw).use(rehypeStringify, { allowDangerousHtml: true });
929
+ };
930
+
931
+ // src/content/read-docs.ts
932
+ import { readdir, readFile } from "node:fs/promises";
933
+ import { join, sep } from "node:path";
934
+ import { VFile } from "vfile";
935
+ import { parse as parseYaml } from "yaml";
936
+
937
+ // src/type/doc-data.ts
938
+ import { z } from "zod";
939
+
940
+ // src/constant/doc.ts
941
+ var doc_type = {
942
+ document: "document",
943
+ blueprint: "blueprint"
944
+ };
945
+ var doc_order_default = Number.MAX_SAFE_INTEGER;
946
+
947
+ // src/type/doc-data.ts
948
+ var docDataSchema = z.object({
949
+ /**
950
+ * 문서 이름 · 제목·목록 · 같은 첫 글자 허용
951
+ */
952
+ name: z.string().trim().min(1),
953
+ /**
954
+ * 짧은 문서 설명 · 사이드바 툴팁
955
+ */
956
+ label: z.string(),
957
+ /**
958
+ * 문서 종류 · blueprint 전용 표현 미구현
959
+ */
960
+ type: z.enum(doc_type).default(doc_type.document),
961
+ /**
962
+ * 사이드바의 문서 묶음
963
+ */
964
+ group: z.string().trim().min(1),
965
+ /**
966
+ * 묶음 안의 읽는 순서 · 미지정 문서는 뒤에서 이름순
967
+ */
968
+ order: z.number().int().nonnegative().default(doc_order_default)
969
+ });
970
+
971
+ // src/content/read-docs.ts
972
+ var readDocs = async (options) => {
973
+ const paths = (await readdir(options.root, { recursive: true })).filter(
974
+ (path) => /\.mdx?$/i.test(path) && !/^(readme|agents|claude)\.md$/i.test(path) && !path.split(sep).includes("node_modules") && !path.startsWith(`dist${sep}`)
975
+ );
976
+ const docs = await Promise.all(
977
+ paths.map(async (path) => {
978
+ const id = path.replace(/\.mdx?$/i, "").split(sep).join("/").toLowerCase();
979
+ const segments = id.split("/");
980
+ if (segments.some((segment) => segment === "" || segment === "." || segment === ".." || segment === "index.html") || /[#?%*:\\]/.test(id) || /[\p{Cc}]/u.test(id) || segments[0] === asset_dir || segments[0] === asset_favicon_path.slice(1)) {
981
+ throw new Error(`${copy_error_doc_id}: ${path}`);
982
+ }
983
+ const source = await readFile(join(options.root, path), "utf8");
984
+ const file = new VFile({ value: source.replace(/^\uFEFF/, ""), path: join(options.root, path) });
985
+ const tree = options.processor.parse(file);
986
+ const frontmatter = tree.children[0];
987
+ const parsed = docDataSchema.safeParse(frontmatter?.type === "yaml" ? parseYaml(frontmatter.value) : {});
988
+ if (!parsed.success) {
989
+ throw new Error(`${copy_error_frontmatter}: ${path}: ${parsed.error.issues.map((issue) => `${issue.path.join(".")} ${issue.message}`).join(", ")}`);
990
+ }
991
+ const fh = { frontmatter: parsed.data, headings: [], sections: [] };
992
+ file.data.fh = fh;
993
+ tree.children = tree.children.filter((node) => node.type !== "yaml");
994
+ const rendered = await options.processor.run(tree, file);
995
+ return {
996
+ id,
997
+ data: parsed.data,
998
+ html: options.processor.stringify(rendered, file),
999
+ outline: { headings: fh.headings, sections: fh.sections }
1000
+ };
1001
+ })
1002
+ );
1003
+ const duplicateIds = [...Map.groupBy(docs, (doc) => doc.id)].filter((entry) => entry[1].length > 1);
1004
+ if (duplicateIds.length > 0) {
1005
+ throw new Error(`${copy_error_doc_id_clash}: ${duplicateIds.map((entry) => entry[0]).join(", ")}`);
1006
+ }
1007
+ return docs;
1008
+ };
1009
+
1010
+ // src/content/read-home.ts
1011
+ import { readdir as readdir2, readFile as readFile2 } from "node:fs/promises";
1012
+ import { join as join2 } from "node:path";
1013
+ import { VFile as VFile2 } from "vfile";
1014
+ var readHome = async (options) => {
1015
+ const paths = (await readdir2(options.root)).filter((path2) => path2.toLowerCase() === "readme.md");
1016
+ if (paths.length > 1) {
1017
+ throw new Error(`${copy_error_home_clash}: ${paths.join(", ")}`);
1018
+ }
1019
+ if (paths.length === 0) {
1020
+ return void 0;
1021
+ }
1022
+ const path = join2(options.root, paths[0]);
1023
+ const fh = { headings: [], sections: [] };
1024
+ const file = new VFile2({ value: (await readFile2(path, "utf8")).replace(/^\uFEFF/, ""), path, data: { fh } });
1025
+ await options.processor.process(file);
1026
+ return { html: String(file), outline: { headings: fh.headings, sections: fh.sections } };
1027
+ };
1028
+
1029
+ // src/dev.ts
1030
+ import { readFile as readFile3 } from "node:fs/promises";
1031
+ import { extname } from "node:path";
1032
+ import { Hono as Hono2 } from "hono";
1033
+ import { streamSSE } from "hono/streaming";
1034
+ var createDevApp = (options) => {
1035
+ const app = new Hono2();
1036
+ const handleAsset = async (c) => {
1037
+ const file = options.files.get(c.req.path);
1038
+ if (file === void 0) {
1039
+ return c.notFound();
1040
+ }
1041
+ c.header("content-type", asset_content_types[extname(file)] ?? asset_content_type_default);
1042
+ if (extname(file) === ".woff2") {
1043
+ c.header("Cache-Control", font_cache_control);
1044
+ }
1045
+ return c.body(await readFile3(file));
1046
+ };
1047
+ app.get(
1048
+ asset_reload_path,
1049
+ (c) => streamSSE(
1050
+ c,
1051
+ (stream) => new Promise((done) => {
1052
+ const handleChange = async () => {
1053
+ await stream.writeSSE({ data: "change" });
1054
+ done();
1055
+ };
1056
+ options.reload.once("change", handleChange);
1057
+ stream.onAbort(() => {
1058
+ options.reload.off("change", handleChange);
1059
+ done();
1060
+ });
1061
+ })
1062
+ )
1063
+ );
1064
+ app.get(`/${asset_dir}/*`, handleAsset);
1065
+ app.get(asset_favicon_path, handleAsset);
1066
+ app.all("/*", (c) => options.pages.fetch(c.req.raw, c.env));
1067
+ return app;
1068
+ };
1069
+
1070
+ // src/type/site-config.ts
1071
+ import { z as z2 } from "zod";
1072
+
1073
+ // src/constant/status.ts
1074
+ var status_kind = {
1075
+ verified: "verified",
1076
+ unverified: "unverified"
1077
+ };
1078
+ var status_default_phrases = [
1079
+ { phrase: "\uD655\uC778\uB428", kind: status_kind.verified, date: true },
1080
+ { phrase: "\uD655\uC778\uB418\uC9C0 \uC54A\uC558\uB2E4", kind: status_kind.unverified }
1081
+ ];
1082
+
1083
+ // src/type/site-config.ts
1084
+ var siteConfigSchema = z2.object({
1085
+ /**
1086
+ * 사이드바 이름과 탭 제목
1087
+ */
1088
+ title: z2.string().default(copy_site_title_default),
1089
+ /**
1090
+ * HTML 설명 메타데이터 · 선택
1091
+ */
1092
+ description: z2.string().optional(),
1093
+ /**
1094
+ * 탐색 묶음의 읽는 순서 · 미지정 묶음은 뒤에서 이름순
1095
+ */
1096
+ navigation: z2.array(z2.string().trim().min(1)).refine((groups) => new Set(groups).size === groups.length, copy_error_navigation_clash).default([...site_navigation_default]),
1097
+ /**
1098
+ * 본문에서 상태 표지로 표시할 문구
1099
+ */
1100
+ status: z2.array(
1101
+ z2.object({
1102
+ /**
1103
+ * 찾을 문구 원문
1104
+ */
1105
+ phrase: z2.string().min(1).refine((phrase) => phrase.trim().length > 0),
1106
+ /**
1107
+ * 상태 표지의 색 종류
1108
+ */
1109
+ kind: z2.enum(status_kind),
1110
+ /**
1111
+ * 문구 뒤의 YYYY-MM-DD 날짜 포함 여부
1112
+ */
1113
+ date: z2.boolean().optional()
1114
+ })
1115
+ ).default(status_default_phrases)
1116
+ });
1117
+
1118
+ // src/util/error/to-error-message.ts
1119
+ var toErrorMessage = (error) => {
1120
+ if (error instanceof Error && "file" in error && typeof error.file === "string" && "line" in error && typeof error.line === "number") {
1121
+ return `${error.file}:${error.line}: ${error.message}`;
1122
+ }
1123
+ return error instanceof Error ? error.message : String(error);
1124
+ };
1125
+
1126
+ // src/util/font/to-font-css.ts
1127
+ import { createHash } from "node:crypto";
1128
+ import { readFileSync } from "node:fs";
1129
+ import { basename, dirname as dirname2, extname as extname2, join as join3 } from "node:path";
1130
+ var toFontCss = (options) => {
1131
+ const files = /* @__PURE__ */ new Map();
1132
+ const css = [...readFileSync(options.css, "utf8").matchAll(/@font-face\s*\{[^}]*\}/g)].map(
1133
+ (match) => match[0].replace(/font-display:\s*[^;]+;/g, `font-display: ${font_display_strategy};`).replace(/url\(([^)]+)\)/g, (_match, relativeUrl) => {
1134
+ const file = join3(dirname2(options.css), relativeUrl);
1135
+ const extension = extname2(file);
1136
+ const hash = createHash("sha256").update(readFileSync(file)).digest("hex").slice(0, font_hash_length);
1137
+ const url = `${options.fontDir}/${basename(file, extension)}.${hash}${extension}`;
1138
+ files.set(url, file);
1139
+ return `url(${url})`;
1140
+ })
1141
+ ).join("\n");
1142
+ return { css, files };
1143
+ };
1144
+
1145
+ // src/cli.ts
1146
+ var commands = ["dev", "build", "preview"];
1147
+ var [command = cli_default_command, docsDir = cli_default_docs_dir] = process.argv.slice(2);
1148
+ var main = async () => {
1149
+ if (!commands.includes(command)) {
1150
+ throw new Error(`${copy_error_unknown_command}: ${command} (${commands.join(", ")})`);
1151
+ }
1152
+ const kitRoot = fileURLToPath(new URL("../", import.meta.url));
1153
+ const docsRoot = resolve2(docsDir);
1154
+ const outDir = join4(docsRoot, "dist");
1155
+ if (command === "preview") {
1156
+ const app2 = new Hono3();
1157
+ app2.use(
1158
+ "/*",
1159
+ serveStatic({
1160
+ root: relative3(process.cwd(), outDir),
1161
+ onFound: (_path, c) => {
1162
+ if (c.req.path.startsWith(`${asset_font_dir}/`)) {
1163
+ c.header("Cache-Control", font_cache_control);
1164
+ }
1165
+ }
1166
+ })
1167
+ );
1168
+ serve({ fetch: app2.fetch, port: cli_dev_port }, (info) => console.log(`http://localhost:${info.port}/`));
1169
+ return;
1170
+ }
1171
+ const configFile = join4(docsRoot, cli_config_file_name);
1172
+ const parsedConfig = siteConfigSchema.safeParse(existsSync2(configFile) ? (await import(pathToFileURL(configFile).href)).default : site_config_absent);
1173
+ if (!parsedConfig.success) {
1174
+ throw new Error(`${copy_error_config}: ${parsedConfig.error.issues.map((issue) => `${issue.path.join(".")} ${issue.message}`).join(", ")}`);
1175
+ }
1176
+ const siteConfig = parsedConfig.data;
1177
+ const sans = toFontCss({ css: join4(kitRoot, font_sans_css), fontDir: asset_font_dir });
1178
+ const mono = toFontCss({ css: join4(kitRoot, font_mono_css), fontDir: asset_font_dir });
1179
+ const brand = toFontCss({ css: join4(kitRoot, font_brand_css), fontDir: asset_font_dir });
1180
+ const sansPreload = [...sans.files].find((entry) => basename2(entry[1]) === font_sans_preload_file);
1181
+ if (sansPreload === void 0) {
1182
+ throw new Error(`${copy_error_font_preload}: ${font_sans_preload_file}`);
1183
+ }
1184
+ const fontCss = [sans.css, mono.css, brand.css].join("\n");
1185
+ const files = new Map([
1186
+ [asset_style_path, join4(kitRoot, "dist/cli.css")],
1187
+ [asset_client_path, join4(kitRoot, "dist/client.js")],
1188
+ [asset_favicon_path, join4(kitRoot, "src/asset/favicon.svg")],
1189
+ ...sans.files,
1190
+ ...mono.files,
1191
+ ...brand.files
1192
+ ]);
1193
+ const processor = createProcessor({ site: siteConfig, root: docsRoot });
1194
+ const [docs, home] = await Promise.all([readDocs({ root: docsRoot, processor }), readHome({ root: docsRoot, processor })]);
1195
+ const store = { docs, home };
1196
+ const app = createApp({
1197
+ site: siteConfig,
1198
+ store,
1199
+ assets: { fontCss, preload: [...brand.files.keys(), sansPreload[0], ...mono.files.keys()], reload: command === "dev" }
1200
+ });
1201
+ if (command === "build") {
1202
+ await rm(outDir, { recursive: true, force: true });
1203
+ const result = await toSSG(app, { writeFile, mkdir }, { dir: outDir });
1204
+ if (!result.success) {
1205
+ throw result.error;
1206
+ }
1207
+ for (const [url, file] of files) {
1208
+ await mkdir(dirname3(join4(outDir, url)), { recursive: true });
1209
+ await copyFile(file, join4(outDir, url));
1210
+ }
1211
+ console.log(`${result.files.length} pages, ${files.size} assets \u2192 ${relative3(process.cwd(), outDir)}`);
1212
+ return;
1213
+ }
1214
+ const reload = new EventEmitter();
1215
+ let generation = 0;
1216
+ serve({ fetch: createDevApp({ pages: app, files, reload }).fetch, port: cli_dev_port }, (info) => console.log(`http://localhost:${info.port}/`));
1217
+ const handleDocsChange = async (_event, filename) => {
1218
+ if (filename !== null && !/\.mdx?$/i.test(filename)) {
1219
+ return;
1220
+ }
1221
+ const currentGeneration = ++generation;
1222
+ try {
1223
+ const [docs2, home2] = await Promise.all([readDocs({ root: docsRoot, processor }), readHome({ root: docsRoot, processor })]);
1224
+ if (currentGeneration !== generation) {
1225
+ return;
1226
+ }
1227
+ store.docs = docs2;
1228
+ store.home = home2;
1229
+ reload.emit("change");
1230
+ } catch (error) {
1231
+ console.error(`${copy_error_prefix}: ${toErrorMessage(error)}`);
1232
+ }
1233
+ };
1234
+ watch(docsRoot, { recursive: true }, handleDocsChange);
1235
+ };
1236
+ try {
1237
+ await main();
1238
+ } catch (error) {
1239
+ console.error(`${copy_error_prefix}: ${toErrorMessage(error)}`);
1240
+ process.exit(1);
1241
+ }