Uses interactive to load content

This commit is contained in:
LittleSheep 2024-02-10 01:31:38 +08:00
parent 8b6c03f020
commit bb65c2a507
9 changed files with 251 additions and 163 deletions

View File

@ -15,13 +15,16 @@
"@astrojs/react": "^3.0.9", "@astrojs/react": "^3.0.9",
"@astrojs/sitemap": "^3.0.5", "@astrojs/sitemap": "^3.0.5",
"@astrojs/tailwind": "^5.1.0", "@astrojs/tailwind": "^5.1.0",
"@keystone-6/document-renderer": "^1.1.2", "@fortawesome/fontawesome-free": "^6.5.1",
"@popperjs/core": "^2.11.8", "@popperjs/core": "^2.11.8",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"@types/react-dom": "^18.2.18", "@types/react-dom": "^18.2.18",
"aplayer": "^1.10.1", "aplayer": "^1.10.1",
"artplayer": "^5.1.1", "artplayer": "^5.1.1",
"astro": "^4.2.1", "astro": "^4.2.1",
"dompurify": "^3.0.8",
"html-react-parser": "^5.1.2",
"marked": "^12.0.0",
"medium-zoom": "^1.1.0", "medium-zoom": "^1.1.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
@ -32,6 +35,7 @@
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/typography": "^0.5.10", "@tailwindcss/typography": "^0.5.10",
"@types/dompurify": "^3.0.5",
"@types/node": "^20.11.5", "@types/node": "^20.11.5",
"daisyui": "^4.6.0", "daisyui": "^4.6.0",
"prettier": "^3.2.4" "prettier": "^3.2.4"

View File

@ -86,7 +86,7 @@ const items: MenuItem[] = [
<div class="navbar-end"> <div class="navbar-end">
<label class="swap swap-rotate px-[16px]" data-toggle-theme="dark,light" data-act-class="swap-active"> <label class="swap swap-rotate px-[16px]" data-toggle-theme="dark,light" data-act-class="swap-active">
<svg <svg
class="swap-on fill-current w-8 h-8" class="swap-on fill-current w-6 h-6"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
> >
@ -97,7 +97,7 @@ const items: MenuItem[] = [
> >
<svg <svg
class="swap-off fill-current w-8 h-8" class="swap-off fill-current w-6 h-6"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
> >

View File

@ -3,39 +3,47 @@ interface Props {
posts: any[]; posts: any[];
} }
import { POST_TYPES } from "../scripts/consts";
const { posts } = Astro.props; const { posts } = Astro.props;
function getThumbnail(item: any): string | null {
for (const attachment of item?.attachments ?? []) {
if (attachment.mimetype.startsWith("image")) {
return attachment.external_url
? attachment.external_url
: `https://feed.smartsheep.studio/api/attachments/o/${attachment.file_id}`;
}
}
return null;
}
--- ---
<div class="grid justify-items-strench shadow-lg"> <div class="grid justify-items-strench shadow-lg">
{ {
posts?.map((item) => ( posts?.map((item) => (
<a href={`/p/${item.slug}`}> <a href={`/p/${item.id}`}>
<div class="card sm:card-side hover:bg-base-200 transition-colors sm:max-w-none"> <div class="card sm:card-side hover:bg-base-200 transition-colors sm:max-w-none">
{item.cover.image.url && ( {getThumbnail(item) && (
<figure class="mx-auto w-full object-cover p-6 max-sm:pb-0 sm:max-w-[12rem] sm:pe-0"> <figure class="mx-auto w-full object-cover p-6 max-sm:pb-0 sm:max-w-[12rem] sm:pe-0">
<img <img
loading="lazy" loading="lazy"
src={item.cover.image.url} src={getThumbnail(item)}
class="border-base-content bg-base-300 rounded-btn border border-opacity-5" class="border-base-content bg-base-300 rounded-btn border border-opacity-5"
alt={item.title} alt={item?.title}
/> />
</figure> </figure>
)} )}
<div class="card-body"> <div class="card-body">
<h2 class="text-xl">{item.title}</h2> <h2 class="text-xl">{item?.title}</h2>
<div class="mx-[-2px] mt-[-4px]"> <div class="mx-[-2px] mt-[-4px]">
<span class="badge badge-accent">{POST_TYPES[item.type]}</span> {item?.categories?.map((category: any) => (
{item.categories?.map((category: any) => (
<span class="badge badge-primary">{category.name}</span> <span class="badge badge-primary">{category.name}</span>
))} ))}
{item.tags?.map((tag: any) => ( {item?.tags?.map((tag: any) => (
<span class="badge badge-secondary">{tag.name}</span> <span class="badge badge-secondary">{tag.name}</span>
))} ))}
</div> </div>
<div class="text-xs opacity-60 line-clamp-3"> <div class="text-xs opacity-60 line-clamp-3">
{item.description} {item?.content?.substring(0, 160).replaceAll("#", "").replaceAll("*", "").trim() + "……"}
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,15 @@
import parse from "html-react-parser";
import mediumZoom from "medium-zoom";
import DOMPurify from "dompurify";
import * as marked from "marked";
import { useEffect } from "react";
export default function Content({ content }: { content: string }) {
useEffect(() => {
mediumZoom(document.querySelectorAll(".post img"), {
background: "var(--fallback-b1,oklch(var(--b1)/1))",
});
});
return <article className="prose max-w-none">{parse(DOMPurify.sanitize(marked.parse(content) as string))}</article>;
}

View File

@ -5,7 +5,7 @@ import { useState, Fragment, useRef, useEffect } from "react";
import "aplayer/dist/APlayer.min.css"; import "aplayer/dist/APlayer.min.css";
function Video({ url, ...rest }: { url: string, className?: string }) { function Video({ url, ...rest }: { url: string; className?: string }) {
const container = useRef<HTMLDivElement>(null); const container = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
@ -27,39 +27,45 @@ function Video({ url, ...rest }: { url: string, className?: string }) {
}); });
}); });
return ( return <div ref={container} {...rest}></div>;
<div ref={container} {...rest}></div>
);
} }
function Audio({ url, artist, caption, ...rest }: { function Audio({
url: string, url,
artist: string, artist,
caption: string, caption,
className?: string ...rest
}: {
url: string;
artist: string;
caption: string;
className?: string;
}) { }) {
const container = useRef(null); const container = useRef(null);
useEffect(() => { useEffect(() => {
new APlayer({ new APlayer({
container: container.current, container: container.current,
audio: [{ audio: [
{
name: caption, name: caption,
artist: artist, artist: artist,
url: url, url: url,
theme: "#49509e" theme: "#49509e",
}] },
],
}); });
}); });
return ( return <div ref={container} {...rest}></div>;
<div ref={container} {...rest}></div>
);
} }
export default function Media({ sources, author }: { export default function Media({
sources: { caption: string; url: string; type: string }[], sources,
author?: { name: string } author,
}: {
sources: { filename: string; mimetype: string }[];
author?: { name: string };
}) { }) {
const [focus, setFocus] = useState<boolean[]>(sources.map((_, idx) => idx === 0)); const [focus, setFocus] = useState<boolean[]>(sources.map((_, idx) => idx === 0));
@ -67,28 +73,32 @@ export default function Media({ sources, author }: {
setFocus(focus.map((_, i) => i === idx)); setFocus(focus.map((_, i) => i === idx));
} }
function getUrl(item: any) {
return item.external_url ? item.external_url : `https://feed.smartsheep.studio/api/attachments/o/${item.file_id}`;
}
return ( return (
<div role="tablist" className="tabs tabs-lifted"> <div role="tablist" className="tabs tabs-lifted">
{sources.map((item, idx) => ( {sources.map((item, idx) => (
<Fragment key={idx}> <Fragment key={idx}>
<input <input
type="radio" type="radio"
name={item.caption} name={item.filename}
role="tab" role="tab"
className="tab" className="tab"
aria-label={item.caption} aria-label={item.filename}
checked={focus[idx]} checked={focus[idx]}
onChange={() => changeFocus(idx)} onChange={() => changeFocus(idx)}
/> />
<div role="tabpanel" className="tab-content bg-base-100 border-base-300 rounded-box w-full"> <div role="tabpanel" className="tab-content bg-base-100 border-base-300 rounded-box w-full">
{item.type === "video" && ( {item.mimetype === "video" && (
<div className="w-full h-[460px]"> <div className="w-full h-[460px]">
<Video className="w-full h-full" url={item.url} /> <Video className="w-full h-full" url={getUrl(item)} />
</div> </div>
)} )}
{item.type === "audio" && ( {item.mimetype === "audio" && (
<div className="w-full"> <div className="w-full">
<Audio url={item.url} artist={author?.name ?? "佚名"} caption={item.caption} /> <Audio url={getUrl(item)} artist={author?.name ?? "佚名"} caption={item.filename} />
</div> </div>
)} )}
</div> </div>

View File

@ -1,5 +1,6 @@
--- ---
import "../assets/fonts/fonts.css"; import "../assets/fonts/fonts.css";
import "@fortawesome/fontawesome-free/css/all.min.css";
import Navbar from "../components/Navbar.astro"; import Navbar from "../components/Navbar.astro";
import { ViewTransitions } from "astro:transitions"; import { ViewTransitions } from "astro:transitions";

View File

@ -2,59 +2,42 @@
import PageLayout from "../../layouts/PageLayout.astro"; import PageLayout from "../../layouts/PageLayout.astro";
// @ts-ignore // @ts-ignore
import Media from "../../components/posts/Media"; import Media from "../../components/posts/Media";
import Content from "../../components/posts/Content";
import { POST_TYPES } from "../../scripts/consts";
import { graphQuery } from "../../scripts/requests";
import { DocumentRenderer } from "@keystone-6/document-renderer";
import { navigate } from "astro:transitions/client";
export const prerender = false; export const prerender = false;
const { slug } = Astro.params; const { slug } = Astro.params;
const { post } = ( const response = await fetch(`https://feed.smartsheep.studio/api/posts/${slug}`);
await graphQuery( const post = (await response.json())["data"];
`query Query($where: PostWhereUniqueInput!) {
post(where: $where) {
slug
type
title
description
author {
name
}
assets {
caption
url
type
}
cover {
image {
url
}
}
content {
document
}
categories {
slug
name
}
tags {
slug
name
}
createdAt
}
}`,
{
where: { slug },
},
)
).data;
if (!post) { if (!post) {
return Astro.redirect("/404"); return Astro.redirect("/404");
} else if (post.realm_id != parseInt(process.env.PUBLIC_REALM_ID ?? "0")) {
return Astro.redirect("https://feed.smartsheep.studio/posts/" + post.id);
}
function getThumbnail(item: any): string | null {
for (const attachment of item?.attachments ?? []) {
if (attachment.mimetype.startsWith("image")) {
return attachment.external_url
? attachment.external_url
: `https://feed.smartsheep.studio/api/attachments/o/${attachment.file_id}`;
}
}
return null;
}
function getAttachments(item: any): any[] {
if (item?.attachments[0] && item?.attachments[0].mimetype.startsWith("image")) {
return item?.attachments?.slice(1, item?.attachments?.length - 1) ?? [];
} else {
return item?.attachments;
}
}
function getAuthorLink(user: any): string {
return `https://feed.smartsheep.studio/accounts/${user.name}`;
} }
--- ---
@ -62,28 +45,37 @@ if (!post) {
<div class="wrapper"> <div class="wrapper">
<div class="card w-full shadow-xl post"> <div class="card w-full shadow-xl post">
{ {
post?.cover && ( getThumbnail(post) && (
<figure> <figure>
<img src={post?.cover?.image?.url} alt={post?.title} /> <img src={getThumbnail(post)} alt={post?.title} />
</figure> </figure>
) )
} }
<div class="card-body"> <div class="card-body">
<div class="mx-1 mb-5">
<h2 class="card-title">{post?.title}</h2> <h2 class="card-title">{post?.title}</h2>
<p class="description">{post?.description ?? "No description"}</p> <div class="text-sm flex max-lg:flex-col gap-x-4">
<div class="divider"></div> <span>
<i class="fa-solid fa-user me-1"></i>
作者
<a class="link" target="_blank" href={getAuthorLink(post?.author)}>{post?.author?.nick ?? "佚名"}</a>
</span>
<span>
<i class="fa-solid fa-calendar me-1"></i>
发布于 {new Date(post?.created_at).toLocaleString()}
</span>
</div>
{ {
post?.assets?.length > 0 && ( getAttachments(post)?.length > 0 && (
<div class="mb-5 w-full"> <div class="mb-5 w-full">
<Media client:only sources={post?.assets} author={post?.author} /> <Media client:only sources={getAttachments(post)} author={post?.author} />
</div> </div>
) )
} }
<div class="prose max-w-none">
<DocumentRenderer document={post?.content?.document ?? []} />
</div> </div>
<Content content={post?.content} client:only />
</div> </div>
</div> </div>
@ -95,12 +87,6 @@ if (!post) {
<div>作者</div> <div>作者</div>
<div>{post?.author?.name ?? "佚名"}</div> <div>{post?.author?.name ?? "佚名"}</div>
</div> </div>
<div>
<div>类型</div>
<div class="text-accent">
{POST_TYPES[post?.type as unknown as string]}
</div>
</div>
<div> <div>
<div>分类</div> <div>分类</div>
<div class="flex gap-1"> <div class="flex gap-1">
@ -136,12 +122,7 @@ if (!post) {
</div> </div>
</PageLayout> </PageLayout>
<script> <script></script>
import mediumZoom from "medium-zoom";
mediumZoom(document.querySelectorAll(".post img"), {
background: "var(--fallback-b1,oklch(var(--b1)/1))",
});
</script>
<style> <style>
.wrapper { .wrapper {

View File

@ -2,45 +2,10 @@
import PageLayout from "../../layouts/PageLayout.astro"; import PageLayout from "../../layouts/PageLayout.astro";
import PostList from "../../components/PostList.astro"; import PostList from "../../components/PostList.astro";
import {graphQuery} from "../../scripts/requests";
export const prerender = false; export const prerender = false;
const {posts} = ( const response = await fetch(`https://feed.smartsheep.studio/api/posts?offset=0&take=10&realmId=${process.env.PUBLIC_REALM_ID}`);
await graphQuery( const posts = (await response.json())["data"];
`query Query($where: PostWhereInput!, $orderBy: [PostOrderByInput!]!) {
posts(where: $where, orderBy: $orderBy) {
slug
type
title
description
cover {
image {
url
}
}
content {
document
}
categories {
name
}
tags {
name
}
createdAt
}
}`,
{
orderBy: [
{
createdAt: "desc",
},
],
where: {}
}
)
).data;
--- ---
<PageLayout title="记录"> <PageLayout title="记录">
@ -50,6 +15,6 @@ const {posts} = (
<p class="pt-2">记录生活,记录理想,记录记录……</p> <p class="pt-2">记录生活,记录理想,记录记录……</p>
</div> </div>
<PostList posts={posts as any[]}/> <PostList posts={posts} />
</div> </div>
</PageLayout> </PageLayout>

116
yarn.lock
View File

@ -490,6 +490,11 @@
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz#a5d300008960bb39677c46bf16f53ec70d8dee04" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz#a5d300008960bb39677c46bf16f53ec70d8dee04"
integrity sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw== integrity sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==
"@fortawesome/fontawesome-free@^6.5.1":
version "6.5.1"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.1.tgz#55cc8410abf1003b726324661ce5b0d1c10de258"
integrity sha512-CNy5vSwN3fsUStPRLX7fUYojyuzoEMSXPl7zSLJ8TgtRfjv24LOnOWKT2zYwaHZCJGkdyRnTmstR0P+Ah503Gw==
"@isaacs/cliui@^8.0.2": "@isaacs/cliui@^8.0.2":
version "8.0.2" version "8.0.2"
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
@ -534,11 +539,6 @@
"@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14" "@jridgewell/sourcemap-codec" "^1.4.14"
"@keystone-6/document-renderer@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@keystone-6/document-renderer/-/document-renderer-1.1.2.tgz#30f8bbc95ac905ba3971e0699b635172d2aff08e"
integrity sha512-fxnQL6xYTK/2xSrZ0dzBTC1Qpa4VVeXmZ+7mMvaZOWquttgvDQzBRY57q9zScRa0dAALNWU1xzq14OL8Kc+eBw==
"@nodelib/fs.scandir@2.1.5": "@nodelib/fs.scandir@2.1.5":
version "2.1.5" version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@ -685,6 +685,13 @@
dependencies: dependencies:
"@types/ms" "*" "@types/ms" "*"
"@types/dompurify@^3.0.5":
version "3.0.5"
resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-3.0.5.tgz#02069a2fcb89a163bacf1a788f73cb415dd75cb7"
integrity sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==
dependencies:
"@types/trusted-types" "*"
"@types/estree@1.0.5", "@types/estree@^1.0.0": "@types/estree@1.0.5", "@types/estree@^1.0.0":
version "1.0.5" version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
@ -761,6 +768,11 @@
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff"
integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==
"@types/trusted-types@*":
version "2.0.7"
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==
"@types/unist@*", "@types/unist@^3.0.0": "@types/unist@*", "@types/unist@^3.0.0":
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20"
@ -1469,6 +1481,41 @@ dlv@^1.1.3:
resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.2"
entities "^4.2.0"
domelementtype@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
domhandler@5.0.3, domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"
dompurify@^3.0.8:
version "3.0.8"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.8.tgz#e0021ab1b09184bc8af7e35c7dd9063f43a8a437"
integrity sha512-b7uwreMYL2eZhrSCRC4ahLTeZcPZxSmYfmcQGXGkXiZSNW1X85v+SDM5KsWcpivIiUBH47Ji7NtyUdpLeF5JZQ==
domutils@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e"
integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"
dset@^3.1.2, dset@^3.1.3: dset@^3.1.2, dset@^3.1.3:
version "3.1.3" version "3.1.3"
resolved "https://registry.yarnpkg.com/dset/-/dset-3.1.3.tgz#c194147f159841148e8e34ca41f638556d9542d2" resolved "https://registry.yarnpkg.com/dset/-/dset-3.1.3.tgz#c194147f159841148e8e34ca41f638556d9542d2"
@ -1524,7 +1571,7 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1:
dependencies: dependencies:
once "^1.4.0" once "^1.4.0"
entities@^4.4.0: entities@^4.2.0, entities@^4.4.0, entities@^4.5.0:
version "4.5.0" version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
@ -1922,16 +1969,44 @@ hastscript@^8.0.0:
property-information "^6.0.0" property-information "^6.0.0"
space-separated-tokens "^2.0.0" space-separated-tokens "^2.0.0"
html-dom-parser@5.0.7:
version "5.0.7"
resolved "https://registry.yarnpkg.com/html-dom-parser/-/html-dom-parser-5.0.7.tgz#33f029b34e8ec4076b7e2624c97debc79abb0c75"
integrity sha512-2YD2/yB0QgrlkBIn0CsGaRXC89E1gtuPVpiOGC52NTzPCC83n0WMdGD+5q7lpcKqbCpnWValQbovuy/NI/0kag==
dependencies:
domhandler "5.0.3"
htmlparser2 "9.1.0"
html-escaper@^3.0.3: html-escaper@^3.0.3:
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-3.0.3.tgz#4d336674652beb1dcbc29ef6b6ba7f6be6fdfed6" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-3.0.3.tgz#4d336674652beb1dcbc29ef6b6ba7f6be6fdfed6"
integrity sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ== integrity sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==
html-react-parser@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/html-react-parser/-/html-react-parser-5.1.2.tgz#547cbebbfc47754f261212e4df0002eefad19903"
integrity sha512-N9QBGQ/Zp1dEizz1+8FtqC+KbO+AJXoz2t5V5phE0dH8QqaOEnrRfw5mYk72yEMbZX0kmMYSJAu09dXKZmXenA==
dependencies:
domhandler "5.0.3"
html-dom-parser "5.0.7"
react-property "2.0.2"
style-to-js "1.1.10"
html-void-elements@^3.0.0: html-void-elements@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7"
integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==
htmlparser2@9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-9.1.0.tgz#cdb498d8a75a51f739b61d3f718136c369bc8c23"
integrity sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils "^3.1.0"
entities "^4.5.0"
http-cache-semantics@^4.1.1: http-cache-semantics@^4.1.1:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a"
@ -1985,6 +2060,11 @@ ini@~1.3.0:
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
inline-style-parser@0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.2.tgz#d498b4e6de0373458fc610ff793f6b14ebf45633"
integrity sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==
is-arrayish@^0.3.1: is-arrayish@^0.3.1:
version "0.3.2" version "0.3.2"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
@ -2249,6 +2329,11 @@ markdown-table@^3.0.0:
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.3.tgz#e6331d30e493127e031dd385488b5bd326e4a6bd" resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.3.tgz#e6331d30e493127e031dd385488b5bd326e4a6bd"
integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw== integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==
marked@^12.0.0:
version "12.0.0"
resolved "https://registry.yarnpkg.com/marked/-/marked-12.0.0.tgz#051ea8c8c7f65148a63003df1499515a2c6de716"
integrity sha512-Vkwtq9rLqXryZnWaQc86+FHLC6tr/fycMfYAhiOIXkrNmeGAyhSxjqu0Rs1i0bBqw5u0S7+lV9fdH2ZSVaoa0w==
mdast-util-definitions@^6.0.0: mdast-util-definitions@^6.0.0:
version "6.0.0" version "6.0.0"
resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz#c1bb706e5e76bb93f9a09dd7af174002ae69ac24" resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz#c1bb706e5e76bb93f9a09dd7af174002ae69ac24"
@ -3207,6 +3292,11 @@ react-dom@^18.2.0:
loose-envify "^1.1.0" loose-envify "^1.1.0"
scheduler "^0.23.0" scheduler "^0.23.0"
react-property@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/react-property/-/react-property-2.0.2.tgz#d5ac9e244cef564880a610bc8d868bd6f60fdda6"
integrity sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==
react-refresh@^0.14.0: react-refresh@^0.14.0:
version "0.14.0" version "0.14.0"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e"
@ -3726,6 +3816,20 @@ strip-json-comments@~2.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
style-to-js@1.1.10:
version "1.1.10"
resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.10.tgz#ec20e1264ba11dc7f71b94b3a3a05566ed856e54"
integrity sha512-VC7MBJa+y0RZhpnLKDPmVRLRswsASLmixkiZ5R8xZpNT9VyjeRzwnXd2pBzAWdgSGv/pCNNH01gPCCUsB9exYg==
dependencies:
style-to-object "1.0.5"
style-to-object@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.5.tgz#5e918349bc3a39eee3a804497d97fcbbf2f0d7c0"
integrity sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==
dependencies:
inline-style-parser "0.2.2"
sucrase@^3.32.0: sucrase@^3.32.0:
version "3.35.0" version "3.35.0"
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263"