diff --git a/components.json b/components.json
new file mode 100644
index 0000000..bbf779f
--- /dev/null
+++ b/components.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "default",
+ "rsc": false,
+ "tsx": true,
+ "tailwind": {
+ "config": "tailwind.config.js",
+ "css": "src/global.css",
+ "baseColor": "slate",
+ "cssVariables": false,
+ "prefix": ""
+ },
+ "aliases": {
+ "components": "@/components",
+ "utils": "@/utility/utils"
+ }
+}
\ No newline at end of file
diff --git a/index.html b/index.html
index 9e569d6..d16bdf2 100644
--- a/index.html
+++ b/index.html
@@ -14,7 +14,7 @@
-
+
diff --git a/package.json b/package.json
index e05a0ac..19fae1a 100644
--- a/package.json
+++ b/package.json
@@ -10,15 +10,20 @@
"preview": "vite preview"
},
"dependencies": {
+ "@radix-ui/react-dialog": "^1.0.5",
+ "class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"howler": "^2.2.4",
+ "lucide-react": "^0.306.0",
"pixi.js": "^7.3.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-helmet": "^6.1.0",
"react-router-dom": "^6.21.1",
"react-toastify": "^9.1.3",
- "tailwind-merge": "^2.2.0"
+ "tailwind-merge": "^2.2.0",
+ "tailwindcss-animate": "^1.0.7",
+ "zustand": "^4.4.7"
},
"devDependencies": {
"@types/howler": "^2.2.11",
@@ -26,6 +31,7 @@
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@types/react-helmet": "^6.1.11",
+ "@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"@typescript-eslint/parser": "^6.14.0",
"@vitejs/plugin-react": "^4.2.1",
diff --git a/public/assets/sfx/kururina-intro.mp3 b/public/assets/sfx/kururina-intro.mp3
new file mode 100644
index 0000000..d5922bf
Binary files /dev/null and b/public/assets/sfx/kururina-intro.mp3 differ
diff --git a/public/assets/sfx/kururina-intro.ogg b/public/assets/sfx/kururina-intro.ogg
new file mode 100644
index 0000000..4b8778a
Binary files /dev/null and b/public/assets/sfx/kururina-intro.ogg differ
diff --git a/public/assets/sfx/kururina-loop.mp3 b/public/assets/sfx/kururina-loop.mp3
new file mode 100644
index 0000000..0ec1c97
Binary files /dev/null and b/public/assets/sfx/kururina-loop.mp3 differ
diff --git a/src/assets/icons/close-outline.svg b/src/assets/icons/close-outline.svg
new file mode 100644
index 0000000..5d783ae
--- /dev/null
+++ b/src/assets/icons/close-outline.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/components/ui/Dialog.tsx b/src/components/ui/Dialog.tsx
new file mode 100644
index 0000000..ad9d680
--- /dev/null
+++ b/src/components/ui/Dialog.tsx
@@ -0,0 +1,120 @@
+import * as React from "react";
+import * as DialogPrimitive from "@radix-ui/react-dialog";
+import { X } from "lucide-react";
+
+import { cn } from "@/utility/utils";
+
+const Dialog = DialogPrimitive.Root;
+
+const DialogTrigger = DialogPrimitive.Trigger;
+
+const DialogPortal = DialogPrimitive.Portal;
+
+const DialogClose = DialogPrimitive.Close;
+
+const DialogOverlay = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
+
+const DialogContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+ {children}
+
+
+ Close
+
+
+
+));
+DialogContent.displayName = DialogPrimitive.Content.displayName;
+
+const DialogHeader = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+DialogHeader.displayName = "DialogHeader";
+
+const DialogFooter = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => (
+
+);
+DialogFooter.displayName = "DialogFooter";
+
+const DialogTitle = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DialogTitle.displayName = DialogPrimitive.Title.displayName;
+
+const DialogDescription = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+DialogDescription.displayName = DialogPrimitive.Description.displayName;
+
+export {
+ Dialog,
+ DialogPortal,
+ DialogOverlay,
+ DialogClose,
+ DialogTrigger,
+ DialogContent,
+ DialogHeader,
+ DialogFooter,
+ DialogTitle,
+ DialogDescription,
+};
diff --git a/src/components/ui/Modal.tsx b/src/components/ui/Modal.tsx
new file mode 100644
index 0000000..2f747ed
--- /dev/null
+++ b/src/components/ui/Modal.tsx
@@ -0,0 +1,58 @@
+import React from "react";
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogOverlay,
+ DialogPortal,
+ DialogTitle,
+} from "./Dialog";
+
+export type ModalProps = {
+ children?: React.ReactNode;
+ isOpen?: boolean;
+ onOpenChange?: (open: boolean) => void;
+ title?: string;
+ description?: string;
+ size?: "sm" | "md" | "lg" | "xl";
+};
+
+const Modal = ({
+ children,
+ isOpen,
+ onOpenChange,
+ title,
+ description,
+ size = "md",
+}: ModalProps) => {
+ return (
+
+ );
+};
+
+export default Modal;
diff --git a/src/hooks/useModal.ts b/src/hooks/useModal.ts
new file mode 100644
index 0000000..ec5c121
--- /dev/null
+++ b/src/hooks/useModal.ts
@@ -0,0 +1,18 @@
+import { useState } from "react";
+
+const useModal = () => {
+ const [isOpen, setOpen] = useState(false);
+
+ return {
+ isOpen,
+ onOpen() {
+ setOpen(true);
+ },
+ onClose() {
+ setOpen(false);
+ },
+ onOpenChange: setOpen,
+ };
+};
+
+export default useModal;
diff --git a/src/pages/home/game.ts b/src/pages/home/game.ts
index 24b3d7e..76120f8 100644
--- a/src/pages/home/game.ts
+++ b/src/pages/home/game.ts
@@ -3,12 +3,14 @@ import {
AnimatedSprite,
Application,
Assets,
+ FederatedPointerEvent,
Sprite,
Text,
TextStyle,
} from "pixi.js";
import StateMachine from "./stateMachine";
import { Howl } from "howler";
+import { gameDataStore } from "./store";
const IMG_URI = "/assets/images/";
const UI_URI = "/assets/ui/";
@@ -28,6 +30,10 @@ const game = async () => {
backgroundColor: "#fff",
});
+ if (app.view.style) {
+ app.view.style.touchAction = "inherit";
+ }
+
const handPetTextures = [...Array(10)].map((_, idx) => {
const uri = `/handpet/handpet_${String(idx + 1).padStart(2, "0")}.webp`;
return Assets.load(IMG_URI + uri);
@@ -46,12 +52,11 @@ const game = async () => {
const sfx = {
prepare: new Howl({
- src: SFX_URI + "pet-the-peepo-prepare.ogg",
+ src: SFX_URI + "kururina-intro.mp3",
preload: true,
}),
music: new Howl({
- // src: SFX_URI + "pet-the-peepo.ogg",
- src: SFX_URI + "kuru-kuru-kururin.ogg",
+ src: SFX_URI + "kururina-loop.mp3",
preload: true,
loop: true,
}),
@@ -78,20 +83,24 @@ const game = async () => {
});
const startText = new Text(
- "Press to Play",
+ "Press to Pet Furina",
new TextStyle({
- fontSize: 28,
+ fontSize: 48,
+ fill: ["#fff"],
+ stroke: "#333",
+ lineJoin: "round",
+ strokeThickness: 12,
+ align: "center",
})
);
startText.anchor.set(0.5);
- startText.position.set(screen.w * 0.5, screen.h * 0.82);
+ startText.position.set(screen.w * 0.5, screen.h * 0.85);
// let musicPlayTimeout: any;
return {
onStart() {
app.stage.addChild(furina, btnStart, startText);
- // musicPlayTimeout = setTimeout(() => sfx.music.play(), 100);
},
loop(time) {
btnStart.scale.set(1.0 + Math.sin(time) * 0.2);
@@ -100,9 +109,6 @@ const game = async () => {
},
onEnd() {
app.stage.removeChild(furina, btnStart, startText);
-
- // clearTimeout(musicPlayTimeout);
- // sfx.music.stop();
},
};
});
@@ -127,21 +133,26 @@ const game = async () => {
return {
onStart() {
app.stage.addChild(furina, hand);
+ sfx.prepare.play();
timers.push(
setTimeout(() => {
furina.visible = true;
- furinaPos.y = screen.h * 0.5;
- sfx.prepare.play();
}, 500)
);
+ timers.push(
+ setTimeout(() => {
+ furinaPos.y = screen.h * 0.48;
+ }, 1200)
+ );
+
timers.push(
setTimeout(() => {
furina.visible = false;
hand.visible = true;
handPos.y = screen.h * 0.5;
- }, 1500)
+ }, 2500)
);
timers.push(
@@ -155,22 +166,36 @@ const game = async () => {
hand.position.x = screen.w * 0.15;
handPos.x = screen.w * 0.25;
hand.scale.set(0.4);
- }, 2400)
+ }, 3500)
);
timers.push(
setTimeout(() => {
- furinaPos.x = screen.w * 0.65;
- furina.scale.set(0.45);
- handPos.x = screen.w * 0.35;
+ handPos.x = screen.w * 0.28;
+ furinaPos.x = screen.w * 0.72;
+ }, 4500)
+ );
+
+ timers.push(
+ setTimeout(() => {
+ handPos.x = screen.w * 0.3;
hand.scale.set(0.45);
- }, 3400)
+ furinaPos.x = screen.w * 0.7;
+ furina.scale.set(0.45);
+ }, 5500)
+ );
+
+ timers.push(
+ setTimeout(() => {
+ handPos.x = screen.w * 0.35;
+ furinaPos.x = screen.w * 0.65;
+ }, 6500)
);
timers.push(
setTimeout(() => {
stateMachine.start(STATE.RUNNING);
- }, 4500)
+ }, 7500)
);
},
loop(_, dt) {
@@ -197,30 +222,56 @@ const game = async () => {
const handPet = new AnimatedSprite(tex.handPet);
handPet.animationSpeed = 0.2;
- handPet.scale.set(0.7);
- handPet.anchor.set(0, 0.5);
- handPet.position.set(0, screen.h * 0.34);
+ handPet.scale.set(0.6);
+ handPet.anchor.set(0.5, 0.6);
+ let handPetPos = { x: 240, y: 320 };
+ handPet.position.set(240, 320);
const touchButtonGuide = new Sprite(tex.uiBtnTouch);
touchButtonGuide.anchor.set(0.5, 1);
touchButtonGuide.position.set(screen.w * 0.5, screen.h * 0.95);
+ let touchCount = gameDataStore.getState().score;
+ let lastTouch = 0.0;
+ let isTouching = false;
+
const touchText = new Text(
- "0",
+ String(touchCount),
new TextStyle({
- fontSize: 64,
+ fontSize: 80,
+ fill: ["#fff"],
+ stroke: "#333",
+ lineJoin: "round",
+ strokeThickness: 12,
+ align: "right",
})
);
- touchText.anchor.set(1, 0);
- touchText.position.set(screen.w * 0.9, screen.h * 0.1);
+ touchText.anchor.set(0.5, 0.8);
+ touchText.position.set(screen.w * 0.5, screen.h * 0.15);
- let touchCount = 0;
- let lastTouch = 0.0;
+ const onTouch = (e: FederatedPointerEvent) => {
+ handPetPos = { x: e.global.x, y: e.global.y };
+ isTouching = true;
+
+ gameDataStore.setState((state) => {
+ touchCount = state.score + 1;
+ return { score: touchCount };
+ });
- const onTouch = () => {
lastTouch = stateMachine.time;
- touchCount += 1;
touchText.text = String(touchCount);
+ touchText.scale.set(1.3);
+ touchText.rotation = 0.2;
+ };
+
+ const onPointerMove = (e: FederatedPointerEvent) => {
+ if (isTouching) {
+ handPetPos = { x: e.global.x, y: e.global.y };
+ }
+ };
+
+ const onTouchUp = () => {
+ isTouching = false;
};
return {
@@ -231,11 +282,18 @@ const game = async () => {
sfx.music.play();
app.stage.eventMode = "static";
+ app.stage.hitArea = app.screen;
app.stage.cursor = "pointer";
app.stage.on("pointerdown", onTouch);
+ app.stage.on("pointerup", onTouchUp);
+ app.stage.on("pointermove", onPointerMove);
},
loop(time, delta) {
- if (time - lastTouch < 0.5) {
+ if (isTouching) {
+ lastTouch = time;
+ }
+
+ if (time - lastTouch < 0.8) {
if (!handPet.playing) {
handPet.play();
handPet.visible = true;
@@ -245,6 +303,8 @@ const game = async () => {
}
furina.scale.y = 1 + Math.sin(time * 40) * 0.01;
furina.rotation = -0.01 + Math.cos(time * 30) * 0.02;
+
+ lerpPos(handPet.position, handPetPos, 12 * delta);
} else {
if (handPet.playing) {
handPet.stop();
@@ -260,6 +320,13 @@ const game = async () => {
touchButtonGuide.scale.set(0.5 + Math.sin(time * 40) * 0.01);
touchButtonGuide.position.y =
screen.h * (0.92 + Math.cos(time * 40) * 0.01);
+
+ if (touchText.scale.x > 1.0) {
+ touchText.scale.set(Math.max(1.0, touchText.scale.x - 10 * delta));
+ }
+ if (touchText.rotation > 0.0) {
+ touchText.rotation = Math.max(0.0, touchText.rotation - 2 * delta);
+ }
},
onEnd() {
handPet.stop();
@@ -269,6 +336,8 @@ const game = async () => {
app.stage.eventMode = "auto";
app.stage.cursor = "";
app.stage.off("pointerdown", onTouch);
+ app.stage.off("pointerup", onTouchUp);
+ app.stage.off("pointermove", onPointerMove);
},
};
});
diff --git a/src/pages/home/page.tsx b/src/pages/home/page.tsx
index 4c89f9b..104aac2 100644
--- a/src/pages/home/page.tsx
+++ b/src/pages/home/page.tsx
@@ -4,6 +4,8 @@ import styles from "./style.module.css";
import { cn } from "@/utility/utils";
import LoadingPage from "../misc/loading-page";
import PageMetadata from "@/components/containers/PageMetadata";
+import Modal from "@/components/ui/Modal";
+import useModal from "@/hooks/useModal";
const HomePage = () => {
const appRef = useRef();
@@ -60,37 +62,35 @@ const HomePage = () => {
const Credits = () => {
const [toggle, setToggle] = useState(false);
+ const modal = useModal();
return (
- {toggle ? (
-
+
+
{`
Furina Stickers:
Guido_ (https://risibank.fr/media/297778-genshin-archon-hydro-c6-r5-soutine)
Coll5 (https://risibank.fr/media/317061-furina-focalor-genshin)
+Music:
+Kururin Furina Cover by Ariyutta (https://facebook.com/arbi.yudatama)
+pet the peepo by NitroiF (https://www.youtube.com/shorts/ll2Au3CdV2k)
+
Hand Sprite:
@soapmangraylace2752 (https://www.youtube.com/shorts/HEguW7Gmu2w)
Fijiwaterhelp (https://jailbreak.fandom.com/wiki/User_blog:Fijiwaterhelp/hand_petting)
-
-Music:
-Kurururin by Raphiiel (https://www.youtube.com/watch?v=NY0ffyEu6uo)
-pet the peepo by NitroiF (https://www.youtube.com/shorts/ll2Au3CdV2k)
`.trim()}
- ) : null}
+
);
};
diff --git a/src/pages/home/store.ts b/src/pages/home/store.ts
new file mode 100644
index 0000000..5bbd5b4
--- /dev/null
+++ b/src/pages/home/store.ts
@@ -0,0 +1,15 @@
+import { createStore } from "zustand";
+import { persist } from "zustand/middleware";
+
+type GameDataStore = {
+ score: number;
+};
+
+export const gameDataStore = createStore(
+ persist(
+ () => ({
+ score: 0,
+ }),
+ { name: "gameData" }
+ )
+);
diff --git a/src/utility/utils.ts b/src/utility/utils.ts
index e71d88d..705c521 100644
--- a/src/utility/utils.ts
+++ b/src/utility/utils.ts
@@ -1,11 +1,10 @@
-import clsx from "clsx";
+import clsx, { ClassValue } from "clsx";
import { toast } from "react-toastify";
import { twMerge } from "tailwind-merge";
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const cn = (...classNames: any[]) => {
- return twMerge(clsx(...classNames));
-};
+export function cn(...classNames: ClassValue[]) {
+ return twMerge(clsx(classNames));
+}
export const copyToClipboard = (data: string) => {
if (typeof navigator !== "undefined") {
diff --git a/tailwind.config.js b/tailwind.config.js
index 926b4e7..be473ac 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,5 +1,6 @@
/** @type {import('tailwindcss').Config} */
-export default {
+module.exports = {
+ darkMode: "class",
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {
@@ -21,7 +22,21 @@ export default {
boxShadow: {
DEFAULT: "rgba(7,65,210,0.2) 0px 9px 20px",
},
+ keyframes: {
+ "accordion-down": {
+ from: { height: "0" },
+ to: { height: "var(--radix-accordion-content-height)" },
+ },
+ "accordion-up": {
+ from: { height: "var(--radix-accordion-content-height)" },
+ to: { height: "0" },
+ },
+ },
+ animation: {
+ "accordion-down": "accordion-down 0.2s ease-out",
+ "accordion-up": "accordion-up 0.2s ease-out",
+ },
},
},
- plugins: [],
+ plugins: [require("tailwindcss-animate")],
};
diff --git a/yarn.lock b/yarn.lock
index 3f99ed0..c7ae6da 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -184,7 +184,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.22.5"
-"@babel/runtime@^7.23.5":
+"@babel/runtime@^7.13.10", "@babel/runtime@^7.23.5":
version "7.23.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.7.tgz#dd7c88deeb218a0f8bd34d5db1aa242e0f203193"
integrity sha512-w06OXVOFso7LcbzMiDGt+3X7Rh7Ho8MmgPoWU3rarH+8upf+wSU/grlGbWzQyr3DkdN6ZeuMFjpdwW0Q+HxobA==
@@ -681,6 +681,148 @@
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
+"@radix-ui/primitive@1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd"
+ integrity sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+
+"@radix-ui/react-compose-refs@1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989"
+ integrity sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+
+"@radix-ui/react-context@1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c"
+ integrity sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+
+"@radix-ui/react-dialog@^1.0.5":
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300"
+ integrity sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/primitive" "1.0.1"
+ "@radix-ui/react-compose-refs" "1.0.1"
+ "@radix-ui/react-context" "1.0.1"
+ "@radix-ui/react-dismissable-layer" "1.0.5"
+ "@radix-ui/react-focus-guards" "1.0.1"
+ "@radix-ui/react-focus-scope" "1.0.4"
+ "@radix-ui/react-id" "1.0.1"
+ "@radix-ui/react-portal" "1.0.4"
+ "@radix-ui/react-presence" "1.0.1"
+ "@radix-ui/react-primitive" "1.0.3"
+ "@radix-ui/react-slot" "1.0.2"
+ "@radix-ui/react-use-controllable-state" "1.0.1"
+ aria-hidden "^1.1.1"
+ react-remove-scroll "2.5.5"
+
+"@radix-ui/react-dismissable-layer@1.0.5":
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4"
+ integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/primitive" "1.0.1"
+ "@radix-ui/react-compose-refs" "1.0.1"
+ "@radix-ui/react-primitive" "1.0.3"
+ "@radix-ui/react-use-callback-ref" "1.0.1"
+ "@radix-ui/react-use-escape-keydown" "1.0.3"
+
+"@radix-ui/react-focus-guards@1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad"
+ integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+
+"@radix-ui/react-focus-scope@1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525"
+ integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-compose-refs" "1.0.1"
+ "@radix-ui/react-primitive" "1.0.3"
+ "@radix-ui/react-use-callback-ref" "1.0.1"
+
+"@radix-ui/react-id@1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0"
+ integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-use-layout-effect" "1.0.1"
+
+"@radix-ui/react-portal@1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15"
+ integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-primitive" "1.0.3"
+
+"@radix-ui/react-presence@1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba"
+ integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-compose-refs" "1.0.1"
+ "@radix-ui/react-use-layout-effect" "1.0.1"
+
+"@radix-ui/react-primitive@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0"
+ integrity sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-slot" "1.0.2"
+
+"@radix-ui/react-slot@1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.2.tgz#a9ff4423eade67f501ffb32ec22064bc9d3099ab"
+ integrity sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-compose-refs" "1.0.1"
+
+"@radix-ui/react-use-callback-ref@1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a"
+ integrity sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+
+"@radix-ui/react-use-controllable-state@1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286"
+ integrity sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-use-callback-ref" "1.0.1"
+
+"@radix-ui/react-use-escape-keydown@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755"
+ integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-use-callback-ref" "1.0.1"
+
+"@radix-ui/react-use-layout-effect@1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399"
+ integrity sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+
"@remix-run/router@1.14.1":
version "1.14.1"
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.14.1.tgz#6d2dd03d52e604279c38911afc1079d58c50a755"
@@ -859,6 +1001,11 @@
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339"
integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==
+"@types/uuid@^9.0.7":
+ version "9.0.7"
+ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.7.tgz#b14cebc75455eeeb160d5fe23c2fcc0c64f724d8"
+ integrity sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==
+
"@typescript-eslint/eslint-plugin@^6.14.0":
version "6.17.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.17.0.tgz#dfc38f790704ba8a54a1277c51efdb489f6ecf9f"
@@ -1033,6 +1180,13 @@ argparse@^2.0.1:
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+aria-hidden@^1.1.1:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.3.tgz#14aeb7fb692bbb72d69bebfa47279c1fd725e954"
+ integrity sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==
+ dependencies:
+ tslib "^2.0.0"
+
array-union@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
@@ -1148,6 +1302,18 @@ chokidar@^3.5.3:
optionalDependencies:
fsevents "~2.3.2"
+class-variance-authority@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.0.tgz#1c3134d634d80271b1837452b06d821915954522"
+ integrity sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==
+ dependencies:
+ clsx "2.0.0"
+
+clsx@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b"
+ integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==
+
clsx@^1.1.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12"
@@ -1237,6 +1403,11 @@ define-data-property@^1.1.1:
gopd "^1.0.1"
has-property-descriptors "^1.0.0"
+detect-node-es@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493"
+ integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
+
didyoumean@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
@@ -1547,6 +1718,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@
has-symbols "^1.0.3"
hasown "^2.0.0"
+get-nonce@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3"
+ integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==
+
glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@@ -1690,6 +1866,13 @@ inherits@2:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+invariant@^2.2.4:
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
+ integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
+ dependencies:
+ loose-envify "^1.0.0"
+
is-binary-path@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
@@ -1834,7 +2017,7 @@ 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==
-loose-envify@^1.1.0, loose-envify@^1.4.0:
+loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@@ -1860,6 +2043,11 @@ lru-cache@^6.0.0:
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484"
integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==
+lucide-react@^0.306.0:
+ version "0.306.0"
+ resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.306.0.tgz#07e427c1c0e6c6d50712b746b889ff807606131c"
+ integrity sha512-eShuk2PI3vxN4YN8kNPmhAsroSvPXbtaxU/UX/zrBcLLg8FeFH9MG7C2EYzYsT2rNrPVjbP7rpBz3mOviZYN3A==
+
merge2@^1.3.0, merge2@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
@@ -2197,6 +2385,25 @@ react-refresh@^0.14.0:
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e"
integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==
+react-remove-scroll-bar@^2.3.3:
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9"
+ integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==
+ dependencies:
+ react-style-singleton "^2.2.1"
+ tslib "^2.0.0"
+
+react-remove-scroll@2.5.5:
+ version "2.5.5"
+ resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77"
+ integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==
+ dependencies:
+ react-remove-scroll-bar "^2.3.3"
+ react-style-singleton "^2.2.1"
+ tslib "^2.1.0"
+ use-callback-ref "^1.3.0"
+ use-sidecar "^1.1.2"
+
react-router-dom@^6.21.1:
version "6.21.1"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.21.1.tgz#58b459d2fe1841388c95bb068f85128c45e27349"
@@ -2217,6 +2424,15 @@ react-side-effect@^2.1.0:
resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.2.tgz#dc6345b9e8f9906dc2eeb68700b615e0b4fe752a"
integrity sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==
+react-style-singleton@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4"
+ integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==
+ dependencies:
+ get-nonce "^1.0.0"
+ invariant "^2.2.4"
+ tslib "^2.0.0"
+
react-toastify@^9.1.3:
version "9.1.3"
resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-9.1.3.tgz#1e798d260d606f50e0fab5ee31daaae1d628c5ff"
@@ -2447,6 +2663,11 @@ tailwind-merge@^2.2.0:
dependencies:
"@babel/runtime" "^7.23.5"
+tailwindcss-animate@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz#318b692c4c42676cc9e67b19b78775742388bef4"
+ integrity sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==
+
tailwindcss@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.0.tgz#045a9c474e6885ebd0436354e611a76af1c76839"
@@ -2516,6 +2737,11 @@ ts-interface-checker@^0.1.9:
resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
+tslib@^2.0.0, tslib@^2.1.0:
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
+ integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
+
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
@@ -2561,6 +2787,26 @@ url@^0.11.0:
punycode "^1.4.1"
qs "^6.11.2"
+use-callback-ref@^1.3.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.1.tgz#9be64c3902cbd72b07fe55e56408ae3a26036fd0"
+ integrity sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ==
+ dependencies:
+ tslib "^2.0.0"
+
+use-sidecar@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2"
+ integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==
+ dependencies:
+ detect-node-es "^1.1.0"
+ tslib "^2.0.0"
+
+use-sync-external-store@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
+ integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
+
util-deprecate@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
@@ -2626,3 +2872,10 @@ yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+
+zustand@^4.4.7:
+ version "4.4.7"
+ resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.7.tgz#355406be6b11ab335f59a66d2cf9815e8f24038c"
+ integrity sha512-QFJWJMdlETcI69paJwhSMJz7PPWjVP8Sjhclxmxmxv/RYI7ZOvR5BHX+ktH0we9gTWQMxcne8q1OY8xxz604gw==
+ dependencies:
+ use-sync-external-store "1.2.0"