Jiseoup/showmycodePublic
EN|KO
  • Code
  • Commits
  • Pull Requests
← Back to list
Merged

feat: add pagination and detail pages for commits and PRs

#5
JiseoupJiseoup · Apr 3, 2026feat/pagination-and-detail-pages → main
feat
OverviewCommitsFiles changed
Changed files

+1979 -197 · 11

@@ -0,0 +1,80 @@
+import Link from "next/link";
+import Image from "next/image";
+import { getCommit } from "@/lib/github";
+import { formatDate } from "@/lib/utils";
+import { getDictionary, type Locale } from "@/lib/i18n.server";
+import { FilesChanged } from "@/components/FilesChanged";
+
+type Props = {
+ params: Promise<{ lang: string; owner: string; repo: string; sha: string }>;
+};
+
+export default async function CommitDetailPage({ params }: Props) {
+ const { lang, owner, repo, sha } = await params;
+
+ const [commit, dict] = await Promise.all([
+ getCommit(owner, repo, sha),
+ getDictionary(lang as Locale),
+ ]);
+
+ const [title, ...bodyLines] = commit.commit.message.split("\n");
+ const body = bodyLines.join("\n").trim();
+
+ return (
+ <main className="flex-1 overflow-auto max-w-4xl mx-auto w-full px-6 py-6 space-y-5">
+ <Link
+ href={`/${lang}/repository/${owner}/${repo}/commits`}
+ className="text-xs text-muted-foreground hover:text-foreground transition-colors"
+ >
+ ← {dict.commits.backToList}
+ </Link>
+
+ {/* 커밋 헤더 */}
+ <div className="border border-border rounded-lg p-4 space-y-3">
+ <div>
+ <p className="font-semibold text-base leading-snug">{title}</p>
+ {body && (
+ <p className="text-sm text-muted-foreground mt-2 whitespace-pre-wrap">{body}</p>
+ )}
+ </div>
+
+ <div className="flex items-center gap-2 pt-2 border-t border-border flex-wrap">
+ {commit.author?.avatar_url ? (
+ <Image
+ src={commit.author.avatar_url}
+ alt={commit.author.login}
+ width={20}
+ height={20}
+ className="rounded-full"
+ />
+ ) : (
+ <div className="w-5 h-5 rounded-full bg-muted" />
+ )}
+ <span className="text-sm text-muted-foreground">
+ {commit.commit.author.name} · {formatDate(commit.commit.author.date, lang)}
+ </span>
+ <code className="ml-auto text-xs font-mono text-muted-foreground bg-muted px-2 py-1 rounded">
+ {commit.sha.slice(0, 7)}
+ </code>
+ </div>
+ </div>
+
+ {/* 변경된 파일 */}
+ <div>
+ <h2 className="text-sm font-semibold mb-3">
+ {dict.commits.filesChanged}
+ <span className="ml-2 font-normal text-muted-foreground">
+ {commit.files.length}{dict.commits.countSuffix}
+ </span>
+ <span className="ml-2 text-xs font-mono font-normal">
+ <span className="text-green-600">+{commit.stats.additions}</span>
+ {" "}
+ <span className="text-red-500">-{commit.stats.deletions}</span>
+ </span>
+ </h2>
+
+ <FilesChanged files={commit.files} dict={dict.commits} />
+ </div>
+ </main>
+ );
+}
@@ -1,23 +1,38 @@
+import Link from "next/link";
import Image from "next/image";
import { getCommits } from "@/lib/github";
import { formatDate } from "@/lib/utils";
import { getDictionary, type Locale } from "@/lib/i18n.server";
-type Props = { params: Promise<{ lang: string; owner: string; repo: string }> };
+const PER_PAGE = 50;
-export default async function CommitsPage({ params }: Props) {
+type Props = {
+ params: Promise<{ lang: string; owner: string; repo: string }>;
+ searchParams: Promise<{ page?: string }>;
+};
+
+export default async function CommitsPage({ params, searchParams }: Props) {
const { lang, owner, repo } = await params;
+ const { page: pageParam } = await searchParams;
+ const page = Math.max(1, parseInt(pageParam ?? "1", 10) || 1);
+
const [commits, dict] = await Promise.all([
- getCommits(owner, repo, 50),
+ getCommits(owner, repo, PER_PAGE, page),
getDictionary(lang as Locale),
]);
+ const hasPrev = page > 1;
+ const hasNext = commits.length === PER_PAGE;
+
+ const pageUrl = (p: number) =>
+ `/${lang}/repository/${owner}/${repo}/commits?page=${p}`;
+
return (
<main className="flex-1 overflow-auto max-w-4xl mx-auto w-full px-6 py-6">
<h2 className="text-lg font-semibold mb-4">
{dict.commits.title}
<span className="ml-2 text-sm font-normal text-muted-foreground">
- {commits.length}{dict.commits.countSuffix}
+ {dict.commits.page} {page}
</span>
</h2>
@@ -27,41 +42,71 @@ export default async function CommitsPage({ params }: Props) {
const body = bodyLines.join("\n").trim();
return (
- <li
- key={c.sha}
- className="flex items-start gap-3 py-3 border-b border-border last:border-0"
- >
- {c.author?.avatar_url ? (
- <Image
- src={c.author.avatar_url}
- alt={c.author.login}
- width={32}
- height={32}
- className="rounded-full shrink-0 mt-0.5"
- />
- ) : (
- <div className="w-8 h-8 rounded-full bg-muted shrink-0 mt-0.5" />
- )}
+ <li key={c.sha} className="border-b border-border last:border-0">
+ <Link
+ href={`/${lang}/repository/${owner}/${repo}/commits/${c.sha}`}
+ className="flex items-start gap-3 py-3 hover:bg-muted/50 transition-colors rounded px-1 -mx-1"
+ >
+ {c.author?.avatar_url ? (
+ <Image
+ src={c.author.avatar_url}
+ alt={c.author.login}
+ width={32}
+ height={32}
+ className="rounded-full shrink-0 mt-0.5"
+ />
+ ) : (
+ <div className="w-8 h-8 rounded-full bg-muted shrink-0 mt-0.5" />
+ )}
- <div className="min-w-0 flex-1">
- <p className="font-medium text-sm leading-snug">{title}</p>
- {body && (
- <p className="text-xs text-muted-foreground mt-1 whitespace-pre-line line-clamp-3">
- {body}
+ <div className="min-w-0 flex-1">
+ <p className="font-medium text-sm leading-snug">{title}</p>
+ {body && (
+ <p className="text-xs text-muted-foreground mt-1 whitespace-pre-line line-clamp-3">
+ {body}
+ </p>
+ )}
+ <p className="text-xs text-muted-foreground mt-1">
+ {c.commit.author.name} · {formatDate(c.commit.author.date, lang)}
</p>
- )}
- <p className="text-xs text-muted-foreground mt-1">
- {c.commit.author.name} · {formatDate(c.commit.author.date, lang)}
- </p>
- </div>
+ </div>
- <code className="text-xs font-mono text-muted-foreground bg-muted px-2 py-1 rounded shrink-0">
- {c.sha.slice(0, 7)}
- </code>
+ <code className="text-xs font-mono text-muted-foreground bg-muted px-2 py-1 rounded shrink-0">
+ {c.sha.slice(0, 7)}
+ </code>
+ </Link>
</li>
);
})}
</ul>
+
+ {(hasPrev || hasNext) && (
+ <div className="flex items-center justify-between mt-6">
+ {hasPrev ? (
+ <Link
+ href={pageUrl(page - 1)}
+ className="px-3 py-1.5 text-sm border border-border rounded hover:bg-muted transition-colors"
+ >
+ ← {dict.commits.prev}
+ </Link>
+ ) : (
+ <div />
+ )}
+ <span className="text-sm text-muted-foreground">
+ {dict.commits.page} {page}
+ </span>
+ {hasNext ? (
+ <Link
+ href={pageUrl(page + 1)}
+ className="px-3 py-1.5 text-sm border border-border rounded hover:bg-muted transition-colors"
+ >
+ {dict.commits.next} →
+ </Link>
+ ) : (
+ <div />
+ )}
+ </div>
+ )}
</main>
);
}
@@ -0,0 +1,206 @@
+import Link from "next/link";
+import Image from "next/image";
+import { getPull, getPullFiles, getPullCommits } from "@/lib/github";
+import { formatDate } from "@/lib/utils";
+import { getDictionary, type Locale } from "@/lib/i18n.server";
+import { FilesChanged } from "@/components/FilesChanged";
+import { MarkdownBody } from "@/components/MarkdownBody";
+
+type Tab = "overview" | "commits" | "files";
+
+type Props = {
+ params: Promise<{ lang: string; owner: string; repo: string; number: string }>;
+ searchParams: Promise<{ tab?: string }>;
+};
+
+function PRBadge({ merged, state, dict }: {
+ merged: boolean;
+ state: string;
+ dict: { merged: string; open: string; closed: string };
+}) {
+ if (merged)
+ return (
+ <span className="text-xs px-2 py-0.5 rounded-full bg-purple-100 text-purple-800 dark:bg-purple-900/40 dark:text-purple-300 font-medium">
+ {dict.merged}
+ </span>
+ );
+ if (state === "open")
+ return (
+ <span className="text-xs px-2 py-0.5 rounded-full bg-green-100 text-green-800 dark:bg-green-900/40 dark:text-green-300 font-medium">
+ {dict.open}
+ </span>
+ );
+ return (
+ <span className="text-xs px-2 py-0.5 rounded-full bg-red-100 text-red-800 dark:bg-red-900/40 dark:text-red-300 font-medium">
+ {dict.closed}
+ </span>
+ );
+}
+
+
+export default async function PullDetailPage({ params, searchParams }: Props) {
+ const { lang, owner, repo, number } = await params;
+ const { tab: tabParam } = await searchParams;
+ const prNumber = parseInt(number, 10);
+
+ const tab: Tab =
+ tabParam === "commits" ? "commits"
+ : tabParam === "files" ? "files"
+ : "overview";
+
+ const [pr, dict] = await Promise.all([
+ getPull(owner, repo, prNumber),
+ getDictionary(lang as Locale),
+ ]);
+
+ // 탭에 따라 필요한 데이터만 패치
+ const [files, commits] = await Promise.all([
+ tab === "files" ? getPullFiles(owner, repo, prNumber) : Promise.resolve(null),
+ tab === "commits" ? getPullCommits(owner, repo, prNumber) : Promise.resolve(null),
+ ]);
+
+ const baseUrl = `/${lang}/repository/${owner}/${repo}/pulls/${prNumber}`;
+ const tabUrl = (t: Tab) => t === "overview" ? baseUrl : `${baseUrl}?tab=${t}`;
+
+ const tabs: { key: Tab; label: string }[] = [
+ { key: "overview", label: dict.pulls.tabOverview },
+ { key: "commits", label: dict.pulls.tabCommits },
+ { key: "files", label: dict.pulls.tabFiles },
+ ];
+
+ return (
+ <main className="flex-1 overflow-auto max-w-4xl mx-auto w-full px-6 py-6 space-y-5">
+ {/* 뒤로가기 */}
+ <Link
+ href={`/${lang}/repository/${owner}/${repo}/pulls`}
+ className="text-xs text-muted-foreground hover:text-foreground transition-colors"
+ >
+ ← {dict.pulls.backToList}
+ </Link>
+
+ {/* PR 헤더 */}
+ <div>
+ <div className="flex items-start gap-2 flex-wrap">
+ <PRBadge merged={!!pr.merged_at} state={pr.state} dict={dict.pulls} />
+ <h1 className="text-lg font-semibold leading-snug">{pr.title}</h1>
+ <span className="text-muted-foreground font-normal">#{pr.number}</span>
+ </div>
+
+ <div className="flex items-center gap-2 mt-2 flex-wrap">
+ <Image
+ src={pr.user.avatar_url}
+ alt={pr.user.login}
+ width={20}
+ height={20}
+ className="rounded-full"
+ />
+ <span className="text-sm text-muted-foreground">
+ {pr.user.login} · {formatDate(pr.created_at, lang)}
+ </span>
+ <span className="text-xs font-mono text-muted-foreground">
+ {pr.head.ref} → {pr.base.ref}
+ </span>
+ </div>
+
+ {pr.labels.length > 0 && (
+ <div className="flex items-center gap-1.5 mt-2 flex-wrap">
+ {pr.labels.map((l) => {
+ const safeColor = /^[0-9a-fA-F]{6}$/.test(l.color) ? l.color : "8b949e";
+ return (
+ <span
+ key={l.name}
+ className="text-xs px-1.5 py-0.5 rounded"
+ style={{
+ background: `#${safeColor}33`,
+ color: `#${safeColor}`,
+ border: `1px solid #${safeColor}55`,
+ }}
+ >
+ {l.name}
+ </span>
+ );
+ })}
+ </div>
+ )}
+ </div>
+
+ {/* 탭 네비게이션 */}
+ <div className="flex gap-1 border-b border-border">
+ {tabs.map(({ key, label }) => (
+ <Link
+ key={key}
+ href={tabUrl(key)}
+ className={[
+ "px-3 py-2 text-sm font-medium border-b-2 -mb-px transition-colors",
+ tab === key
+ ? "border-foreground text-foreground"
+ : "border-transparent text-muted-foreground hover:text-foreground",
+ ].join(" ")}
+ >
+ {label}
+ </Link>
+ ))}
+ </div>
+
+ {/* Overview */}
+ {tab === "overview" && (
+ <div className="border border-border rounded-lg p-4 text-foreground">
+ {pr.body?.trim() ? (
+ <MarkdownBody>{pr.body}</MarkdownBody>
+ ) : (
+ <span className="text-sm text-muted-foreground italic">{dict.pulls.noBody}</span>
+ )}
+ </div>
+ )}
+
+ {/* Commits */}
+ {tab === "commits" && commits && (
+ <ul className="space-y-px">
+ {commits.map((c) => {
+ const [title, ...bodyLines] = c.commit.message.split("\n");
+ const body = bodyLines.join("\n").trim();
+ return (
+ <li key={c.sha} className="border-b border-border last:border-0">
+ <Link
+ href={`/${lang}/repository/${owner}/${repo}/commits/${c.sha}`}
+ className="flex items-start gap-3 py-3 hover:bg-muted/50 transition-colors rounded px-1 -mx-1"
+ >
+ {c.author?.avatar_url ? (
+ <Image
+ src={c.author.avatar_url}
+ alt={c.author.login}
+ width={32}
+ height={32}
+ className="rounded-full shrink-0 mt-0.5"
+ />
+ ) : (
+ <div className="w-8 h-8 rounded-full bg-muted shrink-0 mt-0.5" />
+ )}
+ <div className="min-w-0 flex-1">
+ <p className="font-medium text-sm leading-snug">{title}</p>
+ {body && (
+ <p className="text-xs text-muted-foreground mt-1 whitespace-pre-line line-clamp-3">
+ {body}
+ </p>
+ )}
+ <p className="text-xs text-muted-foreground mt-1">
+ {c.commit.author.name} · {formatDate(c.commit.author.date, lang)}
+ </p>
+ </div>
+ <code className="text-xs font-mono text-muted-foreground bg-muted px-2 py-1 rounded shrink-0">
+ {c.sha.slice(0, 7)}
+ </code>
+ </Link>
+ </li>
+ );
+ })}
+ </ul>
+ )}
+
+ {/* Files changed */}
+ {tab === "files" && files && (
+ <FilesChanged files={files} dict={dict.pulls} />
+ )}
+ </main>
+ );
+}
@@ -1,9 +1,15 @@
+import Link from "next/link";
import Image from "next/image";
import { getPulls } from "@/lib/github";
import { formatDate } from "@/lib/utils";
import { getDictionary, type Locale } from "@/lib/i18n.server";
-type Props = { params: Promise<{ lang: string; owner: string; repo: string }> };
+const PER_PAGE = 30;
+
+type Props = {
+ params: Promise<{ lang: string; owner: string; repo: string }>;
+ searchParams: Promise<{ page?: string }>;
+};
function PRBadge({ merged, state, dict }: {
merged: boolean;
@@ -29,19 +35,28 @@ function PRBadge({ merged, state, dict }: {
);
}
-export default async function PullsPage({ params }: Props) {
+export default async function PullsPage({ params, searchParams }: Props) {
const { lang, owner, repo } = await params;
+ const { page: pageParam } = await searchParams;
+ const page = Math.max(1, parseInt(pageParam ?? "1", 10) || 1);
+
const [pulls, dict] = await Promise.all([
- getPulls(owner, repo, "all"),
+ getPulls(owner, repo, "all", PER_PAGE, page),
getDictionary(lang as Locale),
]);
+ const hasPrev = page > 1;
+ const hasNext = pulls.length === PER_PAGE;
+
+ const pageUrl = (p: number) =>
+ `/${lang}/repository/${owner}/${repo}/pulls?page=${p}`;
+
return (
<main className="flex-1 overflow-auto max-w-4xl mx-auto w-full px-6 py-6">
<h2 className="text-lg font-semibold mb-4">
{dict.pulls.title}
<span className="ml-2 text-sm font-normal text-muted-foreground">
- {pulls.length}{dict.pulls.countSuffix}
+ {dict.pulls.page} {page}
</span>
</h2>
@@ -50,61 +65,91 @@ export default async function PullsPage({ params }: Props) {
) : (
<ul className="space-y-px">
{pulls.map((pr) => (
- <li
- key={pr.number}
- className="flex items-start gap-3 py-4 border-b border-border last:border-0"
- >
- <Image
- src={pr.user.avatar_url}
- alt={pr.user.login}
- width={32}
- height={32}
- className="rounded-full shrink-0 mt-0.5"
- />
-
- <div className="min-w-0 flex-1">
- <div className="flex items-center gap-2 flex-wrap">
- <PRBadge merged={!!pr.merged_at} state={pr.state} dict={dict.pulls} />
- <p className="font-medium text-sm">{pr.title}</p>
- <span className="text-xs text-muted-foreground">#{pr.number}</span>
- </div>
+ <li key={pr.number} className="border-b border-border last:border-0">
+ <Link
+ href={`/${lang}/repository/${owner}/${repo}/pulls/${pr.number}`}
+ className="flex items-start gap-3 py-4 hover:bg-muted/50 transition-colors rounded px-1 -mx-1"
+ >
+ <Image
+ src={pr.user.avatar_url}
+ alt={pr.user.login}
+ width={32}
+ height={32}
+ className="rounded-full shrink-0 mt-0.5"
+ />
- <p className="text-xs text-muted-foreground mt-1 font-mono">
- {pr.head.ref} → {pr.base.ref}
- </p>
+ <div className="min-w-0 flex-1">
+ <div className="flex items-center gap-2 flex-wrap">
+ <PRBadge merged={!!pr.merged_at} state={pr.state} dict={dict.pulls} />
+ <p className="font-medium text-sm">{pr.title}</p>
+ <span className="text-xs text-muted-foreground">#{pr.number}</span>
+ </div>
- {pr.body && (
- <p className="text-xs text-muted-foreground mt-1.5 line-clamp-2">
- {pr.body}
+ <p className="text-xs text-muted-foreground mt-1 font-mono">
+ {pr.head.ref} → {pr.base.ref}
</p>
- )}
- <div className="flex items-center gap-2 mt-2 flex-wrap">
- <span className="text-xs text-muted-foreground">
- {pr.user.login} · {formatDate(pr.created_at, lang)}
- </span>
- {pr.labels.map((l) => {
- const safeColor = /^[0-9a-fA-F]{6}$/.test(l.color) ? l.color : "8b949e";
- return (
- <span
- key={l.name}
- className="text-xs px-1.5 py-0.5 rounded"
- style={{
- background: `#${safeColor}33`,
- color: `#${safeColor}`,
- border: `1px solid #${safeColor}55`,
- }}
- >
- {l.name}
- </span>
- );
- })}
+ {pr.body && (
+ <p className="text-xs text-muted-foreground mt-1.5 line-clamp-2">
+ {pr.body}
+ </p>
+ )}
+
+ <div className="flex items-center gap-2 mt-2 flex-wrap">
+ <span className="text-xs text-muted-foreground">
+ {pr.user.login} · {formatDate(pr.created_at, lang)}
+ </span>
+ {pr.labels.map((l) => {
+ const safeColor = /^[0-9a-fA-F]{6}$/.test(l.color) ? l.color : "8b949e";
+ return (
+ <span
+ key={l.name}
+ className="text-xs px-1.5 py-0.5 rounded"
+ style={{
+ background: `#${safeColor}33`,
+ color: `#${safeColor}`,
+ border: `1px solid #${safeColor}55`,
+ }}
+ >
+ {l.name}
+ </span>
+ );
+ })}
+ </div>
</div>
- </div>
+ </Link>
</li>
))}
</ul>
)}
+
+ {(hasPrev || hasNext) && (
+ <div className="flex items-center justify-between mt-6">
+ {hasPrev ? (
+ <Link
+ href={pageUrl(page - 1)}
+ className="px-3 py-1.5 text-sm border border-border rounded hover:bg-muted transition-colors"
+ >
+ ← {dict.pulls.prev}
+ </Link>
+ ) : (
+ <div />
+ )}
+ <span className="text-sm text-muted-foreground">
+ {dict.pulls.page} {page}
+ </span>
+ {hasNext ? (
+ <Link
+ href={pageUrl(page + 1)}
+ className="px-3 py-1.5 text-sm border border-border rounded hover:bg-muted transition-colors"
+ >
+ {dict.pulls.next} →
+ </Link>
+ ) : (
+ <div />
+ )}
+ </div>
+ )}
</main>
);
}
@@ -0,0 +1,132 @@
+"use client";
+
+import { useState } from "react";
+import type { GhPullFile } from "@/lib/github";
+
+type Dict = {
+ added: string;
+ removed: string;
+ modified: string;
+ renamed: string;
+ binaryFile: string;
+ countSuffix: string;
+ foldAll: string;
+ unfoldAll: string;
+};
+
+function FileStatusBadge({ status, dict }: {
+ status: GhPullFile["status"];
+ dict: Pick<Dict, "added" | "removed" | "modified" | "renamed">;
+}) {
+ const map: Record<string, { label: string; cls: string }> = {
+ added: { label: dict.added, cls: "bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300" },
+ removed: { label: dict.removed, cls: "bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300" },
+ modified: { label: dict.modified, cls: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/40 dark:text-yellow-300" },
+ renamed: { label: dict.renamed, cls: "bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300" },
+ };
+ const { label, cls } = map[status] ?? map.modified;
+ return (
+ <span className={`text-xs px-1.5 py-0.5 rounded font-medium shrink-0 ${cls}`}>
+ {label}
+ </span>
+ );
+}
+
+function DiffView({ patch }: { patch: string }) {
+ const lines = patch.split("\n");
+ return (
+ <div className="overflow-x-auto text-xs font-mono leading-5">
+ {lines.map((line, i) => {
+ let cls: string;
+ if (line.startsWith("@@"))
+ cls = "bg-blue-50 text-blue-600 dark:bg-blue-950/40 dark:text-blue-400";
+ else if (line.startsWith("+"))
+ cls = "bg-green-50 text-green-800 dark:bg-green-950/40 dark:text-green-300";
+ else if (line.startsWith("-"))
+ cls = "bg-red-50 text-red-800 dark:bg-red-950/40 dark:text-red-300";
+ else
+ cls = "text-muted-foreground";
+ return (
+ <div key={i} className={`px-4 whitespace-pre ${cls}`}>
+ {line || " "}
+ </div>
+ );
+ })}
+ </div>
+ );
+}
+
+export function FilesChanged({ files, dict }: { files: GhPullFile[]; dict: Dict }) {
+ const [folded, setFolded] = useState<Record<string, boolean>>({});
+
+ const allFolded = files.every((f) => folded[f.sha]);
+ const toggleAll = () => {
+ if (allFolded) {
+ setFolded({});
+ } else {
+ setFolded(Object.fromEntries(files.map((f) => [f.sha, true])));
+ }
+ };
+
+ const toggle = (sha: string) =>
+ setFolded((prev) => ({ ...prev, [sha]: !prev[sha] }));
+
+ return (
+ <div>
+ <div className="flex items-center justify-between mb-3">
+ <p className="text-xs text-muted-foreground">
+ <span className="text-green-600">+{files.reduce((s, f) => s + f.additions, 0)}</span>
+ {" "}
+ <span className="text-red-500">-{files.reduce((s, f) => s + f.deletions, 0)}</span>
+ {" · "}
+ {files.length}{dict.countSuffix}
+ </p>
+ <button
+ onClick={toggleAll}
+ className="text-xs text-muted-foreground hover:text-foreground transition-colors"
+ >
+ {allFolded ? dict.unfoldAll : dict.foldAll}
+ </button>
+ </div>
+
+ <div className="space-y-3">
+ {files.map((file) => {
+ const isFolded = !!folded[file.sha];
+ return (
+ <div key={file.sha} className="border border-border rounded-lg overflow-hidden">
+ <button
+ onClick={() => toggle(file.sha)}
+ className="w-full flex items-center gap-2 px-4 py-2 bg-muted/50 border-b border-border flex-wrap text-left hover:bg-muted transition-colors"
+ >
+ <span className={`text-muted-foreground transition-transform shrink-0 ${isFolded ? "-rotate-90" : ""}`}>
+ ▾
+ </span>
+ <FileStatusBadge status={file.status} dict={dict} />
+ <span className="text-xs font-mono font-medium min-w-0 truncate flex-1">
+ {file.status === "renamed" && file.previous_filename
+ ? `${file.previous_filename} → ${file.filename}`
+ : file.filename}
+ </span>
+ <span className="text-xs font-mono text-muted-foreground shrink-0">
+ <span className="text-green-600">+{file.additions}</span>
+ {" "}
+ <span className="text-red-500">-{file.deletions}</span>
+ </span>
+ </button>
+
+ {!isFolded && (
+ file.patch ? (
+ <DiffView patch={file.patch} />
+ ) : (
+ <p className="px-4 py-3 text-xs text-muted-foreground italic">
+ {dict.binaryFile}
+ </p>
+ )
+ )}
+ </div>
+ );
+ })}
+ </div>
+ </div>
+ );
+}
@@ -0,0 +1,66 @@
+import ReactMarkdown from "react-markdown";
+import remarkGfm from "remark-gfm";
+import type { Components } from "react-markdown";
+
+const components: Components = {
+ h1: ({ children }) => <h1 className="text-xl font-bold mt-6 mb-3 first:mt-0">{children}</h1>,
+ h2: ({ children }) => <h2 className="text-lg font-semibold mt-5 mb-2 first:mt-0">{children}</h2>,
+ h3: ({ children }) => <h3 className="text-base font-semibold mt-4 mb-1.5 first:mt-0">{children}</h3>,
+ h4: ({ children }) => <h4 className="text-sm font-semibold mt-3 mb-1 first:mt-0">{children}</h4>,
+ p: ({ children }) => <p className="text-sm leading-relaxed mb-3 last:mb-0">{children}</p>,
+ a: ({ href, children }) => (
+ <a href={href} target="_blank" rel="noreferrer" className="text-blue-600 dark:text-blue-400 underline underline-offset-2 hover:opacity-80">
+ {children}
+ </a>
+ ),
+ ul: ({ children }) => <ul className="list-disc pl-5 mb-3 space-y-1 text-sm">{children}</ul>,
+ ol: ({ children }) => <ol className="list-decimal pl-5 mb-3 space-y-1 text-sm">{children}</ol>,
+ li: ({ children }) => <li className="leading-relaxed">{children}</li>,
+ blockquote: ({ children }) => (
+ <blockquote className="border-l-4 border-border pl-4 my-3 text-muted-foreground italic text-sm">
+ {children}
+ </blockquote>
+ ),
+ code: ({ className, children, ...props }) => {
+ const isBlock = className?.startsWith("language-");
+ if (isBlock) {
+ return (
+ <pre className="bg-muted rounded-lg px-4 py-3 overflow-x-auto my-3 text-xs font-mono leading-5">
+ <code className={className}>{children}</code>
+ </pre>
+ );
+ }
+ return (
+ <code className="bg-muted rounded px-1.5 py-0.5 text-xs font-mono" {...props}>
+ {children}
+ </code>
+ );
+ },
+ pre: ({ children }) => <>{children}</>,
+ hr: () => <hr className="border-border my-5" />,
+ strong: ({ children }) => <strong className="font-semibold">{children}</strong>,
+ em: ({ children }) => <em className="italic">{children}</em>,
+ table: ({ children }) => (
+ <div className="overflow-x-auto my-3">
+ <table className="w-full text-sm border-collapse">{children}</table>
+ </div>
+ ),
+ thead: ({ children }) => <thead className="bg-muted">{children}</thead>,
+ th: ({ children }) => (
+ <th className="border border-border px-3 py-1.5 text-left font-semibold text-xs">{children}</th>
+ ),
+ td: ({ children }) => (
+ <td className="border border-border px-3 py-1.5 text-xs">{children}</td>
+ ),
+ input: ({ checked, disabled }) => (
+ <input type="checkbox" checked={checked} disabled={disabled} readOnly className="mr-1.5 align-middle" />
+ ),
+};
+
+export function MarkdownBody({ children }: { children: string }) {
+ return (
+ <ReactMarkdown remarkPlugins={[remarkGfm]} components={components}>
+ {children}
+ </ReactMarkdown>
+ );
+}
@@ -38,13 +38,44 @@ export async function getContents(owner: string, repo: string, path: string) {
}
// 커밋 목록
-export async function getCommits(owner: string, repo: string, perPage = 30) {
- return ghFetch<GhCommit[]>(`repos/${owner}/${repo}/commits`, { per_page: String(perPage) });
+export async function getCommits(owner: string, repo: string, perPage = 30, page = 1) {
+ return ghFetch<GhCommit[]>(`repos/${owner}/${repo}/commits`, {
+ per_page: String(perPage),
+ page: String(page),
+ });
}
// PR 목록
-export async function getPulls(owner: string, repo: string, state: "open" | "closed" | "all" = "all") {
- return ghFetch<GhPull[]>(`repos/${owner}/${repo}/pulls`, { state, per_page: "50" });
+export async function getPulls(owner: string, repo: string, state: "open" | "closed" | "all" = "all", perPage = 30, page = 1) {
+ return ghFetch<GhPull[]>(`repos/${owner}/${repo}/pulls`, {
+ state,
+ per_page: String(perPage),
+ page: String(page),
+ });
+}
+
+// PR 단건
+export async function getPull(owner: string, repo: string, number: number) {
+ return ghFetch<GhPull>(`repos/${owner}/${repo}/pulls/${number}`);
+}
+
+// PR 변경 파일 목록
+export async function getPullFiles(owner: string, repo: string, number: number) {
+ return ghFetch<GhPullFile[]>(`repos/${owner}/${repo}/pulls/${number}/files`, {
+ per_page: "100",
+ });
+}
+
+// PR 커밋 목록
+export async function getPullCommits(owner: string, repo: string, number: number) {
+ return ghFetch<GhCommit[]>(`repos/${owner}/${repo}/pulls/${number}/commits`, {
+ per_page: "100",
+ });
+}
+
+// 커밋 단건 (파일 변경 포함)
+export async function getCommit(owner: string, repo: string, sha: string) {
+ return ghFetch<GhCommitDetail>(`repos/${owner}/${repo}/commits/${sha}`);
}
// --- 타입 ---
@@ -85,6 +116,11 @@ export type GhCommit = {
author: { login: string; avatar_url: string } | null;
};
+export type GhCommitDetail = GhCommit & {
+ stats: { additions: number; deletions: number; total: number };
+ files: GhPullFile[];
+};
+
export type GhPull = {
number: number;
title: string;
@@ -97,3 +133,14 @@ export type GhPull = {
head: { ref: string };
base: { ref: string };
};
+
+export type GhPullFile = {
+ sha: string;
+ filename: string;
+ previous_filename?: string;
+ status: "added" | "removed" | "modified" | "renamed" | "copied" | "changed" | "unchanged";
+ additions: number;
+ deletions: number;
+ changes: number;
+ patch?: string;
+};
@@ -16,15 +16,45 @@
},
"commits": {
"title": "Commit History",
- "countSuffix": ""
+ "countSuffix": "",
+ "page": "Page",
+ "prev": "Prev",
+ "next": "Next",
+ "backToList": "Back to list",
+ "filesChanged": "Files changed",
+ "binaryFile": "Binary file",
+ "added": "added",
+ "removed": "removed",
+ "modified": "modified",
+ "renamed": "renamed",
+ "foldAll": "Fold all",
+ "unfoldAll": "Unfold all"
},
"pulls": {
"title": "Pull Requests",
"countSuffix": "",
"empty": "No pull requests.",
"merged": "Merged",
"open": "Open",
- "closed": "Closed"
+ "closed": "Closed",
+ "page": "Page",
+ "prev": "Prev",
+ "next": "Next",
+ "backToList": "Back to list",
+ "noBody": "No description",
+ "filesChanged": "Files changed",
+ "additions": "additions",
+ "deletions": "deletions",
+ "binaryFile": "Binary file",
+ "added": "added",
+ "removed": "removed",
+ "modified": "modified",
+ "renamed": "renamed",
+ "tabOverview": "Overview",
+ "tabCommits": "Commits",
+ "tabFiles": "Files changed",
+ "foldAll": "Fold all",
+ "unfoldAll": "Unfold all"
},
"error": {
"title": "Failed to load data.",
@@ -16,15 +16,45 @@
},
"commits": {
"title": "커밋 히스토리",
- "countSuffix": "개"
+ "countSuffix": "개",
+ "page": "페이지",
+ "prev": "이전",
+ "next": "다음",
+ "backToList": "목록으로",
+ "filesChanged": "변경된 파일",
+ "binaryFile": "바이너리 파일",
+ "added": "추가됨",
+ "removed": "삭제됨",
+ "modified": "수정됨",
+ "renamed": "이름 변경됨",
+ "foldAll": "모두 접기",
+ "unfoldAll": "모두 펼치기"
},
"pulls": {
"title": "Pull Requests",
"countSuffix": "개",
"empty": "PR이 없습니다.",
"merged": "Merged",
"open": "Open",
- "closed": "Closed"
+ "closed": "Closed",
+ "page": "페이지",
+ "prev": "이전",
+ "next": "다음",
+ "backToList": "목록으로",
+ "noBody": "설명 없음",
+ "filesChanged": "변경된 파일",
+ "additions": "추가",
+ "deletions": "삭제",
+ "binaryFile": "바이너리 파일",
+ "added": "추가됨",
+ "removed": "삭제됨",
+ "modified": "수정됨",
+ "renamed": "이름 변경됨",
+ "tabOverview": "Overview",
+ "tabCommits": "Commits",
+ "tabFiles": "Files changed",
+ "foldAll": "모두 접기",
+ "unfoldAll": "모두 펼치기"
},
"error": {
"title": "데이터를 불러오지 못했습니다.",
@@ -12,6 +12,8 @@
"next": "16.2.1",
"react": "19.2.4",
"react-dom": "19.2.4",
+ "react-markdown": "^10.1.0",
+ "remark-gfm": "^4.0.1",
"shiki": "^4.0.2",
"tailwind-merge": "^3.5.0"
},
@@ -1627,13 +1629,30 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@types/debug": {
+ "version": "4.1.13",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz",
+ "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/ms": "*"
+ }
+ },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
- "dev": true,
"license": "MIT"
},
+ "node_modules/@types/estree-jsx": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz",
+ "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*"
+ }
+ },
"node_modules/@types/hast": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
@@ -1666,6 +1685,12 @@
"@types/unist": "*"
}
},
+ "node_modules/@types/ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+ "license": "MIT"
+ },
"node_modules/@types/node": {
"version": "20.19.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz",
@@ -1680,7 +1705,6 @@
"version": "19.2.14",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"csstype": "^3.2.2"
@@ -2558,6 +2582,16 @@
"node": ">= 0.4"
}
},
+ "node_modules/bail": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
+ "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -2742,6 +2776,16 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/character-entities": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
+ "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/character-entities-html4": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz",
@@ -2762,6 +2806,16 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/client-only": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
@@ -2840,7 +2894,6 @@
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/damerau-levenshtein": {
@@ -2908,7 +2961,6 @@
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -2922,6 +2974,19 @@
}
}
},
+ "node_modules/decode-named-character-reference": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz",
+ "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "character-entities": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -3674,6 +3739,16 @@
"node": ">=4.0"
}
},
+ "node_modules/estree-util-is-identifier-name": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz",
+ "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@@ -3684,6 +3759,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "license": "MIT"
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -4136,6 +4217,33 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/hast-util-to-jsx-runtime": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz",
+ "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "devlop": "^1.0.0",
+ "estree-util-is-identifier-name": "^3.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "mdast-util-mdx-expression": "^2.0.0",
+ "mdast-util-mdx-jsx": "^3.0.0",
+ "mdast-util-mdxjs-esm": "^2.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "style-to-js": "^1.0.0",
+ "unist-util-position": "^5.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/hast-util-whitespace": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
@@ -4166,6 +4274,16 @@
"hermes-estree": "0.25.1"
}
},
+ "node_modules/html-url-attributes": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz",
+ "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/html-void-elements": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz",
@@ -4213,6 +4331,12 @@
"node": ">=0.8.19"
}
},
+ "node_modules/inline-style-parser": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz",
+ "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==",
+ "license": "MIT"
+ },
"node_modules/internal-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
@@ -4228,6 +4352,30 @@
"node": ">= 0.4"
}
},
+ "node_modules/is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-array-buffer": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
@@ -4386,6 +4534,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -4445,6 +4603,16 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-map": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
@@ -4498,6 +4666,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-plain-obj": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
+ "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-regex": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
@@ -5096,6 +5276,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/longest-streak": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
+ "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -5129,6 +5319,16 @@
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
+ "node_modules/markdown-table": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz",
+ "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -5139,131 +5339,866 @@
"node": ">= 0.4"
}
},
- "node_modules/mdast-util-to-hast": {
- "version": "13.2.1",
- "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz",
- "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==",
+ "node_modules/mdast-util-find-and-replace": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz",
+ "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==",
"license": "MIT",
"dependencies": {
- "@types/hast": "^3.0.0",
"@types/mdast": "^4.0.0",
- "@ungap/structured-clone": "^1.0.0",
- "devlop": "^1.0.0",
- "micromark-util-sanitize-uri": "^2.0.0",
- "trim-lines": "^3.0.0",
- "unist-util-position": "^5.0.0",
- "unist-util-visit": "^5.0.0",
- "vfile": "^6.0.0"
+ "escape-string-regexp": "^5.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
+ "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
"license": "MIT",
"engines": {
- "node": ">= 8"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/micromark-util-character": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
- "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
+ "node_modules/mdast-util-from-markdown": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz",
+ "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==",
"license": "MIT",
"dependencies": {
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-to-string": "^4.0.0",
+ "micromark": "^4.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-decode-string": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
- "micromark-util-types": "^2.0.0"
+ "micromark-util-types": "^2.0.0",
+ "unist-util-stringify-position": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
}
},
- "node_modules/micromark-util-encode": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
- "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "license": "MIT"
- },
- "node_modules/micromark-util-sanitize-uri": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
- "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
+ "node_modules/mdast-util-gfm": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz",
+ "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==",
"license": "MIT",
"dependencies": {
- "micromark-util-character": "^2.0.0",
- "micromark-util-encode": "^2.0.0",
- "micromark-util-symbol": "^2.0.0"
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-gfm-autolink-literal": "^2.0.0",
+ "mdast-util-gfm-footnote": "^2.0.0",
+ "mdast-util-gfm-strikethrough": "^2.0.0",
+ "mdast-util-gfm-table": "^2.0.0",
+ "mdast-util-gfm-task-list-item": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
}
},
- "node_modules/micromark-util-symbol": {
+ "node_modules/mdast-util-gfm-autolink-literal": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
- "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "license": "MIT"
- },
- "node_modules/micromark-util-types": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
- "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "license": "MIT"
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz",
+ "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "ccount": "^2.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-find-and-replace": "^3.0.0",
+ "micromark-util-character": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-footnote": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz",
+ "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.1.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-strikethrough": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz",
+ "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-table": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz",
+ "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "markdown-table": "^3.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-gfm-task-list-item": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz",
+ "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-expression": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz",
+ "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdx-jsx": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz",
+ "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "devlop": "^1.1.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "parse-entities": "^4.0.0",
+ "stringify-entities": "^4.0.0",
+ "unist-util-stringify-position": "^4.0.0",
+ "vfile-message": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-mdxjs-esm": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz",
+ "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree-jsx": "^1.0.0",
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "mdast-util-to-markdown": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-phrasing": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz",
+ "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-hast": {
+ "version": "13.2.1",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz",
+ "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "@ungap/structured-clone": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "trim-lines": "^3.0.0",
+ "unist-util-position": "^5.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-markdown": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz",
+ "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "@types/unist": "^3.0.0",
+ "longest-streak": "^3.0.0",
+ "mdast-util-phrasing": "^4.0.0",
+ "mdast-util-to-string": "^4.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-decode-string": "^2.0.0",
+ "unist-util-visit": "^5.0.0",
+ "zwitch": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/mdast-util-to-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz",
+ "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromark": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz",
+ "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "@types/debug": "^4.0.0",
+ "debug": "^4.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-core-commonmark": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz",
+ "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "devlop": "^1.0.0",
+ "micromark-factory-destination": "^2.0.0",
+ "micromark-factory-label": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-title": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-html-tag-name": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-extension-gfm": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz",
+ "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark-extension-gfm-autolink-literal": "^2.0.0",
+ "micromark-extension-gfm-footnote": "^2.0.0",
+ "micromark-extension-gfm-strikethrough": "^2.0.0",
+ "micromark-extension-gfm-table": "^2.0.0",
+ "micromark-extension-gfm-tagfilter": "^2.0.0",
+ "micromark-extension-gfm-task-list-item": "^2.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-autolink-literal": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz",
+ "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-footnote": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz",
+ "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==",
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-strikethrough": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz",
+ "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==",
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-table": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz",
+ "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==",
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-tagfilter": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz",
+ "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==",
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-task-list-item": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz",
+ "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==",
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-factory-destination": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
+ "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-label": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
+ "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-space": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-title": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
+ "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-factory-whitespace": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
+ "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-character": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-chunked": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
+ "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-classify-character": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
+ "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-combine-extensions": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
+ "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-numeric-character-reference": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
+ "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-decode-string": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz",
+ "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decode-named-character-reference": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-encode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-html-tag-name": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
+ "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-normalize-identifier": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
+ "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-resolve-all": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
+ "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-subtokenize": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
+ "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
+ "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
@@ -5300,7 +6235,6 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
"license": "MIT"
},
"node_modules/nanoid": {
@@ -5672,6 +6606,31 @@
"node": ">=6"
}
},
+ "node_modules/parse-entities": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
+ "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/parse-entities/node_modules/@types/unist": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+ "license": "MIT"
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -5848,6 +6807,33 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/react-markdown": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz",
+ "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "devlop": "^1.0.0",
+ "hast-util-to-jsx-runtime": "^2.0.0",
+ "html-url-attributes": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "remark-parse": "^11.0.0",
+ "remark-rehype": "^11.0.0",
+ "unified": "^11.0.0",
+ "unist-util-visit": "^5.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18",
+ "react": ">=18"
+ }
+ },
"node_modules/reflect.getprototypeof": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
@@ -5916,6 +6902,72 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/remark-gfm": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz",
+ "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-gfm": "^3.0.0",
+ "micromark-extension-gfm": "^3.0.0",
+ "remark-parse": "^11.0.0",
+ "remark-stringify": "^11.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-parse": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz",
+ "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-from-markdown": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-rehype": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz",
+ "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/mdast": "^4.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "unified": "^11.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/remark-stringify": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz",
+ "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/mdast": "^4.0.0",
+ "mdast-util-to-markdown": "^2.0.0",
+ "unified": "^11.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/resolve": {
"version": "1.22.11",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
@@ -6478,6 +7530,24 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/style-to-js": {
+ "version": "1.1.21",
+ "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz",
+ "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==",
+ "license": "MIT",
+ "dependencies": {
+ "style-to-object": "1.0.14"
+ }
+ },
+ "node_modules/style-to-object": {
+ "version": "1.0.14",
+ "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz",
+ "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==",
+ "license": "MIT",
+ "dependencies": {
+ "inline-style-parser": "0.2.7"
+ }
+ },
"node_modules/styled-jsx": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
@@ -6629,6 +7699,16 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/trough": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz",
+ "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/ts-api-utils": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
@@ -6829,6 +7909,25 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/unified": {
+ "version": "11.0.5",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz",
+ "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "bail": "^2.0.0",
+ "devlop": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-plain-obj": "^4.0.0",
+ "trough": "^2.0.0",
+ "vfile": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/unist-util-is": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz",
@@ -13,6 +13,8 @@
"next": "16.2.1",
"react": "19.2.4",
"react-dom": "19.2.4",
+ "react-markdown": "^10.1.0",
+ "remark-gfm": "^4.0.1",
"shiki": "^4.0.2",
"tailwind-merge": "^3.5.0"
},