aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/web/components/dashboard/bookmarks/TextCard.tsx8
-rw-r--r--apps/web/components/dashboard/preview/TextContentSection.tsx6
-rw-r--r--apps/web/components/dashboard/settings/AddApiKey.tsx22
-rw-r--r--apps/web/components/ui/copy-button.tsx37
-rw-r--r--apps/web/components/ui/markdown-component.tsx58
-rw-r--r--apps/web/package.json2
-rw-r--r--pnpm-lock.yaml173
7 files changed, 280 insertions, 26 deletions
diff --git a/apps/web/components/dashboard/bookmarks/TextCard.tsx b/apps/web/components/dashboard/bookmarks/TextCard.tsx
index 74b3e8e5..b18efc3d 100644
--- a/apps/web/components/dashboard/bookmarks/TextCard.tsx
+++ b/apps/web/components/dashboard/bookmarks/TextCard.tsx
@@ -1,10 +1,10 @@
"use client";
import { useState } from "react";
+import { MarkdownComponent } from "@/components/ui/markdown-component";
import { api } from "@/lib/trpc";
import { bookmarkLayoutSwitch } from "@/lib/userLocalSettings/bookmarksLayout";
import { cn } from "@/lib/utils";
-import Markdown from "react-markdown";
import type { ZBookmark } from "@hoarder/shared/types/bookmarks";
import { isBookmarkStillTagging } from "@hoarder/shared-react/utils/bookmarkUtils";
@@ -52,11 +52,7 @@ export default function TextCard({
/>
<BookmarkLayoutAdaptingCard
title={bookmark.title}
- content={
- <Markdown className="prose dark:prose-invert">
- {bookmarkedText.text}
- </Markdown>
- }
+ content={<MarkdownComponent>{bookmarkedText.text}</MarkdownComponent>}
footer={null}
wrapTags={true}
bookmark={bookmark}
diff --git a/apps/web/components/dashboard/preview/TextContentSection.tsx b/apps/web/components/dashboard/preview/TextContentSection.tsx
index eba7d28b..2df1e964 100644
--- a/apps/web/components/dashboard/preview/TextContentSection.tsx
+++ b/apps/web/components/dashboard/preview/TextContentSection.tsx
@@ -1,5 +1,5 @@
+import { MarkdownComponent } from "@/components/ui/markdown-component";
import { ScrollArea } from "@radix-ui/react-scroll-area";
-import Markdown from "react-markdown";
import type { ZBookmark } from "@hoarder/shared/types/bookmarks";
@@ -9,9 +9,7 @@ export function TextContentSection({ bookmark }: { bookmark: ZBookmark }) {
}
return (
<ScrollArea className="h-full">
- <Markdown className="prose mx-auto dark:prose-invert">
- {bookmark.content.text}
- </Markdown>
+ <MarkdownComponent>{bookmark.content.text}</MarkdownComponent>
</ScrollArea>
);
}
diff --git a/apps/web/components/dashboard/settings/AddApiKey.tsx b/apps/web/components/dashboard/settings/AddApiKey.tsx
index 15a78d56..34fd2df7 100644
--- a/apps/web/components/dashboard/settings/AddApiKey.tsx
+++ b/apps/web/components/dashboard/settings/AddApiKey.tsx
@@ -5,6 +5,7 @@ import { useState } from "react";
import { useRouter } from "next/navigation";
import { ActionButton } from "@/components/ui/action-button";
import { Button } from "@/components/ui/button";
+import CopyBtn from "@/components/ui/copy-button";
import {
Dialog,
DialogClose,
@@ -28,19 +29,10 @@ import { Input } from "@/components/ui/input";
import { toast } from "@/components/ui/use-toast";
import { api } from "@/lib/trpc";
import { zodResolver } from "@hookform/resolvers/zod";
-import { Check, Copy } from "lucide-react";
import { useForm } from "react-hook-form";
import { z } from "zod";
function ApiKeySuccess({ apiKey }: { apiKey: string }) {
- const [isCopied, setCopied] = useState(false);
-
- const onCopy = () => {
- navigator.clipboard.writeText(apiKey);
- setCopied(true);
- setTimeout(() => setCopied(false), 2000);
- };
-
return (
<div>
<div className="py-4">
@@ -49,13 +41,11 @@ function ApiKeySuccess({ apiKey }: { apiKey: string }) {
</div>
<div className="flex space-x-2 pt-2">
<Input value={apiKey} readOnly />
- <Button onClick={onCopy}>
- {!isCopied ? (
- <Copy className="size-4" />
- ) : (
- <Check className="size-4" />
- )}
- </Button>
+ <CopyBtn
+ getStringToCopy={() => {
+ return apiKey;
+ }}
+ />
</div>
</div>
);
diff --git a/apps/web/components/ui/copy-button.tsx b/apps/web/components/ui/copy-button.tsx
new file mode 100644
index 00000000..a51ce902
--- /dev/null
+++ b/apps/web/components/ui/copy-button.tsx
@@ -0,0 +1,37 @@
+import React, { useEffect } from "react";
+import { Check, Copy } from "lucide-react";
+
+export default function CopyBtn({
+ className,
+ getStringToCopy,
+}: {
+ className?: string;
+ getStringToCopy: () => string;
+}) {
+ const [copyOk, setCopyOk] = React.useState(false);
+ const [disabled, setDisabled] = React.useState(false);
+ useEffect(() => {
+ if (!navigator || !navigator.clipboard) {
+ setDisabled(true);
+ }
+ });
+
+ const handleClick = async () => {
+ await navigator.clipboard.writeText(getStringToCopy());
+ setCopyOk(true);
+ setTimeout(() => {
+ setCopyOk(false);
+ }, 2000);
+ };
+
+ return (
+ <button
+ className={className}
+ onClick={handleClick}
+ disabled={disabled}
+ title={disabled ? "Copying is only available over https" : undefined}
+ >
+ {copyOk ? <Check /> : <Copy />}
+ </button>
+ );
+}
diff --git a/apps/web/components/ui/markdown-component.tsx b/apps/web/components/ui/markdown-component.tsx
new file mode 100644
index 00000000..f92cb3a3
--- /dev/null
+++ b/apps/web/components/ui/markdown-component.tsx
@@ -0,0 +1,58 @@
+import React from "react";
+import CopyBtn from "@/components/ui/copy-button";
+import { cn } from "@/lib/utils";
+import Markdown from "react-markdown";
+import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
+import { dracula } from "react-syntax-highlighter/dist/cjs/styles/prism";
+
+function PreWithCopyBtn({ className, ...props }: React.ComponentProps<"pre">) {
+ const ref = React.useRef<HTMLPreElement>(null);
+ return (
+ <span className="group relative">
+ <CopyBtn
+ className="absolute right-1 top-1 m-1 hidden text-white group-hover:block"
+ getStringToCopy={() => {
+ return ref.current?.textContent ?? "";
+ }}
+ />
+ <pre ref={ref} className={cn(className, "")} {...props} />
+ </span>
+ );
+}
+
+export function MarkdownComponent({
+ children: markdown,
+}: {
+ children: string;
+}) {
+ return (
+ <Markdown
+ className="prose dark:prose-invert"
+ components={{
+ pre({ ...props }) {
+ return <PreWithCopyBtn {...props} />;
+ },
+ code({ className, children, ...props }) {
+ const match = /language-(\w+)/.exec(className ?? "");
+ return match ? (
+ // @ts-expect-error -- Refs are not compatible for some reason
+ <SyntaxHighlighter
+ PreTag="div"
+ language={match[1]}
+ {...props}
+ style={dracula}
+ >
+ {String(children).replace(/\n$/, "")}
+ </SyntaxHighlighter>
+ ) : (
+ <code className={className} {...props}>
+ {children}
+ </code>
+ );
+ },
+ }}
+ >
+ {markdown}
+ </Markdown>
+ );
+}
diff --git a/apps/web/package.json b/apps/web/package.json
index ebec0278..91743602 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -62,6 +62,7 @@
"react-markdown": "^9.0.1",
"react-masonry-css": "^1.0.16",
"react-select": "^5.8.0",
+ "react-syntax-highlighter": "^15.5.0",
"sharp": "^0.33.3",
"superjson": "^2.2.1",
"tailwind-merge": "^2.2.1",
@@ -76,6 +77,7 @@
"@types/emoji-mart": "^3.0.14",
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19",
+ "@types/react-syntax-highlighter": "^15.5.13",
"autoprefixer": "^10.4.17",
"postcss": "^8.4.35",
"tailwindcss": "^3.4.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6bea8ddb..eac8aee8 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -577,6 +577,9 @@ importers:
react-select:
specifier: ^5.8.0
version: 5.8.0(@types/react@18.2.58)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ react-syntax-highlighter:
+ specifier: ^15.5.0
+ version: 15.5.0(react@18.2.0)
sharp:
specifier: ^0.33.3
version: 0.33.3
@@ -614,6 +617,9 @@ importers:
'@types/react-dom':
specifier: ^18.2.19
version: 18.2.19
+ '@types/react-syntax-highlighter':
+ specifier: ^15.5.13
+ version: 15.5.13
autoprefixer:
specifier: ^10.4.17
version: 10.4.17(postcss@8.4.35)
@@ -4178,6 +4184,9 @@ packages:
'@types/har-format@1.2.15':
resolution: {integrity: sha512-RpQH4rXLuvTXKR0zqHq3go0RVXYv/YVqv4TnPH95VbwUxZdQlK1EtcMvQvMpDngHbt13Csh9Z4qT9AbkiQH5BA==}
+ '@types/hast@2.3.10':
+ resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==}
+
'@types/hast@3.0.4':
resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
@@ -4280,6 +4289,9 @@ packages:
'@types/react-router@5.1.20':
resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==}
+ '@types/react-syntax-highlighter@15.5.13':
+ resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==}
+
'@types/react-transition-group@4.4.10':
resolution: {integrity: sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==}
@@ -5195,12 +5207,21 @@ packages:
character-entities-html4@2.1.0:
resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+ character-entities-legacy@1.1.4:
+ resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==}
+
character-entities-legacy@3.0.0:
resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+ character-entities@1.2.4:
+ resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==}
+
character-entities@2.0.2:
resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+ character-reference-invalid@1.1.4:
+ resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
+
character-reference-invalid@2.0.1:
resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
@@ -5402,6 +5423,9 @@ packages:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
+ comma-separated-tokens@1.0.8:
+ resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==}
+
comma-separated-tokens@2.0.3:
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
@@ -6750,6 +6774,9 @@ packages:
fastq@1.17.1:
resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+ fault@1.0.4:
+ resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==}
+
fault@2.0.1:
resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
@@ -7247,6 +7274,9 @@ packages:
hast-util-from-parse5@8.0.1:
resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==}
+ hast-util-parse-selector@2.2.5:
+ resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==}
+
hast-util-parse-selector@4.0.0:
resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
@@ -7265,6 +7295,9 @@ packages:
hast-util-whitespace@3.0.0:
resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+ hastscript@6.0.0:
+ resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==}
+
hastscript@8.0.0:
resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==}
@@ -7291,6 +7324,9 @@ packages:
resolution: {integrity: sha512-cnN7bQUm65UWOy6cbGcCcZ3rpwW8Q/j4OP5aWRhEry4Z2t2aR1cjrbp0BS+KiBN0smvP1caBgAuxutvyvJILzQ==}
engines: {node: '>=8'}
+ highlight.js@10.7.3:
+ resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
+
history@4.10.1:
resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==}
@@ -7567,9 +7603,15 @@ packages:
resolution: {integrity: sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==}
engines: {node: '>=8'}
+ is-alphabetical@1.0.4:
+ resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==}
+
is-alphabetical@2.0.1:
resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
+ is-alphanumerical@1.0.4:
+ resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==}
+
is-alphanumerical@2.0.1:
resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
@@ -7620,6 +7662,9 @@ packages:
resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
engines: {node: '>= 0.4'}
+ is-decimal@1.0.4:
+ resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==}
+
is-decimal@2.0.1:
resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
@@ -7667,6 +7712,9 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
+ is-hexadecimal@1.0.4:
+ resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==}
+
is-hexadecimal@2.0.1:
resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
@@ -8342,6 +8390,9 @@ packages:
resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ lowlight@1.20.0:
+ resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==}
+
lru-cache@10.2.0:
resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==}
engines: {node: 14 || >=16.14}
@@ -9384,6 +9435,9 @@ packages:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
+ parse-entities@2.0.0:
+ resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==}
+
parse-entities@4.0.1:
resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==}
@@ -9960,6 +10014,10 @@ packages:
peerDependencies:
react: '>=16.0.0'
+ prismjs@1.27.0:
+ resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==}
+ engines: {node: '>=6'}
+
prismjs@1.29.0:
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
engines: {node: '>=6'}
@@ -10000,6 +10058,9 @@ packages:
prop-types@15.8.1:
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+ property-information@5.6.0:
+ resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==}
+
property-information@6.4.1:
resolution: {integrity: sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==}
@@ -10421,6 +10482,11 @@ packages:
'@types/react':
optional: true
+ react-syntax-highlighter@15.5.0:
+ resolution: {integrity: sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==}
+ peerDependencies:
+ react: '>= 0.14.0'
+
react-transition-group@4.4.5:
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
peerDependencies:
@@ -10475,6 +10541,9 @@ packages:
resolution: {integrity: sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==}
engines: {node: '>= 0.4'}
+ refractor@3.6.0:
+ resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==}
+
regenerate-unicode-properties@10.1.1:
resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==}
engines: {node: '>=4'}
@@ -10989,6 +11058,9 @@ packages:
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
deprecated: Please use @jridgewell/sourcemap-codec instead
+ space-separated-tokens@1.1.5:
+ resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==}
+
space-separated-tokens@2.0.2:
resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
@@ -18066,6 +18138,11 @@ snapshots:
'@types/har-format@1.2.15': {}
+ '@types/hast@2.3.10':
+ dependencies:
+ '@types/unist': 2.0.10
+ dev: false
+
'@types/hast@3.0.4':
dependencies:
'@types/unist': 3.0.2
@@ -18193,6 +18270,11 @@ snapshots:
'@types/history': 4.7.11
'@types/react': 18.2.58
+ '@types/react-syntax-highlighter@15.5.13':
+ dependencies:
+ '@types/react': 18.2.58
+ dev: true
+
'@types/react-transition-group@4.4.10':
dependencies:
'@types/react': 18.2.58
@@ -19570,10 +19652,19 @@ snapshots:
character-entities-html4@2.1.0: {}
+ character-entities-legacy@1.1.4:
+ dev: false
+
character-entities-legacy@3.0.0: {}
+ character-entities@1.2.4:
+ dev: false
+
character-entities@2.0.2: {}
+ character-reference-invalid@1.1.4:
+ dev: false
+
character-reference-invalid@2.0.1: {}
charenc@0.0.2:
@@ -19844,6 +19935,9 @@ snapshots:
delayed-stream: 1.0.0
dev: false
+ comma-separated-tokens@1.0.8:
+ dev: false
+
comma-separated-tokens@2.0.3: {}
command-exists@1.2.9:
@@ -21709,6 +21803,11 @@ snapshots:
dependencies:
reusify: 1.0.4
+ fault@1.0.4:
+ dependencies:
+ format: 0.2.2
+ dev: false
+
fault@2.0.1:
dependencies:
format: 0.2.2
@@ -22375,6 +22474,9 @@ snapshots:
web-namespaces: 2.0.1
dev: false
+ hast-util-parse-selector@2.2.5:
+ dev: false
+
hast-util-parse-selector@4.0.0:
dependencies:
'@types/hast': 3.0.4
@@ -22453,6 +22555,15 @@ snapshots:
dependencies:
'@types/hast': 3.0.4
+ hastscript@6.0.0:
+ dependencies:
+ '@types/hast': 2.3.10
+ comma-separated-tokens: 1.0.8
+ hast-util-parse-selector: 2.2.5
+ property-information: 5.6.0
+ space-separated-tokens: 1.1.5
+ dev: false
+
hastscript@8.0.0:
dependencies:
'@types/hast': 3.0.4
@@ -22489,6 +22600,9 @@ snapshots:
source-map: 0.7.4
dev: false
+ highlight.js@10.7.3:
+ dev: false
+
history@4.10.1:
dependencies:
'@babel/runtime': 7.23.9
@@ -22836,8 +22950,17 @@ snapshots:
is-absolute-url@3.0.3:
dev: false
+ is-alphabetical@1.0.4:
+ dev: false
+
is-alphabetical@2.0.1: {}
+ is-alphanumerical@1.0.4:
+ dependencies:
+ is-alphabetical: 1.0.4
+ is-decimal: 1.0.4
+ dev: false
+
is-alphanumerical@2.0.1:
dependencies:
is-alphabetical: 2.0.1
@@ -22895,6 +23018,9 @@ snapshots:
dependencies:
has-tostringtag: 1.0.2
+ is-decimal@1.0.4:
+ dev: false
+
is-decimal@2.0.1: {}
is-directory@0.3.1:
@@ -22933,6 +23059,9 @@ snapshots:
dependencies:
is-extglob: 2.1.1
+ is-hexadecimal@1.0.4:
+ dev: false
+
is-hexadecimal@2.0.1: {}
is-installed-globally@0.4.0:
@@ -23715,6 +23844,12 @@ snapshots:
lowercase-keys@3.0.0:
dev: false
+ lowlight@1.20.0:
+ dependencies:
+ fault: 1.0.4
+ highlight.js: 10.7.3
+ dev: false
+
lru-cache@10.2.0: {}
lru-cache@5.1.1:
@@ -25484,6 +25619,16 @@ snapshots:
dependencies:
callsites: 3.1.0
+ parse-entities@2.0.0:
+ dependencies:
+ character-entities: 1.2.4
+ character-entities-legacy: 1.1.4
+ character-reference-invalid: 1.1.4
+ is-alphanumerical: 1.0.4
+ is-decimal: 1.0.4
+ is-hexadecimal: 1.0.4
+ dev: false
+
parse-entities@4.0.1:
dependencies:
'@types/unist': 2.0.10
@@ -26064,6 +26209,9 @@ snapshots:
react: 18.2.0
dev: false
+ prismjs@1.27.0:
+ dev: false
+
prismjs@1.29.0:
dev: false
@@ -26107,6 +26255,11 @@ snapshots:
object-assign: 4.1.1
react-is: 16.13.1
+ property-information@5.6.0:
+ dependencies:
+ xtend: 4.0.2
+ dev: false
+
property-information@6.4.1: {}
proto-list@1.2.4:
@@ -26792,6 +26945,16 @@ snapshots:
tslib: 2.6.2
dev: false
+ react-syntax-highlighter@15.5.0(react@18.2.0):
+ dependencies:
+ '@babel/runtime': 7.23.9
+ highlight.js: 10.7.3
+ lowlight: 1.20.0
+ prismjs: 1.29.0
+ react: 18.2.0
+ refractor: 3.6.0
+ dev: false
+
react-transition-group@4.4.5(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
dependencies:
'@babel/runtime': 7.23.9
@@ -26874,6 +27037,13 @@ snapshots:
globalthis: 1.0.3
which-builtin-type: 1.1.3
+ refractor@3.6.0:
+ dependencies:
+ hastscript: 6.0.0
+ parse-entities: 2.0.0
+ prismjs: 1.27.0
+ dev: false
+
regenerate-unicode-properties@10.1.1:
dependencies:
regenerate: 1.4.2
@@ -27609,6 +27779,9 @@ snapshots:
sourcemap-codec@1.4.8: {}
+ space-separated-tokens@1.1.5:
+ dev: false
+
space-separated-tokens@2.0.2: {}
spdy-transport@3.0.0: