specra 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 (142) hide show
  1. package/LICENSE.MD +21 -0
  2. package/README.md +157 -0
  3. package/dist/app/api/mdx-watch/route.d.mts +12 -0
  4. package/dist/app/api/mdx-watch/route.d.ts +12 -0
  5. package/dist/app/api/mdx-watch/route.js +98 -0
  6. package/dist/app/api/mdx-watch/route.js.map +1 -0
  7. package/dist/app/api/mdx-watch/route.mjs +71 -0
  8. package/dist/app/api/mdx-watch/route.mjs.map +1 -0
  9. package/dist/app/docs-page.d.mts +32 -0
  10. package/dist/app/docs-page.d.ts +32 -0
  11. package/dist/app/docs-page.js +4072 -0
  12. package/dist/app/docs-page.js.map +1 -0
  13. package/dist/app/docs-page.mjs +14 -0
  14. package/dist/app/docs-page.mjs.map +1 -0
  15. package/dist/app/layout.css +297 -0
  16. package/dist/app/layout.css.map +1 -0
  17. package/dist/app/layout.d.mts +19 -0
  18. package/dist/app/layout.d.ts +19 -0
  19. package/dist/app/layout.js +112 -0
  20. package/dist/app/layout.js.map +1 -0
  21. package/dist/app/layout.mjs +13 -0
  22. package/dist/app/layout.mjs.map +1 -0
  23. package/dist/chunk-DR4EPLMT.mjs +1013 -0
  24. package/dist/chunk-DR4EPLMT.mjs.map +1 -0
  25. package/dist/chunk-INL2EC72.mjs +170 -0
  26. package/dist/chunk-INL2EC72.mjs.map +1 -0
  27. package/dist/chunk-IZFGEAD6.mjs +61 -0
  28. package/dist/chunk-IZFGEAD6.mjs.map +1 -0
  29. package/dist/chunk-KTRWWAGL.mjs +50 -0
  30. package/dist/chunk-KTRWWAGL.mjs.map +1 -0
  31. package/dist/chunk-MZJHJ6BV.mjs +21 -0
  32. package/dist/chunk-MZJHJ6BV.mjs.map +1 -0
  33. package/dist/chunk-NXRIAL7T.mjs +3119 -0
  34. package/dist/chunk-NXRIAL7T.mjs.map +1 -0
  35. package/dist/components/index.d.mts +822 -0
  36. package/dist/components/index.d.ts +822 -0
  37. package/dist/components/index.js +3738 -0
  38. package/dist/components/index.js.map +1 -0
  39. package/dist/components/index.mjs +3627 -0
  40. package/dist/components/index.mjs.map +1 -0
  41. package/dist/index.css +297 -0
  42. package/dist/index.css.map +1 -0
  43. package/dist/index.d.mts +545 -0
  44. package/dist/index.d.ts +545 -0
  45. package/dist/index.js +4648 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/index.mjs +347 -0
  48. package/dist/index.mjs.map +1 -0
  49. package/dist/lib/index.d.mts +798 -0
  50. package/dist/lib/index.d.ts +798 -0
  51. package/dist/lib/index.js +1301 -0
  52. package/dist/lib/index.js.map +1 -0
  53. package/dist/lib/index.mjs +89 -0
  54. package/dist/lib/index.mjs.map +1 -0
  55. package/package.json +119 -0
  56. package/src/app/api/mdx-watch/route.ts +86 -0
  57. package/src/app/docs-page.tsx +212 -0
  58. package/src/app/layout.tsx +74 -0
  59. package/src/components/docs/accordion.tsx +53 -0
  60. package/src/components/docs/api/api-endpoint.tsx +59 -0
  61. package/src/components/docs/api/api-params.tsx +43 -0
  62. package/src/components/docs/api/api-playground.tsx +233 -0
  63. package/src/components/docs/api/api-reference.tsx +291 -0
  64. package/src/components/docs/api/api-response.tsx +48 -0
  65. package/src/components/docs/api/index.ts +5 -0
  66. package/src/components/docs/badge.tsx +22 -0
  67. package/src/components/docs/breadcrumb.tsx +51 -0
  68. package/src/components/docs/callout.tsx +109 -0
  69. package/src/components/docs/card.tsx +84 -0
  70. package/src/components/docs/category-index.tsx +112 -0
  71. package/src/components/docs/code-block.tsx +129 -0
  72. package/src/components/docs/columns.tsx +45 -0
  73. package/src/components/docs/componentTextProps.ts +85 -0
  74. package/src/components/docs/dev-mode-badge.tsx +35 -0
  75. package/src/components/docs/doc-layout-wrapper.tsx +54 -0
  76. package/src/components/docs/doc-layout.tsx +111 -0
  77. package/src/components/docs/doc-loading.tsx +15 -0
  78. package/src/components/docs/doc-metadata.tsx +55 -0
  79. package/src/components/docs/doc-navigation.tsx +62 -0
  80. package/src/components/docs/doc-tags.tsx +25 -0
  81. package/src/components/docs/draft-badge.tsx +10 -0
  82. package/src/components/docs/footer.tsx +47 -0
  83. package/src/components/docs/frame.tsx +22 -0
  84. package/src/components/docs/header.tsx +122 -0
  85. package/src/components/docs/hot-reload-indicator.tsx +77 -0
  86. package/src/components/docs/icon.tsx +70 -0
  87. package/src/components/docs/image-card.tsx +95 -0
  88. package/src/components/docs/image.tsx +73 -0
  89. package/src/components/docs/index.ts +48 -0
  90. package/src/components/docs/math.tsx +46 -0
  91. package/src/components/docs/mdx-components.tsx +166 -0
  92. package/src/components/docs/mdx-hot-reload.tsx +37 -0
  93. package/src/components/docs/mermaid.tsx +77 -0
  94. package/src/components/docs/mobile-doc-layout.tsx +115 -0
  95. package/src/components/docs/not-found-content.tsx +55 -0
  96. package/src/components/docs/search-highlight.tsx +127 -0
  97. package/src/components/docs/search-modal.tsx +223 -0
  98. package/src/components/docs/sidebar-skeleton.tsx +39 -0
  99. package/src/components/docs/sidebar.tsx +323 -0
  100. package/src/components/docs/site-banner.tsx +92 -0
  101. package/src/components/docs/steps.tsx +29 -0
  102. package/src/components/docs/tab-context.tsx +28 -0
  103. package/src/components/docs/tab-groups.tsx +50 -0
  104. package/src/components/docs/table-of-contents.tsx +104 -0
  105. package/src/components/docs/tabs.tsx +63 -0
  106. package/src/components/docs/theme-toggle.tsx +39 -0
  107. package/src/components/docs/tooltip.tsx +37 -0
  108. package/src/components/docs/version-switcher.tsx +52 -0
  109. package/src/components/docs/video.tsx +80 -0
  110. package/src/components/global/index.ts +3 -0
  111. package/src/components/global/version-not-found.tsx +26 -0
  112. package/src/components/index.ts +8 -0
  113. package/src/components/theme-provider.tsx +11 -0
  114. package/src/components/ui/badge.tsx +46 -0
  115. package/src/components/ui/button.tsx +60 -0
  116. package/src/components/ui/dialog.tsx +143 -0
  117. package/src/components/ui/index.ts +6 -0
  118. package/src/components/ui/input.tsx +21 -0
  119. package/src/components/ui/textarea.tsx +18 -0
  120. package/src/index.ts +41 -0
  121. package/src/lib/api-parser.types.ts +78 -0
  122. package/src/lib/api.types.ts +202 -0
  123. package/src/lib/category.ts +71 -0
  124. package/src/lib/config.server.ts +170 -0
  125. package/src/lib/config.ts +20 -0
  126. package/src/lib/config.types.ts +295 -0
  127. package/src/lib/dev-utils.ts +75 -0
  128. package/src/lib/index.ts +27 -0
  129. package/src/lib/mdx-cache.ts +200 -0
  130. package/src/lib/mdx.ts +402 -0
  131. package/src/lib/parsers/base-parser.ts +16 -0
  132. package/src/lib/parsers/index.ts +69 -0
  133. package/src/lib/parsers/openapi-parser.ts +251 -0
  134. package/src/lib/parsers/postman-parser.ts +301 -0
  135. package/src/lib/parsers/specra-parser.ts +24 -0
  136. package/src/lib/redirects.ts +40 -0
  137. package/src/lib/remark-code-meta.ts +23 -0
  138. package/src/lib/sidebar-utils.ts +188 -0
  139. package/src/lib/toc.ts +24 -0
  140. package/src/lib/utils.ts +36 -0
  141. package/src/specra.config.json +124 -0
  142. package/src/styles/globals.css +427 -0
@@ -0,0 +1,3119 @@
1
+ import {
2
+ useTabContext
3
+ } from "./chunk-MZJHJ6BV.mjs";
4
+ import {
5
+ extractTableOfContents,
6
+ getAdjacentDocs,
7
+ getCachedAllDocs,
8
+ getCachedDocBySlug,
9
+ getCachedVersions,
10
+ isCategoryPage,
11
+ parseApiSpec,
12
+ sortSidebarGroups,
13
+ sortSidebarItems
14
+ } from "./chunk-DR4EPLMT.mjs";
15
+ import {
16
+ cn,
17
+ getAssetPath,
18
+ getConfig,
19
+ processContentWithEnv
20
+ } from "./chunk-INL2EC72.mjs";
21
+
22
+ // src/components/docs/doc-layout.tsx
23
+ import { ExternalLink as ExternalLink2, FileEdit } from "lucide-react";
24
+ import { MDXRemote } from "next-mdx-remote/rsc";
25
+ import remarkGfm from "remark-gfm";
26
+ import rehypeSlug from "rehype-slug";
27
+
28
+ // src/lib/remark-code-meta.ts
29
+ function remarkCodeMeta() {
30
+ return (tree) => {
31
+ const visit = (node) => {
32
+ if (node.type === "code" && node.meta) {
33
+ node.data = node.data || {};
34
+ node.data.hProperties = node.data.hProperties || {};
35
+ node.data.hProperties.meta = node.meta;
36
+ }
37
+ if (node.children) {
38
+ node.children.forEach(visit);
39
+ }
40
+ };
41
+ visit(tree);
42
+ };
43
+ }
44
+
45
+ // src/components/docs/code-block.tsx
46
+ import { useState } from "react";
47
+ import { Check, Copy } from "lucide-react";
48
+ import { jsx, jsxs } from "react/jsx-runtime";
49
+ function CodeBlock({ code, language, filename }) {
50
+ const [copied, setCopied] = useState(false);
51
+ const handleCopy = async () => {
52
+ await navigator.clipboard.writeText(code);
53
+ setCopied(true);
54
+ setTimeout(() => setCopied(false), 2e3);
55
+ };
56
+ const highlightCode = (code2, lang) => {
57
+ const lines = code2.split("\n");
58
+ return lines.map((line, i) => {
59
+ const tokens = [];
60
+ let currentPos = 0;
61
+ const patterns = [
62
+ { type: "comment", regex: /(\/\/.*$|\/\*[\s\S]*?\*\/|#.*$)/ },
63
+ { type: "string", regex: /("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`)/ },
64
+ {
65
+ type: "keyword",
66
+ regex: /\b(const|let|var|function|return|if|else|for|while|do|break|continue|switch|case|default|import|export|from|as|class|extends|implements|interface|type|enum|namespace|async|await|try|catch|finally|throw|new|this|super|static|public|private|protected|readonly|abstract|void|null|undefined|true|false|typeof|instanceof|delete|in|of)\b/
67
+ },
68
+ { type: "operator", regex: /([+\-*/%=<>!&|^~?:]+)/ },
69
+ { type: "number", regex: /\b(0x[a-fA-F0-9]+|0b[01]+|\d+\.?\d*(?:e[+-]?\d+)?)\b/ },
70
+ { type: "function", regex: /\b([a-zA-Z_$][\w$]*)\s*(?=\()/ },
71
+ { type: "property", regex: /\.([a-zA-Z_$][\w$]*)/ },
72
+ { type: "punctuation", regex: /([{}[\]();,])/ }
73
+ ];
74
+ while (currentPos < line.length) {
75
+ let matched = false;
76
+ for (const { type, regex } of patterns) {
77
+ const match = line.slice(currentPos).match(regex);
78
+ if (match && match.index === 0) {
79
+ tokens.push({ type, value: match[0] });
80
+ currentPos += match[0].length;
81
+ matched = true;
82
+ break;
83
+ }
84
+ }
85
+ if (!matched) {
86
+ const nextSpecialChar = line.slice(currentPos).search(/["'`/\w.+\-*/%=<>!&|^~?:;,()[\]{}#]/);
87
+ if (nextSpecialChar === -1) {
88
+ tokens.push({ type: "text", value: line.slice(currentPos) });
89
+ break;
90
+ } else if (nextSpecialChar > 0) {
91
+ tokens.push({ type: "text", value: line.slice(currentPos, currentPos + nextSpecialChar) });
92
+ currentPos += nextSpecialChar;
93
+ } else {
94
+ tokens.push({ type: "text", value: line[currentPos] });
95
+ currentPos++;
96
+ }
97
+ }
98
+ }
99
+ return /* @__PURE__ */ jsxs("div", { className: "table-row", children: [
100
+ /* @__PURE__ */ jsx("span", { className: "table-cell pr-4 text-right select-none text-muted-foreground/40 w-8 align-top", children: i + 1 }),
101
+ /* @__PURE__ */ jsx("span", { className: "table-cell align-top", children: tokens.length === 0 ? /* @__PURE__ */ jsx("span", { children: "\xA0" }) : tokens.map((token, j) => /* @__PURE__ */ jsx("span", { className: `token-${token.type}`, children: token.value }, j)) })
102
+ ] }, i);
103
+ });
104
+ };
105
+ return /* @__PURE__ */ jsxs("div", { className: "relative group my-2", children: [
106
+ /* @__PURE__ */ jsxs("div", { className: "bg-muted/50 dark:bg-muted/30 px-4 py-2 rounded-t-xl border border-b-0 border-border/50 flex items-center justify-between", children: [
107
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
108
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
109
+ /* @__PURE__ */ jsx("div", { className: "w-3 h-3 rounded-full bg-red-500/80 dark:bg-red-500/60" }),
110
+ /* @__PURE__ */ jsx("div", { className: "w-3 h-3 rounded-full bg-yellow-500/80 dark:bg-yellow-500/60" }),
111
+ /* @__PURE__ */ jsx("div", { className: "w-3 h-3 rounded-full bg-green-500/80 dark:bg-green-500/60" })
112
+ ] }),
113
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-foreground", children: filename || "Code" })
114
+ ] }),
115
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
116
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground/60 font-mono uppercase tracking-wide", children: language }),
117
+ /* @__PURE__ */ jsx(
118
+ "button",
119
+ {
120
+ onClick: handleCopy,
121
+ className: "p-1.5 rounded-md hover:bg-muted/50 transition-colors",
122
+ "aria-label": "Copy code",
123
+ children: copied ? /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 text-green-400" }) : /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4 text-muted-foreground" })
124
+ }
125
+ )
126
+ ] })
127
+ ] }),
128
+ /* @__PURE__ */ jsx("div", { className: "bg-gray-200/50 dark:bg-[#0d1117] rounded-b-xl overflow-x-auto border border-border/50", children: /* @__PURE__ */ jsx("pre", { className: "p-2 text-[13px] font-mono leading-relaxed text-gray-800 dark:text-gray-200", children: /* @__PURE__ */ jsx("code", { className: "table w-full", children: highlightCode(code, language) }) }) })
129
+ ] });
130
+ }
131
+
132
+ // src/components/docs/callout.tsx
133
+ import { Info, AlertTriangle, CheckCircle2, XCircle, Lightbulb } from "lucide-react";
134
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
135
+ function Callout({ children, type = "info", title }) {
136
+ const configs = {
137
+ info: {
138
+ icon: Info,
139
+ className: "bg-blue-500/10 border-blue-500/30 text-blue-900 dark:bg-blue-400/5 dark:border-blue-500/20 dark:text-blue-400",
140
+ iconClassName: "text-blue-600 dark:text-blue-400",
141
+ titleClassName: "text-blue-700 dark:text-blue-300",
142
+ defaultTitle: "Info"
143
+ },
144
+ note: {
145
+ icon: Info,
146
+ className: "bg-blue-500/10 border-blue-500/30 text-blue-900 dark:bg-blue-400/5 dark:border-blue-500/20 dark:text-blue-400",
147
+ iconClassName: "text-blue-600 dark:text-blue-400",
148
+ titleClassName: "text-blue-700 dark:text-blue-300",
149
+ defaultTitle: "Note"
150
+ },
151
+ warning: {
152
+ icon: AlertTriangle,
153
+ className: "bg-yellow-500/10 border-yellow-500/30 text-yellow-900 dark:bg-yellow-400/5 dark:border-yellow-500/20 dark:text-yellow-400",
154
+ iconClassName: "text-yellow-600 dark:text-yellow-400",
155
+ titleClassName: "text-yellow-700 dark:text-yellow-300",
156
+ defaultTitle: "Warning"
157
+ },
158
+ success: {
159
+ icon: CheckCircle2,
160
+ className: "bg-green-500/10 border-green-500/30 text-green-900 dark:bg-green-400/5 dark:border-green-500/20 dark:text-green-400",
161
+ iconClassName: "text-green-600 dark:text-green-400",
162
+ titleClassName: "text-green-700 dark:text-green-300",
163
+ defaultTitle: "Success"
164
+ },
165
+ error: {
166
+ icon: XCircle,
167
+ className: "bg-red-500/10 border-red-500/30 text-red-900 dark:bg-red-400/5 dark:border-red-500/20 dark:text-red-400",
168
+ iconClassName: "text-red-600 dark:text-red-400",
169
+ titleClassName: "text-red-700 dark:text-red-300",
170
+ defaultTitle: "Error"
171
+ },
172
+ danger: {
173
+ icon: XCircle,
174
+ className: "bg-red-500/10 border-red-500/30 text-red-900 dark:bg-red-400/5 dark:border-red-500/20 dark:text-red-400",
175
+ iconClassName: "text-red-600 dark:text-red-400",
176
+ titleClassName: "text-red-700 dark:text-red-300",
177
+ defaultTitle: "Danger"
178
+ },
179
+ tip: {
180
+ icon: Lightbulb,
181
+ className: "bg-purple-500/10 border-purple-500/30 text-purple-900 dark:bg-purple-400/5 dark:border-purple-500/20 dark:text-purple-400",
182
+ iconClassName: "text-purple-600 dark:text-purple-400",
183
+ titleClassName: "text-purple-700 dark:text-purple-300",
184
+ defaultTitle: "Tip"
185
+ }
186
+ };
187
+ const config = configs[type];
188
+ const Icon2 = config.icon;
189
+ let _title = title || config.defaultTitle;
190
+ let content = children;
191
+ if (!title && children && typeof children === "object") {
192
+ const childArray = Array.isArray(children) ? children : [children];
193
+ const firstElement = childArray[0];
194
+ if (firstElement && typeof firstElement === "object" && "props" in firstElement) {
195
+ const props = firstElement.props;
196
+ if (props.children && Array.isArray(props.children)) {
197
+ const strongChild = props.children.find(
198
+ (child) => child && typeof child === "object" && child.type === "strong"
199
+ );
200
+ if (strongChild) {
201
+ _title = strongChild.props.children;
202
+ content = childArray.map((child, idx) => {
203
+ if (idx === 0 && typeof child === "object" && "props" in child) {
204
+ const newChildren = child.props.children.filter((c) => c !== strongChild);
205
+ return { ...child, props: { ...child.props, children: newChildren } };
206
+ }
207
+ return child;
208
+ });
209
+ }
210
+ }
211
+ }
212
+ }
213
+ return /* @__PURE__ */ jsxs2("div", { className: `flex gap-3 p-4 rounded-xl border my-2 ${config.className}`, children: [
214
+ /* @__PURE__ */ jsx2("div", { className: "flex-shrink-0 mt-0.5", children: /* @__PURE__ */ jsx2(Icon2, { className: `h-5 w-5 ${config.iconClassName}` }) }),
215
+ /* @__PURE__ */ jsxs2("div", { className: "flex-1 space-y-0", children: [
216
+ /* @__PURE__ */ jsx2("div", { className: `font-semibold text-sm ${config.titleClassName}`, children: _title }),
217
+ /* @__PURE__ */ jsx2("div", { className: "text-sm leading-relaxed [&>p]:mb-0 [&>p]:text-current", children: content })
218
+ ] })
219
+ ] });
220
+ }
221
+
222
+ // src/components/docs/accordion.tsx
223
+ import { ChevronDown } from "lucide-react";
224
+ import { useState as useState2 } from "react";
225
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
226
+ function AccordionItem({ title, children, defaultOpen = false }) {
227
+ const [isOpen, setIsOpen] = useState2(defaultOpen);
228
+ return /* @__PURE__ */ jsxs3("div", { className: "border border-border rounded-xl overflow-hidden mb-2", children: [
229
+ /* @__PURE__ */ jsxs3(
230
+ "button",
231
+ {
232
+ onClick: () => setIsOpen(!isOpen),
233
+ className: "w-full flex items-center justify-between p-4 text-left bg-muted/30 hover:bg-muted/50 transition-colors",
234
+ children: [
235
+ /* @__PURE__ */ jsx3("span", { className: "font-medium text-foreground", children: title }),
236
+ /* @__PURE__ */ jsx3(
237
+ ChevronDown,
238
+ {
239
+ className: `h-5 w-5 text-muted-foreground transition-transform ${isOpen ? "rotate-180" : ""}`
240
+ }
241
+ )
242
+ ]
243
+ }
244
+ ),
245
+ isOpen && /* @__PURE__ */ jsx3("div", { className: "p-4 border-t border-border bg-background", children: /* @__PURE__ */ jsx3("div", { className: "prose prose-sm dark:prose-invert max-w-none [&>*:last-child]:mb-0", children }) })
246
+ ] });
247
+ }
248
+ function Accordion({ children, type = "multiple", className }) {
249
+ return /* @__PURE__ */ jsx3("div", { className: className || "my-6 space-y-2", children });
250
+ }
251
+
252
+ // src/components/docs/tabs.tsx
253
+ import { useState as useState3, Children, isValidElement } from "react";
254
+ import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
255
+ function Tab({ children }) {
256
+ return /* @__PURE__ */ jsx4(Fragment, { children });
257
+ }
258
+ function Tabs({ children, defaultValue }) {
259
+ const tabs = Children.toArray(children).filter(isValidElement);
260
+ const firstTabLabel = tabs[0]?.props.label || "";
261
+ const [activeTab, setActiveTab] = useState3(defaultValue || firstTabLabel);
262
+ return /* @__PURE__ */ jsxs4("div", { className: "my-6", children: [
263
+ /* @__PURE__ */ jsx4("div", { className: "flex items-center gap-1 border-b border-border mb-4", children: tabs.map((tab) => {
264
+ const label = tab.props.label;
265
+ const isActive = activeTab === label;
266
+ return /* @__PURE__ */ jsx4(
267
+ "button",
268
+ {
269
+ onClick: () => setActiveTab(label),
270
+ className: `px-4 py-2 text-sm font-medium transition-colors border-b-2 -mb-px ${isActive ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground hover:border-border"}`,
271
+ children: label
272
+ },
273
+ label
274
+ );
275
+ }) }),
276
+ tabs.map((tab) => {
277
+ const label = tab.props.label;
278
+ if (activeTab !== label) return null;
279
+ return /* @__PURE__ */ jsx4("div", { className: "prose prose-slate dark:prose-invert max-w-none [&>*:first-child]:mt-0", children: tab.props.children }, label);
280
+ })
281
+ ] });
282
+ }
283
+
284
+ // src/components/docs/image.tsx
285
+ import NextImage from "next/image";
286
+ import { useState as useState4 } from "react";
287
+ import { ZoomIn, X } from "lucide-react";
288
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
289
+ function Image({ src, alt, caption, width, height, zoom = true }) {
290
+ const [isZoomed, setIsZoomed] = useState4(false);
291
+ return /* @__PURE__ */ jsxs5(Fragment2, { children: [
292
+ /* @__PURE__ */ jsxs5("figure", { className: "my-6", children: [
293
+ /* @__PURE__ */ jsxs5("div", { className: "relative group rounded-xl border border-border overflow-hidden bg-muted/30", children: [
294
+ /* @__PURE__ */ jsx5(
295
+ NextImage,
296
+ {
297
+ src,
298
+ alt,
299
+ width: width || 1200,
300
+ height: height || 675,
301
+ className: "w-full h-auto"
302
+ }
303
+ ),
304
+ zoom && /* @__PURE__ */ jsx5(
305
+ "button",
306
+ {
307
+ onClick: () => setIsZoomed(true),
308
+ className: "absolute top-3 right-3 p-2 rounded-md bg-background/80 backdrop-blur-sm border border-border opacity-0 group-hover:opacity-100 transition-opacity hover:bg-background",
309
+ "aria-label": "Zoom image",
310
+ children: /* @__PURE__ */ jsx5(ZoomIn, { className: "h-4 w-4 text-foreground" })
311
+ }
312
+ )
313
+ ] }),
314
+ caption && /* @__PURE__ */ jsx5("figcaption", { className: "mt-2 text-center text-sm text-muted-foreground italic", children: caption })
315
+ ] }),
316
+ isZoomed && /* @__PURE__ */ jsxs5(
317
+ "div",
318
+ {
319
+ className: "fixed inset-0 z-50 bg-background/95 backdrop-blur-sm flex items-center justify-center p-4",
320
+ onClick: () => setIsZoomed(false),
321
+ children: [
322
+ /* @__PURE__ */ jsx5(
323
+ "button",
324
+ {
325
+ onClick: () => setIsZoomed(false),
326
+ className: "absolute top-4 right-4 p-2 rounded-md bg-muted hover:bg-muted/80 transition-colors",
327
+ "aria-label": "Close",
328
+ children: /* @__PURE__ */ jsx5(X, { className: "h-5 w-5 text-foreground" })
329
+ }
330
+ ),
331
+ /* @__PURE__ */ jsx5("div", { className: "max-w-7xl max-h-[90vh] overflow-auto", children: /* @__PURE__ */ jsx5(
332
+ NextImage,
333
+ {
334
+ src,
335
+ alt,
336
+ width: width || 1920,
337
+ height: height || 1080,
338
+ className: "w-full h-auto"
339
+ }
340
+ ) })
341
+ ]
342
+ }
343
+ )
344
+ ] });
345
+ }
346
+
347
+ // src/components/docs/video.tsx
348
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
349
+ function Video({
350
+ src,
351
+ caption,
352
+ autoplay = false,
353
+ loop = false,
354
+ muted = false,
355
+ controls = true,
356
+ poster
357
+ }) {
358
+ const isYouTube = src.includes("youtube.com") || src.includes("youtu.be");
359
+ const isVimeo = src.includes("vimeo.com");
360
+ const getYouTubeId = (url) => {
361
+ const match = url.match(/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/);
362
+ return match ? match[1] : null;
363
+ };
364
+ const getVimeoId = (url) => {
365
+ const match = url.match(/vimeo\.com\/(\d+)/);
366
+ return match ? match[1] : null;
367
+ };
368
+ return /* @__PURE__ */ jsxs6("figure", { className: "my-6", children: [
369
+ /* @__PURE__ */ jsx6("div", { className: "relative rounded-xl border border-border overflow-hidden bg-muted/30", children: isYouTube ? /* @__PURE__ */ jsx6("div", { className: "relative w-full", style: { paddingBottom: "56.25%" }, children: /* @__PURE__ */ jsx6(
370
+ "iframe",
371
+ {
372
+ className: "absolute top-0 left-0 w-full h-full",
373
+ src: `https://www.youtube.com/embed/${getYouTubeId(src)}${autoplay ? "?autoplay=1" : ""}`,
374
+ title: "YouTube video",
375
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
376
+ allowFullScreen: true
377
+ }
378
+ ) }) : isVimeo ? /* @__PURE__ */ jsx6("div", { className: "relative w-full", style: { paddingBottom: "56.25%" }, children: /* @__PURE__ */ jsx6(
379
+ "iframe",
380
+ {
381
+ className: "absolute top-0 left-0 w-full h-full",
382
+ src: `https://player.vimeo.com/video/${getVimeoId(src)}${autoplay ? "?autoplay=1" : ""}`,
383
+ title: "Vimeo video",
384
+ allow: "autoplay; fullscreen; picture-in-picture",
385
+ allowFullScreen: true
386
+ }
387
+ ) }) : /* @__PURE__ */ jsx6(
388
+ "video",
389
+ {
390
+ src,
391
+ controls,
392
+ autoPlay: autoplay,
393
+ loop,
394
+ muted,
395
+ poster,
396
+ className: "w-full h-auto",
397
+ children: "Your browser does not support the video tag."
398
+ }
399
+ ) }),
400
+ caption && /* @__PURE__ */ jsx6("figcaption", { className: "mt-2 text-center text-sm text-muted-foreground italic", children: caption })
401
+ ] });
402
+ }
403
+
404
+ // src/components/docs/card.tsx
405
+ import { ArrowRight, ExternalLink } from "lucide-react";
406
+ import Link from "next/link";
407
+
408
+ // src/components/docs/icon.tsx
409
+ import * as LucideIcons from "lucide-react";
410
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
411
+ function Icon({ icon, iconType = "regular", color, size = 20, className = "" }) {
412
+ if (typeof icon !== "string") {
413
+ return /* @__PURE__ */ jsx7("span", { className: `inline-flex items-center ${className}`, style: { color }, children: icon });
414
+ }
415
+ if (icon.startsWith("http") || icon.startsWith("/")) {
416
+ return /* @__PURE__ */ jsx7(
417
+ "img",
418
+ {
419
+ src: icon,
420
+ alt: "",
421
+ width: size,
422
+ height: size,
423
+ className: `inline-block ${className}`,
424
+ style: { color }
425
+ }
426
+ );
427
+ }
428
+ if (icon.startsWith("fa-")) {
429
+ const faClass = `fa-${iconType} ${icon}`;
430
+ return /* @__PURE__ */ jsx7(
431
+ "i",
432
+ {
433
+ className: `${faClass} ${className}`,
434
+ style: { fontSize: size, color },
435
+ "aria-hidden": "true"
436
+ }
437
+ );
438
+ }
439
+ const iconName = icon.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
440
+ const LucideIcon = LucideIcons[iconName];
441
+ if (LucideIcon) {
442
+ return /* @__PURE__ */ jsx7(
443
+ LucideIcon,
444
+ {
445
+ size,
446
+ className: `inline-block ${className}`,
447
+ style: { color },
448
+ "aria-hidden": "true"
449
+ }
450
+ );
451
+ }
452
+ return /* @__PURE__ */ jsxs7("span", { className: `inline-flex items-center font-mono text-xs ${className}`, style: { color }, children: [
453
+ "[",
454
+ icon,
455
+ "]"
456
+ ] });
457
+ }
458
+
459
+ // src/components/docs/card.tsx
460
+ import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
461
+ function Card({ title, description, href, icon, children, external = false }) {
462
+ const content = /* @__PURE__ */ jsx8(Fragment3, { children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3", children: [
463
+ icon && /* @__PURE__ */ jsx8("div", { className: "shrink-0 w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center text-primary", children: typeof icon === "string" ? /* @__PURE__ */ jsx8(Icon, { icon, size: 20 }) : icon }),
464
+ /* @__PURE__ */ jsxs8("div", { className: "flex-1 min-w-0", children: [
465
+ /* @__PURE__ */ jsx8("h3", { className: `font-semibold text-foreground mb-1 no-underline ${href ? "group-hover:text-primary transition-colors" : ""}`, children: title }),
466
+ description && /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground line-clamp-2 no-underline", children: description }),
467
+ children && /* @__PURE__ */ jsx8("div", { className: "mt-2 text-sm text-muted-foreground no-underline", children })
468
+ ] }),
469
+ href && /* @__PURE__ */ jsx8("div", { className: "shrink-0 self-start mt-1", children: external ? /* @__PURE__ */ jsx8(ExternalLink, { className: "h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" }) : /* @__PURE__ */ jsx8(ArrowRight, { className: "h-4 w-4 text-muted-foreground group-hover:text-primary group-hover:translate-x-1 transition-all" }) })
470
+ ] }) });
471
+ if (href) {
472
+ const Component = external ? "a" : Link;
473
+ return /* @__PURE__ */ jsx8(
474
+ Component,
475
+ {
476
+ href,
477
+ className: "card-link group block p-4 rounded-xl border border-border hover:border-primary/50 hover:bg-muted/50 transition-all",
478
+ ...external ? { target: "_blank", rel: "noopener noreferrer" } : {},
479
+ children: content
480
+ }
481
+ );
482
+ }
483
+ return /* @__PURE__ */ jsx8("div", { className: "p-4 rounded-xl border border-border bg-muted/30 no-underline", children: content });
484
+ }
485
+ function CardGrid({ children, cols = 2 }) {
486
+ const gridCols = {
487
+ 1: "grid-cols-1",
488
+ 2: "grid-cols-1 md:grid-cols-2",
489
+ 3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"
490
+ };
491
+ return /* @__PURE__ */ jsx8("div", { className: `grid ${gridCols[cols]} gap-4 my-6`, children });
492
+ }
493
+
494
+ // src/components/docs/image-card.tsx
495
+ import NextImage2 from "next/image";
496
+ import Link2 from "next/link";
497
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
498
+ function ImageCard({
499
+ src,
500
+ alt,
501
+ title,
502
+ description,
503
+ href,
504
+ external = false,
505
+ aspectRatio = "video"
506
+ }) {
507
+ const aspectRatios = {
508
+ square: "aspect-square",
509
+ video: "aspect-video",
510
+ portrait: "aspect-[3/4]"
511
+ };
512
+ const content = /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-0 p-0", children: [
513
+ /* @__PURE__ */ jsx9("div", { className: `w-full ${aspectRatios[aspectRatio]} overflow-hidden ${title || description ? "rounded-t-xl" : "rounded-xl"} bg-muted relative`, children: /* @__PURE__ */ jsx9(
514
+ NextImage2,
515
+ {
516
+ src,
517
+ alt,
518
+ fill: true,
519
+ sizes: "(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw",
520
+ className: "object-cover transition-transform duration-300 group-hover:scale-105"
521
+ }
522
+ ) }),
523
+ (title || description) && /* @__PURE__ */ jsxs9("div", { className: "p-3 flex flex-col gap-1", children: [
524
+ title && /* @__PURE__ */ jsx9("h3", { className: `font-semibold text-foreground mb-0 no-underline ${href ? "group-hover:text-primary transition-colors" : ""}`, children: title }),
525
+ description && /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground line-clamp-2 no-underline mb-0", children: description })
526
+ ] })
527
+ ] });
528
+ if (href) {
529
+ const Component = external ? "a" : Link2;
530
+ return /* @__PURE__ */ jsx9(
531
+ Component,
532
+ {
533
+ href,
534
+ className: "image-card-link group block rounded-xl border border-border hover:border-primary/50 hover:shadow-lg transition-all overflow-hidden p-0",
535
+ ...external ? { target: "_blank", rel: "noopener noreferrer" } : {},
536
+ children: content
537
+ }
538
+ );
539
+ }
540
+ return /* @__PURE__ */ jsx9("div", { className: "block rounded-xl border border-border overflow-hidden bg-card p-0", children: content });
541
+ }
542
+ function ImageCardGrid({ children, cols = 3 }) {
543
+ const gridCols = {
544
+ 1: "grid-cols-1",
545
+ 2: "grid-cols-1 md:grid-cols-2",
546
+ 3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
547
+ 4: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4"
548
+ };
549
+ return /* @__PURE__ */ jsx9("div", { className: `grid ${gridCols[cols]} gap-4 my-6`, children });
550
+ }
551
+
552
+ // src/components/docs/steps.tsx
553
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
554
+ function Steps({ children }) {
555
+ return /* @__PURE__ */ jsx10("div", { className: "my-6 ml-4 space-y-6 [counter-reset:step]", children });
556
+ }
557
+ function Step({ title, children }) {
558
+ return /* @__PURE__ */ jsxs10("div", { className: "relative pl-8 pb-6 border-l-2 border-border last:border-l-0 last:pb-0 [counter-increment:step] before:content-[counter(step)] before:absolute before:left-0 before:-translate-x-1/2 before:w-8 before:h-8 before:rounded-full before:bg-primary before:text-primary-foreground before:flex before:items-center before:justify-center before:text-sm before:font-semibold before:z-10", children: [
559
+ /* @__PURE__ */ jsx10("div", { className: "mb-2", children: /* @__PURE__ */ jsx10("h3", { className: "text-lg font-semibold text-foreground", children: title }) }),
560
+ /* @__PURE__ */ jsx10("div", { className: "prose prose-sm dark:prose-invert max-w-none [&>*:last-child]:mb-0", children })
561
+ ] });
562
+ }
563
+
564
+ // src/components/docs/mermaid.tsx
565
+ import { useEffect, useRef, useState as useState5 } from "react";
566
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
567
+ function Mermaid({ chart, caption }) {
568
+ const containerRef = useRef(null);
569
+ const [error, setError] = useState5(null);
570
+ useEffect(() => {
571
+ const renderChart = async () => {
572
+ try {
573
+ const mermaid = (await import("mermaid")).default;
574
+ mermaid.initialize({
575
+ startOnLoad: false,
576
+ theme: document.documentElement.classList.contains("dark") ? "dark" : "default",
577
+ securityLevel: "loose",
578
+ fontFamily: "inherit"
579
+ });
580
+ if (containerRef.current) {
581
+ const id = `mermaid-${Math.random().toString(36).substr(2, 9)}`;
582
+ const { svg } = await mermaid.render(id, chart);
583
+ containerRef.current.innerHTML = svg;
584
+ }
585
+ } catch (err) {
586
+ console.error("Mermaid rendering error:", err);
587
+ setError(err instanceof Error ? err.message : "Failed to render diagram");
588
+ }
589
+ };
590
+ renderChart();
591
+ const observer = new MutationObserver((mutations) => {
592
+ mutations.forEach((mutation) => {
593
+ if (mutation.attributeName === "class") {
594
+ renderChart();
595
+ }
596
+ });
597
+ });
598
+ observer.observe(document.documentElement, { attributes: true });
599
+ return () => observer.disconnect();
600
+ }, [chart]);
601
+ if (error) {
602
+ return /* @__PURE__ */ jsx11("div", { className: "my-6 p-4 rounded-xl border border-red-500/50 bg-red-500/10", children: /* @__PURE__ */ jsxs11("p", { className: "text-sm text-red-600 dark:text-red-400 font-mono", children: [
603
+ "Mermaid Error: ",
604
+ error
605
+ ] }) });
606
+ }
607
+ return /* @__PURE__ */ jsxs11("figure", { className: "my-6", children: [
608
+ /* @__PURE__ */ jsx11(
609
+ "div",
610
+ {
611
+ ref: containerRef,
612
+ className: "flex justify-center items-center p-6 rounded-xl border border-border bg-muted/30 overflow-x-auto"
613
+ }
614
+ ),
615
+ caption && /* @__PURE__ */ jsx11("figcaption", { className: "mt-2 text-center text-sm text-muted-foreground italic", children: caption })
616
+ ] });
617
+ }
618
+
619
+ // src/components/docs/math.tsx
620
+ import { useEffect as useEffect2, useRef as useRef2 } from "react";
621
+ import { jsx as jsx12 } from "react/jsx-runtime";
622
+ function Math2({ children, block = false }) {
623
+ const containerRef = useRef2(null);
624
+ useEffect2(() => {
625
+ const renderMath = async () => {
626
+ try {
627
+ const katex = (await import("katex")).default;
628
+ if (containerRef.current) {
629
+ katex.render(children, containerRef.current, {
630
+ throwOnError: false,
631
+ displayMode: block
632
+ });
633
+ }
634
+ } catch (err) {
635
+ console.error("KaTeX rendering error:", err);
636
+ if (containerRef.current) {
637
+ containerRef.current.textContent = children;
638
+ }
639
+ }
640
+ };
641
+ renderMath();
642
+ }, [children, block]);
643
+ if (block) {
644
+ return /* @__PURE__ */ jsx12(
645
+ "div",
646
+ {
647
+ ref: containerRef,
648
+ className: "my-6 overflow-x-auto text-center"
649
+ }
650
+ );
651
+ }
652
+ return /* @__PURE__ */ jsx12("span", { ref: containerRef, className: "inline-block" });
653
+ }
654
+
655
+ // src/components/docs/columns.tsx
656
+ import { jsx as jsx13 } from "react/jsx-runtime";
657
+ function Columns({ children, cols = { sm: 1, md: 2, lg: 3 } }) {
658
+ const colClasses = {
659
+ 1: "grid-cols-1",
660
+ 2: "grid-cols-2",
661
+ 3: "grid-cols-3",
662
+ 4: "grid-cols-4"
663
+ };
664
+ const smClass = cols.sm ? colClasses[cols.sm] : "grid-cols-1";
665
+ const mdClass = cols.md ? `md:${colClasses[cols.md]}` : "";
666
+ const lgClass = cols.lg ? `lg:${colClasses[cols.lg]}` : "";
667
+ const xlClass = cols.xl ? `xl:${colClasses[cols.xl]}` : "";
668
+ return /* @__PURE__ */ jsx13("div", { className: `grid ${smClass} ${mdClass} ${lgClass} ${xlClass} gap-4 my-6`, children });
669
+ }
670
+ function Column({ children, span = 1 }) {
671
+ const spanClass = {
672
+ 1: "col-span-1",
673
+ 2: "col-span-2",
674
+ 3: "col-span-3",
675
+ 4: "col-span-4"
676
+ };
677
+ return /* @__PURE__ */ jsx13("div", { className: spanClass[span], children });
678
+ }
679
+
680
+ // src/components/docs/badge.tsx
681
+ import { jsx as jsx14 } from "react/jsx-runtime";
682
+ function Badge({ children, variant = "default" }) {
683
+ const variants = {
684
+ default: "bg-muted text-foreground border-border",
685
+ success: "bg-green-500/10 text-green-600 dark:text-green-400 border-green-500/20",
686
+ warning: "bg-yellow-500/10 text-yellow-600 dark:text-yellow-400 border-yellow-500/20",
687
+ error: "bg-red-500/10 text-red-600 dark:text-red-400 border-red-500/20",
688
+ info: "bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/20"
689
+ };
690
+ return /* @__PURE__ */ jsx14(
691
+ "span",
692
+ {
693
+ className: `inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium border ${variants[variant]}`,
694
+ children
695
+ }
696
+ );
697
+ }
698
+
699
+ // src/components/docs/tooltip.tsx
700
+ import { useState as useState6 } from "react";
701
+ import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
702
+ function Tooltip({ children, content, position = "top" }) {
703
+ const [isVisible, setIsVisible] = useState6(false);
704
+ const positions = {
705
+ top: "bottom-full left-1/2 -translate-x-1/2 mb-2",
706
+ bottom: "top-full left-1/2 -translate-x-1/2 mt-2",
707
+ left: "right-full top-1/2 -translate-y-1/2 mr-2",
708
+ right: "left-full top-1/2 -translate-y-1/2 ml-2"
709
+ };
710
+ return /* @__PURE__ */ jsxs12(
711
+ "span",
712
+ {
713
+ className: "relative inline-flex underline decoration-dotted cursor-help",
714
+ onMouseEnter: () => setIsVisible(true),
715
+ onMouseLeave: () => setIsVisible(false),
716
+ children: [
717
+ children,
718
+ isVisible && /* @__PURE__ */ jsx15(
719
+ "span",
720
+ {
721
+ className: `absolute ${positions[position]} z-50 px-2 py-1 text-xs text-white bg-gray-900 dark:bg-gray-700 rounded whitespace-nowrap pointer-events-none`,
722
+ children: content
723
+ }
724
+ )
725
+ ]
726
+ }
727
+ );
728
+ }
729
+
730
+ // src/components/docs/frame.tsx
731
+ import { jsx as jsx16 } from "react/jsx-runtime";
732
+ function Frame({ src, title = "Embedded content", height = 500, width = "100%" }) {
733
+ return /* @__PURE__ */ jsx16("div", { className: "my-6 rounded-xl border border-border overflow-hidden bg-muted/30", children: /* @__PURE__ */ jsx16(
734
+ "iframe",
735
+ {
736
+ src,
737
+ title,
738
+ width,
739
+ height,
740
+ className: "w-full",
741
+ loading: "lazy",
742
+ sandbox: "allow-scripts allow-same-origin allow-forms allow-popups"
743
+ }
744
+ ) });
745
+ }
746
+
747
+ // src/components/docs/api/api-endpoint.tsx
748
+ import { useState as useState7 } from "react";
749
+ import { ChevronDown as ChevronDown2 } from "lucide-react";
750
+ import { jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
751
+ var methodColors = {
752
+ GET: "bg-blue-500/10 text-blue-600 dark:text-blue-400",
753
+ POST: "bg-green-500/10 text-green-600 dark:text-green-400",
754
+ PUT: "bg-orange-500/10 text-orange-600 dark:text-orange-400",
755
+ PATCH: "bg-purple-500/10 text-purple-600 dark:text-purple-400",
756
+ DELETE: "bg-red-500/10 text-red-600 dark:text-red-400"
757
+ };
758
+ function ApiEndpoint({ method, path, summary, children, defaultOpen = false }) {
759
+ const [isOpen, setIsOpen] = useState7(defaultOpen);
760
+ return /* @__PURE__ */ jsxs13("div", { className: "not-prose mb-4 rounded-xl border border-border overflow-hidden", children: [
761
+ /* @__PURE__ */ jsxs13(
762
+ "button",
763
+ {
764
+ onClick: () => setIsOpen(!isOpen),
765
+ className: "w-full flex items-center gap-3 px-4 py-3 text-left bg-muted/30 hover:bg-muted/50 transition-colors",
766
+ children: [
767
+ /* @__PURE__ */ jsx17(
768
+ "span",
769
+ {
770
+ className: cn(
771
+ "text-xs font-semibold px-2 py-0.5 rounded",
772
+ methodColors[method]
773
+ ),
774
+ children: method
775
+ }
776
+ ),
777
+ /* @__PURE__ */ jsx17("code", { className: "text-sm font-mono", children: path }),
778
+ summary && /* @__PURE__ */ jsx17("span", { className: "text-sm text-muted-foreground ml-auto mr-2", children: summary }),
779
+ /* @__PURE__ */ jsx17(
780
+ ChevronDown2,
781
+ {
782
+ className: cn(
783
+ "h-5 w-5 text-muted-foreground transition-transform flex-shrink-0",
784
+ isOpen ? "rotate-180" : ""
785
+ )
786
+ }
787
+ )
788
+ ]
789
+ }
790
+ ),
791
+ isOpen && children && /* @__PURE__ */ jsx17("div", { className: "border-t border-border bg-background", children: /* @__PURE__ */ jsx17("div", { className: "px-4 py-4 space-y-6", children }) })
792
+ ] });
793
+ }
794
+
795
+ // src/components/docs/api/api-params.tsx
796
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
797
+ function ApiParams({ title = "Parameters", params }) {
798
+ if (!params || params.length === 0) return null;
799
+ return /* @__PURE__ */ jsxs14("div", { className: "mb-6", children: [
800
+ /* @__PURE__ */ jsx18("h4", { className: "text-sm font-semibold text-foreground mb-3", children: title }),
801
+ /* @__PURE__ */ jsx18("div", { className: "space-y-3", children: params.map((param) => /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1", children: [
802
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
803
+ /* @__PURE__ */ jsx18("code", { className: "text-sm font-mono text-foreground", children: param.name }),
804
+ /* @__PURE__ */ jsx18("span", { className: "text-xs text-muted-foreground", children: param.type }),
805
+ param.required && /* @__PURE__ */ jsx18("span", { className: "text-xs text-red-600 dark:text-red-400", children: "required" }),
806
+ param.default && /* @__PURE__ */ jsxs14("span", { className: "text-xs text-muted-foreground", children: [
807
+ "default: ",
808
+ /* @__PURE__ */ jsx18("code", { className: "text-xs", children: param.default })
809
+ ] })
810
+ ] }),
811
+ param.description && /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: param.description })
812
+ ] }, param.name)) })
813
+ ] });
814
+ }
815
+
816
+ // src/components/docs/api/api-response.tsx
817
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
818
+ var statusColors = {
819
+ "2": "text-green-600 dark:text-green-400",
820
+ "3": "text-blue-600 dark:text-blue-400",
821
+ "4": "text-orange-600 dark:text-orange-400",
822
+ "5": "text-red-600 dark:text-red-400"
823
+ };
824
+ function ApiResponse({ status, description, example, schema }) {
825
+ const statusClass = statusColors[String(status)[0]] || "text-muted-foreground";
826
+ return /* @__PURE__ */ jsxs15("div", { className: "mb-4", children: [
827
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 mb-2", children: [
828
+ /* @__PURE__ */ jsx19("span", { className: `text-sm font-semibold ${statusClass}`, children: status }),
829
+ description && /* @__PURE__ */ jsx19("span", { className: "text-sm text-muted-foreground", children: description })
830
+ ] }),
831
+ example && /* @__PURE__ */ jsxs15("div", { className: "mb-3", children: [
832
+ /* @__PURE__ */ jsx19("p", { className: "text-xs font-semibold text-muted-foreground mb-2", children: "Example Response" }),
833
+ /* @__PURE__ */ jsx19(
834
+ CodeBlock,
835
+ {
836
+ code: typeof example === "string" ? example : JSON.stringify(example, null, 2),
837
+ language: "json"
838
+ }
839
+ )
840
+ ] }),
841
+ schema && /* @__PURE__ */ jsxs15("div", { children: [
842
+ /* @__PURE__ */ jsx19("p", { className: "text-xs font-semibold text-muted-foreground mb-2", children: "Schema" }),
843
+ /* @__PURE__ */ jsx19(
844
+ CodeBlock,
845
+ {
846
+ code: typeof schema === "string" ? schema : JSON.stringify(schema, null, 2),
847
+ language: "json"
848
+ }
849
+ )
850
+ ] })
851
+ ] });
852
+ }
853
+
854
+ // src/components/docs/api/api-playground.tsx
855
+ import { useState as useState8, useMemo } from "react";
856
+
857
+ // src/components/ui/button.tsx
858
+ import { Slot } from "@radix-ui/react-slot";
859
+ import { cva } from "class-variance-authority";
860
+ import { jsx as jsx20 } from "react/jsx-runtime";
861
+ var buttonVariants = cva(
862
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
863
+ {
864
+ variants: {
865
+ variant: {
866
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
867
+ destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
868
+ outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
869
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
870
+ ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
871
+ link: "text-primary underline-offset-4 hover:underline"
872
+ },
873
+ size: {
874
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
875
+ sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
876
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
877
+ icon: "size-9",
878
+ "icon-sm": "size-8",
879
+ "icon-lg": "size-10"
880
+ }
881
+ },
882
+ defaultVariants: {
883
+ variant: "default",
884
+ size: "default"
885
+ }
886
+ }
887
+ );
888
+ function Button({
889
+ className,
890
+ variant,
891
+ size,
892
+ asChild = false,
893
+ ...props
894
+ }) {
895
+ const Comp = asChild ? Slot : "button";
896
+ return /* @__PURE__ */ jsx20(
897
+ Comp,
898
+ {
899
+ "data-slot": "button",
900
+ className: cn(buttonVariants({ variant, size, className })),
901
+ ...props
902
+ }
903
+ );
904
+ }
905
+
906
+ // src/components/ui/input.tsx
907
+ import { jsx as jsx21 } from "react/jsx-runtime";
908
+ function Input({ className, type, ...props }) {
909
+ return /* @__PURE__ */ jsx21(
910
+ "input",
911
+ {
912
+ type,
913
+ "data-slot": "input",
914
+ className: cn(
915
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
916
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
917
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
918
+ className
919
+ ),
920
+ ...props
921
+ }
922
+ );
923
+ }
924
+
925
+ // src/components/ui/textarea.tsx
926
+ import { jsx as jsx22 } from "react/jsx-runtime";
927
+ function Textarea({ className, ...props }) {
928
+ return /* @__PURE__ */ jsx22(
929
+ "textarea",
930
+ {
931
+ "data-slot": "textarea",
932
+ className: cn(
933
+ "border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
934
+ className
935
+ ),
936
+ ...props
937
+ }
938
+ );
939
+ }
940
+
941
+ // src/components/ui/badge.tsx
942
+ import { Slot as Slot2 } from "@radix-ui/react-slot";
943
+ import { cva as cva2 } from "class-variance-authority";
944
+ import { jsx as jsx23 } from "react/jsx-runtime";
945
+ var badgeVariants = cva2(
946
+ "inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
947
+ {
948
+ variants: {
949
+ variant: {
950
+ default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
951
+ secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
952
+ destructive: "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
953
+ outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground"
954
+ }
955
+ },
956
+ defaultVariants: {
957
+ variant: "default"
958
+ }
959
+ }
960
+ );
961
+ function Badge2({
962
+ className,
963
+ variant,
964
+ asChild = false,
965
+ ...props
966
+ }) {
967
+ const Comp = asChild ? Slot2 : "span";
968
+ return /* @__PURE__ */ jsx23(
969
+ Comp,
970
+ {
971
+ "data-slot": "badge",
972
+ className: cn(badgeVariants({ variant }), className),
973
+ ...props
974
+ }
975
+ );
976
+ }
977
+
978
+ // src/components/docs/api/api-playground.tsx
979
+ import { Play, Loader2 } from "lucide-react";
980
+ import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
981
+ function ApiPlayground({
982
+ method,
983
+ path,
984
+ baseUrl = "",
985
+ headers = {},
986
+ defaultBody,
987
+ pathParams = []
988
+ }) {
989
+ const [loading, setLoading] = useState8(false);
990
+ const [response, setResponse] = useState8(null);
991
+ const [error, setError] = useState8(null);
992
+ const [requestBody, setRequestBody] = useState8(defaultBody || "");
993
+ const initialHeaders = useMemo(() => {
994
+ const cleanHeaders = {};
995
+ Object.entries(headers).forEach(([key, value]) => {
996
+ cleanHeaders[key] = value || "";
997
+ });
998
+ return cleanHeaders;
999
+ }, [headers]);
1000
+ const [requestHeaders, setRequestHeaders] = useState8(JSON.stringify(initialHeaders, null, 2));
1001
+ const extractedParams = useMemo(() => {
1002
+ const params = {};
1003
+ const pathParamPattern = /:(\w+)/g;
1004
+ let match;
1005
+ while ((match = pathParamPattern.exec(path)) !== null) {
1006
+ const paramName = match[1];
1007
+ const paramConfig = pathParams.find((p) => p.name === paramName);
1008
+ if (paramConfig?.example !== void 0) {
1009
+ params[paramName] = String(paramConfig.example);
1010
+ } else if (paramConfig?.type === "number") {
1011
+ params[paramName] = "1";
1012
+ } else {
1013
+ params[paramName] = "";
1014
+ }
1015
+ }
1016
+ return params;
1017
+ }, [path, pathParams]);
1018
+ const [pathParamValues, setPathParamValues] = useState8(extractedParams);
1019
+ const buildUrl = () => {
1020
+ let finalPath = path;
1021
+ Object.entries(pathParamValues).forEach(([key, value]) => {
1022
+ finalPath = finalPath.replace(`:${key}`, value);
1023
+ });
1024
+ return `${baseUrl}${finalPath}`;
1025
+ };
1026
+ const handleSend = async () => {
1027
+ setLoading(true);
1028
+ setError(null);
1029
+ setResponse(null);
1030
+ try {
1031
+ const url = buildUrl();
1032
+ const parsedHeaders = JSON.parse(requestHeaders);
1033
+ const options = {
1034
+ method,
1035
+ headers: {
1036
+ "Content-Type": "application/json",
1037
+ ...parsedHeaders
1038
+ }
1039
+ };
1040
+ if (method !== "GET" && method !== "DELETE" && requestBody) {
1041
+ options.body = requestBody;
1042
+ }
1043
+ const res = await fetch(url, options);
1044
+ const data = await res.json();
1045
+ setResponse({
1046
+ status: res.status,
1047
+ statusText: res.statusText,
1048
+ headers: Object.fromEntries(res.headers.entries()),
1049
+ body: data
1050
+ });
1051
+ } catch (err) {
1052
+ setError(err instanceof Error ? err.message : "An error occurred");
1053
+ } finally {
1054
+ setLoading(false);
1055
+ }
1056
+ };
1057
+ return /* @__PURE__ */ jsxs16("div", { className: "not-prose border border-border rounded-lg overflow-hidden bg-card/30", children: [
1058
+ /* @__PURE__ */ jsx24("div", { className: "bg-muted/50 px-4 py-2 border-b border-border", children: /* @__PURE__ */ jsx24("h4", { className: "text-sm font-semibold text-foreground", children: "API Playground" }) }),
1059
+ /* @__PURE__ */ jsxs16("div", { className: "p-4 space-y-4", children: [
1060
+ Object.keys(pathParamValues).length > 0 && /* @__PURE__ */ jsxs16("div", { children: [
1061
+ /* @__PURE__ */ jsx24("label", { className: "text-xs font-semibold text-muted-foreground mb-2 block", children: "Path Parameters" }),
1062
+ /* @__PURE__ */ jsx24("div", { className: "space-y-2", children: Object.entries(pathParamValues).map(([paramName, paramValue]) => {
1063
+ const paramConfig = pathParams.find((p) => p.name === paramName);
1064
+ return /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
1065
+ /* @__PURE__ */ jsxs16("span", { className: "text-xs text-muted-foreground min-w-[80px]", children: [
1066
+ ":",
1067
+ paramName
1068
+ ] }),
1069
+ /* @__PURE__ */ jsx24(
1070
+ Input,
1071
+ {
1072
+ value: paramValue,
1073
+ onChange: (e) => setPathParamValues((prev) => ({ ...prev, [paramName]: e.target.value })),
1074
+ placeholder: paramConfig?.example || paramConfig?.type || "value",
1075
+ className: "font-mono text-sm"
1076
+ }
1077
+ )
1078
+ ] }, paramName);
1079
+ }) })
1080
+ ] }),
1081
+ /* @__PURE__ */ jsxs16("div", { children: [
1082
+ /* @__PURE__ */ jsx24("label", { className: "text-xs font-semibold text-muted-foreground mb-2 block", children: "Request URL" }),
1083
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
1084
+ /* @__PURE__ */ jsx24(Badge2, { variant: "outline", className: "font-mono", children: method }),
1085
+ /* @__PURE__ */ jsx24(Input, { value: buildUrl(), readOnly: true, className: "font-mono text-sm" })
1086
+ ] })
1087
+ ] }),
1088
+ /* @__PURE__ */ jsxs16("div", { children: [
1089
+ /* @__PURE__ */ jsx24("label", { className: "text-xs font-semibold text-muted-foreground mb-2 block", children: "Headers (JSON)" }),
1090
+ /* @__PURE__ */ jsx24(
1091
+ Textarea,
1092
+ {
1093
+ value: requestHeaders,
1094
+ onChange: (e) => setRequestHeaders(e.target.value),
1095
+ className: "font-mono text-sm",
1096
+ rows: 4
1097
+ }
1098
+ )
1099
+ ] }),
1100
+ method !== "GET" && method !== "DELETE" && /* @__PURE__ */ jsxs16("div", { children: [
1101
+ /* @__PURE__ */ jsx24("label", { className: "text-xs font-semibold text-muted-foreground mb-2 block", children: "Request Body (JSON)" }),
1102
+ /* @__PURE__ */ jsx24(
1103
+ Textarea,
1104
+ {
1105
+ value: requestBody,
1106
+ onChange: (e) => setRequestBody(e.target.value),
1107
+ className: "font-mono text-sm",
1108
+ rows: 6,
1109
+ placeholder: '{\\n "key": "value"\\n}'
1110
+ }
1111
+ )
1112
+ ] }),
1113
+ /* @__PURE__ */ jsx24(Button, { onClick: handleSend, disabled: loading, className: "w-full", children: loading ? /* @__PURE__ */ jsxs16(Fragment4, { children: [
1114
+ /* @__PURE__ */ jsx24(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
1115
+ "Sending..."
1116
+ ] }) : /* @__PURE__ */ jsxs16(Fragment4, { children: [
1117
+ /* @__PURE__ */ jsx24(Play, { className: "mr-2 h-4 w-4" }),
1118
+ "Send Request"
1119
+ ] }) }),
1120
+ response && /* @__PURE__ */ jsxs16("div", { className: "mt-4", children: [
1121
+ /* @__PURE__ */ jsxs16("label", { className: "text-xs font-semibold text-muted-foreground mb-2 block", children: [
1122
+ "Response (",
1123
+ response.status,
1124
+ " ",
1125
+ response.statusText,
1126
+ ")"
1127
+ ] }),
1128
+ /* @__PURE__ */ jsx24(CodeBlock, { code: JSON.stringify(response.body, null, 2), language: "json" })
1129
+ ] }),
1130
+ error && /* @__PURE__ */ jsx24("div", { className: "mt-4 p-3 bg-red-500/10 border border-red-500/20 rounded-md", children: /* @__PURE__ */ jsx24("p", { className: "text-sm text-red-600 dark:text-red-400", children: error }) })
1131
+ ] })
1132
+ ] });
1133
+ }
1134
+
1135
+ // src/components/docs/api/api-reference.tsx
1136
+ import { useState as useState9, useEffect as useEffect3 } from "react";
1137
+ import { Loader2 as Loader22 } from "lucide-react";
1138
+ import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
1139
+ function ApiReference({ spec, parser = "auto", showPlayground = true }) {
1140
+ const [apiSpec, setApiSpec] = useState9(null);
1141
+ const [loading, setLoading] = useState9(true);
1142
+ const [error, setError] = useState9(null);
1143
+ useEffect3(() => {
1144
+ async function loadSpec() {
1145
+ try {
1146
+ const response = await fetch(spec);
1147
+ if (!response.ok) {
1148
+ throw new Error(`Failed to load API spec: ${response.statusText}`);
1149
+ }
1150
+ const data = await response.json();
1151
+ const parsedSpec = parseApiSpec(data, parser);
1152
+ setApiSpec(parsedSpec);
1153
+ } catch (err) {
1154
+ setError(err instanceof Error ? err.message : "Failed to load API spec");
1155
+ } finally {
1156
+ setLoading(false);
1157
+ }
1158
+ }
1159
+ loadSpec();
1160
+ }, [spec, parser]);
1161
+ const interpolateEnv = (text, env) => {
1162
+ if (!env) return text;
1163
+ return text.replace(/\{(\w+)\}/g, (match, key) => {
1164
+ return env[key] || match;
1165
+ });
1166
+ };
1167
+ if (loading) {
1168
+ return /* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-center py-12", children: [
1169
+ /* @__PURE__ */ jsx25(Loader22, { className: "h-6 w-6 animate-spin text-muted-foreground" }),
1170
+ /* @__PURE__ */ jsx25("span", { className: "ml-2 text-muted-foreground", children: "Loading API specification..." })
1171
+ ] });
1172
+ }
1173
+ if (error) {
1174
+ return /* @__PURE__ */ jsx25("div", { className: "rounded-lg border border-red-500/20 bg-red-500/10 p-4", children: /* @__PURE__ */ jsxs17("p", { className: "text-sm text-red-600 dark:text-red-400", children: [
1175
+ "Error: ",
1176
+ error
1177
+ ] }) });
1178
+ }
1179
+ if (!apiSpec) {
1180
+ return null;
1181
+ }
1182
+ return /* @__PURE__ */ jsxs17("div", { className: "space-y-6", children: [
1183
+ (apiSpec.title || apiSpec.description) && /* @__PURE__ */ jsxs17("div", { className: "mb-8", children: [
1184
+ apiSpec.title && /* @__PURE__ */ jsx25("h2", { className: "text-2xl font-semibold mb-2 text-foreground", children: apiSpec.title }),
1185
+ apiSpec.description && /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: apiSpec.description }),
1186
+ apiSpec.baseUrl && /* @__PURE__ */ jsxs17("div", { className: "mt-4", children: [
1187
+ /* @__PURE__ */ jsx25("p", { className: "text-sm font-semibold text-muted-foreground mb-1", children: "Base URL" }),
1188
+ /* @__PURE__ */ jsx25("code", { className: "text-sm px-2 py-1 bg-muted rounded", children: apiSpec.baseUrl })
1189
+ ] })
1190
+ ] }),
1191
+ apiSpec.auth && /* @__PURE__ */ jsxs17("div", { className: "rounded-lg border border-border bg-card/30 p-4 mb-6", children: [
1192
+ /* @__PURE__ */ jsx25("h3", { className: "text-lg font-semibold mb-2 text-foreground", children: "Authentication" }),
1193
+ /* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground mb-2", children: apiSpec.auth.description || `This API uses ${apiSpec.auth.type} authentication.` }),
1194
+ apiSpec.auth.type === "bearer" && /* @__PURE__ */ jsx25(
1195
+ CodeBlock,
1196
+ {
1197
+ code: `Authorization: ${apiSpec.auth.tokenPrefix || "Bearer"} {YOUR_TOKEN}`,
1198
+ language: "bash"
1199
+ }
1200
+ ),
1201
+ apiSpec.auth.type === "apiKey" && /* @__PURE__ */ jsx25(
1202
+ CodeBlock,
1203
+ {
1204
+ code: `${apiSpec.auth.headerName || "X-API-Key"}: {YOUR_API_KEY}`,
1205
+ language: "bash"
1206
+ }
1207
+ )
1208
+ ] }),
1209
+ /* @__PURE__ */ jsx25(Accordion, { type: "single", collapsible: true, className: "space-y-4", children: apiSpec.endpoints.map((endpoint, index) => {
1210
+ const allHeaders = [
1211
+ ...apiSpec.globalHeaders || [],
1212
+ ...endpoint.headers || []
1213
+ ].map((header) => ({
1214
+ ...header,
1215
+ value: interpolateEnv(header.value, apiSpec.env)
1216
+ }));
1217
+ return /* @__PURE__ */ jsx25(
1218
+ AccordionItem,
1219
+ {
1220
+ value: `endpoint-${index}`,
1221
+ title: /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-3", children: [
1222
+ /* @__PURE__ */ jsx25(
1223
+ "span",
1224
+ {
1225
+ className: `text-xs font-semibold px-2 py-0.5 rounded ${endpoint.method === "GET" ? "bg-blue-500/10 text-blue-600 dark:text-blue-400" : endpoint.method === "POST" ? "bg-green-500/10 text-green-600 dark:text-green-400" : endpoint.method === "PUT" ? "bg-orange-500/10 text-orange-600 dark:text-orange-400" : endpoint.method === "PATCH" ? "bg-purple-500/10 text-purple-600 dark:text-purple-400" : "bg-red-500/10 text-red-600 dark:text-red-400"}`,
1226
+ children: endpoint.method
1227
+ }
1228
+ ),
1229
+ /* @__PURE__ */ jsx25("code", { className: "text-sm font-mono", children: endpoint.path }),
1230
+ /* @__PURE__ */ jsx25("span", { className: "text-sm text-muted-foreground ml-auto", children: endpoint.title })
1231
+ ] }),
1232
+ children: /* @__PURE__ */ jsxs17("div", { className: "space-y-6 pt-4", children: [
1233
+ endpoint.description && /* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground", children: endpoint.description }),
1234
+ endpoint.pathParams && endpoint.pathParams.length > 0 && /* @__PURE__ */ jsx25(ApiParams, { title: "Path Parameters", params: endpoint.pathParams }),
1235
+ endpoint.queryParams && endpoint.queryParams.length > 0 && /* @__PURE__ */ jsx25(ApiParams, { title: "Query Parameters", params: endpoint.queryParams }),
1236
+ allHeaders.length > 0 && /* @__PURE__ */ jsxs17("div", { children: [
1237
+ /* @__PURE__ */ jsx25("h4", { className: "text-sm font-semibold text-foreground mb-3", children: "Headers" }),
1238
+ /* @__PURE__ */ jsx25("div", { className: "space-y-2", children: allHeaders.map((header, idx) => /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1", children: [
1239
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
1240
+ /* @__PURE__ */ jsx25("code", { className: "text-sm font-mono text-foreground", children: header.name }),
1241
+ /* @__PURE__ */ jsx25("span", { className: "text-xs text-muted-foreground", children: header.value })
1242
+ ] }),
1243
+ header.description && /* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground", children: header.description })
1244
+ ] }, idx)) })
1245
+ ] }),
1246
+ endpoint.body && /* @__PURE__ */ jsxs17("div", { children: [
1247
+ /* @__PURE__ */ jsx25("h4", { className: "text-sm font-semibold text-foreground mb-3", children: "Request Body" }),
1248
+ endpoint.body.description && /* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground mb-2", children: endpoint.body.description }),
1249
+ endpoint.body.example && /* @__PURE__ */ jsx25(
1250
+ CodeBlock,
1251
+ {
1252
+ code: typeof endpoint.body.example === "string" ? endpoint.body.example : JSON.stringify(endpoint.body.example, null, 2),
1253
+ language: "json"
1254
+ }
1255
+ )
1256
+ ] }),
1257
+ /* @__PURE__ */ jsxs17("div", { children: [
1258
+ /* @__PURE__ */ jsx25("h4", { className: "text-sm font-semibold text-foreground mb-3", children: "Responses" }),
1259
+ endpoint.successResponse && /* @__PURE__ */ jsx25(
1260
+ ApiResponse,
1261
+ {
1262
+ status: endpoint.successResponse.status,
1263
+ description: endpoint.successResponse.description,
1264
+ example: endpoint.successResponse.example,
1265
+ schema: endpoint.successResponse.schema
1266
+ }
1267
+ ),
1268
+ endpoint.errorResponses?.map((response, idx) => /* @__PURE__ */ jsx25(
1269
+ ApiResponse,
1270
+ {
1271
+ status: response.status,
1272
+ description: response.description,
1273
+ example: response.example,
1274
+ schema: response.schema
1275
+ },
1276
+ idx
1277
+ ))
1278
+ ] }),
1279
+ endpoint.examples && endpoint.examples.length > 0 && /* @__PURE__ */ jsxs17("div", { children: [
1280
+ /* @__PURE__ */ jsx25("h4", { className: "text-sm font-semibold text-foreground mb-3", children: "Examples" }),
1281
+ endpoint.examples.map((example, idx) => /* @__PURE__ */ jsxs17("div", { className: "mb-3", children: [
1282
+ /* @__PURE__ */ jsx25("p", { className: "text-xs font-semibold text-muted-foreground mb-2", children: example.title }),
1283
+ /* @__PURE__ */ jsx25(CodeBlock, { code: example.code, language: example.language })
1284
+ ] }, idx))
1285
+ ] }),
1286
+ showPlayground && /* @__PURE__ */ jsx25(
1287
+ ApiPlayground,
1288
+ {
1289
+ method: endpoint.method,
1290
+ path: endpoint.path,
1291
+ baseUrl: apiSpec.baseUrl,
1292
+ headers: Object.fromEntries(allHeaders.map((h) => [h.name, h.value])),
1293
+ pathParams: endpoint.pathParams,
1294
+ defaultBody: endpoint.body?.example ? typeof endpoint.body.example === "string" ? endpoint.body.example : JSON.stringify(endpoint.body.example, null, 2) : void 0
1295
+ }
1296
+ )
1297
+ ] })
1298
+ },
1299
+ index
1300
+ );
1301
+ }) })
1302
+ ] });
1303
+ }
1304
+
1305
+ // src/components/docs/mdx-components.tsx
1306
+ import { Fragment as Fragment5, jsx as jsx26 } from "react/jsx-runtime";
1307
+ var mdxComponents = {
1308
+ h1: ({ children }) => /* @__PURE__ */ jsx26("h1", { className: "text-3xl font-semibold tracking-tight mb-6 text-foreground", children }),
1309
+ h2: ({ children, id }) => /* @__PURE__ */ jsx26("h2", { id, className: "text-2xl font-semibold tracking-tight mt-10 mb-4 text-foreground scroll-mt-24", children }),
1310
+ h3: ({ children, id }) => /* @__PURE__ */ jsx26("h3", { id, className: "text-xl font-medium tracking-tight mt-8 mb-3 text-foreground scroll-mt-24", children }),
1311
+ p: ({ children }) => /* @__PURE__ */ jsx26("p", { className: "text-base leading-7 text-muted-foreground mb-4", children }),
1312
+ code: ({ children, className, meta, ...props }) => {
1313
+ const isInline = !className;
1314
+ if (isInline) {
1315
+ return /* @__PURE__ */ jsx26("code", { className: "px-1.5 py-0.5 rounded-md bg-muted/50 text-primary font-mono text-[13px] border border-border/50", children });
1316
+ }
1317
+ const language = className?.replace("language-", "") || "text";
1318
+ const filename = meta || void 0;
1319
+ const code = String(children).replace(/\n$/, "");
1320
+ return /* @__PURE__ */ jsx26(CodeBlock, { code, language, filename });
1321
+ },
1322
+ pre: ({ children }) => /* @__PURE__ */ jsx26(Fragment5, { children }),
1323
+ ul: ({ children }) => /* @__PURE__ */ jsx26("ul", { className: "list-disc list-outside pl-5 space-y-2 mb-4 text-muted-foreground [&_p]:mb-0 [&_p]:inline [&_ul]:ml-6 [&_ol]:ml-6", children }),
1324
+ ol: ({ children }) => /* @__PURE__ */ jsx26("ol", { className: "list-decimal list-outside pl-5 space-y-2 mb-4 text-muted-foreground [&_p]:mb-0 [&_p]:inline [&_ul]:ml-6 [&_ol]:ml-6", children }),
1325
+ li: ({ children }) => /* @__PURE__ */ jsx26("li", { className: "leading-7 [&>p]:mb-0 [&>p]:inline", children }),
1326
+ a: ({ children, href }) => /* @__PURE__ */ jsx26(
1327
+ "a",
1328
+ {
1329
+ href,
1330
+ className: "text-primary hover:underline font-medium",
1331
+ target: href?.startsWith("http") ? "_blank" : void 0,
1332
+ rel: href?.startsWith("http") ? "noopener noreferrer" : void 0,
1333
+ children
1334
+ }
1335
+ ),
1336
+ blockquote: ({ children }) => {
1337
+ const childrenArray = Array.isArray(children) ? children : [children];
1338
+ const firstChild = childrenArray[0];
1339
+ let textContent = "";
1340
+ if (firstChild && typeof firstChild === "object" && "props" in firstChild) {
1341
+ const props = firstChild.props;
1342
+ if (props.children) {
1343
+ const text = Array.isArray(props.children) ? props.children.join("") : String(props.children);
1344
+ textContent = text;
1345
+ }
1346
+ }
1347
+ const alertMatch = textContent.match(/^\[!(INFO|TIP|WARNING|SUCCESS|ERROR)\]/);
1348
+ if (alertMatch) {
1349
+ const type = alertMatch[1].toLowerCase();
1350
+ const processChildren = (node) => {
1351
+ if (typeof node === "string") {
1352
+ return node.replace(/^\[!(INFO|TIP|WARNING|SUCCESS|ERROR)\]\s*\n?/, "");
1353
+ }
1354
+ if (node && typeof node === "object" && "props" in node) {
1355
+ return {
1356
+ ...node,
1357
+ props: {
1358
+ ...node.props,
1359
+ children: Array.isArray(node.props.children) ? node.props.children.map(processChildren) : processChildren(node.props.children)
1360
+ }
1361
+ };
1362
+ }
1363
+ return node;
1364
+ };
1365
+ const cleanedChildren = Array.isArray(children) ? children.map(processChildren) : processChildren(children);
1366
+ return /* @__PURE__ */ jsx26(Callout, { type, children: cleanedChildren });
1367
+ }
1368
+ return /* @__PURE__ */ jsx26("blockquote", { className: "border-l-4 border-primary/50 bg-muted/30 pl-4 pr-4 py-3 my-6 rounded-r-lg", children: /* @__PURE__ */ jsx26("div", { className: "text-muted-foreground italic [&>p]:mb-0", children }) });
1369
+ },
1370
+ table: ({ children }) => /* @__PURE__ */ jsx26("div", { className: "overflow-x-auto mb-6 rounded-xl border border-border", children: /* @__PURE__ */ jsx26("table", { className: "min-w-full border-collapse", children }) }),
1371
+ th: ({ children }) => /* @__PURE__ */ jsx26("th", { className: "border-b border-r border-border bg-muted px-4 py-2 text-left font-semibold text-foreground last:border-r-0", children }),
1372
+ td: ({ children }) => /* @__PURE__ */ jsx26("td", { className: "border-b border-r border-border px-4 py-2 text-muted-foreground last:border-r-0", children }),
1373
+ // Custom components
1374
+ Callout,
1375
+ Accordion,
1376
+ AccordionItem,
1377
+ Tabs,
1378
+ Tab,
1379
+ Image,
1380
+ Video,
1381
+ Card,
1382
+ CardGrid,
1383
+ ImageCard,
1384
+ ImageCardGrid,
1385
+ Steps,
1386
+ Step,
1387
+ Icon,
1388
+ Mermaid,
1389
+ Math: Math2,
1390
+ Columns,
1391
+ Column,
1392
+ Badge,
1393
+ Tooltip,
1394
+ Frame,
1395
+ // API Documentation components
1396
+ ApiEndpoint,
1397
+ ApiParams,
1398
+ ApiResponse,
1399
+ ApiPlayground,
1400
+ ApiReference
1401
+ };
1402
+
1403
+ // src/components/docs/doc-navigation.tsx
1404
+ import Link3 from "next/link";
1405
+ import { ChevronLeft, ChevronRight } from "lucide-react";
1406
+ import { jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
1407
+ function DocNavigation({ previousDoc, nextDoc, version }) {
1408
+ if (!previousDoc && !nextDoc) return null;
1409
+ return /* @__PURE__ */ jsxs18("div", { className: "mt-12 pt-8 border-t border-border grid grid-cols-2 gap-4", children: [
1410
+ previousDoc ? /* @__PURE__ */ jsxs18(
1411
+ Link3,
1412
+ {
1413
+ href: `/docs/${version}/${previousDoc.slug}`,
1414
+ className: "group flex flex-col gap-2 p-4 rounded-xl border border-border hover:border-primary/50 hover:bg-muted/50 transition-all",
1415
+ style: {
1416
+ textDecoration: "none !important"
1417
+ },
1418
+ children: [
1419
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
1420
+ /* @__PURE__ */ jsx27(ChevronLeft, { className: "h-4 w-4" }),
1421
+ /* @__PURE__ */ jsx27("span", { children: "Previous" })
1422
+ ] }),
1423
+ /* @__PURE__ */ jsx27("div", { className: "text-base font-medium text-foreground group-hover:text-primary transition-colors", children: previousDoc.title })
1424
+ ]
1425
+ }
1426
+ ) : /* @__PURE__ */ jsx27("div", {}),
1427
+ nextDoc ? /* @__PURE__ */ jsxs18(
1428
+ Link3,
1429
+ {
1430
+ href: `/docs/${version}/${nextDoc.slug}`,
1431
+ className: "group flex flex-col gap-2 p-4 rounded-xl border border-border hover:border-primary/50 hover:bg-muted/50 transition-all text-right",
1432
+ style: {
1433
+ textDecoration: "none !important"
1434
+ },
1435
+ children: [
1436
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-end gap-2 text-sm text-muted-foreground", children: [
1437
+ /* @__PURE__ */ jsx27("span", { children: "Next" }),
1438
+ /* @__PURE__ */ jsx27(ChevronRight, { className: "h-4 w-4" })
1439
+ ] }),
1440
+ /* @__PURE__ */ jsx27("div", { className: "text-base font-medium text-foreground group-hover:text-primary transition-colors", children: nextDoc.title })
1441
+ ]
1442
+ }
1443
+ ) : /* @__PURE__ */ jsx27("div", {})
1444
+ ] });
1445
+ }
1446
+
1447
+ // src/components/docs/breadcrumb.tsx
1448
+ import Link4 from "next/link";
1449
+ import { ChevronRight as ChevronRight2 } from "lucide-react";
1450
+ import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
1451
+ function Breadcrumb({ version, slug, title }) {
1452
+ const parts = slug.split("/");
1453
+ const breadcrumbs = [
1454
+ { label: "Docs", href: `/docs/${version}` }
1455
+ ];
1456
+ let currentPath = "";
1457
+ for (let i = 0; i < parts.length - 1; i++) {
1458
+ currentPath += (currentPath ? "/" : "") + parts[i];
1459
+ breadcrumbs.push({
1460
+ label: parts[i].replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()),
1461
+ href: `/docs/${version}/${currentPath}`
1462
+ });
1463
+ }
1464
+ breadcrumbs.push({
1465
+ label: title,
1466
+ href: `/docs/${version}/${slug}`
1467
+ });
1468
+ return /* @__PURE__ */ jsx28("nav", { className: "flex items-center gap-2 text-sm text-muted-foreground mb-4", "aria-label": "Breadcrumb", children: breadcrumbs.map((crumb, index) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
1469
+ index > 0 && /* @__PURE__ */ jsx28(ChevronRight2, { className: "h-4 w-4" }),
1470
+ index === breadcrumbs.length - 1 ? /* @__PURE__ */ jsx28("span", { className: "text-foreground font-medium", children: crumb.label }) : /* @__PURE__ */ jsx28(
1471
+ Link4,
1472
+ {
1473
+ href: crumb.href,
1474
+ className: "hover:text-foreground transition-colors",
1475
+ children: crumb.label
1476
+ }
1477
+ )
1478
+ ] }, crumb.href)) });
1479
+ }
1480
+
1481
+ // src/components/docs/doc-metadata.tsx
1482
+ import { Clock, Calendar, User } from "lucide-react";
1483
+ import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
1484
+ function DocMetadata({ meta, config }) {
1485
+ const showReadingTime = config.features?.showReadingTime && meta.reading_time;
1486
+ const showLastUpdated = config.features?.showLastUpdated && meta.last_updated;
1487
+ const showAuthors = config.features?.showAuthors && meta.authors?.length;
1488
+ const hasMetadata = showReadingTime || showLastUpdated || showAuthors;
1489
+ if (!hasMetadata) {
1490
+ return null;
1491
+ }
1492
+ return /* @__PURE__ */ jsxs20("div", { className: "flex flex-wrap items-center gap-4 text-sm text-muted-foreground border-b border-border pb-4 mb-6", children: [
1493
+ showReadingTime && /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-1.5", children: [
1494
+ /* @__PURE__ */ jsx29(Clock, { className: "h-4 w-4" }),
1495
+ /* @__PURE__ */ jsxs20("span", { children: [
1496
+ meta.reading_time,
1497
+ " min read"
1498
+ ] })
1499
+ ] }),
1500
+ showLastUpdated && meta.last_updated && /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-1.5", children: [
1501
+ /* @__PURE__ */ jsx29(Calendar, { className: "h-4 w-4" }),
1502
+ /* @__PURE__ */ jsxs20("span", { children: [
1503
+ "Updated ",
1504
+ new Date(meta.last_updated).toLocaleDateString()
1505
+ ] })
1506
+ ] }),
1507
+ showAuthors && /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-1.5", children: [
1508
+ /* @__PURE__ */ jsx29(User, { className: "h-4 w-4" }),
1509
+ /* @__PURE__ */ jsx29("span", { children: meta.authors.map((author, idx) => /* @__PURE__ */ jsxs20("span", { children: [
1510
+ author.name || author.id,
1511
+ idx < meta.authors.length - 1 && ", "
1512
+ ] }, author.id)) })
1513
+ ] })
1514
+ ] });
1515
+ }
1516
+
1517
+ // src/components/docs/draft-badge.tsx
1518
+ import { FileWarning } from "lucide-react";
1519
+ import { jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
1520
+ function DraftBadge() {
1521
+ return /* @__PURE__ */ jsxs21("div", { className: "inline-flex items-center gap-2 px-3 py-1.5 rounded-md bg-yellow-500/10 border border-yellow-500/20 text-yellow-600 dark:text-yellow-400 text-sm font-medium mb-4", children: [
1522
+ /* @__PURE__ */ jsx30(FileWarning, { className: "h-4 w-4" }),
1523
+ /* @__PURE__ */ jsx30("span", { children: "Draft - Not visible in production" })
1524
+ ] });
1525
+ }
1526
+
1527
+ // src/components/docs/doc-tags.tsx
1528
+ import { Tag } from "lucide-react";
1529
+ import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
1530
+ function DocTags({ tags }) {
1531
+ if (!tags || tags.length === 0) {
1532
+ return null;
1533
+ }
1534
+ return /* @__PURE__ */ jsxs22("div", { className: "flex flex-wrap items-center gap-2 mt-6 pt-6 border-t border-border", children: [
1535
+ /* @__PURE__ */ jsx31(Tag, { className: "h-4 w-4 text-muted-foreground" }),
1536
+ tags.map((tag) => /* @__PURE__ */ jsx31(
1537
+ "span",
1538
+ {
1539
+ className: "inline-flex items-center px-2.5 py-0.5 rounded-md text-xs font-medium bg-primary/10 text-primary border border-primary/20",
1540
+ children: tag
1541
+ },
1542
+ tag
1543
+ ))
1544
+ ] });
1545
+ }
1546
+
1547
+ // src/components/docs/search-highlight.tsx
1548
+ import { useEffect as useEffect4 } from "react";
1549
+ import { useSearchParams } from "next/navigation";
1550
+ function SearchHighlight() {
1551
+ const searchParams = useSearchParams();
1552
+ const query = searchParams.get("q");
1553
+ useEffect4(() => {
1554
+ if (!query) {
1555
+ document.querySelectorAll("mark.search-highlight").forEach((mark) => {
1556
+ const parent = mark.parentNode;
1557
+ if (parent) {
1558
+ parent.replaceChild(document.createTextNode(mark.textContent || ""), mark);
1559
+ parent.normalize();
1560
+ }
1561
+ });
1562
+ return;
1563
+ }
1564
+ const timeout = setTimeout(() => {
1565
+ highlightSearchTerm(query);
1566
+ }, 100);
1567
+ return () => {
1568
+ clearTimeout(timeout);
1569
+ document.querySelectorAll("mark.search-highlight").forEach((mark) => {
1570
+ const parent = mark.parentNode;
1571
+ if (parent) {
1572
+ parent.replaceChild(document.createTextNode(mark.textContent || ""), mark);
1573
+ parent.normalize();
1574
+ }
1575
+ });
1576
+ };
1577
+ }, [query]);
1578
+ return null;
1579
+ }
1580
+ function highlightSearchTerm(searchTerm) {
1581
+ document.querySelectorAll("mark.search-highlight").forEach((mark) => {
1582
+ const parent = mark.parentNode;
1583
+ if (parent) {
1584
+ parent.replaceChild(document.createTextNode(mark.textContent || ""), mark);
1585
+ parent.normalize();
1586
+ }
1587
+ });
1588
+ const contentArea = document.querySelector("main") || document.body;
1589
+ const walker = document.createTreeWalker(
1590
+ contentArea,
1591
+ NodeFilter.SHOW_TEXT,
1592
+ {
1593
+ acceptNode: (node) => {
1594
+ const parent = node.parentElement;
1595
+ if (!parent) return NodeFilter.FILTER_REJECT;
1596
+ const tagName = parent.tagName.toLowerCase();
1597
+ if (["mark", "script", "style", "code", "pre"].includes(tagName)) {
1598
+ return NodeFilter.FILTER_REJECT;
1599
+ }
1600
+ if (node.textContent && node.textContent.toLowerCase().includes(searchTerm.toLowerCase())) {
1601
+ return NodeFilter.FILTER_ACCEPT;
1602
+ }
1603
+ return NodeFilter.FILTER_REJECT;
1604
+ }
1605
+ }
1606
+ );
1607
+ const nodesToHighlight = [];
1608
+ let currentNode;
1609
+ while (currentNode = walker.nextNode()) {
1610
+ if (currentNode.textContent) {
1611
+ nodesToHighlight.push({
1612
+ node: currentNode,
1613
+ text: currentNode.textContent
1614
+ });
1615
+ }
1616
+ }
1617
+ nodesToHighlight.forEach(({ node, text }) => {
1618
+ const regex = new RegExp(`(${escapeRegex(searchTerm)})`, "gi");
1619
+ const parts = text.split(regex);
1620
+ if (parts.length > 1) {
1621
+ const fragment = document.createDocumentFragment();
1622
+ parts.forEach((part) => {
1623
+ if (part.toLowerCase() === searchTerm.toLowerCase()) {
1624
+ const mark = document.createElement("mark");
1625
+ mark.className = "search-highlight bg-yellow-200 dark:bg-yellow-900/50 text-foreground px-1 rounded";
1626
+ mark.textContent = part;
1627
+ fragment.appendChild(mark);
1628
+ } else if (part) {
1629
+ fragment.appendChild(document.createTextNode(part));
1630
+ }
1631
+ });
1632
+ node.parentNode?.replaceChild(fragment, node);
1633
+ }
1634
+ });
1635
+ const firstHighlight = document.querySelector("mark.search-highlight");
1636
+ if (firstHighlight) {
1637
+ setTimeout(() => {
1638
+ firstHighlight.scrollIntoView({ behavior: "smooth", block: "center" });
1639
+ }, 200);
1640
+ }
1641
+ }
1642
+ function escapeRegex(string) {
1643
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1644
+ }
1645
+
1646
+ // src/components/docs/doc-layout.tsx
1647
+ import { jsx as jsx32, jsxs as jsxs23 } from "react/jsx-runtime";
1648
+ async function DocLayout({ content, meta, previousDoc, nextDoc, version, slug, config }) {
1649
+ const isDevelopment = process.env.NODE_ENV === "development";
1650
+ const processedContent = processContentWithEnv(content, config);
1651
+ const editUrl = config.features?.editUrl && typeof config.features.editUrl === "string" ? `${config.features.editUrl}/${version}/${slug}.mdx` : null;
1652
+ return /* @__PURE__ */ jsxs23("article", { className: "flex-1 min-w-0", children: [
1653
+ /* @__PURE__ */ jsx32(SearchHighlight, {}),
1654
+ config.navigation?.showBreadcrumbs && /* @__PURE__ */ jsx32(Breadcrumb, { version, slug, title: meta.title }),
1655
+ isDevelopment && meta.draft && /* @__PURE__ */ jsx32(DraftBadge, {}),
1656
+ /* @__PURE__ */ jsxs23("div", { className: "mb-8", children: [
1657
+ /* @__PURE__ */ jsx32("h1", { className: "text-4xl font-bold tracking-tight mb-3 text-foreground", children: meta.title }),
1658
+ meta.description && /* @__PURE__ */ jsx32("p", { className: "text-lg text-muted-foreground leading-relaxed", children: meta.description })
1659
+ ] }),
1660
+ /* @__PURE__ */ jsx32(DocMetadata, { meta, config }),
1661
+ /* @__PURE__ */ jsx32("div", { className: "prose prose-slate dark:prose-invert max-w-none prose-headings:scroll-mt-24 prose-headings:font-semibold prose-h1:text-4xl prose-h2:text-3xl prose-h2:mt-12 prose-h2:mb-4 prose-h3:text-2xl prose-h3:mt-8 prose-h3:mb-3 prose-p:text-base prose-p:leading-7 prose-p:text-muted-foreground prose-p:mb-4 prose-a:font-normal prose-a:transition-all prose-code:text-primary prose-code:bg-muted/50 prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded-md prose-code:text-[13px] prose-code:font-mono prose-code:border prose-code:border-border/50 prose-code:before:content-none prose-code:after:content-none prose-pre:bg-transparent prose-pre:p-0 prose-ul:list-disc prose-ul:list-inside prose-ul:space-y-2 prose-ul:mb-4 prose-ol:list-decimal prose-ol:list-inside prose-ol:space-y-2 prose-ol:mb-4 prose-li:leading-7 prose-li:text-muted-foreground prose-strong:text-foreground prose-strong:font-semibold", children: /* @__PURE__ */ jsx32(
1662
+ MDXRemote,
1663
+ {
1664
+ source: processedContent,
1665
+ options: {
1666
+ parseFrontmatter: false,
1667
+ mdxOptions: {
1668
+ remarkPlugins: [remarkGfm, remarkCodeMeta],
1669
+ rehypePlugins: [rehypeSlug],
1670
+ development: false
1671
+ }
1672
+ },
1673
+ components: mdxComponents
1674
+ }
1675
+ ) }),
1676
+ config.features?.showTags && meta.tags && meta.tags.length > 0 && /* @__PURE__ */ jsx32(DocTags, { tags: meta.tags }),
1677
+ (editUrl || config.social?.github) && /* @__PURE__ */ jsxs23("div", { className: "mt-12 pt-6 border-t border-border flex items-center justify-between", children: [
1678
+ editUrl ? /* @__PURE__ */ jsxs23(
1679
+ "a",
1680
+ {
1681
+ href: editUrl,
1682
+ target: "_blank",
1683
+ rel: "noopener noreferrer",
1684
+ className: "flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors",
1685
+ children: [
1686
+ /* @__PURE__ */ jsx32(FileEdit, { className: "h-4 w-4" }),
1687
+ "Edit this page"
1688
+ ]
1689
+ }
1690
+ ) : /* @__PURE__ */ jsx32("div", {}),
1691
+ config.social?.github && /* @__PURE__ */ jsxs23(
1692
+ "a",
1693
+ {
1694
+ href: `${config.social.github}/issues/new`,
1695
+ target: "_blank",
1696
+ rel: "noopener noreferrer",
1697
+ className: "flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors",
1698
+ children: [
1699
+ /* @__PURE__ */ jsx32(ExternalLink2, { className: "h-4 w-4" }),
1700
+ "Report an issue"
1701
+ ]
1702
+ }
1703
+ )
1704
+ ] }),
1705
+ /* @__PURE__ */ jsx32(DocNavigation, { previousDoc, nextDoc, version })
1706
+ ] });
1707
+ }
1708
+
1709
+ // src/components/docs/table-of-contents.tsx
1710
+ import { useEffect as useEffect5, useState as useState10 } from "react";
1711
+ import { jsx as jsx33, jsxs as jsxs24 } from "react/jsx-runtime";
1712
+ function TableOfContents({ items, config }) {
1713
+ const [activeId, setActiveId] = useState10("");
1714
+ if (!config.navigation?.showTableOfContents) {
1715
+ return null;
1716
+ }
1717
+ const maxDepth = config.navigation?.tocMaxDepth || 3;
1718
+ const filteredItems = items.filter((item) => item.level <= maxDepth);
1719
+ const hasTabGroups = config.navigation?.tabGroups && config.navigation.tabGroups.length > 0;
1720
+ useEffect5(() => {
1721
+ const observer = new IntersectionObserver(
1722
+ (entries) => {
1723
+ entries.forEach((entry) => {
1724
+ if (entry.isIntersecting) {
1725
+ setActiveId(entry.target.id);
1726
+ }
1727
+ });
1728
+ },
1729
+ { rootMargin: "-80px 0px -80% 0px" }
1730
+ );
1731
+ filteredItems.forEach((item) => {
1732
+ const element = document.getElementById(item.id);
1733
+ if (element) {
1734
+ observer.observe(element);
1735
+ }
1736
+ });
1737
+ return () => observer.disconnect();
1738
+ }, [filteredItems]);
1739
+ const handleClick = (e, id) => {
1740
+ e.preventDefault();
1741
+ const element = document.getElementById(id);
1742
+ if (element) {
1743
+ const offset = 100;
1744
+ const elementPosition = element.getBoundingClientRect().top;
1745
+ const offsetPosition = elementPosition + window.scrollY - offset;
1746
+ window.scrollTo({
1747
+ top: offsetPosition,
1748
+ behavior: "smooth"
1749
+ });
1750
+ window.history.replaceState(null, "", `#${id}`);
1751
+ setActiveId(id);
1752
+ }
1753
+ };
1754
+ const stickyTop = hasTabGroups ? "top-[7.5rem]" : "top-24";
1755
+ const maxHeight = hasTabGroups ? "max-h-[calc(100vh-10rem)]" : "max-h-[calc(100vh-7rem)]";
1756
+ return /* @__PURE__ */ jsx33("aside", { className: `w-64 hidden xl:block shrink-0 sticky ${stickyTop} self-start`, children: filteredItems.length > 0 && /* @__PURE__ */ jsxs24("div", { className: `${maxHeight} overflow-y-auto bg-muted/30 dark:bg-muted/10 rounded-2xl p-4 border border-border/50`, children: [
1757
+ /* @__PURE__ */ jsx33("h3", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-4 px-2", children: "On this page" }),
1758
+ /* @__PURE__ */ jsx33("nav", { className: "space-y-1", children: filteredItems.map((item) => /* @__PURE__ */ jsx33(
1759
+ "a",
1760
+ {
1761
+ href: `#${item.id}`,
1762
+ onClick: (e) => handleClick(e, item.id),
1763
+ className: `block text-sm transition-all cursor-pointer rounded-xl px-3 py-2 ${item.level === 3 ? "ml-3" : ""} ${activeId === item.id ? "text-primary font-medium" : "text-foreground hover:bg-accent/50"}`,
1764
+ children: item.title
1765
+ },
1766
+ item.id
1767
+ )) })
1768
+ ] }) });
1769
+ }
1770
+
1771
+ // src/components/docs/header.tsx
1772
+ import Link5 from "next/link";
1773
+ import { Search as Search2, Menu, Github, Twitter, MessageCircle } from "lucide-react";
1774
+
1775
+ // src/components/docs/version-switcher.tsx
1776
+ import { useState as useState11 } from "react";
1777
+ import { Check as Check2, ChevronDown as ChevronDown3 } from "lucide-react";
1778
+ import { useRouter } from "next/navigation";
1779
+ import { Fragment as Fragment6, jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
1780
+ function VersionSwitcher({ currentVersion, versions }) {
1781
+ const [open, setOpen] = useState11(false);
1782
+ const router = useRouter();
1783
+ const handleVersionChange = (version) => {
1784
+ router.push(`/docs/${version}`);
1785
+ setOpen(false);
1786
+ };
1787
+ return /* @__PURE__ */ jsxs25("div", { className: "relative", children: [
1788
+ /* @__PURE__ */ jsxs25(
1789
+ "button",
1790
+ {
1791
+ onClick: () => setOpen(!open),
1792
+ className: "flex items-center gap-2 px-3 py-2 text-sm text-foreground bg-muted rounded-md hover:bg-muted/80 transition-colors",
1793
+ children: [
1794
+ /* @__PURE__ */ jsx34("span", { className: "font-medium", children: currentVersion }),
1795
+ /* @__PURE__ */ jsx34(ChevronDown3, { className: "h-4 w-4" })
1796
+ ]
1797
+ }
1798
+ ),
1799
+ open && /* @__PURE__ */ jsxs25(Fragment6, { children: [
1800
+ /* @__PURE__ */ jsx34("div", { className: "fixed inset-0 z-40", onClick: () => setOpen(false) }),
1801
+ /* @__PURE__ */ jsx34("div", { className: "absolute right-0 mt-2 w-48 bg-background border border-border rounded-md shadow-lg z-50", children: /* @__PURE__ */ jsx34("div", { className: "p-2", children: versions.map((version) => /* @__PURE__ */ jsxs25(
1802
+ "button",
1803
+ {
1804
+ onClick: () => handleVersionChange(version),
1805
+ className: "flex items-center justify-between w-full px-3 py-2 text-sm text-foreground hover:bg-muted rounded-md transition-colors",
1806
+ children: [
1807
+ /* @__PURE__ */ jsx34("span", { children: version }),
1808
+ version === currentVersion && /* @__PURE__ */ jsx34(Check2, { className: "h-4 w-4 text-primary" })
1809
+ ]
1810
+ },
1811
+ version
1812
+ )) }) })
1813
+ ] })
1814
+ ] });
1815
+ }
1816
+
1817
+ // src/components/docs/theme-toggle.tsx
1818
+ import { Moon, Sun } from "lucide-react";
1819
+ import { useEffect as useEffect6, useState as useState12 } from "react";
1820
+ import { jsx as jsx35 } from "react/jsx-runtime";
1821
+ function ThemeToggle() {
1822
+ const [theme, setTheme] = useState12("dark");
1823
+ useEffect6(() => {
1824
+ const savedTheme = localStorage.getItem("theme");
1825
+ const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
1826
+ const initialTheme = savedTheme || (prefersDark ? "dark" : "light");
1827
+ setTheme(initialTheme);
1828
+ document.documentElement.classList.toggle("dark", initialTheme === "dark");
1829
+ }, []);
1830
+ const toggleTheme = () => {
1831
+ const newTheme = theme === "dark" ? "light" : "dark";
1832
+ setTheme(newTheme);
1833
+ localStorage.setItem("theme", newTheme);
1834
+ document.documentElement.classList.toggle("dark", newTheme === "dark");
1835
+ };
1836
+ return /* @__PURE__ */ jsx35(
1837
+ "button",
1838
+ {
1839
+ onClick: toggleTheme,
1840
+ className: "flex items-center justify-center w-9 h-9 rounded-md border border-border bg-background hover:bg-accent transition-colors",
1841
+ "aria-label": "Toggle theme",
1842
+ children: theme === "dark" ? /* @__PURE__ */ jsx35(Sun, { className: "h-4 w-4 text-foreground" }) : /* @__PURE__ */ jsx35(Moon, { className: "h-4 w-4 text-foreground" })
1843
+ }
1844
+ );
1845
+ }
1846
+
1847
+ // src/components/docs/search-modal.tsx
1848
+ import { useState as useState13, useEffect as useEffect7, useCallback } from "react";
1849
+ import { Search, FileText, Loader2 as Loader23 } from "lucide-react";
1850
+ import { useRouter as useRouter2 } from "next/navigation";
1851
+
1852
+ // src/components/ui/dialog.tsx
1853
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
1854
+ import { XIcon } from "lucide-react";
1855
+ import { jsx as jsx36, jsxs as jsxs26 } from "react/jsx-runtime";
1856
+ function Dialog({
1857
+ ...props
1858
+ }) {
1859
+ return /* @__PURE__ */ jsx36(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
1860
+ }
1861
+ function DialogTrigger({
1862
+ ...props
1863
+ }) {
1864
+ return /* @__PURE__ */ jsx36(DialogPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
1865
+ }
1866
+ function DialogPortal({
1867
+ ...props
1868
+ }) {
1869
+ return /* @__PURE__ */ jsx36(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
1870
+ }
1871
+ function DialogClose({
1872
+ ...props
1873
+ }) {
1874
+ return /* @__PURE__ */ jsx36(DialogPrimitive.Close, { "data-slot": "dialog-close", ...props });
1875
+ }
1876
+ function DialogOverlay({
1877
+ className,
1878
+ ...props
1879
+ }) {
1880
+ return /* @__PURE__ */ jsx36(
1881
+ DialogPrimitive.Overlay,
1882
+ {
1883
+ "data-slot": "dialog-overlay",
1884
+ className: cn(
1885
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50 dark:bg-black/70 backdrop-blur-md",
1886
+ className
1887
+ ),
1888
+ ...props
1889
+ }
1890
+ );
1891
+ }
1892
+ function DialogContent({
1893
+ className,
1894
+ children,
1895
+ showCloseButton = true,
1896
+ ...props
1897
+ }) {
1898
+ return /* @__PURE__ */ jsxs26(DialogPortal, { "data-slot": "dialog-portal", children: [
1899
+ /* @__PURE__ */ jsx36(DialogOverlay, {}),
1900
+ /* @__PURE__ */ jsxs26(
1901
+ DialogPrimitive.Content,
1902
+ {
1903
+ "data-slot": "dialog-content",
1904
+ className: cn(
1905
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
1906
+ className
1907
+ ),
1908
+ ...props,
1909
+ children: [
1910
+ children,
1911
+ showCloseButton && /* @__PURE__ */ jsxs26(
1912
+ DialogPrimitive.Close,
1913
+ {
1914
+ "data-slot": "dialog-close",
1915
+ className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1916
+ children: [
1917
+ /* @__PURE__ */ jsx36(XIcon, {}),
1918
+ /* @__PURE__ */ jsx36("span", { className: "sr-only", children: "Close" })
1919
+ ]
1920
+ }
1921
+ )
1922
+ ]
1923
+ }
1924
+ )
1925
+ ] });
1926
+ }
1927
+ function DialogHeader({ className, ...props }) {
1928
+ return /* @__PURE__ */ jsx36(
1929
+ "div",
1930
+ {
1931
+ "data-slot": "dialog-header",
1932
+ className: cn("flex flex-col gap-2 text-center sm:text-left", className),
1933
+ ...props
1934
+ }
1935
+ );
1936
+ }
1937
+ function DialogFooter({ className, ...props }) {
1938
+ return /* @__PURE__ */ jsx36(
1939
+ "div",
1940
+ {
1941
+ "data-slot": "dialog-footer",
1942
+ className: cn(
1943
+ "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",
1944
+ className
1945
+ ),
1946
+ ...props
1947
+ }
1948
+ );
1949
+ }
1950
+ function DialogTitle({
1951
+ className,
1952
+ ...props
1953
+ }) {
1954
+ return /* @__PURE__ */ jsx36(
1955
+ DialogPrimitive.Title,
1956
+ {
1957
+ "data-slot": "dialog-title",
1958
+ className: cn("text-lg leading-none font-semibold", className),
1959
+ ...props
1960
+ }
1961
+ );
1962
+ }
1963
+ function DialogDescription({
1964
+ className,
1965
+ ...props
1966
+ }) {
1967
+ return /* @__PURE__ */ jsx36(
1968
+ DialogPrimitive.Description,
1969
+ {
1970
+ "data-slot": "dialog-description",
1971
+ className: cn("text-muted-foreground text-sm", className),
1972
+ ...props
1973
+ }
1974
+ );
1975
+ }
1976
+
1977
+ // src/components/docs/search-modal.tsx
1978
+ import { Fragment as Fragment7, jsx as jsx37, jsxs as jsxs27 } from "react/jsx-runtime";
1979
+ function SearchModal({ isOpen, onClose, config }) {
1980
+ const [query, setQuery] = useState13("");
1981
+ const [results, setResults] = useState13([]);
1982
+ const [isLoading, setIsLoading] = useState13(false);
1983
+ const [selectedIndex, setSelectedIndex] = useState13(0);
1984
+ const router = useRouter2();
1985
+ const searchConfig = config.search;
1986
+ const performSearch = useCallback(async (searchQuery) => {
1987
+ if (!searchQuery.trim() || !searchConfig?.enabled) {
1988
+ setResults([]);
1989
+ return;
1990
+ }
1991
+ setIsLoading(true);
1992
+ try {
1993
+ const response = await fetch("/api/search", {
1994
+ method: "POST",
1995
+ headers: { "Content-Type": "application/json" },
1996
+ body: JSON.stringify({
1997
+ query: searchQuery,
1998
+ // filter: 'version = "v1.0.0"',
1999
+ distinct: "version",
2000
+ limit: 2
2001
+ })
2002
+ });
2003
+ if (response.ok) {
2004
+ const data = await response.json();
2005
+ console.log("Search response:", data);
2006
+ setResults(data.hits || []);
2007
+ } else {
2008
+ console.error("Search failed:", response.status, await response.text());
2009
+ }
2010
+ } catch (error) {
2011
+ console.error("Search error:", error);
2012
+ setResults([]);
2013
+ } finally {
2014
+ setIsLoading(false);
2015
+ }
2016
+ }, [searchConfig]);
2017
+ useEffect7(() => {
2018
+ const timer = setTimeout(() => {
2019
+ performSearch(query);
2020
+ }, 300);
2021
+ return () => clearTimeout(timer);
2022
+ }, [query, performSearch]);
2023
+ useEffect7(() => {
2024
+ const handleKeyDown = (e) => {
2025
+ if (!isOpen) return;
2026
+ switch (e.key) {
2027
+ case "Escape":
2028
+ onClose();
2029
+ break;
2030
+ case "ArrowDown":
2031
+ e.preventDefault();
2032
+ setSelectedIndex((prev) => Math.min(prev + 1, results.length - 1));
2033
+ break;
2034
+ case "ArrowUp":
2035
+ e.preventDefault();
2036
+ setSelectedIndex((prev) => Math.max(prev - 1, 0));
2037
+ break;
2038
+ case "Enter":
2039
+ e.preventDefault();
2040
+ if (results[selectedIndex]) {
2041
+ handleResultClick(results[selectedIndex]);
2042
+ }
2043
+ break;
2044
+ }
2045
+ };
2046
+ window.addEventListener("keydown", handleKeyDown);
2047
+ return () => window.removeEventListener("keydown", handleKeyDown);
2048
+ }, [isOpen, results, selectedIndex, onClose]);
2049
+ useEffect7(() => {
2050
+ if (isOpen) {
2051
+ setQuery("");
2052
+ setResults([]);
2053
+ setSelectedIndex(0);
2054
+ }
2055
+ }, [isOpen]);
2056
+ const handleResultClick = (result) => {
2057
+ const url = `/docs/${result.version}/${result.slug}?q=${encodeURIComponent(query)}`;
2058
+ router.push(url);
2059
+ onClose();
2060
+ };
2061
+ const highlightText = (text, query2) => {
2062
+ if (!query2.trim()) return text;
2063
+ const parts = text.split(new RegExp(`(${query2})`, "gi"));
2064
+ return parts.map(
2065
+ (part, i) => part.toLowerCase() === query2.toLowerCase() ? /* @__PURE__ */ jsx37("mark", { className: "bg-yellow-200 dark:bg-yellow-900/50 text-foreground", children: part }, i) : part
2066
+ );
2067
+ };
2068
+ return /* @__PURE__ */ jsx37(Dialog, { open: isOpen, onOpenChange: onClose, modal: true, children: /* @__PURE__ */ jsxs27(
2069
+ DialogContent,
2070
+ {
2071
+ className: "max-w-2xl p-0 gap-0 top-[10vh] translate-y-0",
2072
+ showCloseButton: false,
2073
+ onOpenAutoFocus: (e) => e.preventDefault(),
2074
+ children: [
2075
+ /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-3 px-4 py-3 border-b border-border", children: [
2076
+ /* @__PURE__ */ jsx37(Search, { className: "h-5 w-5 text-muted-foreground shrink-0" }),
2077
+ /* @__PURE__ */ jsx37(
2078
+ "input",
2079
+ {
2080
+ type: "text",
2081
+ value: query,
2082
+ onChange: (e) => setQuery(e.target.value),
2083
+ placeholder: searchConfig?.placeholder || "Search documentation...",
2084
+ className: "flex-1 bg-transparent border-none outline-none text-foreground placeholder:text-muted-foreground",
2085
+ autoFocus: true
2086
+ }
2087
+ ),
2088
+ isLoading && /* @__PURE__ */ jsx37(Loader23, { className: "h-5 w-5 text-muted-foreground animate-spin" })
2089
+ ] }),
2090
+ /* @__PURE__ */ jsxs27("div", { className: "max-h-[60vh] overflow-y-auto", children: [
2091
+ query.trim() && results.length === 0 && !isLoading && /* @__PURE__ */ jsxs27("div", { className: "px-4 py-8 text-center text-muted-foreground", children: [
2092
+ 'No results found for "',
2093
+ query,
2094
+ '"'
2095
+ ] }),
2096
+ results.length > 0 && /* @__PURE__ */ jsx37("div", { className: "py-2", children: results.map((result, index) => /* @__PURE__ */ jsx37(
2097
+ "button",
2098
+ {
2099
+ onClick: () => handleResultClick(result),
2100
+ className: `w-full px-4 py-3 text-left hover:bg-muted/50 transition-colors border-l-2 ${index === selectedIndex ? "bg-muted/50 border-primary" : "border-transparent"}`,
2101
+ onMouseEnter: () => setSelectedIndex(index),
2102
+ children: /* @__PURE__ */ jsxs27("div", { className: "flex items-start gap-3", children: [
2103
+ /* @__PURE__ */ jsx37(FileText, { className: "h-5 w-5 text-muted-foreground shrink-0 mt-0.5" }),
2104
+ /* @__PURE__ */ jsxs27("div", { className: "flex-1 min-w-0", children: [
2105
+ /* @__PURE__ */ jsx37("div", { className: "font-medium text-foreground mb-1", children: highlightText(result.title, query) }),
2106
+ result.content && /* @__PURE__ */ jsx37("div", { className: "text-sm text-muted-foreground line-clamp-2", children: highlightText(result.content, query) }),
2107
+ /* @__PURE__ */ jsxs27("div", { className: "flex items-center gap-2 mt-1 text-xs text-muted-foreground", children: [
2108
+ /* @__PURE__ */ jsx37("span", { children: result.version }),
2109
+ result.category && /* @__PURE__ */ jsxs27(Fragment7, { children: [
2110
+ /* @__PURE__ */ jsx37("span", { children: "\u2022" }),
2111
+ /* @__PURE__ */ jsx37("span", { children: result.category })
2112
+ ] })
2113
+ ] })
2114
+ ] })
2115
+ ] })
2116
+ },
2117
+ result.id
2118
+ )) }),
2119
+ !query.trim() && /* @__PURE__ */ jsxs27("div", { className: "px-4 py-8 text-center text-muted-foreground text-sm", children: [
2120
+ /* @__PURE__ */ jsx37("p", { children: "Start typing to search documentation..." }),
2121
+ /* @__PURE__ */ jsxs27("div", { className: "mt-4 flex items-center justify-center gap-4 text-xs", children: [
2122
+ /* @__PURE__ */ jsx37("kbd", { className: "px-2 py-1 bg-muted rounded border border-border", children: "\u2191\u2193" }),
2123
+ /* @__PURE__ */ jsx37("span", { children: "Navigate" }),
2124
+ /* @__PURE__ */ jsx37("kbd", { className: "px-2 py-1 bg-muted rounded border border-border", children: "Enter" }),
2125
+ /* @__PURE__ */ jsx37("span", { children: "Select" }),
2126
+ /* @__PURE__ */ jsx37("kbd", { className: "px-2 py-1 bg-muted rounded border border-border", children: "Esc" }),
2127
+ /* @__PURE__ */ jsx37("span", { children: "Close" })
2128
+ ] })
2129
+ ] })
2130
+ ] })
2131
+ ]
2132
+ }
2133
+ ) });
2134
+ }
2135
+
2136
+ // src/components/docs/header.tsx
2137
+ import { useState as useState14, useEffect as useEffect8 } from "react";
2138
+ import { jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
2139
+ function Header({ currentVersion, versions, onMenuClick, config }) {
2140
+ const [searchOpen, setSearchOpen] = useState14(false);
2141
+ useEffect8(() => {
2142
+ const handleKeyDown = (e) => {
2143
+ if ((e.metaKey || e.ctrlKey) && e.key === "k") {
2144
+ e.preventDefault();
2145
+ setSearchOpen(true);
2146
+ }
2147
+ };
2148
+ window.addEventListener("keydown", handleKeyDown);
2149
+ return () => window.removeEventListener("keydown", handleKeyDown);
2150
+ }, []);
2151
+ return /* @__PURE__ */ jsxs28("header", { className: "sticky top-0 z-50 w-full border-b border-border bg-background/95 backdrop-blur supports-backdrop-filter:bg-background/60", children: [
2152
+ /* @__PURE__ */ jsxs28("div", { className: "container flex h-16 items-center justify-between px-6 mx-auto", children: [
2153
+ /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-2", children: [
2154
+ /* @__PURE__ */ jsx38(
2155
+ "button",
2156
+ {
2157
+ onClick: onMenuClick,
2158
+ className: "lg:hidden hover:bg-muted p-2 rounded-md transition-colors",
2159
+ "aria-label": "Toggle menu",
2160
+ children: /* @__PURE__ */ jsx38(Menu, { className: "h-5 w-5" })
2161
+ }
2162
+ ),
2163
+ /* @__PURE__ */ jsxs28(Link5, { href: "/", className: "flex items-center gap-2", children: [
2164
+ config.site.logo ? /* @__PURE__ */ jsx38("img", { src: getAssetPath(config.site.logo), alt: config.site.title, className: "h-8 w-auto" }) : /* @__PURE__ */ jsx38("div", { className: "h-8 w-8 rounded-xl bg-primary flex items-center justify-center", children: /* @__PURE__ */ jsx38("span", { className: "text-primary-foreground font-bold text-lg", children: config.site.title.charAt(0).toUpperCase() }) }),
2165
+ /* @__PURE__ */ jsx38("span", { className: "font-semibold text-lg text-foreground", children: "Specra" })
2166
+ ] })
2167
+ ] }),
2168
+ /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-2", children: [
2169
+ config.search?.enabled && /* @__PURE__ */ jsxs28(
2170
+ "button",
2171
+ {
2172
+ onClick: () => setSearchOpen(true),
2173
+ className: "flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground hover:text-foreground bg-muted rounded-md transition-colors",
2174
+ children: [
2175
+ /* @__PURE__ */ jsx38(Search2, { className: "h-4 w-4" }),
2176
+ /* @__PURE__ */ jsx38("span", { className: "hidden sm:inline", children: config.search.placeholder || "Search" }),
2177
+ /* @__PURE__ */ jsx38("kbd", { className: "hidden sm:inline-flex h-5 select-none items-center gap-1 rounded border border-border bg-background px-1.5 font-mono text-xs font-medium", children: "\u2318K" })
2178
+ ]
2179
+ }
2180
+ ),
2181
+ config.features?.versioning && /* @__PURE__ */ jsx38(VersionSwitcher, { currentVersion, versions }),
2182
+ config.social?.github && /* @__PURE__ */ jsx38(
2183
+ "a",
2184
+ {
2185
+ href: config.social.github,
2186
+ target: "_blank",
2187
+ rel: "noopener noreferrer",
2188
+ className: "hidden md:flex items-center justify-center h-9 w-9 rounded-md hover:bg-muted transition-colors",
2189
+ "aria-label": "GitHub",
2190
+ children: /* @__PURE__ */ jsx38(Github, { className: "h-4 w-4" })
2191
+ }
2192
+ ),
2193
+ config.social?.twitter && /* @__PURE__ */ jsx38(
2194
+ "a",
2195
+ {
2196
+ href: config.social.twitter,
2197
+ target: "_blank",
2198
+ rel: "noopener noreferrer",
2199
+ className: "hidden md:flex items-center justify-center h-9 w-9 rounded-md hover:bg-muted transition-colors",
2200
+ "aria-label": "Twitter",
2201
+ children: /* @__PURE__ */ jsx38(Twitter, { className: "h-4 w-4" })
2202
+ }
2203
+ ),
2204
+ config.social?.discord && /* @__PURE__ */ jsx38(
2205
+ "a",
2206
+ {
2207
+ href: config.social.discord,
2208
+ target: "_blank",
2209
+ rel: "noopener noreferrer",
2210
+ className: "hidden md:flex items-center justify-center h-9 w-9 rounded-md hover:bg-muted transition-colors",
2211
+ "aria-label": "Discord",
2212
+ children: /* @__PURE__ */ jsx38(MessageCircle, { className: "h-4 w-4" })
2213
+ }
2214
+ ),
2215
+ /* @__PURE__ */ jsx38(ThemeToggle, {})
2216
+ ] })
2217
+ ] }),
2218
+ /* @__PURE__ */ jsx38(SearchModal, { isOpen: searchOpen, onClose: () => setSearchOpen(false), config })
2219
+ ] });
2220
+ }
2221
+
2222
+ // src/components/docs/doc-layout-wrapper.tsx
2223
+ import { useEffect as useEffect10, useRef as useRef3 } from "react";
2224
+
2225
+ // src/components/docs/mobile-doc-layout.tsx
2226
+ import { useState as useState17, cloneElement, isValidElement as isValidElement2 } from "react";
2227
+
2228
+ // src/components/docs/footer.tsx
2229
+ import Link6 from "next/link";
2230
+ import { jsx as jsx39, jsxs as jsxs29 } from "react/jsx-runtime";
2231
+ function Footer({ config }) {
2232
+ if (!config.footer) {
2233
+ return null;
2234
+ }
2235
+ return /* @__PURE__ */ jsx39("footer", { className: "bg-muted/30 dark:bg-muted/10 rounded-2xl mt-24", children: /* @__PURE__ */ jsxs29("div", { className: "px-6 py-12", children: [
2236
+ config.footer.links && config.footer.links.length > 0 && /* @__PURE__ */ jsx39("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-8 mb-8", children: config.footer.links.map((column, idx) => /* @__PURE__ */ jsxs29("div", { children: [
2237
+ /* @__PURE__ */ jsx39("h3", { className: "font-semibold text-foreground mb-4", children: column.title }),
2238
+ /* @__PURE__ */ jsx39("ul", { className: "space-y-2", children: column.items.map((item, itemIdx) => /* @__PURE__ */ jsx39("li", { children: /* @__PURE__ */ jsx39(
2239
+ Link6,
2240
+ {
2241
+ href: item.href,
2242
+ className: "text-sm text-muted-foreground hover:text-foreground transition-colors",
2243
+ children: item.label
2244
+ }
2245
+ ) }, itemIdx)) })
2246
+ ] }, idx)) }),
2247
+ config.footer.copyright && /* @__PURE__ */ jsx39("div", { className: "pt-8", children: /* @__PURE__ */ jsx39("p", { className: "text-sm text-muted-foreground text-center", children: config.footer.copyright }) })
2248
+ ] }) });
2249
+ }
2250
+
2251
+ // src/components/docs/site-banner.tsx
2252
+ import { X as X2, AlertCircle, CheckCircle, Info as Info2, XCircle as XCircle2 } from "lucide-react";
2253
+ import { useState as useState15, useEffect as useEffect9 } from "react";
2254
+ import { jsx as jsx40, jsxs as jsxs30 } from "react/jsx-runtime";
2255
+ function SiteBanner({ config }) {
2256
+ const [dismissed, setDismissed] = useState15(false);
2257
+ const [mounted, setMounted] = useState15(false);
2258
+ const banner = config.banner;
2259
+ const storageKey = "site-banner-dismissed";
2260
+ useEffect9(() => {
2261
+ setMounted(true);
2262
+ const isDismissed = localStorage.getItem(storageKey) === "true";
2263
+ setDismissed(isDismissed);
2264
+ }, []);
2265
+ const handleDismiss = () => {
2266
+ setDismissed(true);
2267
+ localStorage.setItem(storageKey, "true");
2268
+ };
2269
+ if (!mounted || !banner || !banner.enabled || dismissed) {
2270
+ return null;
2271
+ }
2272
+ const typeConfig = {
2273
+ info: {
2274
+ icon: Info2,
2275
+ bg: "bg-blue-500/10 dark:bg-blue-400/5",
2276
+ border: "border-blue-500/30 dark:border-blue-500/20",
2277
+ iconColor: "text-blue-600 dark:text-blue-400",
2278
+ textColor: "text-blue-900 dark:text-blue-300"
2279
+ },
2280
+ success: {
2281
+ icon: CheckCircle,
2282
+ bg: "bg-green-500/10 dark:bg-green-400/5",
2283
+ border: "border-green-500/30 dark:border-green-500/20",
2284
+ iconColor: "text-green-600 dark:text-green-400",
2285
+ textColor: "text-green-900 dark:text-green-300"
2286
+ },
2287
+ warning: {
2288
+ icon: AlertCircle,
2289
+ bg: "bg-yellow-500/10 dark:bg-yellow-400/5",
2290
+ border: "border-yellow-500/30 dark:border-yellow-500/20",
2291
+ iconColor: "text-yellow-600 dark:text-yellow-400",
2292
+ textColor: "text-yellow-900 dark:text-yellow-300"
2293
+ },
2294
+ error: {
2295
+ icon: XCircle2,
2296
+ bg: "bg-red-500/10 dark:bg-red-400/5",
2297
+ border: "border-red-500/30 dark:border-red-500/20",
2298
+ iconColor: "text-red-600 dark:text-red-400",
2299
+ textColor: "text-red-900 dark:text-red-300"
2300
+ }
2301
+ };
2302
+ const type = banner.type || "info";
2303
+ const { icon: IconComponent, bg, border, iconColor, textColor } = typeConfig[type];
2304
+ return /* @__PURE__ */ jsx40("div", { className: `w-full border-b ${border} ${bg}`, children: /* @__PURE__ */ jsx40("div", { className: "container mx-auto px-6 py-3", children: /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-3", children: [
2305
+ /* @__PURE__ */ jsx40(IconComponent, { className: `h-5 w-5 shrink-0 ${iconColor}` }),
2306
+ /* @__PURE__ */ jsx40("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx40("p", { className: `text-sm font-medium ${textColor}`, children: banner.message }) }),
2307
+ banner.dismissible && /* @__PURE__ */ jsx40(
2308
+ "button",
2309
+ {
2310
+ onClick: handleDismiss,
2311
+ className: `shrink-0 p-1 rounded-md hover:bg-black/5 dark:hover:bg-white/5 transition-colors ${iconColor}`,
2312
+ "aria-label": "Dismiss banner",
2313
+ children: /* @__PURE__ */ jsx40(X2, { className: "h-4 w-4" })
2314
+ }
2315
+ )
2316
+ ] }) }) });
2317
+ }
2318
+
2319
+ // src/components/docs/tab-groups.tsx
2320
+ import { jsx as jsx41, jsxs as jsxs31 } from "react/jsx-runtime";
2321
+ function TabGroups({ tabGroups, activeTabId, onTabChange }) {
2322
+ const activeTab = activeTabId || tabGroups[0]?.id || "";
2323
+ const handleTabChange = (tabId) => {
2324
+ onTabChange?.(tabId);
2325
+ };
2326
+ if (!tabGroups || tabGroups.length === 0) {
2327
+ return null;
2328
+ }
2329
+ return /* @__PURE__ */ jsx41("div", { className: "sticky top-16 z-30 border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60", children: /* @__PURE__ */ jsx41("div", { className: "container mx-auto px-6", children: /* @__PURE__ */ jsx41("nav", { className: "flex gap-1 overflow-x-auto no-scrollbar", "aria-label": "Documentation tabs", children: tabGroups.map((tab) => {
2330
+ const isActive = tab.id === activeTab;
2331
+ return /* @__PURE__ */ jsxs31(
2332
+ "button",
2333
+ {
2334
+ onClick: () => handleTabChange(tab.id),
2335
+ className: `flex items-center gap-2 px-4 py-3 text-sm font-medium whitespace-nowrap transition-all border-b-2 ${isActive ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground hover:border-border"}`,
2336
+ "aria-current": isActive ? "page" : void 0,
2337
+ children: [
2338
+ tab.icon && /* @__PURE__ */ jsx41(Icon, { icon: tab.icon, size: 16, className: "shrink-0" }),
2339
+ tab.label
2340
+ ]
2341
+ },
2342
+ tab.id
2343
+ );
2344
+ }) }) }) });
2345
+ }
2346
+
2347
+ // src/components/docs/sidebar.tsx
2348
+ import Link7 from "next/link";
2349
+ import { usePathname } from "next/navigation";
2350
+ import { ChevronRight as ChevronRight3, ChevronDown as ChevronDown4, FolderOpen } from "lucide-react";
2351
+ import { useState as useState16 } from "react";
2352
+ import { jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
2353
+ function Sidebar({ docs, version, onLinkClick, config, activeTabGroup }) {
2354
+ const pathname = usePathname();
2355
+ const [collapsed, setCollapsed] = useState16(() => {
2356
+ const initial = {};
2357
+ return initial;
2358
+ });
2359
+ if (!config.navigation?.showSidebar) {
2360
+ return null;
2361
+ }
2362
+ const hasTabGroups = config.navigation?.tabGroups && config.navigation.tabGroups.length > 0;
2363
+ const filteredDocs = hasTabGroups && activeTabGroup ? docs.filter((doc) => {
2364
+ const docTabGroup = doc.meta?.tab_group || doc.categoryTabGroup;
2365
+ if (!docTabGroup) {
2366
+ return activeTabGroup === config.navigation?.tabGroups?.[0]?.id;
2367
+ }
2368
+ return docTabGroup === activeTabGroup;
2369
+ }) : docs;
2370
+ const rootGroups = {};
2371
+ const standalone = [];
2372
+ filteredDocs.forEach((doc) => {
2373
+ const pathParts = doc.filePath.split("/");
2374
+ const isIndexFile = doc.filePath.endsWith("/index") || doc.filePath === "index" || pathParts.length > 1 && doc.slug === pathParts.slice(0, -1).join("/");
2375
+ const customGroup = doc.sidebar || doc.group;
2376
+ if (customGroup) {
2377
+ const groupName = customGroup.charAt(0).toUpperCase() + customGroup.slice(1);
2378
+ if (!rootGroups[groupName]) {
2379
+ rootGroups[groupName] = {
2380
+ label: groupName,
2381
+ path: customGroup,
2382
+ items: [],
2383
+ position: 999,
2384
+ collapsible: doc.categoryCollapsible ?? true,
2385
+ defaultCollapsed: doc.categoryCollapsed ?? false,
2386
+ children: {}
2387
+ };
2388
+ }
2389
+ if (isIndexFile) {
2390
+ rootGroups[groupName].position = doc.sidebar_position ?? 999;
2391
+ rootGroups[groupName].icon = doc.categoryIcon;
2392
+ } else {
2393
+ rootGroups[groupName].items.push(doc);
2394
+ }
2395
+ return;
2396
+ }
2397
+ if (pathParts.length > 1) {
2398
+ const folderParts = pathParts.slice(0, -1);
2399
+ let currentLevel = rootGroups;
2400
+ let currentPath = "";
2401
+ for (let i = 0; i < folderParts.length; i++) {
2402
+ const folder = folderParts[i];
2403
+ currentPath = currentPath ? `${currentPath}/${folder}` : folder;
2404
+ const folderLabel = folder.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
2405
+ if (!currentLevel[folder]) {
2406
+ currentLevel[folder] = {
2407
+ label: doc.categoryLabel && i === folderParts.length - 1 ? doc.categoryLabel : folderLabel,
2408
+ path: currentPath,
2409
+ icon: doc.categoryIcon,
2410
+ items: [],
2411
+ position: doc.categoryPosition ?? 999,
2412
+ collapsible: doc.categoryCollapsible ?? true,
2413
+ defaultCollapsed: doc.categoryCollapsed ?? false,
2414
+ children: {}
2415
+ };
2416
+ }
2417
+ if (i === folderParts.length - 1) {
2418
+ if (isIndexFile) {
2419
+ currentLevel[folder].position = doc.categoryPosition ?? doc.sidebar_position ?? 999;
2420
+ if (doc.categoryLabel) {
2421
+ currentLevel[folder].label = doc.categoryLabel;
2422
+ }
2423
+ if (doc.categoryIcon) {
2424
+ currentLevel[folder].icon = doc.categoryIcon;
2425
+ }
2426
+ } else {
2427
+ currentLevel[folder].items.push(doc);
2428
+ }
2429
+ }
2430
+ currentLevel = currentLevel[folder].children;
2431
+ }
2432
+ } else {
2433
+ if (!isIndexFile) {
2434
+ standalone.push(doc);
2435
+ }
2436
+ }
2437
+ });
2438
+ const toggleSection = (section) => {
2439
+ setCollapsed((prev) => ({ ...prev, [section]: !prev[section] }));
2440
+ };
2441
+ const renderGroup = (groupKey, group, depth = 0) => {
2442
+ const sortedItems = sortSidebarItems(group.items);
2443
+ const sortedChildren = sortSidebarGroups(group.children);
2444
+ const hasChildren = sortedChildren.length > 0;
2445
+ const hasItems = sortedItems.length > 0;
2446
+ const hasContent = hasChildren || hasItems;
2447
+ const isActiveInGroup = (g) => {
2448
+ const hasActiveItem2 = g.items.some((doc) => pathname === `/docs/${version}/${doc.slug}`);
2449
+ if (hasActiveItem2) return true;
2450
+ return Object.values(g.children).some((child) => isActiveInGroup(child));
2451
+ };
2452
+ const hasActiveItem = isActiveInGroup(group);
2453
+ const isGroupActive = pathname === `/docs/${version}/${group.path}`;
2454
+ const isCollapsed = hasActiveItem || isGroupActive ? false : collapsed[groupKey] ?? group.defaultCollapsed;
2455
+ const marginLeft = depth > 0 ? "ml-4" : "";
2456
+ const groupHref = `/docs/${version}/${group.path}`;
2457
+ return /* @__PURE__ */ jsxs32("div", { className: `space-y-1 ${marginLeft}`, children: [
2458
+ /* @__PURE__ */ jsxs32("div", { className: "flex items-center group", children: [
2459
+ /* @__PURE__ */ jsxs32(
2460
+ Link7,
2461
+ {
2462
+ href: groupHref,
2463
+ onClick: onLinkClick,
2464
+ className: `flex items-center gap-2 flex-1 px-3 py-2 text-sm font-semibold rounded-l-xl transition-all ${isGroupActive ? "bg-primary/10 text-primary" : "text-foreground hover:bg-accent/50"}`,
2465
+ children: [
2466
+ group.icon ? /* @__PURE__ */ jsx42(Icon, { icon: group.icon, size: 16, className: "shrink-0" }) : /* @__PURE__ */ jsx42(FolderOpen, { size: 16, className: "shrink-0" }),
2467
+ group.label
2468
+ ]
2469
+ }
2470
+ ),
2471
+ hasContent && group.collapsible && config.navigation?.collapsibleSidebar && /* @__PURE__ */ jsx42(
2472
+ "button",
2473
+ {
2474
+ onClick: (e) => {
2475
+ e.preventDefault();
2476
+ e.stopPropagation();
2477
+ toggleSection(groupKey);
2478
+ },
2479
+ className: `p-2 rounded-r-xl transition-all ${isGroupActive ? "hover:bg-primary/20" : "hover:bg-accent/50"}`,
2480
+ "aria-label": isCollapsed ? "Expand section" : "Collapse section",
2481
+ children: isCollapsed ? /* @__PURE__ */ jsx42(ChevronRight3, { className: `h-4 w-4 ${isGroupActive ? "text-primary" : "text-muted-foreground"}` }) : /* @__PURE__ */ jsx42(ChevronDown4, { className: `h-4 w-4 ${isGroupActive ? "text-primary" : "text-muted-foreground"}` })
2482
+ }
2483
+ )
2484
+ ] }),
2485
+ !isCollapsed && hasContent && /* @__PURE__ */ jsx42("div", { className: "ml-4 space-y-1", children: (() => {
2486
+ const merged = [
2487
+ ...sortedChildren.map(([childKey, childGroup]) => ({
2488
+ type: "group",
2489
+ key: childKey,
2490
+ group: childGroup,
2491
+ position: childGroup.position
2492
+ })),
2493
+ ...sortedItems.map((doc) => ({
2494
+ type: "item",
2495
+ doc,
2496
+ position: doc.sidebar_position ?? doc.meta?.sidebar_position ?? doc.meta?.order ?? 999
2497
+ }))
2498
+ ];
2499
+ merged.sort((a, b) => a.position - b.position);
2500
+ return merged.map((item) => {
2501
+ if (item.type === "group") {
2502
+ return renderGroup(`${groupKey}/${item.key}`, item.group, depth + 1);
2503
+ } else {
2504
+ const href = `/docs/${version}/${item.doc.slug}`;
2505
+ const isActive = pathname === href;
2506
+ return /* @__PURE__ */ jsxs32(
2507
+ Link7,
2508
+ {
2509
+ href,
2510
+ onClick: onLinkClick,
2511
+ className: `flex items-center gap-2 px-3 py-2 text-sm rounded-xl transition-all ${isActive ? "bg-primary/10 text-primary font-medium" : "text-foreground hover:text-foreground hover:bg-accent/50"}`,
2512
+ children: [
2513
+ item.doc.meta?.icon && /* @__PURE__ */ jsx42(Icon, { icon: item.doc.meta.icon, size: 16, className: "shrink-0" }),
2514
+ item.doc.title
2515
+ ]
2516
+ },
2517
+ `grouped-${item.doc.slug}`
2518
+ );
2519
+ }
2520
+ });
2521
+ })() })
2522
+ ] }, `group-${groupKey}`);
2523
+ };
2524
+ const sortedRootGroups = sortSidebarGroups(rootGroups);
2525
+ const sortedStandalone = sortSidebarItems(standalone);
2526
+ const stickyTop = hasTabGroups ? "top-[7.5rem]" : "top-24";
2527
+ const maxHeight = hasTabGroups ? "max-h-[calc(100vh-10rem)]" : "max-h-[calc(100vh-7rem)]";
2528
+ return /* @__PURE__ */ jsx42("aside", { className: `w-64 shrink-0 sticky ${stickyTop} self-start`, children: /* @__PURE__ */ jsxs32("div", { className: `${maxHeight} overflow-y-auto bg-muted/30 dark:bg-muted/10 rounded-2xl p-4 border border-border/50`, children: [
2529
+ /* @__PURE__ */ jsx42("h2", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-4 px-2", children: "Documentation" }),
2530
+ /* @__PURE__ */ jsxs32("nav", { className: "space-y-1", children: [
2531
+ sortedStandalone.length > 0 && sortedStandalone.map((doc) => {
2532
+ const href = `/docs/${version}/${doc.slug}`;
2533
+ const isActive = pathname === href;
2534
+ return /* @__PURE__ */ jsxs32(
2535
+ Link7,
2536
+ {
2537
+ href,
2538
+ onClick: onLinkClick,
2539
+ className: `flex items-center gap-2 px-3 py-2 text-sm rounded-xl transition-all ${isActive ? "bg-primary/10 text-primary font-medium" : "text-foreground hover:text-foreground hover:bg-accent/50"}`,
2540
+ children: [
2541
+ doc.meta?.icon && /* @__PURE__ */ jsx42(Icon, { icon: doc.meta.icon, size: 16, className: "shrink-0" }),
2542
+ doc.title
2543
+ ]
2544
+ },
2545
+ `standalone-${doc.slug}`
2546
+ );
2547
+ }),
2548
+ sortedRootGroups.map(([groupKey, group]) => renderGroup(groupKey, group, 0))
2549
+ ] })
2550
+ ] }) });
2551
+ }
2552
+
2553
+ // src/components/docs/mobile-doc-layout.tsx
2554
+ import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
2555
+ function MobileDocLayout({ header, docs, version, content, toc, config, activeTabGroup, onTabChange }) {
2556
+ const [sidebarOpen, setSidebarOpen] = useState17(false);
2557
+ const handleTabChange = (tabId) => {
2558
+ onTabChange?.(tabId);
2559
+ };
2560
+ const closeSidebar = () => setSidebarOpen(false);
2561
+ const toggleSidebar = () => setSidebarOpen(!sidebarOpen);
2562
+ const headerWithProps = isValidElement2(header) ? cloneElement(header, {
2563
+ onMenuClick: toggleSidebar
2564
+ }) : header;
2565
+ return /* @__PURE__ */ jsxs33("div", { className: "min-h-screen bg-background", children: [
2566
+ headerWithProps,
2567
+ /* @__PURE__ */ jsx43(SiteBanner, { config }),
2568
+ config.navigation?.tabGroups && config.navigation.tabGroups.length > 0 && /* @__PURE__ */ jsx43(
2569
+ TabGroups,
2570
+ {
2571
+ tabGroups: config.navigation.tabGroups,
2572
+ activeTabId: activeTabGroup,
2573
+ onTabChange: handleTabChange
2574
+ }
2575
+ ),
2576
+ sidebarOpen && /* @__PURE__ */ jsx43(
2577
+ "div",
2578
+ {
2579
+ className: "lg:hidden fixed inset-0 bg-background/80 backdrop-blur-sm z-40",
2580
+ onClick: () => setSidebarOpen(false)
2581
+ }
2582
+ ),
2583
+ /* @__PURE__ */ jsx43(
2584
+ "div",
2585
+ {
2586
+ className: `lg:hidden fixed top-0 left-0 h-full w-64 bg-background border-r border-border z-40 transform transition-transform duration-300 ease-in-out overflow-y-auto ${sidebarOpen ? "translate-x-0" : "-translate-x-full"}`,
2587
+ children: /* @__PURE__ */ jsx43("div", { className: "pt-20 px-4", children: /* @__PURE__ */ jsx43(
2588
+ Sidebar,
2589
+ {
2590
+ docs,
2591
+ version,
2592
+ config,
2593
+ onLinkClick: closeSidebar,
2594
+ activeTabGroup
2595
+ }
2596
+ ) })
2597
+ }
2598
+ ),
2599
+ /* @__PURE__ */ jsx43("main", { className: "container mx-auto px-6 py-8", children: /* @__PURE__ */ jsxs33("div", { className: "flex", children: [
2600
+ /* @__PURE__ */ jsx43("div", { className: "hidden lg:block", children: /* @__PURE__ */ jsx43(
2601
+ Sidebar,
2602
+ {
2603
+ docs,
2604
+ version,
2605
+ config,
2606
+ activeTabGroup
2607
+ }
2608
+ ) }),
2609
+ /* @__PURE__ */ jsx43("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxs33("div", { className: "flex flex-col gap-2 px-2 md:px-8", children: [
2610
+ content,
2611
+ /* @__PURE__ */ jsx43(Footer, { config })
2612
+ ] }) }),
2613
+ toc
2614
+ ] }) })
2615
+ ] });
2616
+ }
2617
+
2618
+ // src/components/docs/doc-layout-wrapper.tsx
2619
+ import { jsx as jsx44 } from "react/jsx-runtime";
2620
+ function DocLayoutWrapper({ header, docs, version, content, toc, config, currentPageTabGroup }) {
2621
+ const { activeTabGroup, setActiveTabGroup } = useTabContext();
2622
+ const lastPageTabGroupRef = useRef3(void 0);
2623
+ const isInitialMount = useRef3(true);
2624
+ useEffect10(() => {
2625
+ if (isInitialMount.current && currentPageTabGroup) {
2626
+ setActiveTabGroup(currentPageTabGroup);
2627
+ lastPageTabGroupRef.current = currentPageTabGroup;
2628
+ isInitialMount.current = false;
2629
+ return;
2630
+ }
2631
+ if (currentPageTabGroup && lastPageTabGroupRef.current !== currentPageTabGroup) {
2632
+ setActiveTabGroup(currentPageTabGroup);
2633
+ lastPageTabGroupRef.current = currentPageTabGroup;
2634
+ }
2635
+ }, [currentPageTabGroup, setActiveTabGroup]);
2636
+ return /* @__PURE__ */ jsx44(
2637
+ MobileDocLayout,
2638
+ {
2639
+ header,
2640
+ docs,
2641
+ version,
2642
+ content,
2643
+ toc,
2644
+ config,
2645
+ activeTabGroup,
2646
+ onTabChange: setActiveTabGroup
2647
+ }
2648
+ );
2649
+ }
2650
+
2651
+ // src/components/docs/hot-reload-indicator.tsx
2652
+ import { useEffect as useEffect11, useState as useState18 } from "react";
2653
+ import { usePathname as usePathname2 } from "next/navigation";
2654
+ import { RefreshCw } from "lucide-react";
2655
+ import { Fragment as Fragment8, jsx as jsx45, jsxs as jsxs34 } from "react/jsx-runtime";
2656
+ function HotReloadIndicator() {
2657
+ const [isReloading, setIsReloading] = useState18(false);
2658
+ const [lastReload, setLastReload] = useState18(null);
2659
+ const pathname = usePathname2();
2660
+ useEffect11(() => {
2661
+ if (process.env.NODE_ENV !== "development") return;
2662
+ setIsReloading(true);
2663
+ const timer = setTimeout(() => {
2664
+ setIsReloading(false);
2665
+ setLastReload(/* @__PURE__ */ new Date());
2666
+ setTimeout(() => {
2667
+ setLastReload(null);
2668
+ }, 3e3);
2669
+ }, 500);
2670
+ return () => clearTimeout(timer);
2671
+ }, [pathname]);
2672
+ useEffect11(() => {
2673
+ if (process.env.NODE_ENV !== "development") return;
2674
+ const handleBeforeRefresh = () => {
2675
+ setIsReloading(true);
2676
+ };
2677
+ const handleAfterRefresh = () => {
2678
+ setIsReloading(false);
2679
+ setLastReload(/* @__PURE__ */ new Date());
2680
+ setTimeout(() => setLastReload(null), 3e3);
2681
+ };
2682
+ if (typeof window !== "undefined" && window.__NEXT_DATA__) {
2683
+ window.addEventListener("beforeunload", handleBeforeRefresh);
2684
+ }
2685
+ return () => {
2686
+ window.removeEventListener("beforeunload", handleBeforeRefresh);
2687
+ };
2688
+ }, []);
2689
+ if (process.env.NODE_ENV !== "development") return null;
2690
+ return /* @__PURE__ */ jsxs34(Fragment8, { children: [
2691
+ isReloading && /* @__PURE__ */ jsxs34("div", { className: "fixed bottom-4 right-4 z-50 flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-xl shadow-lg animate-in slide-in-from-bottom-2", children: [
2692
+ /* @__PURE__ */ jsx45(RefreshCw, { className: "h-4 w-4 animate-spin" }),
2693
+ /* @__PURE__ */ jsx45("span", { className: "text-sm font-medium", children: "Reloading..." })
2694
+ ] }),
2695
+ lastReload && !isReloading && /* @__PURE__ */ jsxs34("div", { className: "fixed bottom-4 right-4 z-50 flex items-center gap-2 px-4 py-2 bg-green-500 text-white rounded-xl shadow-lg animate-in slide-in-from-bottom-2", children: [
2696
+ /* @__PURE__ */ jsx45(RefreshCw, { className: "h-4 w-4" }),
2697
+ /* @__PURE__ */ jsxs34("span", { className: "text-sm font-medium", children: [
2698
+ "Updated at ",
2699
+ lastReload.toLocaleTimeString()
2700
+ ] })
2701
+ ] })
2702
+ ] });
2703
+ }
2704
+
2705
+ // src/components/docs/dev-mode-badge.tsx
2706
+ import { useEffect as useEffect12, useState as useState19 } from "react";
2707
+ import { Code2 } from "lucide-react";
2708
+ import { jsx as jsx46, jsxs as jsxs35 } from "react/jsx-runtime";
2709
+ function DevModeBadge() {
2710
+ const [isConnected, setIsConnected] = useState19(true);
2711
+ useEffect12(() => {
2712
+ if (process.env.NODE_ENV !== "development") return;
2713
+ const checkConnection = () => {
2714
+ setIsConnected(navigator.onLine);
2715
+ };
2716
+ window.addEventListener("online", checkConnection);
2717
+ window.addEventListener("offline", checkConnection);
2718
+ return () => {
2719
+ window.removeEventListener("online", checkConnection);
2720
+ window.removeEventListener("offline", checkConnection);
2721
+ };
2722
+ }, []);
2723
+ if (process.env.NODE_ENV !== "development") return null;
2724
+ return /* @__PURE__ */ jsxs35("div", { className: "fixed top-20 left-4 z-40 flex items-center gap-2 px-3 py-1.5 bg-orange-500/10 text-orange-600 dark:text-orange-400 border border-orange-500/20 rounded-full text-xs font-medium", children: [
2725
+ /* @__PURE__ */ jsx46(Code2, { className: "h-3 w-3" }),
2726
+ /* @__PURE__ */ jsx46("span", { children: "Dev Mode" }),
2727
+ /* @__PURE__ */ jsx46("div", { className: `h-2 w-2 rounded-full ${isConnected ? "bg-green-500" : "bg-red-500"} animate-pulse` })
2728
+ ] });
2729
+ }
2730
+
2731
+ // src/components/docs/mdx-hot-reload.tsx
2732
+ import { useEffect as useEffect13 } from "react";
2733
+ import { useRouter as useRouter3 } from "next/navigation";
2734
+ function MdxHotReload() {
2735
+ const router = useRouter3();
2736
+ useEffect13(() => {
2737
+ if (process.env.NODE_ENV !== "development") return;
2738
+ const eventSource = new EventSource("/api/mdx-watch");
2739
+ eventSource.onmessage = (event) => {
2740
+ const data = JSON.parse(event.data);
2741
+ if (data.type === "change") {
2742
+ console.log("[MDX Hot Reload] File changed:", data.file);
2743
+ router.refresh();
2744
+ } else if (data.type === "connected") {
2745
+ console.log("[MDX Hot Reload] Watching for changes...");
2746
+ }
2747
+ };
2748
+ eventSource.onerror = (error) => {
2749
+ console.error("[MDX Hot Reload] Connection error:", error);
2750
+ eventSource.close();
2751
+ };
2752
+ return () => {
2753
+ eventSource.close();
2754
+ };
2755
+ }, [router]);
2756
+ return null;
2757
+ }
2758
+
2759
+ // src/components/docs/category-index.tsx
2760
+ import Link8 from "next/link";
2761
+ import { ChevronRight as ChevronRight4, FileText as FileText2 } from "lucide-react";
2762
+ import { MDXRemote as MDXRemote2 } from "next-mdx-remote/rsc";
2763
+ import remarkGfm2 from "remark-gfm";
2764
+ import rehypeSlug2 from "rehype-slug";
2765
+ import { jsx as jsx47, jsxs as jsxs36 } from "react/jsx-runtime";
2766
+ function CategoryIndex({ categoryPath, version, allDocs, title, description, content, config }) {
2767
+ const childDocs = allDocs.filter((doc) => {
2768
+ const parts = doc.slug.split("/");
2769
+ const docParent = parts.slice(0, -1).join("/");
2770
+ return docParent === categoryPath && doc.slug !== categoryPath;
2771
+ });
2772
+ const processedContent = () => {
2773
+ if (content) {
2774
+ return processContentWithEnv(content, config);
2775
+ }
2776
+ return "";
2777
+ };
2778
+ const sortedDocs = sortSidebarItems(childDocs);
2779
+ return /* @__PURE__ */ jsxs36("div", { className: "flex-1 min-w-0", children: [
2780
+ /* @__PURE__ */ jsxs36("div", { className: "mb-8", children: [
2781
+ /* @__PURE__ */ jsx47("h1", { className: "text-4xl font-bold tracking-tight mb-3 text-foreground", children: title }),
2782
+ description && /* @__PURE__ */ jsx47("p", { className: "text-lg text-muted-foreground leading-relaxed", children: description }),
2783
+ /* @__PURE__ */ jsx47("div", { className: "prose prose-slate dark:prose-invert max-w-none prose-headings:scroll-mt-24 prose-headings:font-semibold prose-h1:text-4xl prose-h2:text-3xl prose-h2:mt-12 prose-h2:mb-4 prose-h3:text-2xl prose-h3:mt-8 prose-h3:mb-3 prose-p:text-base prose-p:leading-7 prose-p:text-muted-foreground prose-p:mb-4 prose-a:font-normal prose-a:transition-all prose-code:text-primary prose-code:bg-muted/50 prose-code:px-1.5 prose-code:py-0.5 prose-code:rounded-md prose-code:text-[13px] prose-code:font-mono prose-code:border prose-code:border-border/50 prose-code:before:content-none prose-code:after:content-none prose-pre:bg-transparent prose-pre:p-0 prose-ul:list-disc prose-ul:list-inside prose-ul:space-y-2 prose-ul:mb-4 prose-ol:list-decimal prose-ol:list-inside prose-ol:space-y-2 prose-ol:mb-4 prose-li:leading-7 prose-li:text-muted-foreground prose-strong:text-foreground prose-strong:font-semibold", children: /* @__PURE__ */ jsx47(
2784
+ MDXRemote2,
2785
+ {
2786
+ source: processedContent(),
2787
+ options: {
2788
+ parseFrontmatter: false,
2789
+ mdxOptions: {
2790
+ remarkPlugins: [remarkGfm2, remarkCodeMeta],
2791
+ rehypePlugins: [rehypeSlug2],
2792
+ development: false
2793
+ }
2794
+ },
2795
+ components: mdxComponents
2796
+ }
2797
+ ) })
2798
+ ] }),
2799
+ /* @__PURE__ */ jsx47("div", { className: "grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 gap-4", children: sortedDocs.map((doc) => /* @__PURE__ */ jsx47(
2800
+ Link8,
2801
+ {
2802
+ href: `/docs/${version}/${doc.slug}`,
2803
+ className: "group block p-5 rounded-xl border border-border bg-card hover:bg-accent hover:border-primary/50 transition-all duration-200",
2804
+ style: {
2805
+ textDecoration: "none !important"
2806
+ },
2807
+ children: /* @__PURE__ */ jsxs36("div", { className: "flex items-start justify-between gap-4", children: [
2808
+ /* @__PURE__ */ jsxs36("div", { className: "flex-1 min-w-0", children: [
2809
+ /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 mb-2", children: [
2810
+ /* @__PURE__ */ jsx47(FileText2, { className: "h-6 w-6 text-primary shrink-0" }),
2811
+ /* @__PURE__ */ jsx47("h3", { className: "text-lg font-semibold text-foreground group-hover:text-primary transition-colors", children: doc.meta.title || doc.title })
2812
+ ] }),
2813
+ doc.meta.description && /* @__PURE__ */ jsx47("p", { className: "text-sm text-muted-foreground line-clamp-2", children: doc.meta.description }),
2814
+ doc.meta.reading_time && /* @__PURE__ */ jsxs36("p", { className: "text-xs text-muted-foreground mt-2", children: [
2815
+ doc.meta.reading_time,
2816
+ " min read"
2817
+ ] })
2818
+ ] }),
2819
+ /* @__PURE__ */ jsx47(ChevronRight4, { className: "h-5 w-5 text-muted-foreground group-hover:text-primary group-hover:translate-x-1 transition-all flex-shrink-0 mt-1" })
2820
+ ] })
2821
+ },
2822
+ doc.slug
2823
+ )) }),
2824
+ sortedDocs.length === 0 && /* @__PURE__ */ jsxs36("div", { className: "text-center py-12 text-muted-foreground", children: [
2825
+ /* @__PURE__ */ jsx47(FileText2, { className: "h-12 w-12 mx-auto mb-3 opacity-50" }),
2826
+ /* @__PURE__ */ jsx47("p", { children: "No documents found in this category." })
2827
+ ] })
2828
+ ] });
2829
+ }
2830
+
2831
+ // src/components/docs/not-found-content.tsx
2832
+ import Link9 from "next/link";
2833
+ import { AlertTriangle as AlertTriangle2, Home, ArrowLeft } from "lucide-react";
2834
+ import { jsx as jsx48, jsxs as jsxs37 } from "react/jsx-runtime";
2835
+ function NotFoundContent({ version }) {
2836
+ return /* @__PURE__ */ jsx48("div", { className: "flex min-h-[calc(100vh-12rem)] items-center justify-center px-4 py-12", children: /* @__PURE__ */ jsxs37("div", { className: "w-full max-w-2xl text-center", children: [
2837
+ /* @__PURE__ */ jsx48("div", { className: "mb-6 flex justify-center", children: /* @__PURE__ */ jsx48("div", { className: "rounded-full bg-yellow-500/10 p-4", children: /* @__PURE__ */ jsx48(AlertTriangle2, { className: "h-16 w-16 text-yellow-500" }) }) }),
2838
+ /* @__PURE__ */ jsx48("h1", { className: "mb-3 text-5xl font-bold tracking-tight", children: "404" }),
2839
+ /* @__PURE__ */ jsx48("h2", { className: "mb-4 text-2xl font-semibold", children: "Page Not Found" }),
2840
+ /* @__PURE__ */ jsxs37("p", { className: "mb-8 text-base text-muted-foreground", children: [
2841
+ "The documentation page you're looking for doesn't exist or may have been moved.",
2842
+ /* @__PURE__ */ jsx48("br", {}),
2843
+ "Try using the sidebar to find what you're looking for, or return to the documentation home."
2844
+ ] }),
2845
+ /* @__PURE__ */ jsxs37("div", { className: "flex flex-col items-center justify-center gap-3 sm:flex-row", children: [
2846
+ /* @__PURE__ */ jsxs37(
2847
+ Link9,
2848
+ {
2849
+ href: `/docs/${version}`,
2850
+ className: "inline-flex items-center gap-2 rounded-lg bg-primary px-6 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
2851
+ children: [
2852
+ /* @__PURE__ */ jsx48(ArrowLeft, { className: "h-4 w-4" }),
2853
+ "Back to Documentation"
2854
+ ]
2855
+ }
2856
+ ),
2857
+ /* @__PURE__ */ jsxs37(
2858
+ Link9,
2859
+ {
2860
+ href: "/",
2861
+ className: "inline-flex items-center gap-2 rounded-lg border border-border bg-background px-6 py-3 text-sm font-medium hover:bg-muted transition-colors",
2862
+ children: [
2863
+ /* @__PURE__ */ jsx48(Home, { className: "h-4 w-4" }),
2864
+ "Go to Homepage"
2865
+ ]
2866
+ }
2867
+ )
2868
+ ] }),
2869
+ /* @__PURE__ */ jsx48("div", { className: "mt-12 rounded-lg border border-border bg-muted/30 p-6", children: /* @__PURE__ */ jsxs37("p", { className: "text-sm text-muted-foreground", children: [
2870
+ /* @__PURE__ */ jsx48("strong", { className: "font-medium text-foreground", children: "Tip:" }),
2871
+ " Use the sidebar navigation on the left to browse all available documentation pages."
2872
+ ] }) })
2873
+ ] }) });
2874
+ }
2875
+
2876
+ // src/app/docs-page.tsx
2877
+ import { Suspense } from "react";
2878
+
2879
+ // src/components/docs/doc-loading.tsx
2880
+ import { jsx as jsx49, jsxs as jsxs38 } from "react/jsx-runtime";
2881
+ function DocLoading() {
2882
+ return /* @__PURE__ */ jsx49("div", { className: "max-w-4xl mx-auto px-6 py-8", children: /* @__PURE__ */ jsxs38("div", { className: "animate-pulse space-y-4", children: [
2883
+ /* @__PURE__ */ jsx49("div", { className: "h-8 bg-gray-200 rounded w-3/4" }),
2884
+ /* @__PURE__ */ jsx49("div", { className: "h-4 bg-gray-200 rounded w-1/2" }),
2885
+ /* @__PURE__ */ jsxs38("div", { className: "space-y-3 mt-8", children: [
2886
+ /* @__PURE__ */ jsx49("div", { className: "h-4 bg-gray-200 rounded" }),
2887
+ /* @__PURE__ */ jsx49("div", { className: "h-4 bg-gray-200 rounded w-5/6" }),
2888
+ /* @__PURE__ */ jsx49("div", { className: "h-4 bg-gray-200 rounded w-4/6" })
2889
+ ] })
2890
+ ] }) });
2891
+ }
2892
+
2893
+ // src/app/docs-page.tsx
2894
+ import { Fragment as Fragment9, jsx as jsx50, jsxs as jsxs39 } from "react/jsx-runtime";
2895
+ async function generateMetadata({ params }) {
2896
+ const { version, slug: slugArray } = await params;
2897
+ const slug = slugArray.join("/");
2898
+ const doc = await getCachedDocBySlug(slug, version);
2899
+ if (!doc) {
2900
+ return {
2901
+ title: "Page Not Found",
2902
+ description: "The requested documentation page could not be found."
2903
+ };
2904
+ }
2905
+ const title = doc.meta.title || doc.title;
2906
+ const description = doc.meta.description || `Documentation for ${title}`;
2907
+ const url = `/docs/${version}/${slug}`;
2908
+ return {
2909
+ title: `${title}`,
2910
+ description,
2911
+ openGraph: {
2912
+ title,
2913
+ description,
2914
+ url,
2915
+ siteName: "Documentation Platform",
2916
+ type: "article",
2917
+ locale: "en_US"
2918
+ },
2919
+ twitter: {
2920
+ card: "summary_large_image",
2921
+ title,
2922
+ description
2923
+ },
2924
+ alternates: {
2925
+ canonical: url
2926
+ }
2927
+ };
2928
+ }
2929
+ async function generateStaticParams() {
2930
+ const versions = getCachedVersions();
2931
+ const params = [];
2932
+ for (const version of versions) {
2933
+ const docs = await getCachedAllDocs(version);
2934
+ for (const doc of docs) {
2935
+ params.push({
2936
+ version,
2937
+ slug: doc.slug.split("/").filter(Boolean)
2938
+ });
2939
+ }
2940
+ }
2941
+ return params;
2942
+ }
2943
+ async function DocPage({ params }) {
2944
+ const { version, slug: slugArray } = await params;
2945
+ const slug = slugArray.join("/");
2946
+ const allDocs = await getCachedAllDocs(version);
2947
+ const versions = getCachedVersions();
2948
+ const config = getConfig();
2949
+ const isCategory = isCategoryPage(slug, allDocs);
2950
+ const doc = await getCachedDocBySlug(slug, version);
2951
+ if (!doc && isCategory) {
2952
+ const categoryDoc = allDocs.find((d) => d.slug.startsWith(slug + "/"));
2953
+ const categoryTabGroup = categoryDoc?.meta?.tab_group || categoryDoc?.categoryTabGroup;
2954
+ return /* @__PURE__ */ jsxs39(Fragment9, { children: [
2955
+ /* @__PURE__ */ jsx50(
2956
+ DocLayoutWrapper,
2957
+ {
2958
+ header: /* @__PURE__ */ jsx50(Header, { currentVersion: version, versions, config }),
2959
+ docs: allDocs,
2960
+ version,
2961
+ content: /* @__PURE__ */ jsx50(
2962
+ CategoryIndex,
2963
+ {
2964
+ categoryPath: slug,
2965
+ version,
2966
+ allDocs,
2967
+ title: slug.split("/").pop()?.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()) || "Category",
2968
+ description: "Browse the documentation in this section.",
2969
+ config
2970
+ }
2971
+ ),
2972
+ toc: /* @__PURE__ */ jsx50("div", {}),
2973
+ config,
2974
+ currentPageTabGroup: categoryTabGroup
2975
+ }
2976
+ ),
2977
+ /* @__PURE__ */ jsx50(MdxHotReload, {}),
2978
+ /* @__PURE__ */ jsx50(HotReloadIndicator, {}),
2979
+ /* @__PURE__ */ jsx50(DevModeBadge, {})
2980
+ ] });
2981
+ }
2982
+ if (!doc) {
2983
+ return /* @__PURE__ */ jsx50(Fragment9, { children: /* @__PURE__ */ jsxs39(Suspense, { fallback: /* @__PURE__ */ jsx50(DocLoading, {}), children: [
2984
+ /* @__PURE__ */ jsx50(
2985
+ DocLayoutWrapper,
2986
+ {
2987
+ header: /* @__PURE__ */ jsx50(Header, { currentVersion: version, versions, config }),
2988
+ docs: allDocs,
2989
+ version,
2990
+ content: /* @__PURE__ */ jsx50(NotFoundContent, { version }),
2991
+ toc: /* @__PURE__ */ jsx50("div", {}),
2992
+ config,
2993
+ currentPageTabGroup: void 0
2994
+ }
2995
+ ),
2996
+ /* @__PURE__ */ jsx50(MdxHotReload, {}),
2997
+ /* @__PURE__ */ jsx50(HotReloadIndicator, {}),
2998
+ /* @__PURE__ */ jsx50(DevModeBadge, {})
2999
+ ] }) });
3000
+ }
3001
+ const toc = extractTableOfContents(doc.content);
3002
+ const { previous, next } = getAdjacentDocs(slug, allDocs);
3003
+ const showCategoryIndex = isCategory && doc;
3004
+ const currentPageTabGroup = doc.meta?.tab_group || doc.categoryTabGroup;
3005
+ return /* @__PURE__ */ jsx50(Fragment9, { children: /* @__PURE__ */ jsxs39(Suspense, { fallback: /* @__PURE__ */ jsx50(DocLoading, {}), children: [
3006
+ /* @__PURE__ */ jsx50(
3007
+ DocLayoutWrapper,
3008
+ {
3009
+ header: /* @__PURE__ */ jsx50(Header, { currentVersion: version, versions, config }),
3010
+ docs: allDocs,
3011
+ version,
3012
+ content: showCategoryIndex ? /* @__PURE__ */ jsx50(
3013
+ CategoryIndex,
3014
+ {
3015
+ categoryPath: slug,
3016
+ version,
3017
+ allDocs,
3018
+ title: doc.meta.title,
3019
+ description: doc.meta.description,
3020
+ content: doc.content,
3021
+ config
3022
+ }
3023
+ ) : /* @__PURE__ */ jsx50(
3024
+ DocLayout,
3025
+ {
3026
+ meta: doc.meta,
3027
+ content: doc.content,
3028
+ previousDoc: previous ? { title: previous.meta.title, slug: previous.slug } : void 0,
3029
+ nextDoc: next ? { title: next.meta.title, slug: next.slug } : void 0,
3030
+ version,
3031
+ slug,
3032
+ config
3033
+ }
3034
+ ),
3035
+ toc: showCategoryIndex ? /* @__PURE__ */ jsx50("div", {}) : /* @__PURE__ */ jsx50(TableOfContents, { items: toc, config }),
3036
+ config,
3037
+ currentPageTabGroup
3038
+ }
3039
+ ),
3040
+ /* @__PURE__ */ jsx50(MdxHotReload, {}),
3041
+ /* @__PURE__ */ jsx50(HotReloadIndicator, {}),
3042
+ /* @__PURE__ */ jsx50(DevModeBadge, {})
3043
+ ] }) });
3044
+ }
3045
+
3046
+ export {
3047
+ AccordionItem,
3048
+ Accordion,
3049
+ Badge,
3050
+ Breadcrumb,
3051
+ Callout,
3052
+ Icon,
3053
+ Card,
3054
+ CardGrid,
3055
+ CodeBlock,
3056
+ Tab,
3057
+ Tabs,
3058
+ Image,
3059
+ Video,
3060
+ ImageCard,
3061
+ ImageCardGrid,
3062
+ Steps,
3063
+ Step,
3064
+ Mermaid,
3065
+ Math2 as Math,
3066
+ Columns,
3067
+ Column,
3068
+ Tooltip,
3069
+ Frame,
3070
+ ApiEndpoint,
3071
+ ApiParams,
3072
+ ApiResponse,
3073
+ buttonVariants,
3074
+ Button,
3075
+ Input,
3076
+ Textarea,
3077
+ badgeVariants,
3078
+ Badge2,
3079
+ ApiPlayground,
3080
+ ApiReference,
3081
+ mdxComponents,
3082
+ CategoryIndex,
3083
+ DevModeBadge,
3084
+ DocNavigation,
3085
+ DocMetadata,
3086
+ DraftBadge,
3087
+ DocTags,
3088
+ SearchHighlight,
3089
+ DocLayout,
3090
+ Footer,
3091
+ SiteBanner,
3092
+ TabGroups,
3093
+ Sidebar,
3094
+ MobileDocLayout,
3095
+ DocLayoutWrapper,
3096
+ DocLoading,
3097
+ VersionSwitcher,
3098
+ ThemeToggle,
3099
+ Dialog,
3100
+ DialogTrigger,
3101
+ DialogPortal,
3102
+ DialogClose,
3103
+ DialogOverlay,
3104
+ DialogContent,
3105
+ DialogHeader,
3106
+ DialogFooter,
3107
+ DialogTitle,
3108
+ DialogDescription,
3109
+ SearchModal,
3110
+ Header,
3111
+ HotReloadIndicator,
3112
+ MdxHotReload,
3113
+ NotFoundContent,
3114
+ TableOfContents,
3115
+ generateMetadata,
3116
+ generateStaticParams,
3117
+ DocPage
3118
+ };
3119
+ //# sourceMappingURL=chunk-NXRIAL7T.mjs.map