Update file preview

This commit is contained in:
mbaharip
2023-04-28 00:37:06 +07:00
parent 0653149d27
commit bb6747e241
31 changed files with 1296 additions and 173 deletions
+41 -15
View File
@@ -1,12 +1,11 @@
# Currently in Development
This project is currently in development, and not ready for deployment yet.
---
// LOGO OR BANNER GOES HERE
## Status
Currently still in development, but main features are already working as intended.
You can check the demo [here](https://drive.mbaharip.com).
## What is this?
guDora-index is an indexer for Google Drive, it's a simple project that I made to index my files in Google Drive.
gudora-index is an indexer for Google Drive, it's a simple project that I made to index my files in Google Drive.
It's aim to simplify the process of sharing files using Google Drive, and also implements some features that I think is useful for sharing files.
This project are **HEAVILY INSPIRED** by [onedrive-vercel-index](https://github.com/spencerwooo/onedrive-vercel-index) by SpencerWooo.
@@ -23,21 +22,48 @@ For free plan, Google Drive offering 15GB of storage, and Onedrive offering 5GB
I know there are a lot of people selling cheap edu account for Google Drive and Onedrive, but most of the time those account doesn't last long, especially Google Drive account. So I want to do it legit without buying cheap edu account or anything similar this time.
## Features
TBA
- Share files without any hassle
- Preview files before downloading
- Render readme file inside the folder
- Protect your folder with password
- Search for files easily
- Direct view or download files
- Can be used for hosting assets for your website
## How to use
### Prerequisites
- Google Drive account
- Google Drive API key
- Vercel account
### Setup
1. Fork [gudora-index/mbaharip](https://github.com/mbaharip/gudora-index) repository
2. Open [Setup page](https://drive.mbaharip.com/setup) and follow the instructions
3. Change the `site.config.js` to your liking
4. Deploy your forked repository to Vercel
5. Open your Vercel project, and go to **Settings > Environment Variables**
6. Add `ENCRYPTION_KEY`, `JWT_KEY`, and `NEXT_PUBLIC_DOMAIN` environment variables
7. Redeploy your project
8. Done!
## Credits
- [onedrive-vercel-index](https://github.com/spencerwooo/onedrive-vercel-index) by SpencerWooo for the inspiration and also some file type helpers.
---
## TODO
- [x] Navigate through folders
- [ ] File preview
- [ ] Audio
- [ ] Code
- [ ] Default
- [ ] Image
- [ ] Markdown
- [x] Audio
- [x] Code
- [x] Default
- [x] Image
- [x] Markdown
- [ ] 3D Model
- [ ] Office files (Word, Excel, PowerPoint)
- [ ] PDF
- [ ] Text
- [ ] Video
- [x] PDF
- [x] Text
- [x] Video
- [x] Search for files
- [x] Direct view the files
- [x] Download files
+9 -1
View File
@@ -10,10 +10,13 @@
"cypress": "cypress open"
},
"dependencies": {
"@react-three/drei": "^9.66.1",
"@react-three/fiber": "^8.13.0",
"@types/react": "18.0.35",
"@types/react-dom": "18.0.11",
"autoprefixer": "10.4.14",
"axios": "^1.3.5",
"cors": "^2.8.5",
"googleapis": "^118.0.0",
"jsonwebtoken": "^9.0.0",
"mime-types": "^2.1.35",
@@ -23,9 +26,11 @@
"postcss": "8.4.22",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-h5-audio-player": "^3.8.6",
"react-icons": "^4.8.0",
"react-loading": "^2.0.3",
"react-markdown": "^8.0.7",
"react-player": "^2.12.0",
"react-toastify": "^9.1.2",
"rehype-katex": "^6.0.2",
"rehype-prism-plus": "^1.5.1",
@@ -37,13 +42,16 @@
"remark-slug": "^7.0.1",
"remark-toc": "^8.0.1",
"swr": "^2.1.3",
"tailwindcss": "3.3.1"
"tailwindcss": "3.3.1",
"three": "^0.152.0"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.9",
"@types/cors": "^2.8.13",
"@types/jsonwebtoken": "^9.0.1",
"@types/mime-types": "^2.1.1",
"@types/node": "18.15.11",
"@types/three": "^0.150.2",
"cypress": "^12.10.0",
"eslint": "8.38.0",
"eslint-config-next": "13.3.0",
+22
View File
File diff suppressed because one or more lines are too long
+3 -2
View File
@@ -14,13 +14,14 @@ export default function GridFile({ data }: Props) {
// const Icon = getMimeIcon(data.mimeType as string);
const Icon = isFolder
? BsFolderFill
: getFileIcon(data.fileExtension as string);
: getFileIcon(data.fileExtension as string, data.mimeType as string);
return (
<Link
href={isFolder ? `/folder/${data.id}` : `/file/${data.id}`}
key={data.id}
className={"hover:opacity-100"}
title={data.name as string}
>
<div className='items relative mx-auto h-32 w-32'>
{data.thumbnailLink ? (
@@ -38,7 +39,7 @@ export default function GridFile({ data }: Props) {
<>
<MdPlayCircleFilled className='center absolute h-8 w-8 text-white/50 transition-colors duration-300 group-hover:text-white/80' />
<span className='absolute bottom-0 right-0 rounded-lg rounded-bl-none rounded-tr-none bg-zinc-950/75 px-1 py-0.5 text-xs text-white'>
{formatDuration(data.videoMediaMetadata.durationMillis!)}
{formatDuration(data.videoMediaMetadata.durationMillis || 0)}
</span>
</>
)}
+1 -1
View File
@@ -62,7 +62,7 @@ export default function ListFile({ data }: Props) {
const isFolder = data.mimeType === "application/vnd.google-apps.folder";
const Icon = isFolder
? BsFolderFill
: getFileIcon(data.fileExtension as string);
: getFileIcon(data.fileExtension as string, data.mimeType as string);
if (!data) return null;
return (
@@ -1,12 +1,70 @@
import { TFile } from "@/types/googleapis";
import { drive_v3 } from "googleapis";
import { useEffect, useState } from "react";
import config from "@config/site.config";
import LoadingFeedback from "@components/APIFeedback/Loading";
import ErrorFeedback from "@components/APIFeedback/Error";
import H5AudioPlayer from "react-h5-audio-player";
import "react-h5-audio-player/lib/styles.css";
type Props = {
data: TFile | drive_v3.Schema$File;
};
export default function AudioPreview({ data }: Props) {
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isError, setIsError] = useState<boolean>(false);
const [errorMessage, setErrorMessage] = useState<string>("");
const [audioSrc, setAudioSrc] = useState<string>("");
useEffect(() => {
const timeout = setTimeout(() => {
setIsError(true);
setErrorMessage("Audio took too long to load");
setIsLoading(false);
}, config.preview.timeout);
const audio = new Audio();
audio.src = `/media/${data.id}/${data.name}`;
audio.onloadeddata = () => {
setAudioSrc(audio.src);
setIsLoading(false);
clearTimeout(timeout);
};
audio.onerror = (error: any) => {
setIsError(true);
setErrorMessage(error.message);
setIsLoading(false);
clearTimeout(timeout);
};
return () => {
clearTimeout(timeout);
};
}, [data.id, data.name]);
return (
<div className='flex w-full items-center justify-center'>Audio Preview</div>
<div className='flex w-full items-center justify-center'>
{isLoading ? (
<LoadingFeedback
message={"Loading audio preview..."}
useContainer={false}
/>
) : isError ? (
<ErrorFeedback
message={errorMessage}
useContainer={false}
/>
) : (
<div className={"preview-audio w-full"}>
<H5AudioPlayer
src={audioSrc}
autoPlay={false}
showFilledVolume={true}
customAdditionalControls={[]}
/>
</div>
)}
</div>
);
}
@@ -1,12 +1,61 @@
import { TFile } from "@/types/googleapis";
import { drive_v3 } from "googleapis";
import { useEffect, useState } from "react";
import useSWR from "swr";
import LoadingFeedback from "@components/APIFeedback/Loading";
import ErrorFeedback from "@components/APIFeedback/Error";
import MarkdownRender from "@components/utility/MarkdownRender";
import fetcher from "@utils/swrFetch";
import { getCodeLanguage } from "@utils/mimeTypesHelper";
type Props = {
data: TFile | drive_v3.Schema$File;
};
export default function CodePreview({ data }: Props) {
const [codeContent, setCodeContent] = useState<string>("");
const {
data: swrData,
error,
isLoading,
} = useSWR(`/download/${data.id}/${data.name}`, fetcher, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
refreshWhenOffline: false,
refreshWhenHidden: false,
refreshInterval: 0,
shouldRetryOnError: false,
revalidateIfStale: true,
});
useEffect(() => {
if (swrData) {
const isObject = typeof swrData === "object";
setCodeContent(
`\`\`\`${getCodeLanguage(data.fileExtension as string)}\n${
isObject ? JSON.stringify(swrData, null, 2) : swrData
}\`\`\``,
);
}
}, [swrData, data.fileExtension]);
return (
<div className='flex w-full items-center justify-center'>Code Preview</div>
<div className='flex w-full items-center justify-center'>
{isLoading ? (
<LoadingFeedback
message={"Loading code preview..."}
useContainer={false}
/>
) : error ? (
<ErrorFeedback
message={error.message || "Failed to load code"}
useContainer={false}
/>
) : (
<div className={"w-full"}>
<MarkdownRender content={codeContent} />
</div>
)}
</div>
);
}
@@ -1,5 +1,6 @@
import { TFile } from "@/types/googleapis";
import { drive_v3 } from "googleapis";
import ErrorFeedback from "@components/APIFeedback/Error";
type Props = {
data: TFile | drive_v3.Schema$File;
@@ -7,8 +8,10 @@ type Props = {
export default function DefaultPreview({ data }: Props) {
return (
<div className='flex w-full items-center justify-center'>
Default Preview
<div className='flex h-full flex-col items-center justify-center'>
<ErrorFeedback
message={`.${data.fileExtension} file is currently not supported. Please download the file to view it.`}
/>
</div>
);
}
@@ -12,65 +12,53 @@ type Props = {
};
export default function ImagePreview({ data, hash }: Props) {
const [image, setImage] = useState<string>("");
const [isImageLoaded, setIsImageLoaded] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isError, setIsError] = useState<boolean>(false);
const [error, setError] = useState<Error | null>(null);
const [errorMessage, setErrorMessage] = useState<string>("");
const [imageSrc, setImageSrc] = useState<string>("");
useEffect(() => {
let timeout: NodeJS.Timeout;
if (data) {
try {
let loaded = false;
const _image = new Image();
_image.src = `/api/files/${data.id}/view${
hash ? `?hash=${reverseString(hash)}` : ""
}`;
_image.onload = () => {
setImage(_image.src);
setIsImageLoaded(true);
loaded = true;
};
timeout = setTimeout(() => {
if (!loaded) {
setIsError(true);
setError(
new Error(
"Cannot load image preview, extension probably not supported",
),
);
}
}, config.preview.timeout);
} catch (error: any) {
setIsError(true);
setError(error);
console.error(error);
}
}
const timeout = setTimeout(() => {
setIsError(true);
setErrorMessage("Image took too long to load");
setIsLoading(false);
}, config.preview.timeout);
const image = new Image();
image.src = `/media/${data.id}/${data.name}`;
image.onload = () => {
setImageSrc(image.src);
setIsLoading(false);
clearTimeout(timeout);
};
image.onerror = (error: any) => {
setIsError(true);
setErrorMessage(error.message);
setIsLoading(false);
clearTimeout(timeout);
};
return () => {
clearTimeout(timeout);
};
}, [data]);
}, [data.id, data.name]);
return (
<div className='flex w-full items-center justify-center'>
{!isImageLoaded && !isError && (
{isLoading ? (
<LoadingFeedback
message={"Loading image preview..."}
useContainer={false}
/>
)}
{!isImageLoaded && isError && (
) : isError ? (
<ErrorFeedback
message={error?.message || "Error loading image preview"}
message={errorMessage}
useContainer={false}
/>
)}
{isImageLoaded && !isError && (
) : (
<img
src={image}
alt={data.name as string}
className='bg-size-checkerboard h-full w-full rounded-lg bg-checkerboard dark:bg-checkerboard-dark'
src={imageSrc}
alt={(data.name as string) || reverseString(hash as string)}
className='max-h-full max-w-full rounded-lg'
/>
)}
</div>
@@ -1,14 +1,47 @@
import { TFile } from "@/types/googleapis";
import { drive_v3 } from "googleapis";
import useSWR from "swr";
import LoadingFeedback from "@components/APIFeedback/Loading";
import ErrorFeedback from "@components/APIFeedback/Error";
import MarkdownRender from "@components/utility/MarkdownRender";
import fetcher from "@utils/swrFetch";
type Props = {
data: TFile | drive_v3.Schema$File;
};
export default function MarkdownPreview({ data }: Props) {
const {
data: swrData,
error,
isLoading,
} = useSWR(`/download/${data.id}/${data.name}`, fetcher, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
refreshWhenOffline: false,
refreshWhenHidden: false,
refreshInterval: 0,
shouldRetryOnError: false,
revalidateIfStale: true,
});
return (
<div className='flex w-full items-center justify-center'>
Markdown Preview
{isLoading ? (
<LoadingFeedback
message={"Loading code preview..."}
useContainer={false}
/>
) : error ? (
<ErrorFeedback
message={error.message || "Failed to load code"}
useContainer={false}
/>
) : (
<div className={"w-full"}>
<MarkdownRender content={swrData as string} />
</div>
)}
</div>
);
}
@@ -1,12 +1,98 @@
import { TFile } from "@/types/googleapis";
import { drive_v3 } from "googleapis";
import { Canvas, useFrame, useLoader } from "@react-three/fiber";
import { get3DLoader } from "@utils/mimeTypesHelper";
import { ReactNode, Suspense, useRef } from "react";
import { BufferGeometry } from "three";
import ErrorFeedback from "@components/APIFeedback/Error";
import { Stage, OrbitControls } from "@react-three/drei";
type Props = {
data: TFile | drive_v3.Schema$File;
};
export default function ModelPreview({ data }: Props) {
const getLoader = get3DLoader(data.fileExtension as string);
if (!getLoader) {
return (
<div className='flex w-full items-center justify-center'>
<ErrorFeedback
message={"Failed to load model"}
useContainer={false}
/>
</div>
);
}
// eslint-disable-next-line react-hooks/rules-of-hooks
const loader = useLoader(
getLoader,
`${process.env.NEXT_PUBLIC_DOMAIN}/api/files/${data.id}/download`,
);
return (
<div className='flex w-full items-center justify-center'>Model Preview</div>
<div className='flex w-full items-center justify-center'>
<div className={"aspect-video h-full w-full overflow-hidden rounded-lg"}>
<Canvas
shadows
camera={{ position: [4, 0, -12], fov: 35 }}
>
<Suspense fallback={null}>
<Scene>
<Model model={loader as BufferGeometry} />
</Scene>
</Suspense>
</Canvas>
</div>
</div>
);
}
type SceneProps = {
children: ReactNode | JSX.Element;
};
function Scene({ children }: SceneProps): JSX.Element {
const controlsRef = useRef<any>();
useFrame(() => {
if (controlsRef.current) {
controlsRef.current.update();
}
});
return (
<>
<Stage
intensity={1.5}
environment='city'
shadows={{
type: "accumulative",
color: "#b78135",
colorBlend: 2,
opacity: 2,
}}
adjustCamera={0.9}
>
{children}
</Stage>
<OrbitControls makeDefault />
</>
);
}
function Model({ model }: { model: BufferGeometry }): JSX.Element {
return (
<mesh
geometry={model}
castShadow={true}
receiveShadow={true}
>
<meshStandardMaterial
color={"#b78135"}
roughness={0.5}
metalness={0.5}
/>
</mesh>
);
}
@@ -1,12 +1,71 @@
import { TFile } from "@/types/googleapis";
import { drive_v3 } from "googleapis";
import { useState } from "react";
import config from "@config/site.config";
import LoadingFeedback from "@components/APIFeedback/Loading";
import ErrorFeedback from "@components/APIFeedback/Error";
type Props = {
data: TFile | drive_v3.Schema$File;
};
export default function PDFPreview({ data }: Props) {
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isError, setIsError] = useState<boolean>(false);
const [errorMessage, setErrorMessage] = useState<string>("");
const fileURL = `${process.env.NEXT_PUBLIC_DOMAIN}/api/files/${data.id}/download`;
let providerURL;
switch (config.preview.pdfProvider) {
case "google":
providerURL = `https://drive.google.com/viewerng/viewer?embedded=true&url=${fileURL}`;
break;
case "microsoft":
providerURL = `https://view.officeapps.live.com/op/embed.aspx?src=${fileURL}`;
break;
case "mozilla":
providerURL = `https://mozilla.github.io/pdf.js/web/viewer.html?file=${fileURL}`;
break;
default:
providerURL = `https://drive.google.com/viewerng/viewer?embedded=true&url=${fileURL}`;
break;
}
return (
<div className='flex w-full items-center justify-center'>PDF Preview</div>
<div className='flex w-full items-center justify-center'>
{isLoading ? (
<LoadingFeedback
message={"Loading PDF preview..."}
useContainer={false}
/>
) : isError ? (
<ErrorFeedback
message={errorMessage}
useContainer={false}
/>
) : (
<></>
)}
<div
className={`${
isLoading || isError ? "hidden" : "flex"
} mx-auto min-h-[70vh] w-full overflow-hidden rounded-lg`}
>
<iframe
width={"100%"}
className={"h-auto"}
src={providerURL}
title={data.name as string}
onLoad={() => {
setIsLoading(false);
}}
onError={(error: any) => {
setIsError(true);
setErrorMessage(error.message);
setIsLoading(false);
}}
/>
</div>
</div>
);
}
@@ -1,12 +1,47 @@
import { TFile } from "@/types/googleapis";
import { drive_v3 } from "googleapis";
import useSWR from "swr";
import LoadingFeedback from "@components/APIFeedback/Loading";
import ErrorFeedback from "@components/APIFeedback/Error";
import MarkdownRender from "@components/utility/MarkdownRender";
import fetcher from "@utils/swrFetch";
type Props = {
data: TFile | drive_v3.Schema$File;
};
export default function TextPreview({ data }: Props) {
const {
data: swrData,
error,
isLoading,
} = useSWR(`/download/${data.id}/${data.name}`, fetcher, {
revalidateOnFocus: false,
revalidateOnReconnect: false,
refreshWhenOffline: false,
refreshWhenHidden: false,
refreshInterval: 0,
shouldRetryOnError: false,
revalidateIfStale: true,
});
return (
<div className='flex w-full items-center justify-center'>Text Preview</div>
<div className='flex w-full items-center justify-center'>
{isLoading ? (
<LoadingFeedback
message={"Loading code preview..."}
useContainer={false}
/>
) : error ? (
<ErrorFeedback
message={error.message || "Failed to load code"}
useContainer={false}
/>
) : (
<div className={"w-full"}>
<MarkdownRender content={swrData as string} />
</div>
)}
</div>
);
}
@@ -1,12 +1,53 @@
import { TFile } from "@/types/googleapis";
import { drive_v3 } from "googleapis";
import ReactPlayer from "react-player";
import { useState } from "react";
import LoadingFeedback from "@components/APIFeedback/Loading";
import ErrorFeedback from "@components/APIFeedback/Error";
type Props = {
data: TFile | drive_v3.Schema$File;
};
export default function VideoPreview({ data }: Props) {
const [isLoading, setIsLoading] = useState<boolean>(true);
const [isError, setIsError] = useState<boolean>(false);
const [errorMessage, setErrorMessage] = useState<string>("");
return (
<div className='flex w-full items-center justify-center'>Video Preview</div>
<div className='flex w-full items-center justify-center'>
{isLoading ? (
<LoadingFeedback
message={"Loading video preview..."}
useContainer={false}
/>
) : isError ? (
<ErrorFeedback
message={errorMessage}
useContainer={false}
/>
) : (
<></>
)}
<div
className={`${
isLoading || isError ? "hidden" : "block"
} aspect-video h-full max-h-[70vh] w-full`}
>
<ReactPlayer
url={`/download/${data.id}/${data.name}`}
controls={true}
width='100%'
height='100%'
onReady={() => {
setIsLoading(false);
}}
onError={(error) => {
setIsError(true);
setErrorMessage(error.message);
}}
/>
</div>
</div>
);
}
@@ -1,10 +1,10 @@
import { TFile } from "@/types/googleapis";
import { drive_v3 } from "googleapis";
import { MdCopyAll, MdDownload, MdOpenInBrowser } from "react-icons/md";
import { MdCopyAll, MdDownload } from "react-icons/md";
import Link from "next/link";
import { toast } from "react-toastify";
import config from "@config/site.config";
import { reverseString } from "@utils/hashHelper";
import { useEffect, useState } from "react";
import useCopyText from "@hooks/useCopyText";
type Props = {
data: TFile | drive_v3.Schema$File;
@@ -12,12 +12,19 @@ type Props = {
};
export default function DetailsButtons({ data, hash }: Props) {
const [downloadURL, setDownloadURL] = useState<string>("");
const [viewURL, setViewURL] = useState<string>("");
const copyText = useCopyText();
useEffect(() => {
setDownloadURL(`/download/${data.id}/${data.name}`);
setViewURL(`${window.location.host}/media/${data.id}/${data.name}`);
}, [data]);
return (
<div className={"flex flex-col gap-2"}>
<Link
href={`/api/files/${data.id}/download${
hash ? `?hash=${reverseString(hash)}` : ""
}`}
href={downloadURL}
target={"_blank"}
rel={"noopener noreferrer"}
>
@@ -30,22 +37,6 @@ export default function DetailsButtons({ data, hash }: Props) {
Download file
</button>
</Link>
<Link
href={`/api/files/${data.id}/view${
hash ? `?hash=${reverseString(hash)}` : ""
}`}
target={"_blank"}
rel={"noopener noreferrer"}
>
<button
className={
"secondary flex w-full items-center justify-center gap-2 py-4 tablet:py-2"
}
>
<MdOpenInBrowser />
Open in new tab
</button>
</Link>
<button
className={`flex w-full items-center justify-center gap-2 py-4 tablet:py-2 ${
config.files.allowDownloadProtectedWithoutAccess
@@ -54,17 +45,7 @@ export default function DetailsButtons({ data, hash }: Props) {
}`}
onClick={async (e) => {
e.preventDefault();
if (!window.navigator) {
toast.error("Your browser does not support this feature");
return;
}
const host = window.location.host;
const url = `${host}/api/files/${data.id}/view${
hash ? `?hash=${reverseString(hash)}` : ""
}`;
await window.navigator.clipboard.writeText(url);
toast.success("Copied to clipboard");
copyText(viewURL);
}}
>
<MdCopyAll />
+12 -26
View File
@@ -20,7 +20,10 @@ export default function FileDetails({ data, hash }: Props) {
);
useEffect(() => {
const Preview = getFilePreview(data.fileExtension as string);
const Preview = getFilePreview(
data.fileExtension as string,
data.mimeType as string,
);
setPreviewComponent(
<Preview
data={data}
@@ -33,7 +36,12 @@ export default function FileDetails({ data, hash }: Props) {
useEffect(() => {
if (data) {
const _metadata = [
{ label: "Name", value: data.name as string },
{
label: "File name",
value: (data.name as string).split(
`.${data.fileExtension as string}`,
)[0],
},
{ label: "Size", value: formatBytes(data.size as string) },
{ label: "Type", value: data.mimeType as string },
{
@@ -78,35 +86,13 @@ export default function FileDetails({ data, hash }: Props) {
) : (
<div className={"grid grid-cols-1 gap-4 tablet:grid-cols-4"}>
<div className={"card h-fit tablet:col-span-3"}>
<div className='flex w-full items-center justify-between rounded-lg px-4'>
<div className='flex w-full items-center justify-between rounded-lg'>
<span className='font-bold'>Preview</span>
</div>
<div className={"divider-horizontal"} />
{PreviewComponent}
{/*{data.mimeType?.startsWith("image") && (*/}
{/* <ImagePreview*/}
{/* data={data}*/}
{/* hash={hash || ""}*/}
{/* />*/}
{/*)}*/}
{/*{data.mimeType?.startsWith("audio") && (*/}
<div className='flex w-full items-center justify-center'>
{/*<video*/}
{/* poster={data.thumbnailLink as string}*/}
{/* autoPlay={true}*/}
{/* controls*/}
{/* className={"h-full w-full"}*/}
{/*>*/}
{/* <source*/}
{/* src={`/api/files/${data.id}/view`}*/}
{/* type={data.mimeType as string}*/}
{/* />*/}
{/* Browser not supported*/}
{/*</video>*/}
</div>
{/*)}*/}
</div>
<div
className={
@@ -114,7 +100,7 @@ export default function FileDetails({ data, hash }: Props) {
}
>
<div className={"card"}>
<div className='flex w-full items-center justify-between rounded-lg px-2'>
<div className='flex w-full items-center justify-between rounded-lg'>
<span className='font-bold'>Details</span>
</div>
+2 -2
View File
@@ -68,10 +68,10 @@ export default function GridLayout({ data, pagination }: Props) {
</div>
) : (
<>
{data?.files.map((file) => (
{data?.files.map((file, idx) => (
<GridFile
data={file as drive_v3.Schema$File}
key={file.id}
key={`File-idx${idx}`}
/>
))}
</>
+15 -12
View File
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import siteConfig from "@config/site.config";
import useLocalStorage from "@/hooks/useLocalStorage";
import Link from "next/link";
@@ -27,6 +27,7 @@ export default function Navbar() {
const [isDark, setIsDark] = useState<boolean>(false);
const [isMenuOpen, setIsMenuOpen] = useState(false);
const searchInputRef = useRef<HTMLInputElement>(null);
const [searchQuery, setSearchQuery] = useState("");
const [debouncedSearchQuery, setDebouncedSearchQuery] = useState("");
const [searchResults, setSearchResults] = useState<drive_v3.Schema$File[]>(); // [
@@ -123,7 +124,10 @@ export default function Navbar() {
>
<div
className='relative flex aspect-square h-6 w-6 cursor-pointer items-center justify-center text-inherit'
onClick={() => setIsSearching(true)}
onClick={() => {
setIsSearching(true);
searchInputRef.current?.focus();
}}
>
<MdSearch className='h-full w-full' />
</div>
@@ -186,12 +190,6 @@ export default function Navbar() {
: "pointer-events-none rotate-90 opacity-0"
}`}
/>
{/* <span
className='cursor-pointer'
onPointerDown={() => setIsMenuOpen(!isMenuOpen)}
>
<MdMenu className='h-full w-full' />
</span> */}
</div>
</div>
@@ -218,7 +216,7 @@ export default function Navbar() {
{/* Search Modal */}
<Modal
title={
<span className='flex items-center text-lg'>
<span className='flex items-center gap-2 text-lg'>
<MdSearch /> Search files
</span>
}
@@ -230,6 +228,7 @@ export default function Navbar() {
<div className='relative flex w-full flex-grow items-center'>
<MdSearch className='absolute right-4' />
<input
ref={searchInputRef}
type='text'
className='w-full flex-grow py-2 pr-8'
placeholder='Type folder or file name...'
@@ -268,16 +267,20 @@ export default function Navbar() {
item.mimeType === "application/vnd.google-apps.folder";
const Icon = isFolder
? BsFolderFill
: getFileIcon(item.fileExtension as string);
: getFileIcon(
item.fileExtension as string,
item.mimeType as string,
);
return (
<Link
href={isFolder ? `/folder/${item.id}` : `/file/${item.id}`}
key={item.id}
className='rounded-lg py-1 hover:bg-zinc-300 dark:hover:bg-zinc-600 tablet:px-2 tablet:py-2'
onClick={handleCloseSearch}
>
<div className='flex items-center gap-4'>
<div className='flex aspect-square h-10 w-10 items-center justify-center overflow-hidden rounded-lg tablet:h-12 tablet:w-12'>
<div className='flex aspect-square h-10 w-10 flex-shrink-0 flex-grow-0 items-center justify-center overflow-hidden rounded-lg tablet:h-12 tablet:w-12'>
{item.thumbnailLink ? (
<img
src={item.thumbnailLink}
@@ -288,7 +291,7 @@ export default function Navbar() {
<Icon className='h-full w-full' />
)}
</div>
<div className='flex flex-col'>
<div className='line-clamp-1 flex w-full flex-shrink flex-grow flex-col'>
<div className={"flex items-center gap-2"}>
<Icon className='h-4 w-4' />
<span className='text-sm font-medium'>
+5 -1
View File
@@ -60,7 +60,11 @@ export default function MarkdownRender({ content }: Props) {
<div className='markdown'>
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkMath, remarkSlug, remarkToc]}
rehypePlugins={[rehypeKatex, rehypeRaw, rehypePrism]}
rehypePlugins={[
rehypeKatex,
rehypeRaw,
[rehypePrism, { ignoreMissing: true }],
]}
components={customComponents}
>
{content}
+10 -2
View File
@@ -51,11 +51,14 @@ const config = {
// Or use folder id to use a specific folder as starting point
// rootFolder: "root",
rootFolder: "1KgPV6QB1GYT8fmn2uTfbtr9rDXqcRR0j",
// rootFolder: "1p6znx1BKPsqFnyOPw49uhoc8FNglfYnD",
// If this set to true, any user can download or view protected files.
// If this set to false, only authorized users can download or view protected files.
// The authorized users URL will have a token in it that valid for 1 hour.
allowDownloadProtectedWithoutAccess: false, // If this set to true, any user can download protected files, but can't see the details of the file or folder.
// Only used on API routes.
//
// This take too much time to load, so I disabled it for now.
// Unless someone can help me to make it faster.
allowDownloadProtectedWithoutAccess: true,
},
/* Config for readme file render */
readme: {
@@ -74,6 +77,11 @@ const config = {
// And the thumbnail or the file icon will be shown instead.
// The value is in milliseconds.
timeout: 30000,
// The URL of the preview service
// Available services:
// google / mozilla
// NOTE: the Google service sometimes doesn't work.
pdfProvider: "mozilla",
},
};
+1 -3
View File
@@ -1,6 +1,4 @@
import { Html, Head, Main, NextScript } from 'next/document'
import { Inter, Merriweather, JetBrains_Mono } from "next/font/google";
import { Html, Head, Main, NextScript } from "next/document";
export default function Document() {
return (
+4 -4
View File
@@ -5,11 +5,9 @@ import config from "@config/site.config";
import { validateProtected } from "@utils/driveHelper";
import { ExtendedError } from "@/types/default";
import { reverseString } from "@utils/hashHelper";
import initMiddleware from "@utils/apiMiddleware";
export default async function handler(
request: NextApiRequest,
response: NextApiResponse,
) {
async function handler(request: NextApiRequest, response: NextApiResponse) {
try {
const { id, hash } = request.query;
const { authorization } = request.headers;
@@ -128,3 +126,5 @@ export default async function handler(
return response.status(500).json(payload);
}
}
export default initMiddleware(handler);
+51
View File
@@ -0,0 +1,51 @@
import { promisify } from "util";
import { pipeline } from "stream";
import { GetServerSideProps } from "next";
import drive from "@utils/driveClient";
export default function Download() {
return <div />;
}
const pipelineAsync = promisify(pipeline);
export const getServerSideProps: GetServerSideProps = async ({
res,
query,
}) => {
const { id, fileName } = query;
const getImageMetadata = drive.files.get({
fileId: id as string,
fields: "name, mimeType",
});
const getImageStream = drive.files.get(
{
fileId: id as string,
alt: "media",
},
{ responseType: "stream" },
);
const [{ data: imageMetadata }, imageStream] = await Promise.all([
getImageMetadata,
getImageStream,
]);
// Check fileName === image metadata
if (fileName !== imageMetadata.name) {
return {
notFound: true,
};
}
res.setHeader(
"Content-Disposition",
`attachment; filename=${encodeURIComponent(imageMetadata.name as string)}`,
);
res.setHeader(
"Content-Type",
(imageMetadata.mimeType as string) || "application/octet-stream",
);
await pipelineAsync(imageStream.data, res);
return {
props: {},
};
};
+7 -7
View File
@@ -113,6 +113,13 @@ export default function File({ passwordParent, fileName }: Props) {
return (
<div className='mx-auto flex max-w-screen-xl flex-col gap-4'>
<NextSeo title={fileName || "File preview"} />
<div className='flex items-center justify-between'>
<Breadcrumb
data={data?.parents || []}
isLoading={globalLoading}
/>
</div>
{globalLoading && <LoadingFeedback message={"Loading file details..."} />}
{!globalLoading && error && (
<ErrorFeedback message={error.errors?.message} />
@@ -127,13 +134,6 @@ export default function File({ passwordParent, fileName }: Props) {
)}
{(data.passwordValidated || !data.passwordRequired) && (
<>
<div className='flex items-center justify-between'>
<Breadcrumb
data={data?.parents || []}
isLoading={globalLoading}
/>
</div>
<FileDetails
data={data.file}
hash={passwordStorage?.[passwordParent as string] || ""}
+55
View File
@@ -0,0 +1,55 @@
import { promisify } from "util";
import { pipeline } from "stream";
import { GetServerSideProps } from "next";
import drive from "@utils/driveClient";
export default function Media() {
return <div />;
}
const pipelineAsync = promisify(pipeline);
export const getServerSideProps: GetServerSideProps = async ({
res,
query,
}) => {
const { id, fileName } = query;
const getImageMetadata = drive.files.get({
fileId: id as string,
fields: "name, mimeType",
});
const getImageStream = drive.files.get(
{
fileId: id as string,
alt: "media",
},
{ responseType: "stream" },
);
const [{ data: imageMetadata }, imageStream] = await Promise.all([
getImageMetadata,
getImageStream,
]);
// Only allow images, video, audio, and pdf
if (
!(imageMetadata.mimeType as string).startsWith("image/") &&
!(imageMetadata.mimeType as string).startsWith("video/") &&
!(imageMetadata.mimeType as string).startsWith("audio/") &&
!(imageMetadata.mimeType as string).startsWith("application/pdf")
) {
return {
notFound: true,
};
}
// Check fileName === image metadata
if (fileName !== imageMetadata.name) {
return {
notFound: true,
};
}
res.setHeader("Content-Type", imageMetadata.mimeType as string);
await pipelineAsync(imageStream.data, res);
return {
props: {},
};
};
+33
View File
@@ -0,0 +1,33 @@
import { GetServerSideProps } from "next";
import driveClient from "@utils/driveClient";
import { promisify } from "util";
import { pipeline } from "stream";
export default function Test() {
return <div />;
}
const pipelineAsync = promisify(pipeline);
export const getServerSideProps: GetServerSideProps = async ({ res }) => {
const getImageMetadata = driveClient.files.get({
fileId: "1uAmdeBGJPAEkyEG_M_gYczjP0eVy6ncH",
fields: "name, mimeType",
});
const getImageStream = driveClient.files.get(
{
fileId: "1uAmdeBGJPAEkyEG_M_gYczjP0eVy6ncH",
alt: "media",
},
{ responseType: "stream" },
);
const [imageMetadata, imageStream] = await Promise.all([
getImageMetadata,
getImageStream,
]);
res.setHeader("Content-Type", imageMetadata.data.mimeType as string);
await pipelineAsync(imageStream.data, res);
return {
props: {},
};
};
+12
View File
@@ -208,6 +208,18 @@ html, body {
div.loading > svg {
@apply fill-zinc-900 dark:fill-zinc-100;
}
div.preview-audio > div.rhap_container {
@apply rounded-lg;
@apply bg-zinc-50 dark:bg-zinc-800;
@apply text-zinc-900 dark:text-zinc-100;
}
div.preview-audio div.rhap_time {
@apply text-zinc-900 dark:text-zinc-100;
}
div.preview-audio button {
@apply bg-transparent hover:bg-transparent active:bg-transparent focus:bg-transparent;
}
}
/* Utility */
+5 -2
View File
@@ -31,11 +31,14 @@
}
.markdown ul {
@apply list-disc ml-8 leading-loose;
@apply list-disc leading-loose;
}
.markdown ol {
@apply list-decimal leading-loose;
}
.markdown li {
@apply ml-8;
}
.markdown table {
@apply block w-full overflow-auto border-collapse mb-4 border-spacing-0;
@@ -66,6 +69,6 @@
@apply pl-2 border-l-4 border-l-zinc-500;
}
.markdown hr {
@apply my-2
@apply my-4 border-t-0 border-b-2 tablet:border-b-4 border-b-zinc-400 dark:border-b-zinc-700;
}
}
+43
View File
@@ -0,0 +1,43 @@
import { NextApiHandler, NextApiRequest, NextApiResponse } from "next";
import Cors, { CorsRequest } from "cors";
import { ErrorResponse } from "@/types/googleapis";
function _initMiddleware(middleware: CorsRequest | any) {
return (req: NextApiRequest, res: NextApiResponse) =>
new Promise((resolve, reject) => {
middleware(req, res, (result: any) => {
if (result instanceof Error) {
return reject(result);
}
return resolve(result);
});
});
}
const initMiddleware =
(handler: NextApiHandler) =>
async (request: NextApiRequest, response: NextApiResponse) => {
try {
const allowedMethods = ["GET"];
const initCORS = _initMiddleware(
Cors({
methods: allowedMethods,
}),
);
await initCORS(request, response);
return handler(request, response);
} catch (error: any) {
const payload: ErrorResponse = {
success: false,
timestamp: new Date().toISOString(),
code: error.code || 500,
errors: {
message: error.message || "Internal Server Error",
reason: error.reason || "internalError",
},
};
return response.status(error.code || 500).json(payload);
}
};
export default initMiddleware;
+58 -7
View File
@@ -29,6 +29,11 @@ import CodePreview from "@components/FilePreview/CodePreview";
import TextPreview from "@components/FilePreview/TextPreview";
import VideoPreview from "@components/FilePreview/VideoPreview";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
import { STLLoader } from "three/examples/jsm/loaders/STLLoader";
function findMimeType(extension: string): string {
return mime.lookup(extension) || "application/octet-stream";
}
@@ -37,7 +42,7 @@ const type = {
"3d": "3d", // model preview
"audio": "audio", // audio preview
"archive": "archive", // default preview
"rich_text": "markdown", // markdown preview
"rich_text": "rich_text", // markdown preview
"officeWord": "officeWord", // office preview
"officeExcel": "officeExcel", // office preview
"officePowerPoint": "officePowerPoint", // office preview
@@ -163,6 +168,8 @@ const extToTypeMap: { [key: string]: string } = {
"tsx": type.code,
"xml": type.code,
"yaml": type.code,
"vue": type.code,
"toml": type.code,
// Text
"txt": type.text,
@@ -189,17 +196,17 @@ const extToTypeMap: { [key: string]: string } = {
"msi": type.binary,
};
export function getFilePreview(extension: string) {
export function getFilePreview(extension: string, mimeType?: string) {
if (overlapVideo.includes(extension)) {
const isVideo = findMimeType(extension).startsWith("video");
const isVideo = !!mimeType?.startsWith("video");
if (isVideo) {
return VideoPreview;
}
}
const category = extToTypeMap[extension] || type.default;
switch (category) {
case type["3d"]:
return ModelPreview;
// case type["3d"]:
// return ModelPreview;
case type.audio:
return AudioPreview;
case type.rich_text:
@@ -223,9 +230,9 @@ export function getFilePreview(extension: string) {
}
}
export function getFileIcon(extension: string): IconType {
export function getFileIcon(extension: string, mimeType?: string): IconType {
if (overlapVideo.includes(extension)) {
const isVideo = findMimeType(extension).startsWith("video");
const isVideo = !!mimeType?.startsWith("video");
if (isVideo) {
return iconsForType["video"];
}
@@ -233,3 +240,47 @@ export function getFileIcon(extension: string): IconType {
const category = extToTypeMap[extension] || type.default;
return iconsForType[category];
}
// Not all extensions are included here
// Taken from onedrive-vercel-index by SpencerWoo
// https://github.com/spencerwooo/onedrive-vercel-index/blob/main/src/utils/getPreviewType.ts
export function getCodeLanguage(extension: string) {
switch (extension) {
case "ts":
case "tsx":
return "typescript";
case "rs":
return "rust";
case "js":
case "jsx":
case "vue":
return "javascript";
case "sh":
return "shell";
case "cs":
return "csharp";
case "py":
return "python";
case "yml":
return "yaml";
default:
return extension;
}
}
export function get3DLoader(extension: string) {
switch (extension) {
case "fbx":
return FBXLoader;
case "gltf":
return GLTFLoader;
case "glb":
return GLTFLoader;
case "obj":
return OBJLoader;
case "stl":
return STLLoader;
default:
return null;
}
}
+490 -4
View File
@@ -2,13 +2,40 @@
# yarn lockfile v1
"@babel/runtime@^7.20.7":
"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.16.7", "@babel/runtime@^7.17.8", "@babel/runtime@^7.20.7":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
dependencies:
regenerator-runtime "^0.13.11"
"@chevrotain/cst-dts-gen@10.5.0":
version "10.5.0"
resolved "https://registry.yarnpkg.com/@chevrotain/cst-dts-gen/-/cst-dts-gen-10.5.0.tgz#922ebd8cc59d97241bb01b1b17561a5c1ae0124e"
integrity sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==
dependencies:
"@chevrotain/gast" "10.5.0"
"@chevrotain/types" "10.5.0"
lodash "4.17.21"
"@chevrotain/gast@10.5.0":
version "10.5.0"
resolved "https://registry.yarnpkg.com/@chevrotain/gast/-/gast-10.5.0.tgz#e4e614bc46d17a8892742f38e56cd33f1f3ad162"
integrity sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==
dependencies:
"@chevrotain/types" "10.5.0"
lodash "4.17.21"
"@chevrotain/types@10.5.0":
version "10.5.0"
resolved "https://registry.yarnpkg.com/@chevrotain/types/-/types-10.5.0.tgz#52a97d74a8cfbc197f054636d93ecd8912d33d21"
integrity sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==
"@chevrotain/utils@10.5.0":
version "10.5.0"
resolved "https://registry.yarnpkg.com/@chevrotain/utils/-/utils-10.5.0.tgz#0ee36f65b49b447fbac71b9e5af5c5c6c98ac057"
integrity sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==
"@colors/colors@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
@@ -97,6 +124,16 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
"@iconify/icons-mdi@~1.1.0":
version "1.1.47"
resolved "https://registry.yarnpkg.com/@iconify/icons-mdi/-/icons-mdi-1.1.47.tgz#4bbe1e5d126de7acde05a66addd869c66bd97ca0"
integrity sha512-6AZfvWru20Rl9pXULStkVvTWnua6VG56zOIKdkCzLh25XVeTDEp6f1dL7iX9w+way5+1hI0BBuqTQd61qYaKdg==
"@iconify/react@^3.1.3":
version "3.2.2"
resolved "https://registry.yarnpkg.com/@iconify/react/-/react-3.2.2.tgz#ab5241dc01562076bae3b0c22238aff7e5f029cc"
integrity sha512-z3+Jno3VcJzgNHsN5mEvYMsgCkOZkydqdIwOxjXh45+i2Vs9RGH68Y52vt39izwFSfuYUXhaW+1u7m7+IhCn/g==
"@jridgewell/gen-mapping@^0.3.2":
version "0.3.3"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
@@ -224,6 +261,92 @@
tiny-glob "^0.2.9"
tslib "^2.4.0"
"@react-spring/animated@~9.6.1":
version "9.6.1"
resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.6.1.tgz#ccc626d847cbe346f5f8815d0928183c647eb425"
integrity sha512-ls/rJBrAqiAYozjLo5EPPLLOb1LM0lNVQcXODTC1SMtS6DbuBCPaKco5svFUQFMP2dso3O+qcC4k9FsKc0KxMQ==
dependencies:
"@react-spring/shared" "~9.6.1"
"@react-spring/types" "~9.6.1"
"@react-spring/core@~9.6.1":
version "9.6.1"
resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.6.1.tgz#ebe07c20682b360b06af116ea24e2b609e778c10"
integrity sha512-3HAAinAyCPessyQNNXe5W0OHzRfa8Yo5P748paPcmMowZ/4sMfaZ2ZB6e5x5khQI8NusOHj8nquoutd6FRY5WQ==
dependencies:
"@react-spring/animated" "~9.6.1"
"@react-spring/rafz" "~9.6.1"
"@react-spring/shared" "~9.6.1"
"@react-spring/types" "~9.6.1"
"@react-spring/rafz@~9.6.1":
version "9.6.1"
resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.6.1.tgz#d71aafb92b78b24e4ff84639f52745afc285c38d"
integrity sha512-v6qbgNRpztJFFfSE3e2W1Uz+g8KnIBs6SmzCzcVVF61GdGfGOuBrbjIcp+nUz301awVmREKi4eMQb2Ab2gGgyQ==
"@react-spring/shared@~9.6.1":
version "9.6.1"
resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.6.1.tgz#4e2e4296910656c02bd9fd54c559702bc836ac4e"
integrity sha512-PBFBXabxFEuF8enNLkVqMC9h5uLRBo6GQhRMQT/nRTnemVENimgRd+0ZT4yFnAQ0AxWNiJfX3qux+bW2LbG6Bw==
dependencies:
"@react-spring/rafz" "~9.6.1"
"@react-spring/types" "~9.6.1"
"@react-spring/three@~9.6.1":
version "9.6.1"
resolved "https://registry.yarnpkg.com/@react-spring/three/-/three-9.6.1.tgz#095fcd1dc6509127c33c14486d88289b89baeb9d"
integrity sha512-Tyw2YhZPKJAX3t2FcqvpLRb71CyTe1GvT3V+i+xJzfALgpk10uPGdGaQQ5Xrzmok1340DAeg2pR/MCfaW7b8AA==
dependencies:
"@react-spring/animated" "~9.6.1"
"@react-spring/core" "~9.6.1"
"@react-spring/shared" "~9.6.1"
"@react-spring/types" "~9.6.1"
"@react-spring/types@~9.6.1":
version "9.6.1"
resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.6.1.tgz#913d3a68c5cbc1124fdb18eff919432f7b6abdde"
integrity sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==
"@react-three/drei@^9.66.1":
version "9.66.1"
resolved "https://registry.yarnpkg.com/@react-three/drei/-/drei-9.66.1.tgz#b5684d267949ea83ff84e9db01ea41b842d70f9b"
integrity sha512-nbSMsdoL52bLZtOZFMjkjjGzLLkx8hOuYEgvxX19TxR9+YpFnjbfzC3NtsjK719O4OJdNEHZOxmmxoANJJAXEA==
dependencies:
"@babel/runtime" "^7.11.2"
"@react-spring/three" "~9.6.1"
"@use-gesture/react" "^10.2.24"
camera-controls "^2.3.1"
detect-gpu "^5.0.14"
glsl-noise "^0.0.0"
lodash.clamp "^4.0.3"
lodash.omit "^4.5.0"
lodash.pick "^4.4.0"
maath "^0.5.2"
meshline "^3.1.6"
react-composer "^5.0.3"
react-merge-refs "^1.1.0"
stats.js "^0.17.0"
suspend-react "^0.0.8"
three-mesh-bvh "^0.5.23"
three-stdlib "^2.21.8"
troika-three-text "^0.47.1"
utility-types "^3.10.0"
zustand "^3.5.13"
"@react-three/fiber@^8.13.0":
version "8.13.0"
resolved "https://registry.yarnpkg.com/@react-three/fiber/-/fiber-8.13.0.tgz#c9eabe60f2276a66d7ce9a3b927083894f4202f9"
integrity sha512-hPFzFNgikEMyEbL+NpSA7q+UWZxInrrkJldWaCR2w34Fwf20x9p68bsyN0/yn9oM2VlWoJcJjR8hw1tN9AxHuA==
dependencies:
"@babel/runtime" "^7.17.8"
"@types/react-reconciler" "^0.26.7"
its-fine "^1.0.6"
react-reconciler "^0.27.0"
react-use-measure "^2.1.1"
scheduler "^0.21.0"
suspend-react "^0.0.8"
zustand "^3.7.1"
"@rushstack/eslint-patch@^1.1.3":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz#8be36a1f66f3265389e90b5f9c9962146758f728"
@@ -246,6 +369,13 @@
lodash.merge "^4.6.2"
postcss-selector-parser "6.0.10"
"@types/cors@^2.8.13":
version "2.8.13"
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94"
integrity sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==
dependencies:
"@types/node" "*"
"@types/debug@^4.0.0":
version "4.1.7"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82"
@@ -324,6 +454,11 @@
resolved "https://registry.yarnpkg.com/@types/nprogress/-/nprogress-0.2.0.tgz#86c593682d4199212a0509cc3c4d562bbbd6e45f"
integrity sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==
"@types/offscreencanvas@^2019.6.4":
version "2019.7.0"
resolved "https://registry.yarnpkg.com/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz#e4a932069db47bb3eabeb0b305502d01586fa90d"
integrity sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg==
"@types/parse5@^6.0.0":
version "6.0.3"
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb"
@@ -346,6 +481,20 @@
dependencies:
"@types/react" "*"
"@types/react-reconciler@^0.26.7":
version "0.26.7"
resolved "https://registry.yarnpkg.com/@types/react-reconciler/-/react-reconciler-0.26.7.tgz#0c4643f30821ae057e401b0d9037e03e8e9b2a36"
integrity sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==
dependencies:
"@types/react" "*"
"@types/react-reconciler@^0.28.0":
version "0.28.2"
resolved "https://registry.yarnpkg.com/@types/react-reconciler/-/react-reconciler-0.28.2.tgz#f16b0e8cc4748af70ca975eaaace0d79582c71fa"
integrity sha512-8tu6lHzEgYPlfDf/J6GOQdIc+gs+S2yAqlby3zTsB3SP2svlqTYe5fwZNtZyfactP74ShooP2vvi1BOp9ZemWw==
dependencies:
"@types/react" "*"
"@types/react@*", "@types/react@18.0.35":
version "18.0.35"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.35.tgz#192061cb1044fe01f2d3a94272cd35dd50502741"
@@ -370,11 +519,31 @@
resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef"
integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==
"@types/stats.js@*":
version "0.17.0"
resolved "https://registry.yarnpkg.com/@types/stats.js/-/stats.js-0.17.0.tgz#0ed81d48e03b590c24da85540c1d952077a9fe20"
integrity sha512-9w+a7bR8PeB0dCT/HBULU2fMqf6BAzvKbxFboYhmDtDkKPiyXYbjoe2auwsXlEFI7CFNMF1dCv3dFH5Poy9R1w==
"@types/three@^0.150.2":
version "0.150.2"
resolved "https://registry.yarnpkg.com/@types/three/-/three-0.150.2.tgz#6f36b299a3d21416cc07342cc87accffbde32db4"
integrity sha512-cvcz/81Mmj4oiAA+uxzwaRK3t8lYw8WxejXKqIBfu6PqvwSAEEiCi3VfCiVY18UflBqL0LDX/za85+sfqjMoIw==
dependencies:
"@types/stats.js" "*"
"@types/webxr" "*"
fflate "~0.6.9"
lil-gui "~0.17.0"
"@types/unist@*", "@types/unist@^2.0.0":
version "2.0.6"
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
"@types/webxr@*":
version "0.5.1"
resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.5.1.tgz#4908349419104bd476a4252d04e4c3abb496748d"
integrity sha512-xlFXPfgJR5vIuDefhaHuUM9uUgvPaXB6GKdXy2gdEh8gBWQZ2ul24AJz3foUd8NNKlSTQuWYJpCb1/pL81m1KQ==
"@types/yauzl@^2.9.1":
version "2.10.0"
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599"
@@ -426,6 +595,23 @@
"@typescript-eslint/types" "5.58.0"
eslint-visitor-keys "^3.3.0"
"@use-gesture/core@10.2.26":
version "10.2.26"
resolved "https://registry.yarnpkg.com/@use-gesture/core/-/core-10.2.26.tgz#c2fc4aa7d36cee7319a98a898b0698c66b01663e"
integrity sha512-NyFpQ3iID9iFBROXyyvU1D0NK+t+dP+WAVByhCvqHUenpxLD2NlRLVRpoK3XGGwksr6mU3PvZ2Nm4q0q+gLJPA==
"@use-gesture/react@^10.2.24":
version "10.2.26"
resolved "https://registry.yarnpkg.com/@use-gesture/react/-/react-10.2.26.tgz#593549fed30ebcac71cfd197993eaede0795c098"
integrity sha512-0QhaE5mhaQbFlip4MX7n1nwCX8gax6Da1LsP2fZ/BU6xW9zyEmV6NX7DPelDxq1rr2NiBJh30vx9RIp80YeA/A==
dependencies:
"@use-gesture/core" "10.2.26"
"@webgpu/glslang@^0.0.15":
version "0.0.15"
resolved "https://registry.yarnpkg.com/@webgpu/glslang/-/glslang-0.0.15.tgz#f5ccaf6015241e6175f4b90906b053f88483d1f2"
integrity sha512-niT+Prh3Aff8Uf1MVBVUsaNjFj9rJAKDXuoHIKiQbB+6IUP/3J3JIhBNyZ7lDhytvXxw6ppgnwKZdDJ08UMj4Q==
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@@ -687,6 +873,13 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
bidi-js@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bidi-js/-/bidi-js-1.0.2.tgz#1a497a762c2ddea377429d2649c9ce0f8a91527f"
integrity sha512-rzSy/k7WdX5zOyeHHCOixGXbCHkyogkxPKL2r8QtzHmVQDiWCXUWa18bLdMWT9CYMLOYTjWpTHawuev2ouYJVw==
dependencies:
require-from-string "^2.0.2"
bignumber.js@^9.0.0:
version "9.1.1"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6"
@@ -780,6 +973,11 @@ camelcase-css@^2.0.1:
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
camera-controls@^2.3.1:
version "2.3.4"
resolved "https://registry.yarnpkg.com/camera-controls/-/camera-controls-2.3.4.tgz#f372b5a4012b474df0ed0c67da7a3198d7efee0b"
integrity sha512-swhc87YVHf9te0glBI7Oa/QBgsSCL4ZxtoR4V3vE6l7mEebsYRNL8y7Y2m2E6MrT0UTphM1S7mQqs0Sp7QTZ2g==
caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464:
version "1.0.30001479"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001479.tgz#ef3d6f76011e44181af411fd4896123afbc14eda"
@@ -823,6 +1021,18 @@ check-more-types@^2.24.0:
resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==
chevrotain@^10.1.2:
version "10.5.0"
resolved "https://registry.yarnpkg.com/chevrotain/-/chevrotain-10.5.0.tgz#9c1dc62ef0753bb562dbe521b5f72d041bad624e"
integrity sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==
dependencies:
"@chevrotain/cst-dts-gen" "10.5.0"
"@chevrotain/gast" "10.5.0"
"@chevrotain/types" "10.5.0"
"@chevrotain/utils" "10.5.0"
lodash "4.17.21"
regexp-to-ast "0.5.0"
chokidar@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
@@ -941,6 +1151,14 @@ core-util-is@1.0.2:
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==
cors@^2.8.5:
version "2.8.5"
resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==
dependencies:
object-assign "^4"
vary "^1"
cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
@@ -1025,6 +1243,11 @@ dayjs@^1.10.4:
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2"
integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==
debounce@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==
debug@4, debug@^4.0.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
@@ -1074,6 +1297,11 @@ deep-is@^0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
deepmerge@^4.0.0:
version "4.3.1"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
define-lazy-prop@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
@@ -1097,6 +1325,13 @@ dequal@^2.0.0:
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
detect-gpu@^5.0.14:
version "5.0.21"
resolved "https://registry.yarnpkg.com/detect-gpu/-/detect-gpu-5.0.21.tgz#91fc05655e219a294b5030b8659ee05ce4307c48"
integrity sha512-Dcf+4zxB3/4+7nVje3zQffJ3ksS7DiUztlNR0jC4AUF8FTBTeKWoIRxRAq4dGaRft8hEadUIDbjZbiKhCFo/Bw==
dependencies:
webgl-constants "^1.1.1"
didyoumean@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
@@ -1133,6 +1368,11 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
draco3d@^1.4.1:
version "1.5.6"
resolved "https://registry.yarnpkg.com/draco3d/-/draco3d-1.5.6.tgz#0d570a9792e3a3a9fafbfea065b692940441c626"
integrity sha512-+3NaRjWktb5r61ZFoDejlykPEFKT5N/LkbXsaddlw6xNSXBanUYpFc2AXXpbJDilPHazcSreU/DpQIaxfX0NfQ==
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
@@ -1589,6 +1829,11 @@ fd-slicer@~1.1.0:
dependencies:
pend "~1.2.0"
fflate@^0.6.9, fflate@~0.6.9:
version "0.6.10"
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.6.10.tgz#5f40f9659205936a2d18abf88b2e7781662b6d43"
integrity sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==
figures@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
@@ -1886,6 +2131,11 @@ globrex@^0.1.2:
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
glsl-noise@^0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/glsl-noise/-/glsl-noise-0.0.0.tgz#367745f3a33382c0eeec4cb54b7e99cfc1d7670b"
integrity sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==
google-auth-library@^8.0.2:
version "8.7.0"
resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-8.7.0.tgz#e36e255baba4755ce38dded4c50f896cf8515e51"
@@ -2436,6 +2686,13 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
its-fine@^1.0.6:
version "1.1.1"
resolved "https://registry.yarnpkg.com/its-fine/-/its-fine-1.1.1.tgz#e74b93fddd487441f978a50f64f0f5af4d2fc38e"
integrity sha512-v1Ia1xl20KbuSGlwoaGsW0oxsw8Be+TrXweidxD9oT/1lAh6O3K3/GIM95Tt6WCiv6W+h2M7RB1TwdoAjQyyKw==
dependencies:
"@types/react-reconciler" "^0.28.0"
jiti@^1.17.2:
version "1.18.2"
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd"
@@ -2587,6 +2844,11 @@ kleur@^4.0.3:
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
ktx-parse@^0.4.5:
version "0.4.5"
resolved "https://registry.yarnpkg.com/ktx-parse/-/ktx-parse-0.4.5.tgz#79905e22281a9d3e602b2ff522df1ee7d1813aa6"
integrity sha512-MK3FOody4TXbFf8Yqv7EBbySw7aPvEcPX++Ipt6Sox+/YMFvR5xaTyhfNSk1AEmMy+RYIw81ctN4IMxCB8OAlg==
language-subtag-registry@~0.3.2:
version "0.3.22"
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d"
@@ -2612,6 +2874,11 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"
lil-gui@~0.17.0:
version "0.17.0"
resolved "https://registry.yarnpkg.com/lil-gui/-/lil-gui-0.17.0.tgz#b41ae55d0023fcd9185f7395a218db0f58189663"
integrity sha512-MVBHmgY+uEbmJNApAaPbtvNh1RCAeMnKym82SBjtp5rODTYKWtM+MXHCifLe2H2Ti1HuBGBtK/5SyG4ShQ3pUQ==
lilconfig@^2.0.5, lilconfig@^2.0.6:
version "2.1.0"
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52"
@@ -2636,6 +2903,11 @@ listr2@^3.8.3:
through "^2.3.8"
wrap-ansi "^7.0.0"
load-script@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/load-script/-/load-script-1.0.0.tgz#0491939e0bee5643ee494a7e3da3d2bac70c6ca4"
integrity sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==
locate-path@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
@@ -2648,6 +2920,11 @@ lodash.castarray@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115"
integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==
lodash.clamp@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/lodash.clamp/-/lodash.clamp-4.0.3.tgz#5c24bedeeeef0753560dc2b4cb4671f90a6ddfaa"
integrity sha512-HvzRFWjtcguTW7yd8NJBshuNaCa8aqNFtnswdT7f/cMd/1YKy5Zzoq4W/Oxvnx9l7aeY258uSdDfM793+eLsVg==
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
@@ -2658,12 +2935,22 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
lodash.omit@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
integrity sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==
lodash.once@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==
lodash@^4.17.21:
lodash.pick@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==
lodash@4.17.21, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -2705,6 +2992,11 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
maath@^0.5.2:
version "0.5.3"
resolved "https://registry.yarnpkg.com/maath/-/maath-0.5.3.tgz#777a1f9b8463c6ffb199ea43406874a357c0cd58"
integrity sha512-ut63A4zTd9abtpi+sOHW1fPWPtAFrjK0E17eAthx1k93W/T2cWLKV5oaswyotJVDvvW1EXSdokAqhK5KOu0Qdw==
markdown-table@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.3.tgz#e6331d30e493127e031dd385488b5bd326e4a6bd"
@@ -2870,6 +3162,11 @@ mdast-util-toc@^6.0.0:
unist-util-is "^5.0.0"
unist-util-visit "^4.0.0"
memoize-one@^5.1.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
@@ -2880,6 +3177,11 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
meshline@^3.1.6:
version "3.1.6"
resolved "https://registry.yarnpkg.com/meshline/-/meshline-3.1.6.tgz#eee67d9b0fd9841652cc1dc2d3833093ae8e68ca"
integrity sha512-8JZJOdaL5oz3PI/upG8JvP/5FfzYUOhrkJ8np/WKvXzl0/PZ2V9pqTvCIjSKv+w9ccg2xb+yyBhXAwt6ier3ug==
micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1:
version "1.0.6"
resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz#edff4c72e5993d93724a3c206970f5a15b0585ad"
@@ -3205,6 +3507,11 @@ minimist@^1.2.0, minimist@^1.2.6, minimist@^1.2.8:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
mmd-parser@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mmd-parser/-/mmd-parser-1.0.4.tgz#87cc05782cb5974ca854f0303fc5147bc9d690e7"
integrity sha512-Qi0VCU46t2IwfGv5KF0+D/t9cizcDug7qnNoy9Ggk7aucp0tssV8IwTMkBlDbm+VqAf3cdQHTCARKSsuS2MYFg==
mri@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
@@ -3314,7 +3621,7 @@ nprogress@^0.2.0:
resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1"
integrity sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==
object-assign@^4.0.1, object-assign@^4.1.1:
object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
@@ -3410,6 +3717,14 @@ open@^8.4.0:
is-docker "^2.1.1"
is-wsl "^2.2.0"
opentype.js@^1.3.3:
version "1.3.4"
resolved "https://registry.yarnpkg.com/opentype.js/-/opentype.js-1.3.4.tgz#1c0e72e46288473cc4a4c6a2dc60fd7fe6020d77"
integrity sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==
dependencies:
string.prototype.codepointat "^0.2.1"
tiny-inflate "^1.0.3"
optionator@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
@@ -3604,6 +3919,11 @@ postcss@8.4.22, postcss@^8.0.9:
picocolors "^1.0.0"
source-map-js "^1.0.2"
potpack@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.2.tgz#23b99e64eb74f5741ffe7656b5b5c4ddce8dfc14"
integrity sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@@ -3624,7 +3944,7 @@ pretty-bytes@^5.6.0:
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==
prop-types@^15.0.0, prop-types@^15.8.1:
prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -3690,6 +4010,13 @@ quick-lru@^5.1.1:
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
react-composer@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/react-composer/-/react-composer-5.0.3.tgz#7beb9513da5e8687f4f434ea1333ef36a4f3091b"
integrity sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA==
dependencies:
prop-types "^15.6.0"
react-dom@18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
@@ -3698,6 +4025,20 @@ react-dom@18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"
react-fast-compare@^3.0.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.1.tgz#53933d9e14f364281d6cba24bfed7a4afb808b5f"
integrity sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg==
react-h5-audio-player@^3.8.6:
version "3.8.6"
resolved "https://registry.yarnpkg.com/react-h5-audio-player/-/react-h5-audio-player-3.8.6.tgz#e7ee69ba6c0a82d317d4f987d83bb18b356a4415"
integrity sha512-eyViI47jRRybCcCkGdoAMd6yfhg3UMyXp39mqOWCbNQfAYI8U6zC0+0DLZjhrB7//DJtHhZx8h1q99HMxYkMWQ==
dependencies:
"@babel/runtime" "^7.10.2"
"@iconify/icons-mdi" "~1.1.0"
"@iconify/react" "^3.1.3"
react-icons@^4.8.0:
version "4.8.0"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.8.0.tgz#621e900caa23b912f737e41be57f27f6b2bff445"
@@ -3739,6 +4080,30 @@ react-markdown@^8.0.7:
unist-util-visit "^4.0.0"
vfile "^5.0.0"
react-merge-refs@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06"
integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==
react-player@^2.12.0:
version "2.12.0"
resolved "https://registry.yarnpkg.com/react-player/-/react-player-2.12.0.tgz#2fc05dbfec234c829292fbca563b544064bd14f0"
integrity sha512-rymLRz/2GJJD+Wc01S7S+i9pGMFYnNmQibR2gVE3KmHJCBNN8BhPAlOPTGZtn1uKpJ6p4RPLlzPQ1OLreXd8gw==
dependencies:
deepmerge "^4.0.0"
load-script "^1.0.0"
memoize-one "^5.1.1"
prop-types "^15.7.2"
react-fast-compare "^3.0.1"
react-reconciler@^0.27.0:
version "0.27.0"
resolved "https://registry.yarnpkg.com/react-reconciler/-/react-reconciler-0.27.0.tgz#360124fdf2d76447c7491ee5f0e04503ed9acf5b"
integrity sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.21.0"
react-toastify@^9.1.2:
version "9.1.2"
resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.2.tgz#293aa1f952240129fe485ae5cb2f8d09c652cf3f"
@@ -3746,6 +4111,13 @@ react-toastify@^9.1.2:
dependencies:
clsx "^1.1.1"
react-use-measure@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/react-use-measure/-/react-use-measure-2.1.1.tgz#5824537f4ee01c9469c45d5f7a8446177c6cc4ba"
integrity sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==
dependencies:
debounce "^1.2.1"
react@18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
@@ -3782,6 +4154,11 @@ regenerator-runtime@^0.13.11:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
regexp-to-ast@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz#56c73856bee5e1fef7f73a00f1473452ab712a24"
integrity sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==
regexp.prototype.flags@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
@@ -3921,6 +4298,11 @@ request-progress@^3.0.0:
dependencies:
throttleit "^1.0.0"
require-from-string@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
@@ -4009,6 +4391,13 @@ safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
scheduler@^0.21.0:
version "0.21.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.21.0.tgz#6fd2532ff5a6d877b6edb12f00d8ab7e8f308820"
integrity sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==
dependencies:
loose-envify "^1.1.0"
scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
@@ -4114,6 +4503,11 @@ sshpk@^1.14.1:
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
stats.js@^0.17.0:
version "0.17.0"
resolved "https://registry.yarnpkg.com/stats.js/-/stats.js-0.17.0.tgz#b1c3dc46d94498b578b7fd3985b81ace7131cc7d"
integrity sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==
stop-iteration-iterator@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4"
@@ -4135,6 +4529,11 @@ string-width@^4.1.0, string-width@^4.2.0:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string.prototype.codepointat@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz#004ad44c8afc727527b108cd462b4d971cd469bc"
integrity sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==
string.prototype.matchall@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3"
@@ -4244,6 +4643,11 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
suspend-react@^0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/suspend-react/-/suspend-react-0.0.8.tgz#b0740c1386b4eb652f17affe4339915ee268bd31"
integrity sha512-ZC3r8Hu1y0dIThzsGw0RLZplnX9yXwfItcvaIzJc2VQVi8TGyGDlu92syMB5ulybfvGLHAI5Ghzlk23UBPF8xg==
swr@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/swr/-/swr-2.1.3.tgz#ae3608d4dc19f75121e0b51d1982735fbf02f52e"
@@ -4313,6 +4717,33 @@ thenify-all@^1.0.0:
dependencies:
any-promise "^1.0.0"
three-mesh-bvh@^0.5.23:
version "0.5.23"
resolved "https://registry.yarnpkg.com/three-mesh-bvh/-/three-mesh-bvh-0.5.23.tgz#08e5b629144b48b11acbd433519680e457d398ed"
integrity sha512-nyk+MskdyDgECqkxdv57UjazqqhrMi+Al9PxJN6yFtx1CTW4r0eCQ27FtyYKY5gCIWhxjtNfWYDPVy8lzx6LkA==
three-stdlib@^2.21.8:
version "2.21.10"
resolved "https://registry.yarnpkg.com/three-stdlib/-/three-stdlib-2.21.10.tgz#cfebcd4ff8bee7313c3a82f0fb7c5dd8c01e2805"
integrity sha512-YGkR3stmgmXSHL27+1A5dWAKKB+e63PLVkRWV/LLZ7f5+ExsqjLPm4YfBmJgkoSLgILYpQs6O7baY9gnIZlmNA==
dependencies:
"@babel/runtime" "^7.16.7"
"@types/offscreencanvas" "^2019.6.4"
"@webgpu/glslang" "^0.0.15"
chevrotain "^10.1.2"
draco3d "^1.4.1"
fflate "^0.6.9"
ktx-parse "^0.4.5"
mmd-parser "^1.0.4"
opentype.js "^1.3.3"
potpack "^1.0.1"
zstddec "^0.0.2"
three@^0.152.0:
version "0.152.0"
resolved "https://registry.yarnpkg.com/three/-/three-0.152.0.tgz#a50034af675c636322135b6bb829d6e7e3a6213d"
integrity sha512-uvKoYo4b2bnqzsR4RJFuWecxwMKcgT1nFNmiWooCNr6AxZLCtfkj/xcfFgoi5mFopSVorh7bnvTHPfeW8DINGg==
throttleit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
@@ -4331,6 +4762,11 @@ tiny-glob@^0.2.9:
globalyzer "0.1.0"
globrex "^0.1.2"
tiny-inflate@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4"
integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==
tmp@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
@@ -4363,6 +4799,26 @@ trim-lines@^3.0.0:
resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338"
integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==
troika-three-text@^0.47.1:
version "0.47.1"
resolved "https://registry.yarnpkg.com/troika-three-text/-/troika-three-text-0.47.1.tgz#4a239b122242d7ea93dbbf66a9f1863eca83d979"
integrity sha512-/fPRUmxCkXxyUT8k6REC/aWeFzKbNr37ivrkrplSJNb3JcBUXvVt8MT0Ac5wTUvFsYTviYWprYS4/8Laen08WA==
dependencies:
bidi-js "^1.0.2"
troika-three-utils "^0.47.0"
troika-worker-utils "^0.47.0"
webgl-sdf-generator "1.1.1"
troika-three-utils@^0.47.0:
version "0.47.0"
resolved "https://registry.yarnpkg.com/troika-three-utils/-/troika-three-utils-0.47.0.tgz#4749334ad2ae043767916f79bcc365cbb5ea64b5"
integrity sha512-yoVTQxVbpQX3a55giIwqwq6hyJA6oYvq7kaNGwFTeicoWmTZCqqTbytafx1gcuL5umrtw5MYgsxYUSOha+xp5w==
troika-worker-utils@^0.47.0:
version "0.47.0"
resolved "https://registry.yarnpkg.com/troika-worker-utils/-/troika-worker-utils-0.47.0.tgz#bea382fee55333e177955e7ba6497d64b9d9388d"
integrity sha512-PSUc9vunDEkbE23jpgXD3PcF96jQHKjgMjS+4o5g6DEK/ZAPTnldb+FNddhppawfUcuraMFrslo0GmIC8UpEmA==
trough@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876"
@@ -4574,6 +5030,11 @@ util-deprecate@^1.0.2:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
utility-types@^3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b"
integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
@@ -4594,6 +5055,11 @@ uvu@^0.5.0:
kleur "^4.0.3"
sade "^1.7.3"
vary@^1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
@@ -4634,6 +5100,16 @@ web-namespaces@^2.0.0:
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692"
integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==
webgl-constants@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/webgl-constants/-/webgl-constants-1.1.1.tgz#f9633ee87fea56647a60b9ce735cbdfb891c6855"
integrity sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==
webgl-sdf-generator@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz#3e1b422b3d87cd3cc77f2602c9db63bc0f6accbd"
integrity sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
@@ -4738,6 +5214,16 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
zstddec@^0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/zstddec/-/zstddec-0.0.2.tgz#57e2f28dd1ff56b750e07d158a43f0611ad9eeb4"
integrity sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA==
zustand@^3.5.13, zustand@^3.7.1:
version "3.7.2"
resolved "https://registry.yarnpkg.com/zustand/-/zustand-3.7.2.tgz#7b44c4f4a5bfd7a8296a3957b13e1c346f42514d"
integrity sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==
zwitch@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7"