@plateerlab/xgen-gallery 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.
package/dist/index.js ADDED
@@ -0,0 +1,571 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ XgenGallery: () => XgenGallery
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/XgenGallery.tsx
38
+ var import_react = require("react");
39
+
40
+ // src/api.ts
41
+ var API = "https://api.github.com";
42
+ function headers(token) {
43
+ const h = { Accept: "application/vnd.github.v3+json" };
44
+ if (token) h.Authorization = `Bearer ${token}`;
45
+ return h;
46
+ }
47
+ async function fetchRepos(org, token) {
48
+ try {
49
+ const res = await fetch(`${API}/orgs/${org}/repos?per_page=100&sort=updated`, {
50
+ headers: headers(token)
51
+ });
52
+ if (!res.ok) return [];
53
+ return res.json();
54
+ } catch {
55
+ return [];
56
+ }
57
+ }
58
+ async function fetchReadme(org, repo, token) {
59
+ try {
60
+ const res = await fetch(`${API}/repos/${org}/${repo}/readme`, {
61
+ headers: { ...headers(token), Accept: "application/vnd.github.v3.raw" }
62
+ });
63
+ if (!res.ok) return null;
64
+ return res.text();
65
+ } catch {
66
+ return null;
67
+ }
68
+ }
69
+ async function fetchDemoSnippets(org, repo, readme, token) {
70
+ for (const path of [".xgen-gallery/demo.json", "demo.json"]) {
71
+ try {
72
+ const res = await fetch(`${API}/repos/${org}/${repo}/contents/${path}`, {
73
+ headers: { ...headers(token), Accept: "application/vnd.github.v3.raw" }
74
+ });
75
+ if (!res.ok) continue;
76
+ const data = await res.json();
77
+ if (data.snippets?.length) return data.snippets;
78
+ } catch {
79
+ continue;
80
+ }
81
+ }
82
+ try {
83
+ const res = await fetch(`${API}/repos/${org}/${repo}/contents/examples`, {
84
+ headers: headers(token)
85
+ });
86
+ if (res.ok) {
87
+ const files = await res.json();
88
+ const pyFiles = files.filter((f) => f.name.endsWith(".py")).slice(0, 5);
89
+ const snippets = [];
90
+ for (const f of pyFiles) {
91
+ try {
92
+ const r = await fetch(f.download_url);
93
+ if (r.ok) {
94
+ const code = await r.text();
95
+ snippets.push({ label: f.name.replace(/\.py$/, "").replace(/[_-]/g, " "), code: code.trim() });
96
+ }
97
+ } catch {
98
+ continue;
99
+ }
100
+ }
101
+ if (snippets.length) return snippets;
102
+ }
103
+ } catch {
104
+ }
105
+ let md = readme;
106
+ if (!md) md = await fetchReadme(org, repo, token);
107
+ if (md) {
108
+ const blocks = extractPythonBlocks(md);
109
+ if (blocks.length) return blocks;
110
+ }
111
+ return [];
112
+ }
113
+ function extractPythonBlocks(readme) {
114
+ const snippets = [];
115
+ const lines = readme.split("\n");
116
+ let i = 0;
117
+ while (i < lines.length) {
118
+ if (/^```(?:python|py)\s*$/i.test(lines[i].trim())) {
119
+ let label = "";
120
+ for (let j = i - 1; j >= Math.max(0, i - 5); j--) {
121
+ const prev = lines[j].trim();
122
+ if (/^#{1,4}\s+/.test(prev)) {
123
+ label = prev.replace(/^#+\s+/, "");
124
+ break;
125
+ }
126
+ if (prev && !label) label = prev;
127
+ }
128
+ const codeLines = [];
129
+ i++;
130
+ while (i < lines.length && !lines[i].trim().startsWith("```")) {
131
+ codeLines.push(lines[i]);
132
+ i++;
133
+ }
134
+ const code = codeLines.join("\n").trim();
135
+ if (code && code.split("\n").length >= 2 && !code.startsWith("pip ") && !code.startsWith("$ pip")) {
136
+ snippets.push({ label: label || `Example ${snippets.length + 1}`, code });
137
+ }
138
+ }
139
+ i++;
140
+ }
141
+ return snippets;
142
+ }
143
+
144
+ // src/styles.ts
145
+ var themes = {
146
+ dark: {
147
+ bg: "#0a0a0f",
148
+ bgCard: "#12121a",
149
+ bgCardHover: "#1a1a25",
150
+ border: "#1e1e2e",
151
+ text: "#e8e8f0",
152
+ textSecondary: "#a0a0b8",
153
+ textMuted: "#6b6b80",
154
+ accent: "#6c63ff",
155
+ accentLight: "#8b83ff",
156
+ accentGlow: "rgba(108,99,255,0.15)"
157
+ },
158
+ light: {
159
+ bg: "#f8f9fa",
160
+ bgCard: "#ffffff",
161
+ bgCardHover: "#f0f0f5",
162
+ border: "#e0e0e8",
163
+ text: "#1a1a2e",
164
+ textSecondary: "#4a4a5a",
165
+ textMuted: "#8a8a9a",
166
+ accent: "#5b52e0",
167
+ accentLight: "#5b52e0",
168
+ accentGlow: "rgba(91,82,224,0.1)"
169
+ }
170
+ };
171
+ var LANG_COLORS = {
172
+ Python: "#3572A5",
173
+ TypeScript: "#3178c6",
174
+ JavaScript: "#f1e05a",
175
+ Rust: "#dea584",
176
+ HTML: "#e34c26",
177
+ CSS: "#563d7c",
178
+ Go: "#00ADD8",
179
+ Shell: "#89e051",
180
+ Java: "#b07219",
181
+ "C++": "#f34b7d",
182
+ C: "#555555",
183
+ Ruby: "#701516"
184
+ };
185
+
186
+ // src/ReadmeView.tsx
187
+ var import_react_markdown = __toESM(require("react-markdown"));
188
+ var import_remark_gfm = __toESM(require("remark-gfm"));
189
+ var import_rehype_raw = __toESM(require("rehype-raw"));
190
+ var import_jsx_runtime = require("react/jsx-runtime");
191
+ function ReadmeView({
192
+ org,
193
+ repoName,
194
+ content,
195
+ t
196
+ }) {
197
+ if (!content) {
198
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { textAlign: "center", padding: 40, color: t.textMuted }, children: "README not found" });
199
+ }
200
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "xgen-markdown", style: { color: t.text, lineHeight: 1.7, fontSize: 14 }, children: [
201
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: markdownStyles(t) }),
202
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
203
+ import_react_markdown.default,
204
+ {
205
+ remarkPlugins: [import_remark_gfm.default],
206
+ rehypePlugins: [import_rehype_raw.default],
207
+ components: {
208
+ img: ({ src, alt, ...props }) => {
209
+ let resolved = src;
210
+ if (typeof src === "string" && !src.startsWith("http")) {
211
+ resolved = `https://raw.githubusercontent.com/${org}/${repoName}/main/${src}`;
212
+ }
213
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: resolved, alt: alt || "", style: { maxWidth: "100%" }, ...props });
214
+ },
215
+ a: ({ href, children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href, target: "_blank", rel: "noopener noreferrer", style: { color: t.accentLight }, ...props, children }),
216
+ code: ({ children, className, ...props }) => {
217
+ const isBlock = className?.includes("language-");
218
+ if (isBlock) {
219
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
220
+ "code",
221
+ {
222
+ style: {
223
+ display: "block",
224
+ background: t.bg,
225
+ padding: 16,
226
+ borderRadius: 8,
227
+ overflow: "auto",
228
+ fontSize: 13,
229
+ lineHeight: 1.6
230
+ },
231
+ ...props,
232
+ children
233
+ }
234
+ );
235
+ }
236
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { style: { background: t.accentGlow, padding: "2px 6px", borderRadius: 4, fontSize: 13 }, ...props, children });
237
+ }
238
+ },
239
+ children: content
240
+ }
241
+ )
242
+ ] });
243
+ }
244
+ function markdownStyles(t) {
245
+ return `
246
+ .xgen-markdown h1, .xgen-markdown h2, .xgen-markdown h3 { color: ${t.text}; margin: 1.2em 0 0.5em; }
247
+ .xgen-markdown h1 { font-size: 1.8em; border-bottom: 1px solid ${t.border}; padding-bottom: 8px; }
248
+ .xgen-markdown h2 { font-size: 1.4em; border-bottom: 1px solid ${t.border}; padding-bottom: 6px; }
249
+ .xgen-markdown h3 { font-size: 1.15em; }
250
+ .xgen-markdown p { margin: 0.8em 0; }
251
+ .xgen-markdown ul, .xgen-markdown ol { padding-left: 24px; }
252
+ .xgen-markdown li { margin: 4px 0; }
253
+ .xgen-markdown pre { background: ${t.bg}; border: 1px solid ${t.border}; border-radius: 8px; padding: 16px; overflow: auto; margin: 12px 0; }
254
+ .xgen-markdown blockquote { border-left: 3px solid ${t.accent}; padding-left: 12px; color: ${t.textSecondary}; margin: 12px 0; }
255
+ .xgen-markdown table { border-collapse: collapse; width: 100%; margin: 12px 0; }
256
+ .xgen-markdown th, .xgen-markdown td { border: 1px solid ${t.border}; padding: 8px 12px; text-align: left; }
257
+ .xgen-markdown th { background: ${t.bgCard}; font-weight: 600; }
258
+ .xgen-markdown hr { border: none; border-top: 1px solid ${t.border}; margin: 16px 0; }
259
+ `;
260
+ }
261
+
262
+ // src/XgenGallery.tsx
263
+ var import_jsx_runtime2 = require("react/jsx-runtime");
264
+ function XgenGallery({ org, token, theme: themeName = "dark", limit, onRepoClick }) {
265
+ const t = themes[themeName];
266
+ const [repos, setRepos] = (0, import_react.useState)([]);
267
+ const [loading, setLoading] = (0, import_react.useState)(true);
268
+ const [search, setSearch] = (0, import_react.useState)("");
269
+ const [lang, setLang] = (0, import_react.useState)(null);
270
+ const [view, setView] = (0, import_react.useState)({ type: "list" });
271
+ (0, import_react.useEffect)(() => {
272
+ fetchRepos(org, token).then((data) => {
273
+ setRepos(limit ? data.slice(0, limit) : data);
274
+ setLoading(false);
275
+ });
276
+ }, [org, token, limit]);
277
+ const languages = [...new Set(repos.map((r) => r.language).filter(Boolean))];
278
+ const filtered = repos.filter((r) => {
279
+ if (lang && r.language !== lang) return false;
280
+ if (search) {
281
+ const q = search.toLowerCase();
282
+ return r.name.toLowerCase().includes(q) || (r.description || "").toLowerCase().includes(q);
283
+ }
284
+ return true;
285
+ });
286
+ const handleCardClick = (0, import_react.useCallback)((repo) => {
287
+ if (onRepoClick) {
288
+ onRepoClick(repo);
289
+ } else {
290
+ setView({ type: "detail", repo });
291
+ }
292
+ }, [onRepoClick]);
293
+ if (view.type === "detail") {
294
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RepoDetail, { org, repo: view.repo, token, t, onBack: () => setView({ type: "list" }) });
295
+ }
296
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { background: t.bg, color: t.text, fontFamily: "system-ui, -apple-system, sans-serif", padding: 24 }, children: [
297
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginBottom: 24 }, children: [
298
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { style: { fontSize: 24, fontWeight: 700, margin: 0 }, children: org }),
299
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { style: { color: t.textMuted, fontSize: 14, margin: "4px 0 0" }, children: [
300
+ repos.length,
301
+ " repositories"
302
+ ] })
303
+ ] }),
304
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap", marginBottom: 16 }, children: [
305
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
306
+ "input",
307
+ {
308
+ type: "text",
309
+ placeholder: "Search...",
310
+ value: search,
311
+ onChange: (e) => setSearch(e.target.value),
312
+ style: {
313
+ background: t.bgCard,
314
+ border: `1px solid ${t.border}`,
315
+ borderRadius: 8,
316
+ padding: "8px 12px",
317
+ color: t.text,
318
+ fontSize: 14,
319
+ outline: "none",
320
+ flex: "1 1 200px"
321
+ }
322
+ }
323
+ ),
324
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
325
+ "button",
326
+ {
327
+ onClick: () => setLang(null),
328
+ style: {
329
+ padding: "6px 12px",
330
+ borderRadius: 8,
331
+ fontSize: 12,
332
+ fontWeight: 500,
333
+ cursor: "pointer",
334
+ background: !lang ? t.accent : "transparent",
335
+ color: !lang ? "#fff" : t.textMuted,
336
+ border: `1px solid ${!lang ? t.accent : t.border}`
337
+ },
338
+ children: "All"
339
+ }
340
+ ),
341
+ languages.map((l) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
342
+ "button",
343
+ {
344
+ onClick: () => setLang(lang === l ? null : l),
345
+ style: {
346
+ padding: "6px 12px",
347
+ borderRadius: 8,
348
+ fontSize: 12,
349
+ fontWeight: 500,
350
+ cursor: "pointer",
351
+ background: lang === l ? t.accent : "transparent",
352
+ color: lang === l ? "#fff" : t.textMuted,
353
+ border: `1px solid ${lang === l ? t.accent : t.border}`
354
+ },
355
+ children: l
356
+ },
357
+ l
358
+ ))
359
+ ] }),
360
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { textAlign: "center", padding: 60, color: t.textMuted }, children: "Loading..." }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(300px, 1fr))", gap: 16 }, children: filtered.map((repo) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RepoCard, { repo, t, onClick: () => handleCardClick(repo) }, repo.name)) }),
361
+ !loading && filtered.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { textAlign: "center", padding: 60, color: t.textMuted }, children: "No results" })
362
+ ] });
363
+ }
364
+ function RepoCard({ repo, t, onClick }) {
365
+ const [hover, setHover] = (0, import_react.useState)(false);
366
+ const langColor = repo.language ? LANG_COLORS[repo.language] || "#888" : null;
367
+ const date = new Date(repo.updated_at).toLocaleDateString("ko-KR", { year: "numeric", month: "short", day: "numeric" });
368
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
369
+ "div",
370
+ {
371
+ onClick,
372
+ onMouseEnter: () => setHover(true),
373
+ onMouseLeave: () => setHover(false),
374
+ style: {
375
+ background: hover ? t.bgCardHover : t.bgCard,
376
+ border: `1px solid ${hover ? t.accent : t.border}`,
377
+ borderRadius: 12,
378
+ padding: 20,
379
+ cursor: "pointer",
380
+ transform: hover ? "translateY(-2px)" : "none",
381
+ boxShadow: hover ? `0 0 20px ${t.accentGlow}` : "none",
382
+ transition: "all 0.2s"
383
+ },
384
+ children: [
385
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: 8 }, children: [
386
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 16, fontWeight: 600, color: t.accentLight }, children: repo.name }),
387
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
388
+ "button",
389
+ {
390
+ onClick: (e) => {
391
+ e.stopPropagation();
392
+ window.open(repo.html_url, "_blank");
393
+ },
394
+ style: {
395
+ fontSize: 11,
396
+ padding: "2px 8px",
397
+ borderRadius: 6,
398
+ cursor: "pointer",
399
+ border: `1px solid ${t.border}`,
400
+ background: "transparent",
401
+ color: t.textMuted
402
+ },
403
+ children: "GitHub \u2192"
404
+ }
405
+ )
406
+ ] }),
407
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { fontSize: 13, color: t.textSecondary, margin: "0 0 12px", lineHeight: 1.5, minHeight: 40 }, children: repo.description || "No description" }),
408
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: 12, fontSize: 12, color: t.textMuted }, children: [
409
+ langColor && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
410
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { width: 10, height: 10, borderRadius: "50%", background: langColor, display: "inline-block" } }),
411
+ repo.language
412
+ ] }),
413
+ repo.stargazers_count > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
414
+ "\u2605 ",
415
+ repo.stargazers_count
416
+ ] }),
417
+ repo.forks_count > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
418
+ "Fork ",
419
+ repo.forks_count
420
+ ] }),
421
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: date })
422
+ ] })
423
+ ]
424
+ }
425
+ );
426
+ }
427
+ function RepoDetail({ org, repo, token, t, onBack }) {
428
+ const [tab, setTab] = (0, import_react.useState)("readme");
429
+ const [readme, setReadme] = (0, import_react.useState)(null);
430
+ const [snippets, setSnippets] = (0, import_react.useState)([]);
431
+ const [loading, setLoading] = (0, import_react.useState)(true);
432
+ (0, import_react.useEffect)(() => {
433
+ Promise.all([
434
+ fetchReadme(org, repo.name, token),
435
+ fetchDemoSnippets(org, repo.name, void 0, token)
436
+ ]).then(([md, s]) => {
437
+ setReadme(md);
438
+ setSnippets(s);
439
+ setLoading(false);
440
+ });
441
+ }, [org, repo.name, token]);
442
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { background: t.bg, color: t.text, fontFamily: "system-ui, -apple-system, sans-serif", padding: 24 }, children: [
443
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
444
+ "button",
445
+ {
446
+ onClick: onBack,
447
+ style: {
448
+ background: "transparent",
449
+ border: "none",
450
+ color: t.accentLight,
451
+ cursor: "pointer",
452
+ fontSize: 14,
453
+ padding: 0,
454
+ marginBottom: 16
455
+ },
456
+ children: "\u2190 Back"
457
+ }
458
+ ),
459
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { background: t.bgCard, border: `1px solid ${t.border}`, borderRadius: 12, padding: 24, marginBottom: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", flexWrap: "wrap", gap: 16 }, children: [
460
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
461
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { style: { fontSize: 22, fontWeight: 700, margin: 0 }, children: repo.name }),
462
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { color: t.textSecondary, fontSize: 14, margin: "8px 0" }, children: repo.description || "No description" })
463
+ ] }),
464
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
465
+ "a",
466
+ {
467
+ href: repo.html_url,
468
+ target: "_blank",
469
+ rel: "noopener noreferrer",
470
+ style: {
471
+ display: "inline-flex",
472
+ alignItems: "center",
473
+ gap: 8,
474
+ padding: "8px 16px",
475
+ borderRadius: 8,
476
+ fontSize: 14,
477
+ fontWeight: 500,
478
+ background: t.accent,
479
+ color: "#fff",
480
+ textDecoration: "none",
481
+ height: "fit-content"
482
+ },
483
+ children: "View on GitHub"
484
+ }
485
+ )
486
+ ] }) }),
487
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", gap: 4, borderBottom: `1px solid ${t.border}`, marginBottom: 16 }, children: ["readme", ...snippets.length > 0 ? ["demo"] : []].map((key) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
488
+ "button",
489
+ {
490
+ onClick: () => setTab(key),
491
+ style: {
492
+ padding: "10px 16px",
493
+ fontSize: 14,
494
+ fontWeight: 500,
495
+ cursor: "pointer",
496
+ background: "transparent",
497
+ border: "none",
498
+ color: tab === key ? t.accentLight : t.textMuted,
499
+ borderBottom: tab === key ? `2px solid ${t.accent}` : "2px solid transparent"
500
+ },
501
+ children: key === "readme" ? "README" : "Demo"
502
+ },
503
+ key
504
+ )) }),
505
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { background: t.bgCard, border: `1px solid ${t.border}`, borderRadius: 12, padding: 24 }, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { textAlign: "center", padding: 40, color: t.textMuted }, children: "Loading..." }) : tab === "readme" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ReadmeView, { org, repoName: repo.name, content: readme, t }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DemoView, { snippets, t }) })
506
+ ] });
507
+ }
508
+ function DemoView({ snippets, t }) {
509
+ const [idx, setIdx] = (0, import_react.useState)(0);
510
+ const snippet = snippets[idx];
511
+ if (!snippet) return null;
512
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
513
+ snippets.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", gap: 6, marginBottom: 12, flexWrap: "wrap" }, children: snippets.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
514
+ "button",
515
+ {
516
+ onClick: () => setIdx(i),
517
+ style: {
518
+ padding: "4px 12px",
519
+ borderRadius: 99,
520
+ fontSize: 12,
521
+ cursor: "pointer",
522
+ background: i === idx ? t.accentGlow : "transparent",
523
+ color: i === idx ? t.accentLight : t.textMuted,
524
+ border: `1px solid ${i === idx ? t.accent : t.border}`
525
+ },
526
+ children: s.label
527
+ },
528
+ i
529
+ )) }),
530
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
531
+ "pre",
532
+ {
533
+ style: {
534
+ background: t.bg,
535
+ border: `1px solid ${t.border}`,
536
+ borderRadius: 8,
537
+ padding: 16,
538
+ fontSize: 13,
539
+ lineHeight: 1.6,
540
+ overflow: "auto",
541
+ color: t.textSecondary,
542
+ margin: 0
543
+ },
544
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { children: snippet.code })
545
+ }
546
+ ),
547
+ snippet.expectedOutput && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginTop: 12 }, children: [
548
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 12, color: t.textMuted }, children: "Expected Output:" }),
549
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
550
+ "pre",
551
+ {
552
+ style: {
553
+ background: t.bg,
554
+ border: `1px solid ${t.border}`,
555
+ borderRadius: 8,
556
+ padding: 12,
557
+ fontSize: 12,
558
+ color: t.textMuted,
559
+ margin: "4px 0 0"
560
+ },
561
+ children: snippet.expectedOutput
562
+ }
563
+ )
564
+ ] })
565
+ ] });
566
+ }
567
+ // Annotate the CommonJS export names for ESM import in node:
568
+ 0 && (module.exports = {
569
+ XgenGallery
570
+ });
571
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/XgenGallery.tsx","../src/api.ts","../src/styles.ts","../src/ReadmeView.tsx"],"sourcesContent":["export { XgenGallery } from \"./XgenGallery\";\r\nexport type { GalleryProps, Repo, DemoSnippet } from \"./types\";\r\n","import { useEffect, useState, useCallback } from \"react\";\r\nimport type { Repo, GalleryProps, DemoSnippet } from \"./types\";\r\nimport { fetchRepos, fetchReadme, fetchDemoSnippets } from \"./api\";\r\nimport { themes, LANG_COLORS, Theme } from \"./styles\";\r\nimport { ReadmeView } from \"./ReadmeView\";\r\n\r\ntype View = { type: \"list\" } | { type: \"detail\"; repo: Repo };\r\n\r\nexport function XgenGallery({ org, token, theme: themeName = \"dark\", limit, onRepoClick }: GalleryProps) {\r\n const t = themes[themeName];\r\n const [repos, setRepos] = useState<Repo[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [search, setSearch] = useState(\"\");\r\n const [lang, setLang] = useState<string | null>(null);\r\n const [view, setView] = useState<View>({ type: \"list\" });\r\n\r\n useEffect(() => {\r\n fetchRepos(org, token).then((data) => {\r\n setRepos(limit ? data.slice(0, limit) : data);\r\n setLoading(false);\r\n });\r\n }, [org, token, limit]);\r\n\r\n const languages = [...new Set(repos.map((r) => r.language).filter(Boolean))] as string[];\r\n\r\n const filtered = repos.filter((r) => {\r\n if (lang && r.language !== lang) return false;\r\n if (search) {\r\n const q = search.toLowerCase();\r\n return r.name.toLowerCase().includes(q) || (r.description || \"\").toLowerCase().includes(q);\r\n }\r\n return true;\r\n });\r\n\r\n const handleCardClick = useCallback((repo: Repo) => {\r\n if (onRepoClick) {\r\n onRepoClick(repo);\r\n } else {\r\n setView({ type: \"detail\", repo });\r\n }\r\n }, [onRepoClick]);\r\n\r\n if (view.type === \"detail\") {\r\n return <RepoDetail org={org} repo={view.repo} token={token} t={t} onBack={() => setView({ type: \"list\" })} />;\r\n }\r\n\r\n return (\r\n <div style={{ background: t.bg, color: t.text, fontFamily: \"system-ui, -apple-system, sans-serif\", padding: 24 }}>\r\n {/* Header */}\r\n <div style={{ marginBottom: 24 }}>\r\n <h2 style={{ fontSize: 24, fontWeight: 700, margin: 0 }}>{org}</h2>\r\n <p style={{ color: t.textMuted, fontSize: 14, margin: \"4px 0 0\" }}>\r\n {repos.length} repositories\r\n </p>\r\n </div>\r\n\r\n {/* Search + Filter */}\r\n <div style={{ display: \"flex\", gap: 8, flexWrap: \"wrap\", marginBottom: 16 }}>\r\n <input\r\n type=\"text\"\r\n placeholder=\"Search...\"\r\n value={search}\r\n onChange={(e) => setSearch(e.target.value)}\r\n style={{\r\n background: t.bgCard, border: `1px solid ${t.border}`, borderRadius: 8,\r\n padding: \"8px 12px\", color: t.text, fontSize: 14, outline: \"none\", flex: \"1 1 200px\",\r\n }}\r\n />\r\n <button\r\n onClick={() => setLang(null)}\r\n style={{\r\n padding: \"6px 12px\", borderRadius: 8, fontSize: 12, fontWeight: 500, cursor: \"pointer\",\r\n background: !lang ? t.accent : \"transparent\",\r\n color: !lang ? \"#fff\" : t.textMuted,\r\n border: `1px solid ${!lang ? t.accent : t.border}`,\r\n }}\r\n >\r\n All\r\n </button>\r\n {languages.map((l) => (\r\n <button\r\n key={l}\r\n onClick={() => setLang(lang === l ? null : l)}\r\n style={{\r\n padding: \"6px 12px\", borderRadius: 8, fontSize: 12, fontWeight: 500, cursor: \"pointer\",\r\n background: lang === l ? t.accent : \"transparent\",\r\n color: lang === l ? \"#fff\" : t.textMuted,\r\n border: `1px solid ${lang === l ? t.accent : t.border}`,\r\n }}\r\n >\r\n {l}\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Grid */}\r\n {loading ? (\r\n <div style={{ textAlign: \"center\", padding: 60, color: t.textMuted }}>Loading...</div>\r\n ) : (\r\n <div style={{ display: \"grid\", gridTemplateColumns: \"repeat(auto-fill, minmax(300px, 1fr))\", gap: 16 }}>\r\n {filtered.map((repo) => (\r\n <RepoCard key={repo.name} repo={repo} t={t} onClick={() => handleCardClick(repo)} />\r\n ))}\r\n </div>\r\n )}\r\n {!loading && filtered.length === 0 && (\r\n <div style={{ textAlign: \"center\", padding: 60, color: t.textMuted }}>No results</div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/* ---------- RepoCard ---------- */\r\n\r\nfunction RepoCard({ repo, t, onClick }: { repo: Repo; t: Theme; onClick: () => void }) {\r\n const [hover, setHover] = useState(false);\r\n const langColor = repo.language ? LANG_COLORS[repo.language] || \"#888\" : null;\r\n const date = new Date(repo.updated_at).toLocaleDateString(\"ko-KR\", { year: \"numeric\", month: \"short\", day: \"numeric\" });\r\n\r\n return (\r\n <div\r\n onClick={onClick}\r\n onMouseEnter={() => setHover(true)}\r\n onMouseLeave={() => setHover(false)}\r\n style={{\r\n background: hover ? t.bgCardHover : t.bgCard,\r\n border: `1px solid ${hover ? t.accent : t.border}`,\r\n borderRadius: 12, padding: 20, cursor: \"pointer\",\r\n transform: hover ? \"translateY(-2px)\" : \"none\",\r\n boxShadow: hover ? `0 0 20px ${t.accentGlow}` : \"none\",\r\n transition: \"all 0.2s\",\r\n }}\r\n >\r\n <div style={{ display: \"flex\", justifyContent: \"space-between\", marginBottom: 8 }}>\r\n <span style={{ fontSize: 16, fontWeight: 600, color: t.accentLight }}>{repo.name}</span>\r\n <button\r\n onClick={(e) => { e.stopPropagation(); window.open(repo.html_url, \"_blank\"); }}\r\n style={{\r\n fontSize: 11, padding: \"2px 8px\", borderRadius: 6, cursor: \"pointer\",\r\n border: `1px solid ${t.border}`, background: \"transparent\", color: t.textMuted,\r\n }}\r\n >\r\n GitHub →\r\n </button>\r\n </div>\r\n <p style={{ fontSize: 13, color: t.textSecondary, margin: \"0 0 12px\", lineHeight: 1.5, minHeight: 40 }}>\r\n {repo.description || \"No description\"}\r\n </p>\r\n <div style={{ display: \"flex\", gap: 12, fontSize: 12, color: t.textMuted }}>\r\n {langColor && (\r\n <span style={{ display: \"flex\", alignItems: \"center\", gap: 4 }}>\r\n <span style={{ width: 10, height: 10, borderRadius: \"50%\", background: langColor, display: \"inline-block\" }} />\r\n {repo.language}\r\n </span>\r\n )}\r\n {repo.stargazers_count > 0 && <span>★ {repo.stargazers_count}</span>}\r\n {repo.forks_count > 0 && <span>Fork {repo.forks_count}</span>}\r\n <span>{date}</span>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n/* ---------- RepoDetail ---------- */\r\n\r\nfunction RepoDetail({ org, repo, token, t, onBack }: { org: string; repo: Repo; token?: string; t: Theme; onBack: () => void }) {\r\n const [tab, setTab] = useState<\"readme\" | \"demo\">(\"readme\");\r\n const [readme, setReadme] = useState<string | null>(null);\r\n const [snippets, setSnippets] = useState<DemoSnippet[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n\r\n useEffect(() => {\r\n Promise.all([\r\n fetchReadme(org, repo.name, token),\r\n fetchDemoSnippets(org, repo.name, undefined, token),\r\n ]).then(([md, s]) => {\r\n setReadme(md);\r\n setSnippets(s);\r\n setLoading(false);\r\n });\r\n }, [org, repo.name, token]);\r\n\r\n return (\r\n <div style={{ background: t.bg, color: t.text, fontFamily: \"system-ui, -apple-system, sans-serif\", padding: 24 }}>\r\n {/* Back */}\r\n <button\r\n onClick={onBack}\r\n style={{\r\n background: \"transparent\", border: \"none\", color: t.accentLight,\r\n cursor: \"pointer\", fontSize: 14, padding: 0, marginBottom: 16,\r\n }}\r\n >\r\n ← Back\r\n </button>\r\n\r\n {/* Header */}\r\n <div style={{ background: t.bgCard, border: `1px solid ${t.border}`, borderRadius: 12, padding: 24, marginBottom: 16 }}>\r\n <div style={{ display: \"flex\", justifyContent: \"space-between\", flexWrap: \"wrap\", gap: 16 }}>\r\n <div>\r\n <h1 style={{ fontSize: 22, fontWeight: 700, margin: 0 }}>{repo.name}</h1>\r\n <p style={{ color: t.textSecondary, fontSize: 14, margin: \"8px 0\" }}>{repo.description || \"No description\"}</p>\r\n </div>\r\n <a\r\n href={repo.html_url}\r\n target=\"_blank\"\r\n rel=\"noopener noreferrer\"\r\n style={{\r\n display: \"inline-flex\", alignItems: \"center\", gap: 8,\r\n padding: \"8px 16px\", borderRadius: 8, fontSize: 14, fontWeight: 500,\r\n background: t.accent, color: \"#fff\", textDecoration: \"none\",\r\n height: \"fit-content\",\r\n }}\r\n >\r\n View on GitHub\r\n </a>\r\n </div>\r\n </div>\r\n\r\n {/* Tabs */}\r\n <div style={{ display: \"flex\", gap: 4, borderBottom: `1px solid ${t.border}`, marginBottom: 16 }}>\r\n {([\"readme\", ...(snippets.length > 0 ? [\"demo\"] : [])] as const).map((key) => (\r\n <button\r\n key={key}\r\n onClick={() => setTab(key as typeof tab)}\r\n style={{\r\n padding: \"10px 16px\", fontSize: 14, fontWeight: 500, cursor: \"pointer\",\r\n background: \"transparent\", border: \"none\",\r\n color: tab === key ? t.accentLight : t.textMuted,\r\n borderBottom: tab === key ? `2px solid ${t.accent}` : \"2px solid transparent\",\r\n }}\r\n >\r\n {key === \"readme\" ? \"README\" : \"Demo\"}\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Content */}\r\n <div style={{ background: t.bgCard, border: `1px solid ${t.border}`, borderRadius: 12, padding: 24 }}>\r\n {loading ? (\r\n <div style={{ textAlign: \"center\", padding: 40, color: t.textMuted }}>Loading...</div>\r\n ) : tab === \"readme\" ? (\r\n <ReadmeView org={org} repoName={repo.name} content={readme} t={t} />\r\n ) : (\r\n <DemoView snippets={snippets} t={t} />\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n/* ---------- DemoView ---------- */\r\n\r\nfunction DemoView({ snippets, t }: { snippets: DemoSnippet[]; t: Theme }) {\r\n const [idx, setIdx] = useState(0);\r\n const snippet = snippets[idx];\r\n\r\n if (!snippet) return null;\r\n\r\n return (\r\n <div>\r\n {snippets.length > 1 && (\r\n <div style={{ display: \"flex\", gap: 6, marginBottom: 12, flexWrap: \"wrap\" }}>\r\n {snippets.map((s, i) => (\r\n <button\r\n key={i}\r\n onClick={() => setIdx(i)}\r\n style={{\r\n padding: \"4px 12px\", borderRadius: 99, fontSize: 12, cursor: \"pointer\",\r\n background: i === idx ? t.accentGlow : \"transparent\",\r\n color: i === idx ? t.accentLight : t.textMuted,\r\n border: `1px solid ${i === idx ? t.accent : t.border}`,\r\n }}\r\n >\r\n {s.label}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n <pre\r\n style={{\r\n background: t.bg, border: `1px solid ${t.border}`, borderRadius: 8,\r\n padding: 16, fontSize: 13, lineHeight: 1.6, overflow: \"auto\",\r\n color: t.textSecondary, margin: 0,\r\n }}\r\n >\r\n <code>{snippet.code}</code>\r\n </pre>\r\n {snippet.expectedOutput && (\r\n <div style={{ marginTop: 12 }}>\r\n <span style={{ fontSize: 12, color: t.textMuted }}>Expected Output:</span>\r\n <pre\r\n style={{\r\n background: t.bg, border: `1px solid ${t.border}`, borderRadius: 8,\r\n padding: 12, fontSize: 12, color: t.textMuted, margin: \"4px 0 0\",\r\n }}\r\n >\r\n {snippet.expectedOutput}\r\n </pre>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import type { Repo, DemoSnippet } from \"./types\";\r\n\r\nconst API = \"https://api.github.com\";\r\n\r\nfunction headers(token?: string): HeadersInit {\r\n const h: Record<string, string> = { Accept: \"application/vnd.github.v3+json\" };\r\n if (token) h.Authorization = `Bearer ${token}`;\r\n return h;\r\n}\r\n\r\nexport async function fetchRepos(org: string, token?: string): Promise<Repo[]> {\r\n try {\r\n const res = await fetch(`${API}/orgs/${org}/repos?per_page=100&sort=updated`, {\r\n headers: headers(token),\r\n });\r\n if (!res.ok) return [];\r\n return res.json();\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\nexport async function fetchReadme(org: string, repo: string, token?: string): Promise<string | null> {\r\n try {\r\n const res = await fetch(`${API}/repos/${org}/${repo}/readme`, {\r\n headers: { ...headers(token), Accept: \"application/vnd.github.v3.raw\" },\r\n });\r\n if (!res.ok) return null;\r\n return res.text();\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nexport async function fetchDemoSnippets(\r\n org: string,\r\n repo: string,\r\n readme?: string | null,\r\n token?: string,\r\n): Promise<DemoSnippet[]> {\r\n // 1. demo.json\r\n for (const path of [\".xgen-gallery/demo.json\", \"demo.json\"]) {\r\n try {\r\n const res = await fetch(`${API}/repos/${org}/${repo}/contents/${path}`, {\r\n headers: { ...headers(token), Accept: \"application/vnd.github.v3.raw\" },\r\n });\r\n if (!res.ok) continue;\r\n const data = await res.json();\r\n if (data.snippets?.length) return data.snippets;\r\n } catch {\r\n continue;\r\n }\r\n }\r\n\r\n // 2. examples/\r\n try {\r\n const res = await fetch(`${API}/repos/${org}/${repo}/contents/examples`, {\r\n headers: headers(token),\r\n });\r\n if (res.ok) {\r\n const files: { name: string; download_url: string }[] = await res.json();\r\n const pyFiles = files.filter((f) => f.name.endsWith(\".py\")).slice(0, 5);\r\n const snippets: DemoSnippet[] = [];\r\n for (const f of pyFiles) {\r\n try {\r\n const r = await fetch(f.download_url);\r\n if (r.ok) {\r\n const code = await r.text();\r\n snippets.push({ label: f.name.replace(/\\.py$/, \"\").replace(/[_-]/g, \" \"), code: code.trim() });\r\n }\r\n } catch { continue; }\r\n }\r\n if (snippets.length) return snippets;\r\n }\r\n } catch { /* ignore */ }\r\n\r\n // 3. README python blocks\r\n let md = readme;\r\n if (!md) md = await fetchReadme(org, repo, token);\r\n if (md) {\r\n const blocks = extractPythonBlocks(md);\r\n if (blocks.length) return blocks;\r\n }\r\n\r\n return [];\r\n}\r\n\r\nfunction extractPythonBlocks(readme: string): DemoSnippet[] {\r\n const snippets: DemoSnippet[] = [];\r\n const lines = readme.split(\"\\n\");\r\n let i = 0;\r\n while (i < lines.length) {\r\n if (/^```(?:python|py)\\s*$/i.test(lines[i].trim())) {\r\n let label = \"\";\r\n for (let j = i - 1; j >= Math.max(0, i - 5); j--) {\r\n const prev = lines[j].trim();\r\n if (/^#{1,4}\\s+/.test(prev)) { label = prev.replace(/^#+\\s+/, \"\"); break; }\r\n if (prev && !label) label = prev;\r\n }\r\n const codeLines: string[] = [];\r\n i++;\r\n while (i < lines.length && !lines[i].trim().startsWith(\"```\")) { codeLines.push(lines[i]); i++; }\r\n const code = codeLines.join(\"\\n\").trim();\r\n if (code && code.split(\"\\n\").length >= 2 && !code.startsWith(\"pip \") && !code.startsWith(\"$ pip\")) {\r\n snippets.push({ label: label || `Example ${snippets.length + 1}`, code });\r\n }\r\n }\r\n i++;\r\n }\r\n return snippets;\r\n}\r\n","export const themes = {\r\n dark: {\r\n bg: \"#0a0a0f\",\r\n bgCard: \"#12121a\",\r\n bgCardHover: \"#1a1a25\",\r\n border: \"#1e1e2e\",\r\n text: \"#e8e8f0\",\r\n textSecondary: \"#a0a0b8\",\r\n textMuted: \"#6b6b80\",\r\n accent: \"#6c63ff\",\r\n accentLight: \"#8b83ff\",\r\n accentGlow: \"rgba(108,99,255,0.15)\",\r\n },\r\n light: {\r\n bg: \"#f8f9fa\",\r\n bgCard: \"#ffffff\",\r\n bgCardHover: \"#f0f0f5\",\r\n border: \"#e0e0e8\",\r\n text: \"#1a1a2e\",\r\n textSecondary: \"#4a4a5a\",\r\n textMuted: \"#8a8a9a\",\r\n accent: \"#5b52e0\",\r\n accentLight: \"#5b52e0\",\r\n accentGlow: \"rgba(91,82,224,0.1)\",\r\n },\r\n};\r\n\r\nexport type Theme = {\r\n bg: string; bgCard: string; bgCardHover: string; border: string;\r\n text: string; textSecondary: string; textMuted: string;\r\n accent: string; accentLight: string; accentGlow: string;\r\n};\r\n\r\nexport const LANG_COLORS: Record<string, string> = {\r\n Python: \"#3572A5\",\r\n TypeScript: \"#3178c6\",\r\n JavaScript: \"#f1e05a\",\r\n Rust: \"#dea584\",\r\n HTML: \"#e34c26\",\r\n CSS: \"#563d7c\",\r\n Go: \"#00ADD8\",\r\n Shell: \"#89e051\",\r\n Java: \"#b07219\",\r\n \"C++\": \"#f34b7d\",\r\n C: \"#555555\",\r\n Ruby: \"#701516\",\r\n};\r\n","import ReactMarkdown from \"react-markdown\";\r\nimport remarkGfm from \"remark-gfm\";\r\nimport rehypeRaw from \"rehype-raw\";\r\nimport type { Theme } from \"./styles\";\r\n\r\nexport function ReadmeView({\r\n org,\r\n repoName,\r\n content,\r\n t,\r\n}: {\r\n org: string;\r\n repoName: string;\r\n content: string | null;\r\n t: Theme;\r\n}) {\r\n if (!content) {\r\n return <div style={{ textAlign: \"center\", padding: 40, color: t.textMuted }}>README not found</div>;\r\n }\r\n\r\n return (\r\n <div className=\"xgen-markdown\" style={{ color: t.text, lineHeight: 1.7, fontSize: 14 }}>\r\n <style>{markdownStyles(t)}</style>\r\n <ReactMarkdown\r\n remarkPlugins={[remarkGfm]}\r\n rehypePlugins={[rehypeRaw]}\r\n components={{\r\n img: ({ src, alt, ...props }) => {\r\n let resolved = src;\r\n if (typeof src === \"string\" && !src.startsWith(\"http\")) {\r\n resolved = `https://raw.githubusercontent.com/${org}/${repoName}/main/${src}`;\r\n }\r\n return <img src={resolved} alt={alt || \"\"} style={{ maxWidth: \"100%\" }} {...props} />;\r\n },\r\n a: ({ href, children, ...props }) => (\r\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: t.accentLight }} {...props}>\r\n {children}\r\n </a>\r\n ),\r\n code: ({ children, className, ...props }) => {\r\n const isBlock = className?.includes(\"language-\");\r\n if (isBlock) {\r\n return (\r\n <code\r\n style={{\r\n display: \"block\", background: t.bg, padding: 16, borderRadius: 8,\r\n overflow: \"auto\", fontSize: 13, lineHeight: 1.6,\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </code>\r\n );\r\n }\r\n return (\r\n <code style={{ background: t.accentGlow, padding: \"2px 6px\", borderRadius: 4, fontSize: 13 }} {...props}>\r\n {children}\r\n </code>\r\n );\r\n },\r\n }}\r\n >\r\n {content}\r\n </ReactMarkdown>\r\n </div>\r\n );\r\n}\r\n\r\nfunction markdownStyles(t: Theme): string {\r\n return `\r\n .xgen-markdown h1, .xgen-markdown h2, .xgen-markdown h3 { color: ${t.text}; margin: 1.2em 0 0.5em; }\r\n .xgen-markdown h1 { font-size: 1.8em; border-bottom: 1px solid ${t.border}; padding-bottom: 8px; }\r\n .xgen-markdown h2 { font-size: 1.4em; border-bottom: 1px solid ${t.border}; padding-bottom: 6px; }\r\n .xgen-markdown h3 { font-size: 1.15em; }\r\n .xgen-markdown p { margin: 0.8em 0; }\r\n .xgen-markdown ul, .xgen-markdown ol { padding-left: 24px; }\r\n .xgen-markdown li { margin: 4px 0; }\r\n .xgen-markdown pre { background: ${t.bg}; border: 1px solid ${t.border}; border-radius: 8px; padding: 16px; overflow: auto; margin: 12px 0; }\r\n .xgen-markdown blockquote { border-left: 3px solid ${t.accent}; padding-left: 12px; color: ${t.textSecondary}; margin: 12px 0; }\r\n .xgen-markdown table { border-collapse: collapse; width: 100%; margin: 12px 0; }\r\n .xgen-markdown th, .xgen-markdown td { border: 1px solid ${t.border}; padding: 8px 12px; text-align: left; }\r\n .xgen-markdown th { background: ${t.bgCard}; font-weight: 600; }\r\n .xgen-markdown hr { border: none; border-top: 1px solid ${t.border}; margin: 16px 0; }\r\n `;\r\n}\r\n"],"mappings":"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","names":["ReactMarkdown","remarkGfm","rehypeRaw","import_jsx_runtime"]}