diff --git a/apps/web-mobile/bun.lock b/apps/web-mobile/bun.lock index 4931870e..1bdb60bd 100644 --- a/apps/web-mobile/bun.lock +++ b/apps/web-mobile/bun.lock @@ -37,8 +37,8 @@ "react-dom": "^18.3.1", "react-hook-form": "^7.54.2", "react-i18next": "^15.4.0", - "react-router": "^7.1.3", - "react-router-dom": "^7.1.3", + "react-router": "^7.6.3", + "react-router-dom": "^7.6.3", "recharts": "^2.15.1", "styletron-engine-monolithic": "^1.0.0", "styletron-react": "^6.1.1", @@ -457,8 +457,6 @@ "@types/babel__traverse": ["@types/babel__traverse@7.20.6", "", { "dependencies": { "@babel/types": "^7.20.7" } }, "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg=="], - "@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="], - "@types/d3-array": ["@types/d3-array@3.2.1", "", {}, "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="], "@types/d3-color": ["@types/d3-color@3.1.3", "", {}, "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="], @@ -1153,9 +1151,9 @@ "react-range": ["react-range@1.10.0", "", { "peerDependencies": { "react": "*", "react-dom": "*" } }, "sha512-kDo0LiBUHIQIP8menx0UoxTnHr7UXBYpIYl/DR9jCaO1o29VwvCLpkP/qOTNQz5hkJadPg1uEM07XJcJ1XGoKw=="], - "react-router": ["react-router@7.1.3", "", { "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0", "turbo-stream": "2.4.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" }, "optionalPeers": ["react-dom"] }, "sha512-EezYymLY6Guk/zLQ2vRA8WvdUhWFEj5fcE3RfWihhxXBW7+cd1LsIiA3lmx+KCmneAGQuyBv820o44L2+TtkSA=="], + "react-router": ["react-router@7.6.3", "", { "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" }, "optionalPeers": ["react-dom"] }, "sha512-zf45LZp5skDC6I3jDLXQUu0u26jtuP4lEGbc7BbdyxenBN1vJSTA18czM2D+h5qyMBuMrD+9uB+mU37HIoKGRA=="], - "react-router-dom": ["react-router-dom@7.1.3", "", { "dependencies": { "react-router": "7.1.3" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-qQGTE+77hleBzv9SIUIkGRvuFBQGagW+TQKy53UTZAO/3+YFNBYvRsNIZ1GT17yHbc63FylMOdS+m3oUriF1GA=="], + "react-router-dom": ["react-router-dom@7.6.3", "", { "dependencies": { "react-router": "7.6.3" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-DiWJm9qdUAmiJrVWaeJdu4TKu13+iB/8IEi0EW/XgaHCjW/vWGrwzup0GVvaMteuZjKnh5bEvJP/K0MDnzawHw=="], "react-smooth": ["react-smooth@4.0.4", "", { "dependencies": { "fast-equals": "^5.0.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q=="], @@ -1293,8 +1291,6 @@ "tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], - "turbo-stream": ["turbo-stream@2.4.0", "", {}, "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g=="], - "tween-functions": ["tween-functions@1.2.0", "", {}, "sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA=="], "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], diff --git a/apps/web-mobile/package.json b/apps/web-mobile/package.json index cfd7a3fd..610e5a94 100644 --- a/apps/web-mobile/package.json +++ b/apps/web-mobile/package.json @@ -47,8 +47,8 @@ "react-dom": "^18.3.1", "react-hook-form": "^7.54.2", "react-i18next": "^15.4.0", - "react-router": "^7.1.3", - "react-router-dom": "^7.1.3", + "react-router": "^7.6.3", + "react-router-dom": "^7.6.3", "recharts": "^2.15.1", "styletron-engine-monolithic": "^1.0.0", "styletron-react": "^6.1.1", diff --git a/apps/web/.gitignore b/apps/web/.gitignore index be5bf931..2ec3b782 100644 --- a/apps/web/.gitignore +++ b/apps/web/.gitignore @@ -31,4 +31,6 @@ dist-ssr .env .env.prod -.env.local \ No newline at end of file +.env.local + +.tanstack \ No newline at end of file diff --git a/apps/web/package.json b/apps/web/package.json index bdb70fae..d1852289 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -37,7 +37,10 @@ "@tailwindcss/vite": "^4.1.4", "@tanstack/react-query": "^5.76.0", "@tanstack/react-query-devtools": "^5.76.0", + "@tanstack/react-router": "^1.125.4", + "@tanstack/react-router-devtools": "^1.125.4", "@tanstack/react-table": "^8.21.2", + "@tanstack/zod-adapter": "^1.125.4", "@types/numeral": "^2.0.5", "@vitest/ui": "^3.0.4", "axios": "^1.7.9", @@ -58,8 +61,6 @@ "react-dom": "^18.3.1", "react-hook-form": "^7.54.2", "react-i18next": "^15.4.0", - "react-router": "^7.1.3", - "react-router-dom": "^7.1.3", "recharts": "^2.15.1", "styletron-engine-monolithic": "^1.0.0", "styletron-react": "^6.1.1", @@ -79,6 +80,7 @@ "@storybook/react": "^8.5.2", "@storybook/react-vite": "^8.5.2", "@storybook/test": "^8.5.2", + "@tanstack/router-plugin": "^1.125.4", "@types/lodash": "^4.17.15", "@types/ramda": "^0.30.2", "@types/react": "^18.3.18", diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx deleted file mode 100644 index ba582ddb..00000000 --- a/apps/web/src/App.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { useAtomValue } from "jotai"; -import { useEffect } from "react"; -import { BrowserRouter, Route, Routes } from "react-router-dom"; -import { themeAtom } from "./atoms/theme"; -import AlbumPage from "./pages/album"; -import ApiKeys from "./pages/apikeys"; -import ArtistPage from "./pages/artist"; -import Dropbox from "./pages/dropbox"; -import DropboxWithId from "./pages/dropbox/DropboxWithId"; -import GoogleDrive from "./pages/googledrive"; -import GoogleDriveWithId from "./pages/googledrive/GoogleDriveWithId"; -import HomePage from "./pages/home"; -import Loading from "./pages/loading"; -import PlaylistPage from "./pages/playlist"; -import ProfilePage from "./pages/profile"; -import SongPage from "./pages/song"; - -function App() { - const { darkMode } = useAtomValue(themeAtom); - useEffect(() => { - const root = document.getElementById("root"); - if (darkMode) { - root!.classList.add("dark"); - return; - } - root!.classList.remove("dark"); - }, [darkMode]); - - return ( - - - } /> - } - /> - } - /> - } - /> - } - /> - } - /> - } - /> - } /> - } /> - } - /> - } - /> - } /> - } /> - - - ); -} - -export default App; diff --git a/apps/web/src/components/Handle/Handle.tsx b/apps/web/src/components/Handle/Handle.tsx index db557ccb..3a26f311 100644 --- a/apps/web/src/components/Handle/Handle.tsx +++ b/apps/web/src/components/Handle/Handle.tsx @@ -1,10 +1,10 @@ +import { Link } from "@tanstack/react-router"; import { Avatar } from "baseui/avatar"; import { Block } from "baseui/block"; import { StatefulPopover, TRIGGER_TYPE } from "baseui/popover"; import { LabelMedium, LabelSmall } from "baseui/typography"; import { useAtom } from "jotai"; import { useEffect } from "react"; -import { Link } from "react-router"; import { profilesAtom } from "../../atoms/profiles"; import { statsAtom } from "../../atoms/stats"; import { diff --git a/apps/web/src/components/Handle/NowPlaying/NowPlaying.tsx b/apps/web/src/components/Handle/NowPlaying/NowPlaying.tsx index 02b3c1b9..ac5eb26c 100644 --- a/apps/web/src/components/Handle/NowPlaying/NowPlaying.tsx +++ b/apps/web/src/components/Handle/NowPlaying/NowPlaying.tsx @@ -1,11 +1,11 @@ import styled from "@emotion/styled"; +import { Link as DefaultLink } from "@tanstack/react-router"; import axios from "axios"; import { ProgressBar } from "baseui/progress-bar"; import { LabelXSmall } from "baseui/typography"; import { useAtom, useAtomValue } from "jotai"; import _ from "lodash"; import { useCallback, useEffect, useRef } from "react"; -import { Link as DefaultLink } from "react-router"; import { playerAtom } from "../../../atoms/player"; import { userNowPlayingAtom } from "../../../atoms/userNowplaying"; import { API_URL } from "../../../consts"; @@ -187,7 +187,9 @@ function NowPlaying({ did }: NowPlayingProps) { <>
{!!nowPlaying[did]?.albumUri && ( - + )} @@ -198,7 +200,7 @@ function NowPlaying({ did }: NowPlayingProps) {
{nowPlaying[did]?.songUri && ( {nowPlaying[did]?.title} @@ -213,7 +215,7 @@ function NowPlaying({ did }: NowPlayingProps) {
{!!nowPlaying[did]?.artistUri?.split("at://")[1] && ( diff --git a/apps/web/src/components/ScrobblesAreaChart/ScrobblesAreaChart.tsx b/apps/web/src/components/ScrobblesAreaChart/ScrobblesAreaChart.tsx index 7384f110..53999ff3 100644 --- a/apps/web/src/components/ScrobblesAreaChart/ScrobblesAreaChart.tsx +++ b/apps/web/src/components/ScrobblesAreaChart/ScrobblesAreaChart.tsx @@ -1,8 +1,8 @@ +import { useParams, useRouter } from "@tanstack/react-router"; import { LabelMedium } from "baseui/typography"; import dayjs from "dayjs"; import numeral from "numeral"; import { useEffect, useState } from "react"; -import { useLocation, useParams } from "react-router"; import { Area, AreaChart, Tooltip, TooltipProps, XAxis } from "recharts"; import useChart from "../../hooks/useChart"; @@ -37,8 +37,12 @@ function ScrobblesAreaChart() { getSongChart, getProfileChart, } = useChart(); - const { pathname } = useLocation(); - const { did, rkey } = useParams<{ did: string; rkey: string }>(); + const { + state: { + location: { pathname }, + }, + } = useRouter(); + const { did, rkey } = useParams({ strict: false }); const [data, setData] = useState< { date: string; diff --git a/apps/web/src/components/Shout/Shout.tsx b/apps/web/src/components/Shout/Shout.tsx index b70ce19a..bbd04060 100644 --- a/apps/web/src/components/Shout/Shout.tsx +++ b/apps/web/src/components/Shout/Shout.tsx @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { zodResolver } from "@hookform/resolvers/zod"; +import { useParams } from "@tanstack/react-router"; import { Button } from "baseui/button"; import { Spinner } from "baseui/spinner"; import { Textarea } from "baseui/textarea"; @@ -7,7 +8,6 @@ import { LabelLarge, LabelMedium } from "baseui/typography"; import { useAtomValue, useSetAtom } from "jotai"; import { useState } from "react"; import { Controller, useForm } from "react-hook-form"; -import { useLocation, useParams } from "react-router"; import z from "zod"; import { profileAtom } from "../../atoms/profile"; import { shoutsAtom } from "../../atoms/shouts"; @@ -44,8 +44,8 @@ function Shout(props: ShoutProps) { message: "", }, }); - const { did, rkey } = useParams<{ did: string; rkey: string }>(); - const location = useLocation(); + const { did, rkey } = useParams({ strict: false }); + const location = window.location; const [loading, setLoading] = useState(false); const onShout = async ({ message }: z.infer) => { @@ -56,19 +56,19 @@ function Shout(props: ShoutProps) { uri = `at://${did}`; } - if (location.pathname.includes("app.rocksky.song")) { + if (location.pathname.includes("/song/")) { uri = `at://${did}/app.rocksky.song/${rkey}`; } - if (location.pathname.includes("app.rocksky.album")) { + if (location.pathname.includes("/album/")) { uri = `at://${did}/app.rocksky.album/${rkey}`; } - if (location.pathname.includes("app.rocksky.artist")) { + if (location.pathname.includes("/artist/")) { uri = `at://${did}/app.rocksky.artist/${rkey}`; } - if (location.pathname.includes("app.rocksky.scrobble")) { + if (location.pathname.includes("/scrobble/")) { uri = `at://${did}/app.rocksky.scrobble/${rkey}`; } diff --git a/apps/web/src/components/Shout/ShoutList/Shout/ReplyModal/ReplyModal.tsx b/apps/web/src/components/Shout/ShoutList/Shout/ReplyModal/ReplyModal.tsx index 4e54fc61..9445eed1 100644 --- a/apps/web/src/components/Shout/ShoutList/Shout/ReplyModal/ReplyModal.tsx +++ b/apps/web/src/components/Shout/ShoutList/Shout/ReplyModal/ReplyModal.tsx @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import styled from "@emotion/styled"; import { zodResolver } from "@hookform/resolvers/zod"; +import { Link as DefaultLink, useParams } from "@tanstack/react-router"; import { Modal, ModalBody, @@ -14,7 +15,6 @@ import { LabelMedium } from "baseui/typography"; import { useAtomValue, useSetAtom } from "jotai"; import { useState } from "react"; import { Controller, useForm } from "react-hook-form"; -import { Link as DefaultLink, useParams } from "react-router"; import z from "zod"; import { profileAtom } from "../../../../../atoms/profile"; import { shoutsAtom } from "../../../../../atoms/shouts"; @@ -67,7 +67,7 @@ function ReplyModal(props: ReplyModalProps) { const profile = useAtomValue(profileAtom); const shouts = useAtomValue(shoutsAtom); const setShouts = useSetAtom(shoutsAtom); - const { did, rkey } = useParams<{ did: string; rkey: string }>(); + const { did, rkey } = useParams({ strict: false }); const [loading, setLoading] = useState(false); const { control, handleSubmit, reset, watch } = useForm< @@ -98,19 +98,19 @@ function ReplyModal(props: ReplyModalProps) { uri = `at://${did}`; } - if (location.pathname.includes("app.rocksky.scrobble")) { + if (location.pathname.includes("/scrobble/")) { uri = `at://${did}/app.rocksky.scrobble/${rkey}`; } - if (location.pathname.includes("app.rocksky.song")) { + if (location.pathname.includes("/song/")) { uri = `at://${did}/app.rocksky.song/${rkey}`; } - if (location.pathname.includes("app.rocksky.album")) { + if (location.pathname.includes("/album/")) { uri = `at://${did}/app.rocksky.album/${rkey}`; } - if (location.pathname.includes("app.rocksky.artist")) { + if (location.pathname.includes("/artist/")) { uri = `at://${did}/app.rocksky.artist/${rkey}`; } diff --git a/apps/web/src/components/Shout/ShoutList/Shout/Shout.tsx b/apps/web/src/components/Shout/ShoutList/Shout/Shout.tsx index b0029086..fd9043f7 100644 --- a/apps/web/src/components/Shout/ShoutList/Shout/Shout.tsx +++ b/apps/web/src/components/Shout/ShoutList/Shout/Shout.tsx @@ -1,6 +1,7 @@ import styled from "@emotion/styled"; import { Ellipsis } from "@styled-icons/fa-solid"; import { ArrowReplyDown } from "@styled-icons/fluentui-system-filled"; +import { Link as DefaultLink } from "@tanstack/react-router"; import { ListItem } from "baseui/list"; import { NestedMenus, StatefulMenu } from "baseui/menu"; import { PLACEMENT, StatefulPopover } from "baseui/popover"; @@ -9,7 +10,6 @@ import { LabelMedium } from "baseui/typography"; import dayjs from "dayjs"; import { useAtomValue } from "jotai"; import { useState } from "react"; -import { Link as DefaultLink } from "react-router"; import { profileAtom } from "../../../../atoms/profile"; import useLike from "../../../../hooks/useLike"; import useShout from "../../../../hooks/useShout"; diff --git a/apps/web/src/components/Shout/ShoutList/ShoutList.tsx b/apps/web/src/components/Shout/ShoutList/ShoutList.tsx index 43028e9f..c3a9dd60 100644 --- a/apps/web/src/components/Shout/ShoutList/ShoutList.tsx +++ b/apps/web/src/components/Shout/ShoutList/ShoutList.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { useParams, useRouter } from "@tanstack/react-router"; import { useAtomValue, useSetAtom } from "jotai"; import { useEffect } from "react"; -import { useLocation, useParams } from "react-router"; import { shoutsAtom } from "../../../atoms/shouts"; import useShout from "../../../hooks/useShout"; import Shout from "./Shout"; @@ -9,9 +9,13 @@ import Shout from "./Shout"; function ShoutList() { const shouts = useAtomValue(shoutsAtom); const setShouts = useSetAtom(shoutsAtom); - const { pathname } = useLocation(); + const { + state: { + location: { pathname }, + }, + } = useRouter(); const { getShouts } = useShout(); - const { did, rkey } = useParams<{ did: string; rkey: string }>(); + const { did, rkey } = useParams({ strict: false }); useEffect(() => { fetchShouts(); @@ -34,19 +38,19 @@ function ShoutList() { return; } - if (pathname.includes("app.rocksky.scrobble")) { + if (pathname.includes("/scrobble/")) { uri = `at://${did}/app.rocksky.scrobble/${rkey}`; } - if (pathname.includes("app.rocksky.song")) { + if (pathname.includes("/song/")) { uri = `at://${did}/app.rocksky.song/${rkey}`; } - if (pathname.includes("app.rocksky.album")) { + if (pathname.includes("/album/")) { uri = `at://${did}/app.rocksky.album/${rkey}`; } - if (pathname.includes("app.rocksky.artist")) { + if (pathname.includes("/artist/")) { uri = `at://${did}/app.rocksky.artist/${rkey}`; } diff --git a/apps/web/src/components/StickyPlayer/StrickyPlayer.tsx b/apps/web/src/components/StickyPlayer/StrickyPlayer.tsx index 7dd554f7..66ff31de 100644 --- a/apps/web/src/components/StickyPlayer/StrickyPlayer.tsx +++ b/apps/web/src/components/StickyPlayer/StrickyPlayer.tsx @@ -1,8 +1,8 @@ import styled from "@emotion/styled"; +import { Link as DefaultLink } from "@tanstack/react-router"; import { ProgressBar } from "baseui/progress-bar"; import { LabelSmall } from "baseui/typography"; import { useRef } from "react"; -import { Link as DefaultLink } from "react-router-dom"; import { useTimeFormat } from "../../hooks/useFormat"; import Equalizer from "../Icons/Equalizer"; import Heart from "../Icons/Heart"; @@ -135,7 +135,9 @@ function StickyPlayer(props: StickyPlayerProps) { {nowPlaying?.albumUri && ( - + )} @@ -146,7 +148,7 @@ function StickyPlayer(props: StickyPlayerProps) {
{!!nowPlaying?.songUri && ( {!!nowPlaying?.artistUri && ( useQuery({ @@ -23,7 +22,7 @@ export const useTemporaryLinkQuery = (id: string) => function useDropbox() { const getFiles = async (id?: string) => { - const response = await axios.get<{ + const response = await client.get<{ cursor: string; entries: { ".tag": string; @@ -32,7 +31,7 @@ function useDropbox() { path_display: string; }[]; has_more: boolean; - }>(`${API_URL}/dropbox/files`, { + }>(`/dropbox/files`, { headers: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, @@ -44,12 +43,12 @@ function useDropbox() { }; const getFile = async (id: string) => { - const response = await axios.get<{ + const response = await client.get<{ ".tag": string; id: string; name: string; path_display: string; - }>(`${API_URL}/dropbox/file`, { + }>(`/dropbox/file`, { headers: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, @@ -61,9 +60,9 @@ function useDropbox() { }; const getTemporaryLink = async (id: string) => { - const response = await axios.get<{ + const response = await client.get<{ link: string; - }>(`${API_URL}/dropbox/temporary-link`, { + }>(`/dropbox/temporary-link`, { headers: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, diff --git a/apps/web/src/layouts/CloudDrive/CloudDrive.tsx b/apps/web/src/layouts/CloudDrive/CloudDrive.tsx index 70def4e5..a2c29f1e 100644 --- a/apps/web/src/layouts/CloudDrive/CloudDrive.tsx +++ b/apps/web/src/layouts/CloudDrive/CloudDrive.tsx @@ -1,8 +1,8 @@ import styled from "@emotion/styled"; +import { useNavigate } from "@tanstack/react-router"; import { LabelMedium } from "baseui/typography"; import { useAtomValue } from "jotai"; import { useState } from "react"; -import { useNavigate } from "react-router"; import { profileAtom } from "../../atoms/profile"; import Dropbox from "../../components/Icons/Dropbox"; import GoogleDrive from "../../components/Icons/GoogleDrive"; @@ -35,7 +35,7 @@ function CloudDrive() { } if (profile?.googledriveUser?.isBeta) { - navigate("/googledrive"); + navigate({ to: "/googledrive" }); return; } @@ -62,7 +62,7 @@ function CloudDrive() { } if (profile?.dropboxUser?.isBeta) { - navigate("/dropbox"); + navigate({ to: "/dropbox" }); return; } diff --git a/apps/web/src/layouts/ExternalLinks/ExternalLinks.tsx b/apps/web/src/layouts/ExternalLinks/ExternalLinks.tsx index be6693ab..6f8e3765 100644 --- a/apps/web/src/layouts/ExternalLinks/ExternalLinks.tsx +++ b/apps/web/src/layouts/ExternalLinks/ExternalLinks.tsx @@ -1,8 +1,8 @@ import styled from "@emotion/styled"; import { Spotify } from "@styled-icons/boxicons-logos"; +import { useRouter } from "@tanstack/react-router"; import { LabelLarge } from "baseui/typography"; import { useAtomValue } from "jotai"; -import { useLocation } from "react-router"; import { songAtom } from "../../atoms/song"; const Link = styled.a` @@ -15,8 +15,11 @@ const Link = styled.a` function ExternalLinks() { const song = useAtomValue(songAtom); - const location = useLocation(); - const { pathname } = location; + const { + state: { + location: { pathname }, + }, + } = useRouter(); const display = pathname.includes("app.rocksky.scrobble") || pathname.includes("app.rocksky.song"); diff --git a/apps/web/src/layouts/Main.tsx b/apps/web/src/layouts/Main.tsx index f917db58..4b72d14d 100644 --- a/apps/web/src/layouts/Main.tsx +++ b/apps/web/src/layouts/Main.tsx @@ -1,11 +1,11 @@ import styled from "@emotion/styled"; +import { useSearch } from "@tanstack/react-router"; import { Button } from "baseui/button"; import { Input } from "baseui/input"; import { PLACEMENT, ToasterContainer } from "baseui/toast"; import { LabelMedium } from "baseui/typography"; import { useAtomValue } from "jotai"; import { useEffect, useState } from "react"; -import { useLocation } from "react-router"; import { profileAtom } from "../atoms/profile"; import ScrobblesAreaChart from "../components/ScrobblesAreaChart"; import StickyPlayer from "../components/StickyPlayer"; @@ -69,15 +69,12 @@ function Main(props: MainProps) { const { children } = props; const withRightPane = props.withRightPane ?? true; const [handle, setHandle] = useState(""); - const { search } = useLocation(); const jwt = localStorage.getItem("token"); const profile = useAtomValue(profileAtom); const [token, setToken] = useState(null); + const { did, cli } = useSearch({ strict: false }); useEffect(() => { - const query = new URLSearchParams(search); - const did = query.get("did"); - if (did && did !== "null") { localStorage.setItem("did", did); @@ -93,7 +90,7 @@ function Main(props: MainProps) { localStorage.setItem("token", data.token); setToken(data.token); - if (query.get("cli")) { + if (cli) { await fetch("http://localhost:6996/token", { method: "POST", headers: { @@ -113,7 +110,7 @@ function Main(props: MainProps) { fetchToken(); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [search]); + }, []); useProfile(token || localStorage.getItem("token")); diff --git a/apps/web/src/layouts/Navbar/Navbar.tsx b/apps/web/src/layouts/Navbar/Navbar.tsx index cb15100e..816c8e00 100644 --- a/apps/web/src/layouts/Navbar/Navbar.tsx +++ b/apps/web/src/layouts/Navbar/Navbar.tsx @@ -1,6 +1,7 @@ import styled from "@emotion/styled"; import { Copy } from "@styled-icons/ionicons-outline"; import { useQuery } from "@tanstack/react-query"; +import { Link, useNavigate } from "@tanstack/react-router"; import { Avatar } from "baseui/avatar"; import { Checkbox, LABEL_PLACEMENT, STYLE_TYPE } from "baseui/checkbox"; import { NestedMenus, StatefulMenu } from "baseui/menu"; @@ -14,7 +15,6 @@ import { useAtom, useAtomValue, useSetAtom } from "jotai"; import numeral from "numeral"; import * as R from "ramda"; import { useEffect, useMemo, useState } from "react"; -import { Link, useNavigate } from "react-router"; import { profileAtom } from "../../atoms/profile"; import { themeAtom } from "../../atoms/theme"; import { API_URL } from "../../consts"; @@ -120,7 +120,7 @@ function Navbar() {
- + @@ -232,10 +233,15 @@ function Navbar() { onItemSelect={({ item }) => { switch (item.id) { case "profile": - navigate(`/profile/${profile.handle}`); + navigate({ + to: "/profile/$did", + params: { did: profile.handle }, + }); break; case "api-applications": - navigate("/apikeys"); + navigate({ + to: "/apikeys", + }); break; case "signout": setProfile(null); diff --git a/apps/web/src/layouts/Search/Search.tsx b/apps/web/src/layouts/Search/Search.tsx index f0759d88..5a694930 100644 --- a/apps/web/src/layouts/Search/Search.tsx +++ b/apps/web/src/layouts/Search/Search.tsx @@ -2,12 +2,12 @@ import styled from "@emotion/styled"; import { zodResolver } from "@hookform/resolvers/zod"; import { Search as SearchIcon } from "@styled-icons/evaicons-solid"; +import { Link as DefaultLink } from "@tanstack/react-router"; import { Input } from "baseui/input"; import { PLACEMENT, Popover } from "baseui/popover"; import _ from "lodash"; import { useEffect, useState } from "react"; import { Controller, useForm } from "react-hook-form"; -import { Link as DefaultLink } from "react-router"; import z from "zod"; import Artist from "../../components/Icons/Artist"; import Disc from "../../components/Icons/Disc"; @@ -108,7 +108,9 @@ function Search() { (item.name || item.title) && item._federation.indexUid !== "users" && (
@@ -31,7 +46,7 @@ createRoot(document.getElementById("root")!).render( api_host: "https://us.i.posthog.com", }} > - + diff --git a/apps/web/src/pages/album/Album.tsx b/apps/web/src/pages/album/Album.tsx index f2d94e47..f0375b1c 100644 --- a/apps/web/src/pages/album/Album.tsx +++ b/apps/web/src/pages/album/Album.tsx @@ -1,5 +1,6 @@ import styled from "@emotion/styled"; import { ExternalLink } from "@styled-icons/evaicons-solid"; +import { Link as DefaultLink, useParams } from "@tanstack/react-router"; import { TableBuilder, TableBuilderColumn } from "baseui/table-semantic"; import { HeadingMedium, @@ -11,7 +12,6 @@ import dayjs from "dayjs"; import numeral from "numeral"; import { useEffect, useState } from "react"; import ContentLoader from "react-content-loader"; -import { Link as DefaultLink, useParams } from "react-router"; import Disc from "../../components/Icons/Disc"; import Shout from "../../components/Shout/Shout"; import SongCover from "../../components/SongCover"; @@ -49,7 +49,7 @@ type Row = { const Album = () => { const { formatTime } = useTimeFormat(); - const { did, rkey } = useParams<{ did: string; rkey: string }>(); + const { did, rkey } = useParams({ strict: false }); const { data, isLoading, isError } = useAlbumQuery(did!, rkey!); const [disc, setDisc] = useState(1); @@ -140,7 +140,9 @@ const Album = () => { {album.title} {album.artistUri && ( - + {album.artist} @@ -261,7 +263,7 @@ const Album = () => {
{row.uri && ( {row.title} @@ -276,7 +278,7 @@ const Album = () => {
{row.artistUri && ( {row.albumArtist} @@ -362,7 +364,7 @@ const Album = () => {
{row.uri && ( {row.title} @@ -377,7 +379,7 @@ const Album = () => {
{row.artistUri && ( {row.albumArtist} diff --git a/apps/web/src/pages/apikeys/ApiKeys.tsx b/apps/web/src/pages/apikeys/ApiKeys.tsx index b7d2c423..fdae0796 100644 --- a/apps/web/src/pages/apikeys/ApiKeys.tsx +++ b/apps/web/src/pages/apikeys/ApiKeys.tsx @@ -1,6 +1,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { Plus } from "@styled-icons/evaicons-solid"; import { Copy, Trash } from "@styled-icons/ionicons-outline"; +import { useNavigate } from "@tanstack/react-router"; import { Button } from "baseui/button"; import { Input } from "baseui/input"; import { Modal, ModalBody, ModalFooter, ModalHeader } from "baseui/modal"; @@ -11,7 +12,6 @@ import { HeadingMedium } from "baseui/typography"; import copy from "copy-to-clipboard"; import { useState } from "react"; import { Controller, useForm } from "react-hook-form"; -import { useNavigate } from "react-router"; import z from "zod"; import { useApikeysQuery, @@ -90,7 +90,7 @@ function ApiKeys() { }; if (!jwt) { - navigate("/"); + navigate({ to: "/" }); } return ( diff --git a/apps/web/src/pages/artist/Albums/Albums.tsx b/apps/web/src/pages/artist/Albums/Albums.tsx index e68e1790..0ad7e745 100644 --- a/apps/web/src/pages/artist/Albums/Albums.tsx +++ b/apps/web/src/pages/artist/Albums/Albums.tsx @@ -1,8 +1,8 @@ import styled from "@emotion/styled"; +import { Link as DefaultLink } from "@tanstack/react-router"; import { BlockProps } from "baseui/block"; import { FlexGrid, FlexGridItem } from "baseui/flex-grid"; import { HeadingSmall, LabelMedium, LabelSmall } from "baseui/typography"; -import { Link as DefaultLink } from "react-router"; import SongCover from "../../../components/SongCover"; const Link = styled(DefaultLink)` @@ -46,13 +46,17 @@ function Albums(props: AlbumsProps) { props.topAlbums.map((album: any) => ( {album.uri && ( - + )} {!album.uri && } {album.uri && ( - + {album.title} @@ -60,7 +64,9 @@ function Albums(props: AlbumsProps) { )} {!album.uri && {album.title}} {album.artistUri && ( - + {album.artist} diff --git a/apps/web/src/pages/artist/Artist.tsx b/apps/web/src/pages/artist/Artist.tsx index bcc47489..6e4f82e8 100644 --- a/apps/web/src/pages/artist/Artist.tsx +++ b/apps/web/src/pages/artist/Artist.tsx @@ -1,11 +1,11 @@ import styled from "@emotion/styled"; import { ExternalLink } from "@styled-icons/evaicons-solid"; +import { useParams } from "@tanstack/react-router"; import { Avatar } from "baseui/avatar"; import { HeadingMedium, HeadingXSmall, LabelMedium } from "baseui/typography"; import { useAtomValue, useSetAtom } from "jotai"; import numeral from "numeral"; import { useEffect, useState } from "react"; -import { useParams } from "react-router"; import { artistAtom } from "../../atoms/artist"; import ArtistIcon from "../../components/Icons/Artist"; import Shout from "../../components/Shout/Shout"; @@ -26,7 +26,7 @@ const Group = styled.div` `; const Artist = () => { - const { did, rkey } = useParams<{ did: string; rkey: string }>(); + const { did, rkey } = useParams({ strict: false }); const uri = `at://${did}/app.rocksky.artist/${rkey}`; const artistResult = useArtistQuery(did!, rkey!); diff --git a/apps/web/src/pages/artist/PopularSongs/PopularSongs.tsx b/apps/web/src/pages/artist/PopularSongs/PopularSongs.tsx index 0a35a95b..5c225cc3 100644 --- a/apps/web/src/pages/artist/PopularSongs/PopularSongs.tsx +++ b/apps/web/src/pages/artist/PopularSongs/PopularSongs.tsx @@ -1,7 +1,7 @@ import styled from "@emotion/styled"; +import { Link as DefaultLink } from "@tanstack/react-router"; import { TableBuilder, TableBuilderColumn } from "baseui/table-semantic"; import { HeadingSmall } from "baseui/typography"; -import { Link as DefaultLink } from "react-router"; const Link = styled(DefaultLink)` color: inherit; @@ -94,7 +94,9 @@ function PopularSongs(props: PopularSongsProps) {
{row.albumUri && ( - + {!!row.albumArt && ( {row.title} {row.artistUri && ( {row.albumArtist} diff --git a/apps/web/src/pages/dropbox/Dropbox.tsx b/apps/web/src/pages/dropbox/Dropbox.tsx index 190f1907..59cc2903 100644 --- a/apps/web/src/pages/dropbox/Dropbox.tsx +++ b/apps/web/src/pages/dropbox/Dropbox.tsx @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Folder2, MusicNoteBeamed } from "@styled-icons/bootstrap"; +import { Link, useRouter } from "@tanstack/react-router"; import { createColumnHelper } from "@tanstack/react-table"; import { Breadcrumbs } from "baseui/breadcrumbs"; import { HeadingMedium } from "baseui/typography"; @@ -7,7 +8,6 @@ import { useAtom } from "jotai"; import _ from "lodash"; import { useEffect, useState } from "react"; import ContentLoader from "react-content-loader"; -import { Link, useLocation } from "react-router"; import { dropboxAtom } from "../../atoms/dropbox"; import Table from "../../components/Table"; import { AUDIO_EXTENSIONS } from "../../consts"; @@ -35,7 +35,11 @@ const Dropbox = (props: DropboxProps) => { const { getFiles, getFile, getTemporaryLink } = useDropbox(); const [loading, setLoading] = useState(true); - const { pathname } = useLocation(); + const { + state: { + location: { pathname }, + }, + } = useRouter(); const playFile = async (id: string) => { const { link } = await getTemporaryLink(id); @@ -149,9 +153,8 @@ const Dropbox = (props: DropboxProps) => { {parent_dir && current_dir !== "Music" && ( {parent_dir} diff --git a/apps/web/src/pages/dropbox/DropboxWithId.tsx b/apps/web/src/pages/dropbox/DropboxWithId.tsx index 784d4ce2..97c29054 100644 --- a/apps/web/src/pages/dropbox/DropboxWithId.tsx +++ b/apps/web/src/pages/dropbox/DropboxWithId.tsx @@ -1,8 +1,9 @@ -import { useParams } from "react-router"; +import { useParams } from "@tanstack/react-router"; import Dropbox from "./Dropbox"; function DropboxWithId() { - const { id } = useParams<{ id: string }>(); + const { id } = useParams({ strict: false }); + console.log(">> id", id); return ; } diff --git a/apps/web/src/pages/dropbox/styles.tsx b/apps/web/src/pages/dropbox/styles.tsx index 7c084c8a..08f0870a 100644 --- a/apps/web/src/pages/dropbox/styles.tsx +++ b/apps/web/src/pages/dropbox/styles.tsx @@ -1,5 +1,5 @@ import styled from "@emotion/styled"; -import { Link } from "react-router"; +import { Link } from "@tanstack/react-router"; export const Directory = styled(Link)` color: var(--color-text) !important; diff --git a/apps/web/src/pages/googledrive/GoogleDrive.tsx b/apps/web/src/pages/googledrive/GoogleDrive.tsx index e1251b07..d6e4a304 100644 --- a/apps/web/src/pages/googledrive/GoogleDrive.tsx +++ b/apps/web/src/pages/googledrive/GoogleDrive.tsx @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Folder2, MusicNoteBeamed } from "@styled-icons/bootstrap"; +import { Link, useRouter } from "@tanstack/react-router"; import { createColumnHelper } from "@tanstack/react-table"; import { Breadcrumbs } from "baseui/breadcrumbs"; import { HeadingMedium } from "baseui/typography"; @@ -7,7 +8,6 @@ import { useAtom } from "jotai"; import _ from "lodash"; import { useEffect, useState } from "react"; import ContentLoader from "react-content-loader"; -import { Link, useLocation } from "react-router"; import googleDriveAtom from "../../atoms/googledrive"; import Table from "../../components/Table"; import { AUDIO_EXTENSIONS } from "../../consts"; @@ -32,7 +32,11 @@ const GoogleDrive = (props: GoogleDriveProps) => { const { getFiles, getFile } = useGoogleDrive(); const [loading, setLoading] = useState(true); - const { pathname } = useLocation(); + const { + state: { + location: { pathname }, + }, + } = useRouter(); const columns = [ columnHelper.accessor("name", { @@ -146,10 +150,9 @@ const GoogleDrive = (props: GoogleDriveProps) => { {parent_dir && current_dir !== "Music" && ( {parent_dir} diff --git a/apps/web/src/pages/googledrive/GoogleDriveWithId.tsx b/apps/web/src/pages/googledrive/GoogleDriveWithId.tsx index 210741f4..b5623078 100644 --- a/apps/web/src/pages/googledrive/GoogleDriveWithId.tsx +++ b/apps/web/src/pages/googledrive/GoogleDriveWithId.tsx @@ -1,8 +1,8 @@ -import { useParams } from "react-router"; +import { useParams } from "@tanstack/react-router"; import GoogleDrive from "./GoogleDrive"; function GoogleDriveWithId() { - const { id } = useParams<{ id: string }>(); + const { id } = useParams({ strict: false }); return ; } diff --git a/apps/web/src/pages/googledrive/styles.tsx b/apps/web/src/pages/googledrive/styles.tsx index ecf5ae50..a2468e02 100644 --- a/apps/web/src/pages/googledrive/styles.tsx +++ b/apps/web/src/pages/googledrive/styles.tsx @@ -1,5 +1,5 @@ import styled from "@emotion/styled"; -import { Link } from "react-router"; +import { Link } from "@tanstack/react-router"; export const Directory = styled(Link)` color: var(--color-text) !important; diff --git a/apps/web/src/pages/home/feed/Feed.tsx b/apps/web/src/pages/home/feed/Feed.tsx index cfb51c47..a0f9c230 100644 --- a/apps/web/src/pages/home/feed/Feed.tsx +++ b/apps/web/src/pages/home/feed/Feed.tsx @@ -1,4 +1,5 @@ import styled from "@emotion/styled"; +import { Link } from "@tanstack/react-router"; import { BlockProps } from "baseui/block"; import { FlexGrid, FlexGridItem } from "baseui/flex-grid"; import { StatefulTooltip } from "baseui/tooltip"; @@ -6,7 +7,6 @@ import { HeadingMedium, LabelMedium } from "baseui/typography"; import dayjs from "dayjs"; import relativeTime from "dayjs/plugin/relativeTime"; import ContentLoader from "react-content-loader"; -import { Link } from "react-router"; import Handle from "../../../components/Handle"; import SongCover from "../../../components/SongCover"; import { useFeedQuery } from "../../../hooks/useFeed"; @@ -75,7 +75,13 @@ function Feed() { // eslint-disable-next-line @typescript-eslint/no-explicit-any data.map((song: any) => ( - + { - const query = new URLSearchParams(search); - const handle = query.get("handle"); - if (handle) { window.location.href = `${API_URL}/login?handle=${handle}`; } - }, [search]); + }, [handle]); return (
diff --git a/apps/web/src/pages/playlist/Playlist.tsx b/apps/web/src/pages/playlist/Playlist.tsx index 18f27b6b..2ac210fa 100644 --- a/apps/web/src/pages/playlist/Playlist.tsx +++ b/apps/web/src/pages/playlist/Playlist.tsx @@ -1,12 +1,11 @@ import styled from "@emotion/styled"; import { ExternalLink } from "@styled-icons/evaicons-solid"; +import { Link as DefaultLink, useParams } from "@tanstack/react-router"; import { Avatar } from "baseui/avatar"; import { TableBuilder, TableBuilderColumn } from "baseui/table-semantic"; import { HeadingMedium, LabelMedium } from "baseui/typography"; import { useEffect, useState } from "react"; import ContentLoader from "react-content-loader"; -import { useParams } from "react-router"; -import { Link as DefaultLink } from "react-router-dom"; import Disc from "../../components/Icons/Disc"; import SongCover from "../../components/SongCover"; import { useTimeFormat } from "../../hooks/useFormat"; @@ -43,7 +42,7 @@ type Row = { }; function Playlist() { - const { did, rkey } = useParams<{ did: string; rkey: string }>(); + const { did, rkey } = useParams({ strict: false }); const { formatTime } = useTimeFormat(); const [playlist, setPlaylist] = useState<{ id: string; @@ -252,7 +251,7 @@ function Playlist() {
{row.uri && ( {row.title} @@ -267,7 +266,7 @@ function Playlist() {
{row.artistUri && ( {row.albumArtist} diff --git a/apps/web/src/pages/profile/Profile.tsx b/apps/web/src/pages/profile/Profile.tsx index 5f4db841..391b7316 100644 --- a/apps/web/src/pages/profile/Profile.tsx +++ b/apps/web/src/pages/profile/Profile.tsx @@ -1,12 +1,12 @@ import styled from "@emotion/styled"; import { ExternalLink } from "@styled-icons/evaicons-solid"; +import { useParams, useSearch } from "@tanstack/react-router"; import { Avatar } from "baseui/avatar"; import { Tab, Tabs } from "baseui/tabs-motion"; import { HeadingMedium, LabelLarge } from "baseui/typography"; import dayjs from "dayjs"; import { useAtom, useSetAtom } from "jotai"; import { Key, useEffect, useState } from "react"; -import { useParams, useSearchParams } from "react-router"; import { profilesAtom } from "../../atoms/profiles"; import { userAtom } from "../../atoms/user"; import Shout from "../../components/Shout/Shout"; @@ -27,20 +27,18 @@ const Group = styled.div` function Profile() { const [profiles, setProfiles] = useAtom(profilesAtom); const [activeKey, setActiveKey] = useState("0"); - const { did } = useParams<{ did: string }>(); + const { did } = useParams({ strict: false }); const profile = useProfileByDidQuery(did!); const setUser = useSetAtom(userAtom); - const [searchParams] = useSearchParams(); + const { tab } = useSearch({ strict: false }); useEffect(() => { - const tab = searchParams.get("tab"); - if (!tab) { return; } setActiveKey(1); - }, [searchParams]); + }, [tab]); useEffect(() => { if (profile.isLoading || profile.isError) { diff --git a/apps/web/src/pages/profile/library/Library.tsx b/apps/web/src/pages/profile/library/Library.tsx index a8f44d14..f95c594c 100644 --- a/apps/web/src/pages/profile/library/Library.tsx +++ b/apps/web/src/pages/profile/library/Library.tsx @@ -1,7 +1,7 @@ +import { useSearch } from "@tanstack/react-router"; import { Tab, Tabs } from "baseui/tabs-motion"; import { HeadingSmall } from "baseui/typography"; import { Key, useEffect, useState } from "react"; -import { useSearchParams } from "react-router"; import RecentTracks from "../overview/recenttracks"; import TopArtists from "../overview/topartists"; import TopTracks from "../overview/toptracks"; @@ -9,17 +9,16 @@ import Albums from "./albums"; function Library() { const [activeKey, setActiveKey] = useState("0"); - const [searchParams] = useSearchParams(); + const { tab } = useSearch({ strict: false }); + console.log("tab", tab); useEffect(() => { - const tab = searchParams.get("tab"); - if (!tab) { return; } setActiveKey(tab); - }, [searchParams]); + }, [tab]); return ( <> diff --git a/apps/web/src/pages/profile/library/albums/Albums.tsx b/apps/web/src/pages/profile/library/albums/Albums.tsx index d3eb9a47..e1b6d867 100644 --- a/apps/web/src/pages/profile/library/albums/Albums.tsx +++ b/apps/web/src/pages/profile/library/albums/Albums.tsx @@ -1,12 +1,12 @@ import { css } from "@emotion/react"; import styled from "@emotion/styled"; +import { Link as DefaultLink, useParams } from "@tanstack/react-router"; import { Pagination } from "baseui/pagination"; import { TableBuilder, TableBuilderColumn } from "baseui/table-semantic"; import { HeadingXSmall, LabelSmall } from "baseui/typography"; import { useAtomValue, useSetAtom } from "jotai"; import numeral from "numeral"; import { useEffect, useMemo, useState } from "react"; -import { Link as DefaultLink, useParams } from "react-router"; import { themeAtom } from "../../../../atoms/theme"; import { topAlbumsAtom } from "../../../../atoms/topAlbums"; import { userAtom } from "../../../../atoms/user"; @@ -55,7 +55,7 @@ function Albums(props: AlbumsProps) { const setTopAlbums = useSetAtom(topAlbumsAtom); const topAlbums = useAtomValue(topAlbumsAtom); const { darkMode } = useAtomValue(themeAtom); - const { did } = useParams<{ did: string }>(); + const { did } = useParams({ strict: false }); const profileStats = useProfileStatsByDidQuery(did!); const [currentPage, setCurrentPage] = useState(1); const albumsResult = useAlbumsQuery(did!, (currentPage - 1) * size, size); @@ -158,7 +158,9 @@ function Albums(props: AlbumsProps) {
{row.uri && ( - + {!!row.albumArt && ( {row.title} {row.artistUri && ( {row.artist} diff --git a/apps/web/src/pages/profile/lovedtracks/LovedTracks.tsx b/apps/web/src/pages/profile/lovedtracks/LovedTracks.tsx index 1511a4e8..7d614fa1 100644 --- a/apps/web/src/pages/profile/lovedtracks/LovedTracks.tsx +++ b/apps/web/src/pages/profile/lovedtracks/LovedTracks.tsx @@ -1,4 +1,5 @@ import styled from "@emotion/styled"; +import { Link as DefaultLink, useParams } from "@tanstack/react-router"; import { Pagination } from "baseui/pagination"; import { TableBuilder, TableBuilderColumn } from "baseui/table-semantic"; import { StatefulTooltip } from "baseui/tooltip"; @@ -7,7 +8,6 @@ import dayjs from "dayjs"; import { useAtomValue, useSetAtom } from "jotai"; import numeral from "numeral"; import { useEffect, useMemo, useState } from "react"; -import { Link as DefaultLink, useParams } from "react-router"; import { lovedTracksAtom } from "../../../atoms/lovedTracks"; import { userAtom } from "../../../atoms/user"; import { useLovedTracksQuery } from "../../../hooks/useLibrary"; @@ -38,7 +38,7 @@ const Link = styled(DefaultLink)` function LovedTracks() { const size = 50; - const { did } = useParams<{ did: string }>(); + const { did } = useParams({ strict: false }); const lovedTracks = useAtomValue(lovedTracksAtom); const setLovedTracks = useSetAtom(lovedTracksAtom); const [currentPage, setCurrentPage] = useState(1); @@ -133,7 +133,9 @@ function LovedTracks() { {(row: Row) => (
{row.albumUri && ( - + {!!row.albumArt && ( {row.uri && ( {row.title} @@ -175,7 +177,7 @@ function LovedTracks() { {!row.uri &&
{row.title}
} {row.artistUri && ( {row.albumArtist} diff --git a/apps/web/src/pages/profile/overview/Overview.tsx b/apps/web/src/pages/profile/overview/Overview.tsx index 77293322..cf212893 100644 --- a/apps/web/src/pages/profile/overview/Overview.tsx +++ b/apps/web/src/pages/profile/overview/Overview.tsx @@ -1,6 +1,6 @@ +import { useParams } from "@tanstack/react-router"; import { useAtomValue, useSetAtom } from "jotai"; import { useEffect } from "react"; -import { useParams } from "react-router"; import { statsAtom } from "../../../atoms/stats"; import Stats from "../../../components/Stats/Stats"; import { useProfileStatsByDidQuery } from "../../../hooks/useProfile"; @@ -10,7 +10,7 @@ import TopArtists from "./topartists"; import TopTracks from "./toptracks"; function Overview() { - const { did } = useParams<{ did: string }>(); + const { did } = useParams({ strict: false }); const profileStats = useProfileStatsByDidQuery(did!); const setStats = useSetAtom(statsAtom); const stats = useAtomValue(statsAtom); diff --git a/apps/web/src/pages/profile/overview/recenttracks/RecentTracks.tsx b/apps/web/src/pages/profile/overview/recenttracks/RecentTracks.tsx index afaf2f6d..a4ed6b76 100644 --- a/apps/web/src/pages/profile/overview/recenttracks/RecentTracks.tsx +++ b/apps/web/src/pages/profile/overview/recenttracks/RecentTracks.tsx @@ -1,5 +1,6 @@ import { css } from "@emotion/react"; import styled from "@emotion/styled"; +import { Link as DefaultLink, useParams } from "@tanstack/react-router"; import { Pagination } from "baseui/pagination"; import { TableBuilder, TableBuilderColumn } from "baseui/table-semantic"; import { StatefulTooltip } from "baseui/tooltip"; @@ -8,7 +9,6 @@ import dayjs from "dayjs"; import { useAtomValue, useSetAtom } from "jotai"; import numeral from "numeral"; import { useEffect, useMemo, useState } from "react"; -import { Link as DefaultLink, useParams } from "react-router"; import { recentTracksAtom } from "../../../../atoms/recentTracks"; import { userAtom } from "../../../../atoms/user"; import { @@ -63,7 +63,7 @@ function RecentTracks(props: RecentTracksProps) { size: 10, ...props, }; - const { did } = useParams<{ did: string }>(); + const { did } = useParams({ strict: false }); const profileStats = useProfileStatsByDidQuery(did!); const [currentPage, setCurrentPage] = useState(1); const recentTracksResult = useRecentTracksByDidQuery( @@ -197,7 +197,9 @@ function RecentTracks(props: RecentTracksProps) { {(row: Row) => (
- + {row.title}
{row.title} @@ -219,7 +221,7 @@ function RecentTracks(props: RecentTracksProps) { {(row: Row) => ( diff --git a/apps/web/src/pages/profile/overview/topalbums/TopAlbums.tsx b/apps/web/src/pages/profile/overview/topalbums/TopAlbums.tsx index 46de924c..3aaf79c2 100644 --- a/apps/web/src/pages/profile/overview/topalbums/TopAlbums.tsx +++ b/apps/web/src/pages/profile/overview/topalbums/TopAlbums.tsx @@ -1,10 +1,10 @@ import styled from "@emotion/styled"; +import { Link as DefaultLink, useParams } from "@tanstack/react-router"; import { BlockProps } from "baseui/block"; import { FlexGrid, FlexGridItem } from "baseui/flex-grid"; import { HeadingSmall, LabelMedium, LabelSmall } from "baseui/typography"; import { useAtomValue, useSetAtom } from "jotai"; import { useEffect } from "react"; -import { Link as DefaultLink, useParams } from "react-router"; import { topAlbumsAtom } from "../../../../atoms/topAlbums"; import { userAtom } from "../../../../atoms/user"; import SongCover from "../../../../components/SongCover"; @@ -27,7 +27,7 @@ const Link = styled(DefaultLink)` function TopAlbums() { const setTopAlbums = useSetAtom(topAlbumsAtom); const topAlbums = useAtomValue(topAlbumsAtom); - const { did } = useParams<{ did: string }>(); + const { did } = useParams({ strict: false }); const albumsResult = useAlbumsQuery(did!); const user = useAtomValue(userAtom); @@ -75,16 +75,22 @@ function TopAlbums() { // eslint-disable-next-line @typescript-eslint/no-explicit-any topAlbums.map((album: any) => ( - + - + {album.title} {album.artistUri && ( - + {album.artist} diff --git a/apps/web/src/pages/profile/overview/topartists/TopArtists.tsx b/apps/web/src/pages/profile/overview/topartists/TopArtists.tsx index 69d1f2ef..a9c1bd9a 100644 --- a/apps/web/src/pages/profile/overview/topartists/TopArtists.tsx +++ b/apps/web/src/pages/profile/overview/topartists/TopArtists.tsx @@ -1,12 +1,12 @@ import { css } from "@emotion/react"; import styled from "@emotion/styled"; +import { Link, useParams } from "@tanstack/react-router"; import { Pagination } from "baseui/pagination"; import { TableBuilder, TableBuilderColumn } from "baseui/table-semantic"; import { HeadingSmall, HeadingXSmall, LabelSmall } from "baseui/typography"; import { useAtomValue, useSetAtom } from "jotai"; import numeral from "numeral"; import { useEffect, useMemo, useState } from "react"; -import { Link, useParams } from "react-router"; import { themeAtom } from "../../../../atoms/theme"; import { topArtistsAtom } from "../../../../atoms/topArtists"; import { userAtom } from "../../../../atoms/user"; @@ -47,7 +47,7 @@ function TopArtists(props: TopArtistsProps) { const setTopArtists = useSetAtom(topArtistsAtom); const topArtists = useAtomValue(topArtistsAtom); const { darkMode } = useAtomValue(themeAtom); - const { did } = useParams<{ did: string }>(); + const { did } = useParams({ strict: false }); const profileStats = useProfileStatsByDidQuery(did!); const [currentPage, setCurrentPage] = useState(1); const artistsResult = useArtistsQuery(did!, (currentPage - 1) * size, size); @@ -158,7 +158,13 @@ function TopArtists(props: TopArtistsProps) { : row.index + 1}
- + {!!row.picture && (
{row.name} diff --git a/apps/web/src/pages/profile/overview/toptracks/TopTracks.tsx b/apps/web/src/pages/profile/overview/toptracks/TopTracks.tsx index 86cee026..18764936 100644 --- a/apps/web/src/pages/profile/overview/toptracks/TopTracks.tsx +++ b/apps/web/src/pages/profile/overview/toptracks/TopTracks.tsx @@ -1,12 +1,12 @@ import { css } from "@emotion/react"; import styled from "@emotion/styled"; +import { Link as DefaultLink, useParams } from "@tanstack/react-router"; import { Pagination } from "baseui/pagination"; import { TableBuilder, TableBuilderColumn } from "baseui/table-semantic"; import { HeadingSmall, HeadingXSmall, LabelSmall } from "baseui/typography"; import { useAtomValue, useSetAtom } from "jotai"; import numeral from "numeral"; import { useEffect, useMemo, useState } from "react"; -import { Link as DefaultLink, useParams } from "react-router"; import { themeAtom } from "../../../../atoms/theme"; import { topTracksAtom } from "../../../../atoms/topTracks"; import { userAtom } from "../../../../atoms/user"; @@ -63,7 +63,7 @@ function TopTracks(props: TopTracksProps) { const setTopTracks = useSetAtom(topTracksAtom); const topTracks = useAtomValue(topTracksAtom); const { darkMode } = useAtomValue(themeAtom); - const { did } = useParams<{ did: string }>(); + const { did } = useParams({ strict: false }); const profileStats = useProfileStatsByDidQuery(did!); const [currentPage, setCurrentPage] = useState(1); const tracksResult = useTracksQuery( @@ -181,7 +181,9 @@ function TopTracks(props: TopTracksProps) {
{row.albumUri && ( - + {!!row.albumArt && ( {row.title} {row.artistUri && ( {row.albumArtist} diff --git a/apps/web/src/pages/profile/playlists/Playlists.tsx b/apps/web/src/pages/profile/playlists/Playlists.tsx index dc901297..49bd68d1 100644 --- a/apps/web/src/pages/profile/playlists/Playlists.tsx +++ b/apps/web/src/pages/profile/playlists/Playlists.tsx @@ -1,10 +1,10 @@ import styled from "@emotion/styled"; +import { Link as DefaultLink, useParams } from "@tanstack/react-router"; import { BlockProps } from "baseui/block"; import { FlexGrid, FlexGridItem } from "baseui/flex-grid"; import { HeadingSmall, LabelMedium, LabelSmall } from "baseui/typography"; import { useAtomValue, useSetAtom } from "jotai"; import { useEffect } from "react"; -import { Link as DefaultLink, useParams } from "react-router"; import { playlistsAtom } from "../../../atoms/playlists"; import SongCover from "../../../components/SongCover"; import { usePlaylistsQuery } from "../../../hooks/usePlaylists"; @@ -24,7 +24,7 @@ const Link = styled(DefaultLink)` `; function Playlists() { - const { did } = useParams<{ did: string }>(); + const { did } = useParams({ strict: false }); const playlists = useAtomValue(playlistsAtom); const setPlaylists = useSetAtom(playlistsAtom); const playlistsData = usePlaylistsQuery(did!); @@ -58,10 +58,14 @@ function Playlists() { // eslint-disable-next-line @typescript-eslint/no-explicit-any playlists.map((playlist: any) => ( - + - + {playlist.name} diff --git a/apps/web/src/pages/song/PopularAlbums/PopularAlbums.tsx b/apps/web/src/pages/song/PopularAlbums/PopularAlbums.tsx index 7662b64d..0060c9e4 100644 --- a/apps/web/src/pages/song/PopularAlbums/PopularAlbums.tsx +++ b/apps/web/src/pages/song/PopularAlbums/PopularAlbums.tsx @@ -1,8 +1,8 @@ import styled from "@emotion/styled"; +import { Link as DefaultLink } from "@tanstack/react-router"; import { BlockProps } from "baseui/block"; import { FlexGrid, FlexGridItem } from "baseui/flex-grid"; import { HeadingXSmall, LabelMedium, LabelSmall } from "baseui/typography"; -import { Link as DefaultLink } from "react-router"; import SongCover from "../../../components/SongCover"; const Link = styled(DefaultLink)` @@ -50,13 +50,17 @@ function PopularAlbums(props: PopularAlbumsProps) { props.topAlbums.map((album: any) => ( {album.uri && ( - + )} {!album.uri && } {album.uri && ( - + {album.title} @@ -64,7 +68,9 @@ function PopularAlbums(props: PopularAlbumsProps) { )} {!album.uri && {album.title}} {album.artistUri && ( - + {album.artist} diff --git a/apps/web/src/pages/song/PopularTracks/PopularTracks.tsx b/apps/web/src/pages/song/PopularTracks/PopularTracks.tsx index 5517b647..10c49860 100644 --- a/apps/web/src/pages/song/PopularTracks/PopularTracks.tsx +++ b/apps/web/src/pages/song/PopularTracks/PopularTracks.tsx @@ -1,7 +1,7 @@ import styled from "@emotion/styled"; +import { Link as DefaultLink } from "@tanstack/react-router"; import { TableBuilder, TableBuilderColumn } from "baseui/table-semantic"; import { HeadingXSmall, LabelMedium } from "baseui/typography"; -import { Link as DefaultLink } from "react-router"; const Link = styled(DefaultLink)` color: inherit; @@ -99,42 +99,25 @@ function PopularTracks(props: PopularTracksProps) { > {(row: Row) => ( -
+
{row.index + 1}
{row.albumUri && ( - + {!!row.albumArt && ( {row.title} )} {!row.albumArt && ( -
+
)} )} @@ -144,37 +127,24 @@ function PopularTracks(props: PopularTracksProps) { {row.title} )} {!row.albumArt && ( -
+
)}
)}
{row.title} {row.artistUri && ( {row.albumArtist} diff --git a/apps/web/src/pages/song/Song.tsx b/apps/web/src/pages/song/Song.tsx index 98759ef5..a1b5b0bc 100644 --- a/apps/web/src/pages/song/Song.tsx +++ b/apps/web/src/pages/song/Song.tsx @@ -1,5 +1,10 @@ import styled from "@emotion/styled"; import { ExternalLink } from "@styled-icons/evaicons-solid"; +import { + Link as DefaultLink, + useParams, + useRouter, +} from "@tanstack/react-router"; import { KIND, Tag } from "baseui/tag"; import { HeadingMedium, @@ -11,7 +16,6 @@ import { useAtomValue, useSetAtom } from "jotai"; import numeral from "numeral"; import { useEffect, useState } from "react"; import ContentLoader from "react-content-loader"; -import { Link as DefaultLink, useParams } from "react-router"; import { songAtom } from "../../atoms/song"; import Disc from "../../components/Icons/Disc"; import Shout from "../../components/Shout/Shout"; @@ -54,14 +58,19 @@ const ShowMore = styled.div` `; const Song = () => { - const { did, rkey } = useParams<{ did: string; rkey: string }>(); + const { did, rkey } = useParams({ strict: false }); + const { + state: { + location: { pathname }, + }, + } = useRouter(); let uri = `at://${did}/app.rocksky.scrobble/${rkey}`; - if (window.location.pathname.includes("app.rocksky.song")) { + if (pathname.includes("/song/")) { uri = `at://${did}/app.rocksky.song/${rkey}`; } - if (window.location.pathname.includes("app.rocksky.scrobble")) { + if (pathname.includes("/scrobble/")) { uri = `at://${did}/app.rocksky.scrobble/${rkey}`; } @@ -113,7 +122,7 @@ const Song = () => { }; useEffect(() => { - if (!window.location.pathname.includes("app.rocksky.song")) { + if (!pathname.includes("/song/")) { return; } @@ -130,7 +139,7 @@ const Song = () => { }, [songResult.data, songResult.isLoading, songResult.isError, did]); useEffect(() => { - if (!window.location.pathname.includes("app.rocksky.scrobble")) { + if (!pathname.includes("/scrobble/")) { return; } @@ -164,6 +173,7 @@ const Song = () => { albumArt: x.albumArt, uri: x.uri, artistUri: x.artistUri, + albumUri: x.albumUri, scrobbles: x.playCount, })) ); @@ -212,7 +222,9 @@ const Song = () => { <> {song?.albumUri && ( - + {song.cover && } {!song.cover && (
@@ -240,7 +252,9 @@ const Song = () => { {song?.title} {song?.artistUri && ( - + rootRouteImport, +} as any) +const LoadingRoute = LoadingRouteImport.update({ + id: '/loading', + path: '/loading', + getParentRoute: () => rootRouteImport, +} as any) +const GoogledriveRoute = GoogledriveRouteImport.update({ + id: '/googledrive', + path: '/googledrive', + getParentRoute: () => rootRouteImport, +} as any) +const DropboxRoute = DropboxRouteImport.update({ + id: '/dropbox', + path: '/dropbox', + getParentRoute: () => rootRouteImport, +} as any) +const ApikeysRoute = ApikeysRouteImport.update({ + id: '/apikeys', + path: '/apikeys', + getParentRoute: () => rootRouteImport, +} as any) +const IndexRoute = IndexRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRouteImport, +} as any) +const ProfileDidRoute = ProfileDidRouteImport.update({ + id: '/profile/$did', + path: '/profile/$did', + getParentRoute: () => rootRouteImport, +} as any) +const GoogledriveIdRoute = GoogledriveIdRouteImport.update({ + id: '/$id', + path: '/$id', + getParentRoute: () => GoogledriveRoute, +} as any) +const DropboxIdRoute = DropboxIdRouteImport.update({ + id: '/$id', + path: '/$id', + getParentRoute: () => DropboxRoute, +} as any) +const DidSongRkeyRoute = DidSongRkeyRouteImport.update({ + id: '/$did/song/$rkey', + path: '/$did/song/$rkey', + getParentRoute: () => rootRouteImport, +} as any) +const DidScrobbleRkeyRoute = DidScrobbleRkeyRouteImport.update({ + id: '/$did/scrobble/$rkey', + path: '/$did/scrobble/$rkey', + getParentRoute: () => rootRouteImport, +} as any) +const DidPlaylistRkeyRoute = DidPlaylistRkeyRouteImport.update({ + id: '/$did/playlist/$rkey', + path: '/$did/playlist/$rkey', + getParentRoute: () => rootRouteImport, +} as any) +const DidArtistRkeyRoute = DidArtistRkeyRouteImport.update({ + id: '/$did/artist/$rkey', + path: '/$did/artist/$rkey', + getParentRoute: () => rootRouteImport, +} as any) +const DidAlbumRkeyRoute = DidAlbumRkeyRouteImport.update({ + id: '/$did/album/$rkey', + path: '/$did/album/$rkey', + getParentRoute: () => rootRouteImport, +} as any) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute + '/apikeys': typeof ApikeysRoute + '/dropbox': typeof DropboxRouteWithChildren + '/googledrive': typeof GoogledriveRouteWithChildren + '/loading': typeof LoadingRoute + '/scrobble': typeof ScrobbleRoute + '/dropbox/$id': typeof DropboxIdRoute + '/googledrive/$id': typeof GoogledriveIdRoute + '/profile/$did': typeof ProfileDidRoute + '/$did/album/$rkey': typeof DidAlbumRkeyRoute + '/$did/artist/$rkey': typeof DidArtistRkeyRoute + '/$did/playlist/$rkey': typeof DidPlaylistRkeyRoute + '/$did/scrobble/$rkey': typeof DidScrobbleRkeyRoute + '/$did/song/$rkey': typeof DidSongRkeyRoute +} +export interface FileRoutesByTo { + '/': typeof IndexRoute + '/apikeys': typeof ApikeysRoute + '/dropbox': typeof DropboxRouteWithChildren + '/googledrive': typeof GoogledriveRouteWithChildren + '/loading': typeof LoadingRoute + '/scrobble': typeof ScrobbleRoute + '/dropbox/$id': typeof DropboxIdRoute + '/googledrive/$id': typeof GoogledriveIdRoute + '/profile/$did': typeof ProfileDidRoute + '/$did/album/$rkey': typeof DidAlbumRkeyRoute + '/$did/artist/$rkey': typeof DidArtistRkeyRoute + '/$did/playlist/$rkey': typeof DidPlaylistRkeyRoute + '/$did/scrobble/$rkey': typeof DidScrobbleRkeyRoute + '/$did/song/$rkey': typeof DidSongRkeyRoute +} +export interface FileRoutesById { + __root__: typeof rootRouteImport + '/': typeof IndexRoute + '/apikeys': typeof ApikeysRoute + '/dropbox': typeof DropboxRouteWithChildren + '/googledrive': typeof GoogledriveRouteWithChildren + '/loading': typeof LoadingRoute + '/scrobble': typeof ScrobbleRoute + '/dropbox/$id': typeof DropboxIdRoute + '/googledrive/$id': typeof GoogledriveIdRoute + '/profile/$did': typeof ProfileDidRoute + '/$did/album/$rkey': typeof DidAlbumRkeyRoute + '/$did/artist/$rkey': typeof DidArtistRkeyRoute + '/$did/playlist/$rkey': typeof DidPlaylistRkeyRoute + '/$did/scrobble/$rkey': typeof DidScrobbleRkeyRoute + '/$did/song/$rkey': typeof DidSongRkeyRoute +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: + | '/' + | '/apikeys' + | '/dropbox' + | '/googledrive' + | '/loading' + | '/scrobble' + | '/dropbox/$id' + | '/googledrive/$id' + | '/profile/$did' + | '/$did/album/$rkey' + | '/$did/artist/$rkey' + | '/$did/playlist/$rkey' + | '/$did/scrobble/$rkey' + | '/$did/song/$rkey' + fileRoutesByTo: FileRoutesByTo + to: + | '/' + | '/apikeys' + | '/dropbox' + | '/googledrive' + | '/loading' + | '/scrobble' + | '/dropbox/$id' + | '/googledrive/$id' + | '/profile/$did' + | '/$did/album/$rkey' + | '/$did/artist/$rkey' + | '/$did/playlist/$rkey' + | '/$did/scrobble/$rkey' + | '/$did/song/$rkey' + id: + | '__root__' + | '/' + | '/apikeys' + | '/dropbox' + | '/googledrive' + | '/loading' + | '/scrobble' + | '/dropbox/$id' + | '/googledrive/$id' + | '/profile/$did' + | '/$did/album/$rkey' + | '/$did/artist/$rkey' + | '/$did/playlist/$rkey' + | '/$did/scrobble/$rkey' + | '/$did/song/$rkey' + fileRoutesById: FileRoutesById +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute + ApikeysRoute: typeof ApikeysRoute + DropboxRoute: typeof DropboxRouteWithChildren + GoogledriveRoute: typeof GoogledriveRouteWithChildren + LoadingRoute: typeof LoadingRoute + ScrobbleRoute: typeof ScrobbleRoute + ProfileDidRoute: typeof ProfileDidRoute + DidAlbumRkeyRoute: typeof DidAlbumRkeyRoute + DidArtistRkeyRoute: typeof DidArtistRkeyRoute + DidPlaylistRkeyRoute: typeof DidPlaylistRkeyRoute + DidScrobbleRkeyRoute: typeof DidScrobbleRkeyRoute + DidSongRkeyRoute: typeof DidSongRkeyRoute +} + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/scrobble': { + id: '/scrobble' + path: '/scrobble' + fullPath: '/scrobble' + preLoaderRoute: typeof ScrobbleRouteImport + parentRoute: typeof rootRouteImport + } + '/loading': { + id: '/loading' + path: '/loading' + fullPath: '/loading' + preLoaderRoute: typeof LoadingRouteImport + parentRoute: typeof rootRouteImport + } + '/googledrive': { + id: '/googledrive' + path: '/googledrive' + fullPath: '/googledrive' + preLoaderRoute: typeof GoogledriveRouteImport + parentRoute: typeof rootRouteImport + } + '/dropbox': { + id: '/dropbox' + path: '/dropbox' + fullPath: '/dropbox' + preLoaderRoute: typeof DropboxRouteImport + parentRoute: typeof rootRouteImport + } + '/apikeys': { + id: '/apikeys' + path: '/apikeys' + fullPath: '/apikeys' + preLoaderRoute: typeof ApikeysRouteImport + parentRoute: typeof rootRouteImport + } + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexRouteImport + parentRoute: typeof rootRouteImport + } + '/profile/$did': { + id: '/profile/$did' + path: '/profile/$did' + fullPath: '/profile/$did' + preLoaderRoute: typeof ProfileDidRouteImport + parentRoute: typeof rootRouteImport + } + '/googledrive/$id': { + id: '/googledrive/$id' + path: '/$id' + fullPath: '/googledrive/$id' + preLoaderRoute: typeof GoogledriveIdRouteImport + parentRoute: typeof GoogledriveRoute + } + '/dropbox/$id': { + id: '/dropbox/$id' + path: '/$id' + fullPath: '/dropbox/$id' + preLoaderRoute: typeof DropboxIdRouteImport + parentRoute: typeof DropboxRoute + } + '/$did/song/$rkey': { + id: '/$did/song/$rkey' + path: '/$did/song/$rkey' + fullPath: '/$did/song/$rkey' + preLoaderRoute: typeof DidSongRkeyRouteImport + parentRoute: typeof rootRouteImport + } + '/$did/scrobble/$rkey': { + id: '/$did/scrobble/$rkey' + path: '/$did/scrobble/$rkey' + fullPath: '/$did/scrobble/$rkey' + preLoaderRoute: typeof DidScrobbleRkeyRouteImport + parentRoute: typeof rootRouteImport + } + '/$did/playlist/$rkey': { + id: '/$did/playlist/$rkey' + path: '/$did/playlist/$rkey' + fullPath: '/$did/playlist/$rkey' + preLoaderRoute: typeof DidPlaylistRkeyRouteImport + parentRoute: typeof rootRouteImport + } + '/$did/artist/$rkey': { + id: '/$did/artist/$rkey' + path: '/$did/artist/$rkey' + fullPath: '/$did/artist/$rkey' + preLoaderRoute: typeof DidArtistRkeyRouteImport + parentRoute: typeof rootRouteImport + } + '/$did/album/$rkey': { + id: '/$did/album/$rkey' + path: '/$did/album/$rkey' + fullPath: '/$did/album/$rkey' + preLoaderRoute: typeof DidAlbumRkeyRouteImport + parentRoute: typeof rootRouteImport + } + } +} + +interface DropboxRouteChildren { + DropboxIdRoute: typeof DropboxIdRoute +} + +const DropboxRouteChildren: DropboxRouteChildren = { + DropboxIdRoute: DropboxIdRoute, +} + +const DropboxRouteWithChildren = + DropboxRoute._addFileChildren(DropboxRouteChildren) + +interface GoogledriveRouteChildren { + GoogledriveIdRoute: typeof GoogledriveIdRoute +} + +const GoogledriveRouteChildren: GoogledriveRouteChildren = { + GoogledriveIdRoute: GoogledriveIdRoute, +} + +const GoogledriveRouteWithChildren = GoogledriveRoute._addFileChildren( + GoogledriveRouteChildren, +) + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + ApikeysRoute: ApikeysRoute, + DropboxRoute: DropboxRouteWithChildren, + GoogledriveRoute: GoogledriveRouteWithChildren, + LoadingRoute: LoadingRoute, + ScrobbleRoute: ScrobbleRoute, + ProfileDidRoute: ProfileDidRoute, + DidAlbumRkeyRoute: DidAlbumRkeyRoute, + DidArtistRkeyRoute: DidArtistRkeyRoute, + DidPlaylistRkeyRoute: DidPlaylistRkeyRoute, + DidScrobbleRkeyRoute: DidScrobbleRkeyRoute, + DidSongRkeyRoute: DidSongRkeyRoute, +} +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes() diff --git a/apps/web/src/routes/$did.album.$rkey.tsx b/apps/web/src/routes/$did.album.$rkey.tsx new file mode 100644 index 00000000..7449c3a4 --- /dev/null +++ b/apps/web/src/routes/$did.album.$rkey.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import AlbumPage from "../pages/album"; + +export const Route = createFileRoute("/$did/album/$rkey")({ + component: AlbumPage, +}); diff --git a/apps/web/src/routes/$did.artist.$rkey.tsx b/apps/web/src/routes/$did.artist.$rkey.tsx new file mode 100644 index 00000000..13c84056 --- /dev/null +++ b/apps/web/src/routes/$did.artist.$rkey.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import ArtistPage from "../pages/artist"; + +export const Route = createFileRoute("/$did/artist/$rkey")({ + component: ArtistPage, +}); diff --git a/apps/web/src/routes/$did.playlist.$rkey.tsx b/apps/web/src/routes/$did.playlist.$rkey.tsx new file mode 100644 index 00000000..33a428fe --- /dev/null +++ b/apps/web/src/routes/$did.playlist.$rkey.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import PlaylistPage from "../pages/playlist"; + +export const Route = createFileRoute("/$did/playlist/$rkey")({ + component: PlaylistPage, +}); diff --git a/apps/web/src/routes/$did.scrobble.$rkey.tsx b/apps/web/src/routes/$did.scrobble.$rkey.tsx new file mode 100644 index 00000000..5f23a4cb --- /dev/null +++ b/apps/web/src/routes/$did.scrobble.$rkey.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import SongPage from "../pages/song"; + +export const Route = createFileRoute("/$did/scrobble/$rkey")({ + component: SongPage, +}); diff --git a/apps/web/src/routes/$did.song.$rkey.tsx b/apps/web/src/routes/$did.song.$rkey.tsx new file mode 100644 index 00000000..a1c45a7e --- /dev/null +++ b/apps/web/src/routes/$did.song.$rkey.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import SongPage from "../pages/song"; + +export const Route = createFileRoute("/$did/song/$rkey")({ + component: SongPage, +}); diff --git a/apps/web/src/routes/__root.tsx b/apps/web/src/routes/__root.tsx new file mode 100644 index 00000000..f9f3b963 --- /dev/null +++ b/apps/web/src/routes/__root.tsx @@ -0,0 +1,27 @@ +import { Outlet, createRootRoute } from "@tanstack/react-router"; +import { useAtomValue } from "jotai"; +import * as React from "react"; +import { themeAtom } from "../atoms/theme"; + +export const Route = createRootRoute({ + component: RootComponent, +}); + +function RootComponent() { + const { darkMode } = useAtomValue(themeAtom); + + React.useEffect(() => { + const root = document.getElementById("root"); + if (darkMode) { + root!.classList.add("dark"); + return; + } + root!.classList.remove("dark"); + }, [darkMode]); + + return ( + + + + ); +} diff --git a/apps/web/src/routes/apikeys.tsx b/apps/web/src/routes/apikeys.tsx new file mode 100644 index 00000000..97a5f710 --- /dev/null +++ b/apps/web/src/routes/apikeys.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import ApiKeysPage from "../pages/apikeys"; + +export const Route = createFileRoute("/apikeys")({ + component: ApiKeysPage, +}); diff --git a/apps/web/src/routes/dropbox.$id.tsx b/apps/web/src/routes/dropbox.$id.tsx new file mode 100644 index 00000000..10cfa39b --- /dev/null +++ b/apps/web/src/routes/dropbox.$id.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import DropboxWithIdPage from "../pages/dropbox/DropboxWithId"; + +export const Route = createFileRoute("/dropbox/$id")({ + component: DropboxWithIdPage, +}); diff --git a/apps/web/src/routes/dropbox.tsx b/apps/web/src/routes/dropbox.tsx new file mode 100644 index 00000000..317f3d09 --- /dev/null +++ b/apps/web/src/routes/dropbox.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import DropboxPage from "../pages/dropbox"; + +export const Route = createFileRoute("/dropbox")({ + component: DropboxPage, +}); diff --git a/apps/web/src/routes/googledrive.$id.tsx b/apps/web/src/routes/googledrive.$id.tsx new file mode 100644 index 00000000..8aa6203a --- /dev/null +++ b/apps/web/src/routes/googledrive.$id.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import GoogleDriveWithIdPage from "../pages/googledrive/GoogleDriveWithId"; + +export const Route = createFileRoute("/googledrive/$id")({ + component: GoogleDriveWithIdPage, +}); diff --git a/apps/web/src/routes/googledrive.tsx b/apps/web/src/routes/googledrive.tsx new file mode 100644 index 00000000..39f64ec9 --- /dev/null +++ b/apps/web/src/routes/googledrive.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import GoogleDrivePage from "../pages/googledrive"; + +export const Route = createFileRoute("/googledrive")({ + component: GoogleDrivePage, +}); diff --git a/apps/web/src/routes/index.tsx b/apps/web/src/routes/index.tsx new file mode 100644 index 00000000..819b2b68 --- /dev/null +++ b/apps/web/src/routes/index.tsx @@ -0,0 +1,14 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { zodValidator } from "@tanstack/zod-adapter"; +import z from "zod"; +import HomePage from "../pages/home"; + +export const HomePageSchema = z.object({ + did: z.string().optional(), + cli: z.string().optional(), +}); + +export const Route = createFileRoute("/")({ + component: HomePage, + validateSearch: zodValidator(HomePageSchema), +}); diff --git a/apps/web/src/routes/loading.tsx b/apps/web/src/routes/loading.tsx new file mode 100644 index 00000000..59912b6c --- /dev/null +++ b/apps/web/src/routes/loading.tsx @@ -0,0 +1,13 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { zodValidator } from "@tanstack/zod-adapter"; +import z from "zod"; +import LoadingPage from "../pages/loading"; + +const validateSearch = z.object({ + handle: z.string(), +}); + +export const Route = createFileRoute("/loading")({ + component: LoadingPage, + validateSearch: zodValidator(validateSearch), +}); diff --git a/apps/web/src/routes/profile.$did.tsx b/apps/web/src/routes/profile.$did.tsx new file mode 100644 index 00000000..cd2a996f --- /dev/null +++ b/apps/web/src/routes/profile.$did.tsx @@ -0,0 +1,13 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { zodValidator } from "@tanstack/zod-adapter"; +import z from "zod"; +import ProfilePage from "../pages/profile"; + +const validateSearch = z.object({ + tab: z.number().optional(), +}); + +export const Route = createFileRoute("/profile/$did")({ + component: ProfilePage, + validateSearch: zodValidator(validateSearch), +}); diff --git a/apps/web/src/routes/scrobble.tsx b/apps/web/src/routes/scrobble.tsx new file mode 100644 index 00000000..3df7b6d2 --- /dev/null +++ b/apps/web/src/routes/scrobble.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from "@tanstack/react-router"; +import SongPage from "../pages/song"; + +export const Route = createFileRoute("/scrobble")({ + component: SongPage, +}); diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 03038e86..6b9d6dec 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -1,9 +1,18 @@ import tailwindcss from "@tailwindcss/vite"; +import { tanstackRouter } from "@tanstack/router-plugin/vite"; import react from "@vitejs/plugin-react-swc"; import { defineConfig } from "vite"; + // https://vite.dev/config/ export default defineConfig({ - plugins: [react(), tailwindcss()], + plugins: [ + tanstackRouter({ + target: "react", + autoCodeSplitting: true, + }), + react(), + tailwindcss(), + ], optimizeDeps: { force: true, }, diff --git a/bun.lock b/bun.lock index e7963dbd..1dc7e0bd 100644 --- a/bun.lock +++ b/bun.lock @@ -179,7 +179,10 @@ "@tailwindcss/vite": "^4.1.4", "@tanstack/react-query": "^5.76.0", "@tanstack/react-query-devtools": "^5.76.0", + "@tanstack/react-router": "^1.125.4", + "@tanstack/react-router-devtools": "^1.125.4", "@tanstack/react-table": "^8.21.2", + "@tanstack/zod-adapter": "^1.125.4", "@types/numeral": "^2.0.5", "@vitest/ui": "^3.0.4", "axios": "^1.7.9", @@ -200,8 +203,6 @@ "react-dom": "^18.3.1", "react-hook-form": "^7.54.2", "react-i18next": "^15.4.0", - "react-router": "^7.1.3", - "react-router-dom": "^7.1.3", "recharts": "^2.15.1", "styletron-engine-monolithic": "^1.0.0", "styletron-react": "^6.1.1", @@ -221,6 +222,7 @@ "@storybook/react": "^8.5.2", "@storybook/react-vite": "^8.5.2", "@storybook/test": "^8.5.2", + "@tanstack/router-plugin": "^1.125.4", "@types/lodash": "^4.17.15", "@types/ramda": "^0.30.2", "@types/react": "^18.3.18", @@ -320,16 +322,32 @@ "@babel/compat-data": ["@babel/compat-data@7.27.5", "", {}, "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg=="], - "@babel/core": ["@babel/core@7.27.4", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.4", "@babel/parser": "^7.27.4", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.4", "@babel/types": "^7.27.3", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g=="], + "@babel/core": ["@babel/core@7.28.0", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.6", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ=="], - "@babel/generator": ["@babel/generator@7.27.5", "", { "dependencies": { "@babel/parser": "^7.27.5", "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw=="], + "@babel/generator": ["@babel/generator@7.28.0", "", { "dependencies": { "@babel/parser": "^7.28.0", "@babel/types": "^7.28.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg=="], + + "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="], "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="], + "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.27.1", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.27.1", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A=="], + + "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], + + "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA=="], + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="], "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.27.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.27.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg=="], + "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.27.1", "", { "dependencies": { "@babel/types": "^7.27.1" } }, "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw=="], + + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="], + + "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.27.1", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/traverse": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA=="], + + "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg=="], + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="], @@ -338,15 +356,25 @@ "@babel/helpers": ["@babel/helpers@7.27.6", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.27.6" } }, "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug=="], - "@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="], + "@babel/parser": ["@babel/parser@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.0" }, "bin": "./bin/babel-parser.js" }, "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g=="], + + "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w=="], + + "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ=="], + + "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.27.1", "", { "dependencies": { "@babel/helper-module-transforms": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw=="], + + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.0", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg=="], + + "@babel/preset-typescript": ["@babel/preset-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-transform-modules-commonjs": "^7.27.1", "@babel/plugin-transform-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ=="], "@babel/runtime": ["@babel/runtime@7.27.6", "", {}, "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q=="], "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], - "@babel/traverse": ["@babel/traverse@7.27.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.27.3", "@babel/parser": "^7.27.4", "@babel/template": "^7.27.2", "@babel/types": "^7.27.3", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA=="], + "@babel/traverse": ["@babel/traverse@7.28.0", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/types": "^7.28.0", "debug": "^4.3.1" } }, "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg=="], - "@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + "@babel/types": ["@babel/types@7.28.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg=="], "@cbor-extract/cbor-extract-darwin-arm64": ["@cbor-extract/cbor-extract-darwin-arm64@2.2.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w=="], @@ -1038,6 +1066,8 @@ "@tailwindcss/vite": ["@tailwindcss/vite@4.1.10", "", { "dependencies": { "@tailwindcss/node": "4.1.10", "@tailwindcss/oxide": "4.1.10", "tailwindcss": "4.1.10" }, "peerDependencies": { "vite": "^5.2.0 || ^6" } }, "sha512-QWnD5HDY2IADv+vYR82lOhqOlS1jSCUUAmfem52cXAhRTKxpDh3ARX8TTXJTCCO7Rv7cD2Nlekabv02bwP3a2A=="], + "@tanstack/history": ["@tanstack/history@1.121.34", "", {}, "sha512-YL8dGi5ZU+xvtav2boRlw4zrRghkY6hvdcmHhA0RGSJ/CBgzv+cbADW9eYJLx74XMZvIQ1pp6VMbrpXnnM5gHA=="], + "@tanstack/query-core": ["@tanstack/query-core@5.81.2", "", {}, "sha512-QLYkPdrudoMATDFa3MiLEwRhNnAlzHWDf0LKaXUqJd0/+QxN8uTPi7bahRlxoAyH0UbLMBdeDbYzWALj7THOtw=="], "@tanstack/query-devtools": ["@tanstack/query-devtools@5.81.2", "", {}, "sha512-jCeJcDCwKfoyyBXjXe9+Lo8aTkavygHHsUHAlxQKKaDeyT0qyQNLKl7+UyqYH2dDF6UN/14873IPBHchcsU+Zg=="], @@ -1046,10 +1076,32 @@ "@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.81.2", "", { "dependencies": { "@tanstack/query-devtools": "5.81.2" }, "peerDependencies": { "@tanstack/react-query": "^5.81.2", "react": "^18 || ^19" } }, "sha512-TX0OQ4cbgX6z2uN8c9x0QUNbyePGyUGdcgrGnV6TYEJc7KPT8PqeASuzoA5NGw1CiMGvyFAkIGA2KipvhM9d1g=="], + "@tanstack/react-router": ["@tanstack/react-router@1.125.4", "", { "dependencies": { "@tanstack/history": "1.121.34", "@tanstack/react-store": "^0.7.0", "@tanstack/router-core": "1.125.4", "isbot": "^5.1.22", "jsesc": "^3.1.0", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-IIlDiFCR+RN/17dWtYKMYiJvH38tmtgTyciHkeZvr8vSWhThAeuwjzKneF4mQl3B//YHYcrFm7rZM59c24As/A=="], + + "@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.125.4", "", { "dependencies": { "@tanstack/router-devtools-core": "^1.125.4" }, "peerDependencies": { "@tanstack/react-router": "^1.125.4", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-eRg6Ht6bLno+Eo2Gps3cfjp++Mvy0brc6qs81At4beKZsCkS7jlmqHgrq6pXdH3l2bAQ/Dhr8J9zXvzxvRxf/g=="], + + "@tanstack/react-store": ["@tanstack/react-store@0.7.1", "", { "dependencies": { "@tanstack/store": "0.7.1", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-qUTEKdId6QPWGiWyKAPf/gkN29scEsz6EUSJ0C3HgLMgaqTAyBsQ2sMCfGVcqb+kkhEXAdjleCgH6LAPD6f2sA=="], + "@tanstack/react-table": ["@tanstack/react-table@8.21.3", "", { "dependencies": { "@tanstack/table-core": "8.21.3" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww=="], + "@tanstack/router-core": ["@tanstack/router-core@1.125.4", "", { "dependencies": { "@tanstack/history": "1.121.34", "@tanstack/store": "^0.7.0", "cookie-es": "^1.2.2", "jsesc": "^3.1.0", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-tdgGI0Kwt3Lgs9ceLbG32NPh4I2H1T9t2TKjcS+I78sifm5rjTWV8lfqVRNrvMPk5ek60vXPOL2AHAUg6ohwsA=="], + + "@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.125.4", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "solid-js": "^1.9.5" }, "peerDependencies": { "@tanstack/router-core": "^1.125.4", "csstype": "^3.0.10", "tiny-invariant": "^1.3.3" }, "optionalPeers": ["csstype"] }, "sha512-5QbCQCcJcN/M0NF2TARKqauJ8QeRuk7kyHQMCqOoSJWWGUVcDHEmcbg1ZCJevfPVZPgnUjV9mqDfCPTYWT8/+w=="], + + "@tanstack/router-generator": ["@tanstack/router-generator@1.125.4", "", { "dependencies": { "@tanstack/router-core": "^1.125.4", "@tanstack/router-utils": "1.121.21", "@tanstack/virtual-file-routes": "^1.121.21", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-jF71znMvpZxmkQF0MxfjKKyvXtft9NWRCVcLhb+6d/8nrVGNiEw+dsXn/CLpeRQLk7Mg/fsp/WipBql1dd3Qaw=="], + + "@tanstack/router-plugin": ["@tanstack/router-plugin@1.125.4", "", { "dependencies": { "@babel/core": "^7.27.7", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.7", "@babel/types": "^7.27.7", "@tanstack/router-core": "^1.125.4", "@tanstack/router-generator": "1.125.4", "@tanstack/router-utils": "1.121.21", "@tanstack/virtual-file-routes": "^1.121.21", "babel-dead-code-elimination": "^1.0.10", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.125.4", "vite": ">=5.0.0 || >=6.0.0", "vite-plugin-solid": "^2.11.2", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-k3m7z5p64IT8MHG+PwecqCm/vUyzz4ZnEAdOJ1W1Kz6ZreP+FAMDNKY69U82MbhV5TU6a/luWIH/7IyfXDxs3A=="], + + "@tanstack/router-utils": ["@tanstack/router-utils@1.121.21", "", { "dependencies": { "@babel/core": "^7.27.4", "@babel/generator": "^7.27.5", "@babel/parser": "^7.27.5", "@babel/preset-typescript": "^7.27.1", "ansis": "^4.1.0", "diff": "^8.0.2" } }, "sha512-u7ubq1xPBtNiU7Fm+EOWlVWdgFLzuKOa1thhqdscVn8R4dNMUd1VoOjZ6AKmLw201VaUhFtlX+u0pjzI6szX7A=="], + + "@tanstack/store": ["@tanstack/store@0.7.1", "", {}, "sha512-PjUQKXEXhLYj2X5/6c1Xn/0/qKY0IVFxTJweopRfF26xfjVyb14yALydJrHupDh3/d+1WKmfEgZPBVCmDkzzwg=="], + "@tanstack/table-core": ["@tanstack/table-core@8.21.3", "", {}, "sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg=="], + "@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.121.21", "", {}, "sha512-3nuYsTyaq6ZN7jRZ9z6Gj3GXZqBOqOT0yzd/WZ33ZFfv4yVNIvsa5Lw+M1j3sgyEAxKMqGu/FaNi7FCjr3yOdw=="], + + "@tanstack/zod-adapter": ["@tanstack/zod-adapter@1.125.4", "", { "peerDependencies": { "@tanstack/react-router": ">=1.43.2", "zod": "^3.23.8" } }, "sha512-3/ycN2IM43gicOk5ZY/yrXCQ4B2NVqsgVkIab1WlPWNkvCKP+vp4+j4b42BuHMv501kBnSsGBdhaRs11IUHLoQ=="], + "@testing-library/dom": ["@testing-library/dom@10.4.0", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "pretty-format": "^27.0.2" } }, "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ=="], "@testing-library/jest-dom": ["@testing-library/jest-dom@6.5.0", "", { "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", "chalk": "^3.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", "lodash": "^4.17.21", "redent": "^3.0.0" } }, "sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA=="], @@ -1222,6 +1274,8 @@ "ansi-styles": ["ansi-styles@2.2.1", "", {}, "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA=="], + "ansis": ["ansis@4.1.0", "", {}, "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w=="], + "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], @@ -1264,6 +1318,8 @@ "axios": ["axios@1.10.0", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw=="], + "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.10", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA=="], + "babel-plugin-macros": ["babel-plugin-macros@3.1.0", "", { "dependencies": { "@babel/runtime": "^7.12.5", "cosmiconfig": "^7.0.0", "resolve": "^1.19.0" } }, "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg=="], "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], @@ -1280,6 +1336,8 @@ "bignumber.js": ["bignumber.js@9.3.0", "", {}, "sha512-EM7aMFTXbptt/wZdMlBv2t8IViwQL+h6SLHosp8Yf0dqJMTnY6iL32opnAB6kAdL0SZPuvcAzFr31o0c/R3/RA=="], + "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], + "bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="], "biome": ["biome@0.3.3", "", { "dependencies": { "bluebird": "^3.4.1", "chalk": "^1.1.3", "commander": "^2.9.0", "editor": "^1.0.0", "fs-promise": "^0.5.0", "inquirer-promise": "0.0.3", "request-promise": "^3.0.0", "untildify": "^3.0.2", "user-home": "^2.0.0" }, "bin": { "biome": "./dist/index.js" } }, "sha512-4LXjrQYbn9iTXu9Y4SKT7ABzTV0WnLDHCVSd2fPUOKsy1gQ+E4xPFmlY1zcWexoi0j7fGHItlL6OWA2CZ/yYAQ=="], @@ -1390,7 +1448,7 @@ "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], - "convert-source-map": ["convert-source-map@1.9.0", "", {}, "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="], + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], "cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], @@ -1546,6 +1604,8 @@ "devalue": ["devalue@4.3.3", "", {}, "sha512-UH8EL6H2ifcY8TbD2QsxwCC/pr5xSwPvv85LrLXVihmHVC3T3YqTCIwnR5ak0yO1KYqlxrPVOA/JVZJYPy2ATg=="], + "diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="], + "doctrine": ["doctrine@3.0.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="], "dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="], @@ -1776,6 +1836,8 @@ "globals": ["globals@15.15.0", "", {}, "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg=="], + "goober": ["goober@2.1.16", "", { "peerDependencies": { "csstype": "^3.0.10" } }, "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g=="], + "google-auth-library": ["google-auth-library@9.15.1", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^6.1.1", "gcp-metadata": "^6.1.0", "gtoken": "^7.0.0", "jws": "^4.0.0" } }, "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng=="], "google-logging-utils": ["google-logging-utils@0.0.2", "", {}, "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ=="], @@ -1870,6 +1932,8 @@ "is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="], + "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], + "is-buffer": ["is-buffer@1.1.6", "", {}, "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="], "is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="], @@ -1908,6 +1972,8 @@ "is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="], + "isbot": ["isbot@5.1.28", "", {}, "sha512-qrOp4g3xj8YNse4biorv6O5ZShwsJM0trsoda4y7j/Su7ZtTTfVXFzbKkpgcSoDrHS8FcTuUwcU04YimZlZOxw=="], + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "iso-datestring-validator": ["iso-datestring-validator@2.2.2", "", {}, "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA=="], @@ -2360,10 +2426,6 @@ "react-range": ["react-range@1.10.0", "", { "peerDependencies": { "react": "*", "react-dom": "*" } }, "sha512-kDo0LiBUHIQIP8menx0UoxTnHr7UXBYpIYl/DR9jCaO1o29VwvCLpkP/qOTNQz5hkJadPg1uEM07XJcJ1XGoKw=="], - "react-router": ["react-router@7.6.2", "", { "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" }, "optionalPeers": ["react-dom"] }, "sha512-U7Nv3y+bMimgWjhlT5CRdzHPu2/KVmqPwKUCChW8en5P3znxUqwlYFlbmyj8Rgp1SF6zs5X4+77kBVknkg6a0w=="], - - "react-router-dom": ["react-router-dom@7.6.2", "", { "dependencies": { "react-router": "7.6.2" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-Q8zb6VlTbdYKK5JJBLQEN06oTUa/RAbG/oQS1auK1I0TbJOXktqm+QENEVJU6QvWynlXPRBXI3fiOQcSEA78rA=="], - "react-smooth": ["react-smooth@4.0.4", "", { "dependencies": { "fast-equals": "^5.0.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q=="], "react-transition-group": ["react-transition-group@4.4.5", "", { "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", "loose-envify": "^1.4.0", "prop-types": "^15.6.2" }, "peerDependencies": { "react": ">=16.6.0", "react-dom": ">=16.6.0" } }, "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g=="], @@ -2456,9 +2518,11 @@ "send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], - "serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="], + "seroval": ["seroval@1.3.2", "", {}, "sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ=="], - "set-cookie-parser": ["set-cookie-parser@2.7.1", "", {}, "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="], + "seroval-plugins": ["seroval-plugins@1.3.2", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-0QvCV2lM3aj/U3YozDiVwx9zpH0q8A60CTWIv4Jszj/givcudPb48B+rkU5D51NJ0pTpweGMttHjboPa9/zoIQ=="], + + "serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="], "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], @@ -2496,6 +2560,8 @@ "slice-ansi": ["slice-ansi@4.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" } }, "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ=="], + "solid-js": ["solid-js@1.9.7", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-/saTKi8iWEM233n5OSi1YHCCuh66ZIQ7aK2hsToPe4tqGm7qAejU1SwNuTPivbWAYq7SjuHVVYxxuZQNRbICiw=="], + "sonic-boom": ["sonic-boom@3.8.1", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg=="], "source-map": ["source-map@0.7.4", "", {}, "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="], @@ -2578,6 +2644,8 @@ "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], + "tiny-warning": ["tiny-warning@1.0.3", "", {}, "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="], + "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], @@ -2668,7 +2736,7 @@ "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], - "unplugin": ["unplugin@1.16.1", "", { "dependencies": { "acorn": "^8.14.0", "webpack-virtual-modules": "^0.6.2" } }, "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w=="], + "unplugin": ["unplugin@2.3.5", "", { "dependencies": { "acorn": "^8.14.1", "picomatch": "^4.0.2", "webpack-virtual-modules": "^0.6.2" } }, "sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw=="], "unstorage": ["unstorage@1.16.0", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^4.0.3", "destr": "^2.0.5", "h3": "^1.15.2", "lru-cache": "^10.4.3", "node-fetch-native": "^1.6.6", "ofetch": "^1.4.1", "ufo": "^1.6.1" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA=="], @@ -2796,17 +2864,29 @@ "@atproto/xrpc-server/express": ["express@4.21.2", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.19.0", "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA=="], - "@babel/core/convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], - "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + "@babel/generator/@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg=="], + + "@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.29", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ=="], "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@babel/traverse/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], + "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-module-imports/@babel/traverse": ["@babel/traverse@7.27.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.27.3", "@babel/parser": "^7.27.4", "@babel/template": "^7.27.2", "@babel/types": "^7.27.3", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA=="], + + "@babel/helper-module-imports/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + + "@babel/helper-module-transforms/@babel/traverse": ["@babel/traverse@7.27.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.27.3", "@babel/parser": "^7.27.4", "@babel/template": "^7.27.2", "@babel/types": "^7.27.3", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA=="], + + "@babel/helpers/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + + "@babel/template/@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="], + + "@babel/template/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], "@chromatic-com/storybook/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], @@ -2814,6 +2894,8 @@ "@cloudflare/vitest-pool-workers/wrangler": ["wrangler@3.109.1", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", "@esbuild-plugins/node-globals-polyfill": "0.2.3", "@esbuild-plugins/node-modules-polyfill": "0.2.2", "blake3-wasm": "2.1.5", "esbuild": "0.17.19", "miniflare": "3.20250204.1", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.1", "workerd": "1.20250204.0" }, "optionalDependencies": { "fsevents": "~2.3.2", "sharp": "^0.33.5" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20250204.0" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-1Jx+nZ6eCXPQ2rsGdrV6Qy/LGvhpqudeuTl4AYHl9P8Zugp44Uzxnj5w11qF4v/rv1dOZoA5TydSt9xMFfhpKg=="], + "@emotion/babel-plugin/convert-source-map": ["convert-source-map@1.9.0", "", {}, "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="], + "@emotion/babel-plugin/source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], @@ -2930,6 +3012,8 @@ "@storybook/core/esbuild": ["esbuild@0.25.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.5", "@esbuild/android-arm": "0.25.5", "@esbuild/android-arm64": "0.25.5", "@esbuild/android-x64": "0.25.5", "@esbuild/darwin-arm64": "0.25.5", "@esbuild/darwin-x64": "0.25.5", "@esbuild/freebsd-arm64": "0.25.5", "@esbuild/freebsd-x64": "0.25.5", "@esbuild/linux-arm": "0.25.5", "@esbuild/linux-arm64": "0.25.5", "@esbuild/linux-ia32": "0.25.5", "@esbuild/linux-loong64": "0.25.5", "@esbuild/linux-mips64el": "0.25.5", "@esbuild/linux-ppc64": "0.25.5", "@esbuild/linux-riscv64": "0.25.5", "@esbuild/linux-s390x": "0.25.5", "@esbuild/linux-x64": "0.25.5", "@esbuild/netbsd-arm64": "0.25.5", "@esbuild/netbsd-x64": "0.25.5", "@esbuild/openbsd-arm64": "0.25.5", "@esbuild/openbsd-x64": "0.25.5", "@esbuild/sunos-x64": "0.25.5", "@esbuild/win32-arm64": "0.25.5", "@esbuild/win32-ia32": "0.25.5", "@esbuild/win32-x64": "0.25.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ=="], + "@storybook/csf-plugin/unplugin": ["unplugin@1.16.1", "", { "dependencies": { "acorn": "^8.14.0", "webpack-virtual-modules": "^0.6.2" } }, "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w=="], + "@storybook/instrumenter/@vitest/utils": ["@vitest/utils@2.1.9", "", { "dependencies": { "@vitest/pretty-format": "2.1.9", "loupe": "^3.1.2", "tinyrainbow": "^1.2.0" } }, "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ=="], "@storybook/test/@vitest/expect": ["@vitest/expect@2.0.5", "", { "dependencies": { "@vitest/spy": "2.0.5", "@vitest/utils": "2.0.5", "chai": "^5.1.1", "tinyrainbow": "^1.2.0" } }, "sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA=="], @@ -2948,6 +3032,12 @@ "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "@tanstack/router-plugin/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], + + "@tanstack/router-utils/@babel/generator": ["@babel/generator@7.27.5", "", { "dependencies": { "@babel/parser": "^7.27.5", "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw=="], + + "@tanstack/router-utils/@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="], + "@testing-library/dom/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "@testing-library/jest-dom/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="], @@ -2956,6 +3046,18 @@ "@ts-morph/common/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], + "@types/babel__core/@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="], + + "@types/babel__core/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + + "@types/babel__generator/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + + "@types/babel__template/@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="], + + "@types/babel__template/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + + "@types/babel__traverse/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], @@ -3094,7 +3196,11 @@ "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], - "react-router/cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="], + "react-docgen/@babel/core": ["@babel/core@7.27.4", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.27.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.4", "@babel/parser": "^7.27.4", "@babel/template": "^7.27.2", "@babel/traverse": "^7.27.4", "@babel/types": "^7.27.3", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g=="], + + "react-docgen/@babel/traverse": ["@babel/traverse@7.27.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.27.3", "@babel/parser": "^7.27.4", "@babel/template": "^7.27.2", "@babel/types": "^7.27.3", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA=="], + + "react-docgen/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], "react-uid/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], @@ -3248,6 +3354,20 @@ "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + "@babel/helper-module-imports/@babel/traverse/@babel/generator": ["@babel/generator@7.27.5", "", { "dependencies": { "@babel/parser": "^7.27.5", "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw=="], + + "@babel/helper-module-imports/@babel/traverse/@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="], + + "@babel/helper-module-imports/@babel/traverse/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], + + "@babel/helper-module-transforms/@babel/traverse/@babel/generator": ["@babel/generator@7.27.5", "", { "dependencies": { "@babel/parser": "^7.27.5", "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw=="], + + "@babel/helper-module-transforms/@babel/traverse/@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="], + + "@babel/helper-module-transforms/@babel/traverse/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + + "@babel/helper-module-transforms/@babel/traverse/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], + "@chromatic-com/storybook/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], "@cloudflare/vitest-pool-workers/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.17.19", "", { "os": "android", "cpu": "arm" }, "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A=="], @@ -3464,10 +3584,22 @@ "@storybook/core/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g=="], + "@storybook/csf-plugin/unplugin/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + "@storybook/test/@vitest/expect/@vitest/utils": ["@vitest/utils@2.0.5", "", { "dependencies": { "@vitest/pretty-format": "2.0.5", "estree-walker": "^3.0.3", "loupe": "^3.1.1", "tinyrainbow": "^1.2.0" } }, "sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime/tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="], + "@tanstack/router-plugin/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "@tanstack/router-plugin/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + + "@tanstack/router-utils/@babel/generator/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + + "@tanstack/router-utils/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + + "@tanstack/router-utils/@babel/parser/@babel/types": ["@babel/types@7.27.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q=="], + "@testing-library/dom/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "@testing-library/dom/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], @@ -3592,6 +3724,18 @@ "pkgroll/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g=="], + "react-docgen/@babel/core/@babel/generator": ["@babel/generator@7.27.5", "", { "dependencies": { "@babel/parser": "^7.27.5", "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw=="], + + "react-docgen/@babel/core/@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="], + + "react-docgen/@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "react-docgen/@babel/traverse/@babel/generator": ["@babel/generator@7.27.5", "", { "dependencies": { "@babel/parser": "^7.27.5", "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw=="], + + "react-docgen/@babel/traverse/@babel/parser": ["@babel/parser@7.27.5", "", { "dependencies": { "@babel/types": "^7.27.3" }, "bin": "./bin/babel-parser.js" }, "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg=="], + + "react-docgen/@babel/traverse/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], + "send/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], "styled-components/@emotion/is-prop-valid/@emotion/memoize": ["@emotion/memoize@0.8.1", "", {}, "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="], @@ -3756,6 +3900,10 @@ "@atproto/xrpc-server/express/type-is/media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="], + "@babel/helper-module-imports/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + + "@babel/helper-module-transforms/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + "@cloudflare/vitest-pool-workers/wrangler/unenv/ohash": ["ohash@1.1.6", "", {}, "sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg=="], "@cloudflare/vitest-pool-workers/wrangler/workerd/@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20250204.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-HpsgbWEfvdcwuZ8WAZhi1TlSCyyHC3tbghpKsOqGDaQNltyAFAWqa278TPNfcitYf/FmV4961v3eqUE+RFdHNQ=="], @@ -3818,6 +3966,8 @@ "@storybook/test/@vitest/expect/@vitest/utils/estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + "@tanstack/router-plugin/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "@vitest/mocker/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], "@vitest/mocker/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], @@ -3874,6 +4024,10 @@ "biome/chalk/strip-ansi/ansi-regex": ["ansi-regex@2.1.1", "", {}, "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="], + "react-docgen/@babel/core/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + + "react-docgen/@babel/traverse/@babel/generator/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + "vite-node/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], "vite-node/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="],