+
+ Real-time click analytics
+
}>
-
-
+
+ }>
+
+
+
);
}
@@ -42,8 +45,6 @@ async function ProjectAnalyticsRSC({
}),
);
- console.log("Refreshed analytics data");
-
const chartData = analytics[0].map(
(data: { start: string; clicks: number }, i) => {
return {
diff --git a/components/projects/project-content-wrapper.tsx b/components/projects/project-content-wrapper.tsx
new file mode 100644
index 0000000..e2f2dc6
--- /dev/null
+++ b/components/projects/project-content-wrapper.tsx
@@ -0,0 +1,20 @@
+import { cn } from "@dub/utils";
+
+export default function ProjectContentWrapper({
+ className,
+ children,
+}: {
+ className?: string;
+ children: React.ReactNode;
+}) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/components/projects/project-layout-tabs.tsx b/components/projects/project-layout-tabs.tsx
index ae79516..98058b5 100644
--- a/components/projects/project-layout-tabs.tsx
+++ b/components/projects/project-layout-tabs.tsx
@@ -16,7 +16,7 @@ export default function ProjectLayoutTabs() {
return (
-
+
{PROJECT_TABS.map((t) => (
+ {project.readme}
+
+ );
+}
diff --git a/components/projects/project-tab-note.tsx b/components/projects/project-tab-note.tsx
index 8e99e19..bc56d43 100644
--- a/components/projects/project-tab-note.tsx
+++ b/components/projects/project-tab-note.tsx
@@ -1,6 +1,6 @@
import { cn } from "@dub/utils";
import { Info } from "lucide-react";
-import ReactMarkdown from "react-markdown";
+import ReactMarkdown from "../ui/react-markdown";
export default function ProjectTabNote(props: {
className?: string;
@@ -15,20 +15,7 @@ export default function ProjectTabNote(props: {
>
{typeof props.children === "string" ? (
- (
-
- ),
- }}
- >
- {props.children}
-
+ {props.children}
) : (
props.children
)}
diff --git a/components/projects/project-team.tsx b/components/projects/project-team.tsx
index 7f5f46c..8b68505 100644
--- a/components/projects/project-team.tsx
+++ b/components/projects/project-team.tsx
@@ -2,6 +2,7 @@ import { EnrichedProjectProps } from "@/lib/types";
import { cn } from "@dub/utils";
import Link from "next/link";
import EditTeamButton from "./edit-team-button";
+import ProjectContentWrapper from "./project-content-wrapper";
export default function ProjectTeam({
project,
@@ -11,7 +12,7 @@ export default function ProjectTeam({
const { users } = project;
return (
- <>
+
@@ -42,6 +43,6 @@ export default function ProjectTeam({
))}
- >
+
);
}
diff --git a/components/ui/react-markdown.tsx b/components/ui/react-markdown.tsx
new file mode 100644
index 0000000..ebc9499
--- /dev/null
+++ b/components/ui/react-markdown.tsx
@@ -0,0 +1,79 @@
+import { cn } from "@dub/utils";
+import ReactMarkdownHelper from "react-markdown";
+import rehypeAutolinkHeadings from "rehype-autolink-headings";
+import rehypeRaw from "rehype-raw";
+
+import rehypeSlug from "rehype-slug";
+import remarkGfm from "remark-gfm";
+import { visit } from "unist-util-visit";
+
+export default function ReactMarkdown({
+ className,
+ children,
+}: {
+ className?: string;
+ children: string;
+}) {
+ return (
+
(
+
+ ),
+ }}
+ remarkPlugins={[remarkGfm]}
+ rehypePlugins={[
+ rehypeRaw,
+ rehypeSlug,
+ () => (tree) => {
+ visit(tree, (node) => {
+ if (node?.type === "element" && node?.tagName === "pre") {
+ const [codeEl] = node.children;
+
+ if (codeEl.tagName !== "code") return;
+
+ node.raw = codeEl.children?.[0].value;
+ }
+ });
+ },
+ // [
+ // rehypePrettyCode,
+ // {
+ // theme: "github-light",
+ // },
+ // ],
+ () => (tree) => {
+ visit(tree, (node) => {
+ if (node?.type === "element" && node?.tagName === "div") {
+ if (!("data-rehype-pretty-code-fragment" in node.properties)) {
+ return;
+ }
+
+ for (const child of node.children) {
+ if (child.tagName === "pre") {
+ child.properties["raw"] = node.raw;
+ }
+ }
+ }
+ });
+ },
+ [
+ rehypeAutolinkHeadings,
+ {
+ properties: {
+ className: ["anchor"],
+ "data-mdx-heading": "",
+ },
+ },
+ ],
+ ]}
+ >
+ {children}
+
+ );
+}
diff --git a/lib/actions/get-project.ts b/lib/actions/get-project.ts
index b849072..b16c7d1 100644
--- a/lib/actions/get-project.ts
+++ b/lib/actions/get-project.ts
@@ -1,4 +1,5 @@
import { cache } from "react";
+import { getRepo } from "../github";
import prisma from "../prisma";
import { EnrichedProjectProps } from "../types";
@@ -27,12 +28,38 @@ export const getProject = cache(
},
});
if (!project) return null;
+
const githubLink = project.links.find((link) => link.type === "GITHUB")!;
const websiteLink = project.links.find((link) => link.type === "WEBSITE");
+
+ const { stars, default_branch } = await getRepo(githubLink.url);
+
+ if (stars !== project.stars) {
+ await prisma.project.update({
+ where: {
+ slug,
+ },
+ data: {
+ stars,
+ },
+ });
+ }
+
+ const readmeUrl =
+ githubLink.url
+ .replace("github.com", "raw.githubusercontent.com")
+ .replace(/\/$/, "") + `/${default_branch}/README.md`;
+
+ const readme = await fetch(readmeUrl)
+ .then((res) => res.text())
+ .catch(() => "");
+
return {
...project,
+ stars,
githubLink,
websiteLink,
+ readme,
users: project.users.map(({ userId, role, user }) => ({
id: userId,
role,
diff --git a/lib/github.ts b/lib/github.ts
index 98de88e..d8d2a21 100644
--- a/lib/github.ts
+++ b/lib/github.ts
@@ -22,6 +22,7 @@ export async function getRepo(url: string) {
owner,
stargazers_count: stars,
forks,
+ default_branch,
} = data;
return {
@@ -32,5 +33,6 @@ export async function getRepo(url: string) {
homepage,
stars,
forks,
+ default_branch,
};
}
diff --git a/lib/types.ts b/lib/types.ts
index c888e3c..8891fbe 100644
--- a/lib/types.ts
+++ b/lib/types.ts
@@ -3,6 +3,7 @@ import { Link, Project } from "@prisma/client";
export interface EnrichedProjectProps extends Project {
links: Link[];
githubLink: Link;
+ readme: string;
websiteLink: Link | null;
users: {
id: string;
diff --git a/package.json b/package.json
index ae08a27..29689a2 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,11 @@
"react-markdown": "^9.0.1",
"react-textarea-autosize": "^8.5.3",
"react@latest": "link:@@types/react@latest",
+ "rehype-autolink-headings": "^7.1.0",
+ "rehype-pretty-code": "^0.13.1",
+ "rehype-raw": "^7.0.0",
+ "rehype-slug": "^6.0.0",
+ "remark-gfm": "^4.0.0",
"sonner": "^1.4.41",
"typescript": "5.4.5",
"use-debounce": "^9.0.4",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 69e02b0..eba683a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -71,6 +71,21 @@ dependencies:
react@latest:
specifier: link:@@types/react@latest
version: link:@@types/react@latest
+ rehype-autolink-headings:
+ specifier: ^7.1.0
+ version: 7.1.0
+ rehype-pretty-code:
+ specifier: ^0.13.1
+ version: 0.13.1(shiki@1.3.0)
+ rehype-raw:
+ specifier: ^7.0.0
+ version: 7.0.0
+ rehype-slug:
+ specifier: ^6.0.0
+ version: 6.0.0
+ remark-gfm:
+ specifier: ^4.0.0
+ version: 4.0.0
sonner:
specifier: ^1.4.41
version: 1.4.41(react-dom@18.2.0)(react@18.2.0)
@@ -1433,6 +1448,10 @@ packages:
'@babel/runtime': 7.24.4
dev: false
+ /@shikijs/core@1.3.0:
+ resolution: {integrity: sha512-7fedsBfuILDTBmrYZNFI8B6ATTxhQAasUHllHmjvSZPnoq4bULWoTpHwmuQvZ8Aq03/tAa2IGo6RXqWtHdWaCA==}
+ dev: false
+
/@sindresorhus/slugify@2.2.1:
resolution: {integrity: sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw==}
engines: {node: '>=12'}
@@ -1976,6 +1995,11 @@ packages:
resolution: {integrity: sha512-wRmWJ8F7rgmINuI32S6r2SLrw/h/bJQsDSvBiq9GBfvc2Lh73qTOwn73r3Cf67mjVgFGJYcYtmERzySa5jIWlg==}
dev: true
+ /entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+ dev: false
+
/escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
@@ -2083,6 +2107,10 @@ packages:
engines: {node: '>=6'}
dev: false
+ /github-slugger@2.0.0:
+ resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
+ dev: false
+
/glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -2115,6 +2143,66 @@ packages:
dependencies:
function-bind: 1.1.1
+ /hast-util-from-html@2.0.1:
+ resolution: {integrity: sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==}
+ dependencies:
+ '@types/hast': 3.0.4
+ devlop: 1.1.0
+ hast-util-from-parse5: 8.0.1
+ parse5: 7.1.2
+ vfile: 6.0.1
+ vfile-message: 4.0.2
+ dev: false
+
+ /hast-util-from-parse5@8.0.1:
+ resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==}
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.2
+ devlop: 1.1.0
+ hastscript: 8.0.0
+ property-information: 6.5.0
+ vfile: 6.0.1
+ vfile-location: 5.0.2
+ web-namespaces: 2.0.1
+ dev: false
+
+ /hast-util-heading-rank@3.0.0:
+ resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==}
+ dependencies:
+ '@types/hast': 3.0.4
+ dev: false
+
+ /hast-util-is-element@3.0.0:
+ resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
+ dependencies:
+ '@types/hast': 3.0.4
+ dev: false
+
+ /hast-util-parse-selector@4.0.0:
+ resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
+ dependencies:
+ '@types/hast': 3.0.4
+ dev: false
+
+ /hast-util-raw@9.0.2:
+ resolution: {integrity: sha512-PldBy71wO9Uq1kyaMch9AHIghtQvIwxBUkv823pKmkTM3oV1JxtsTNYdevMxvUHqcnOAuO65JKU2+0NOxc2ksA==}
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.2
+ '@ungap/structured-clone': 1.2.0
+ hast-util-from-parse5: 8.0.1
+ hast-util-to-parse5: 8.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.1.0
+ parse5: 7.1.2
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.1
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+ dev: false
+
/hast-util-to-jsx-runtime@2.3.0:
resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==}
dependencies:
@@ -2137,16 +2225,48 @@ packages:
- supports-color
dev: false
+ /hast-util-to-parse5@8.0.0:
+ resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==}
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+ dev: false
+
+ /hast-util-to-string@3.0.0:
+ resolution: {integrity: sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==}
+ dependencies:
+ '@types/hast': 3.0.4
+ dev: false
+
/hast-util-whitespace@3.0.0:
resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
dependencies:
'@types/hast': 3.0.4
dev: false
+ /hastscript@8.0.0:
+ resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==}
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ hast-util-parse-selector: 4.0.0
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+ dev: false
+
/html-url-attributes@3.0.0:
resolution: {integrity: sha512-/sXbVCWayk6GDVg3ctOX6nxaVj7So40FcFAnWlWGNAB1LpYKcV5Cd10APjPjW80O7zYW2MsjBV4zZ7IZO5fVow==}
dev: false
+ /html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+ dev: false
+
/inflight@1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
dependencies:
@@ -2301,6 +2421,19 @@ packages:
react: 18.2.0
dev: false
+ /markdown-table@3.0.3:
+ resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
+ dev: false
+
+ /mdast-util-find-and-replace@3.0.1:
+ resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==}
+ dependencies:
+ '@types/mdast': 4.0.3
+ escape-string-regexp: 5.0.0
+ unist-util-is: 6.0.0
+ unist-util-visit-parents: 6.0.1
+ dev: false
+
/mdast-util-from-markdown@2.0.0:
resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==}
dependencies:
@@ -2320,6 +2453,75 @@ packages:
- supports-color
dev: false
+ /mdast-util-gfm-autolink-literal@2.0.0:
+ resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==}
+ dependencies:
+ '@types/mdast': 4.0.3
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-find-and-replace: 3.0.1
+ micromark-util-character: 2.1.0
+ dev: false
+
+ /mdast-util-gfm-footnote@2.0.0:
+ resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==}
+ dependencies:
+ '@types/mdast': 4.0.3
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.0
+ mdast-util-to-markdown: 2.1.0
+ micromark-util-normalize-identifier: 2.0.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /mdast-util-gfm-strikethrough@2.0.0:
+ resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
+ dependencies:
+ '@types/mdast': 4.0.3
+ mdast-util-from-markdown: 2.0.0
+ mdast-util-to-markdown: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /mdast-util-gfm-table@2.0.0:
+ resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
+ dependencies:
+ '@types/mdast': 4.0.3
+ devlop: 1.1.0
+ markdown-table: 3.0.3
+ mdast-util-from-markdown: 2.0.0
+ mdast-util-to-markdown: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /mdast-util-gfm-task-list-item@2.0.0:
+ resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
+ dependencies:
+ '@types/mdast': 4.0.3
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.0
+ mdast-util-to-markdown: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /mdast-util-gfm@3.0.0:
+ resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==}
+ dependencies:
+ 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.1.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
/mdast-util-mdx-expression@2.0.0:
resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==}
dependencies:
@@ -2431,6 +2633,78 @@ packages:
micromark-util-types: 2.0.0
dev: false
+ /micromark-extension-gfm-autolink-literal@2.0.0:
+ resolution: {integrity: sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==}
+ dependencies:
+ micromark-util-character: 2.1.0
+ micromark-util-sanitize-uri: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ dev: false
+
+ /micromark-extension-gfm-footnote@2.0.0:
+ resolution: {integrity: sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==}
+ dependencies:
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.1
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.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
+ dev: false
+
+ /micromark-extension-gfm-strikethrough@2.0.0:
+ resolution: {integrity: sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==}
+ dependencies:
+ devlop: 1.1.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
+ dev: false
+
+ /micromark-extension-gfm-table@2.0.0:
+ resolution: {integrity: sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==}
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ dev: false
+
+ /micromark-extension-gfm-tagfilter@2.0.0:
+ resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
+ dependencies:
+ micromark-util-types: 2.0.0
+ dev: false
+
+ /micromark-extension-gfm-task-list-item@2.0.1:
+ resolution: {integrity: sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==}
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ dev: false
+
+ /micromark-extension-gfm@3.0.0:
+ resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
+ 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.1
+ micromark-util-combine-extensions: 2.0.0
+ micromark-util-types: 2.0.0
+ dev: false
+
/micromark-factory-destination@2.0.0:
resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==}
dependencies:
@@ -2734,6 +3008,16 @@ packages:
is-hexadecimal: 2.0.1
dev: false
+ /parse-numeric-range@1.3.0:
+ resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==}
+ dev: false
+
+ /parse5@7.1.2:
+ resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
+ dependencies:
+ entities: 4.5.0
+ dev: false
+
/path-is-absolute@1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
@@ -3175,6 +3459,71 @@ packages:
resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
dev: false
+ /rehype-autolink-headings@7.1.0:
+ resolution: {integrity: sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==}
+ dependencies:
+ '@types/hast': 3.0.4
+ '@ungap/structured-clone': 1.2.0
+ hast-util-heading-rank: 3.0.0
+ hast-util-is-element: 3.0.0
+ unified: 11.0.4
+ unist-util-visit: 5.0.0
+ dev: false
+
+ /rehype-parse@9.0.0:
+ resolution: {integrity: sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==}
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-from-html: 2.0.1
+ unified: 11.0.4
+ dev: false
+
+ /rehype-pretty-code@0.13.1(shiki@1.3.0):
+ resolution: {integrity: sha512-Lw3cZohiw5J2NMMD0M11W9HlIKrZ7JjxfJmY0nxVa/HG5oMT+kkhcrUEFB5ajaEk/E9uR8+n9AmQbGJci9/TqA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ shiki: ^1.0.0
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-to-string: 3.0.0
+ parse-numeric-range: 1.3.0
+ rehype-parse: 9.0.0
+ shiki: 1.3.0
+ unified: 11.0.4
+ unist-util-visit: 5.0.0
+ dev: false
+
+ /rehype-raw@7.0.0:
+ resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-raw: 9.0.2
+ vfile: 6.0.1
+ dev: false
+
+ /rehype-slug@6.0.0:
+ resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==}
+ dependencies:
+ '@types/hast': 3.0.4
+ github-slugger: 2.0.0
+ hast-util-heading-rank: 3.0.0
+ hast-util-to-string: 3.0.0
+ unist-util-visit: 5.0.0
+ dev: false
+
+ /remark-gfm@4.0.0:
+ resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==}
+ dependencies:
+ '@types/mdast': 4.0.3
+ 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.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
/remark-parse@11.0.0:
resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
dependencies:
@@ -3196,6 +3545,14 @@ packages:
vfile: 6.0.1
dev: false
+ /remark-stringify@11.0.0:
+ resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+ dependencies:
+ '@types/mdast': 4.0.3
+ mdast-util-to-markdown: 2.1.0
+ unified: 11.0.4
+ dev: false
+
/resolve@1.22.6:
resolution: {integrity: sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==}
hasBin: true
@@ -3223,6 +3580,12 @@ packages:
resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==}
dev: false
+ /shiki@1.3.0:
+ resolution: {integrity: sha512-9aNdQy/etMXctnPzsje1h1XIGm9YfRcSksKOGqZWXA/qP9G18/8fpz5Bjpma8bOgz3tqIpjERAd6/lLjFyzoww==}
+ dependencies:
+ '@shikijs/core': 1.3.0
+ dev: false
+
/sonner@1.4.41(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-uG511ggnnsw6gcn/X+YKkWPo5ep9il9wYi3QJxHsYe7yTZ4+cOd1wuodOUmOpFuXL+/RE3R04LczdNCDygTDgQ==}
peerDependencies:
@@ -3572,6 +3935,13 @@ packages:
- '@types/react-dom'
dev: false
+ /vfile-location@5.0.2:
+ resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==}
+ dependencies:
+ '@types/unist': 3.0.2
+ vfile: 6.0.1
+ dev: false
+
/vfile-message@4.0.2:
resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
dependencies:
@@ -3606,6 +3976,10 @@ packages:
d3-timer: 3.0.1
dev: false
+ /web-namespaces@2.0.1:
+ resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
+ dev: false
+
/wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}