The recipes.blue monorepo recipes.blue
recipes appview atproto

feat: working on updating the web app now (finally!)

hayden.moe 0efd62d9 7ea96a3e

verified
+6 -4
apps/web/package.json
··· 27 27 "@radix-ui/react-dialog": "^1.1.4", 28 28 "@radix-ui/react-dropdown-menu": "^2.1.4", 29 29 "@radix-ui/react-icons": "^1.3.2", 30 - "@radix-ui/react-label": "^2.1.0", 31 - "@radix-ui/react-separator": "^1.1.0", 32 - "@radix-ui/react-slot": "^1.1.0", 30 + "@radix-ui/react-label": "^2.1.8", 31 + "@radix-ui/react-separator": "^1.1.8", 32 + "@radix-ui/react-slot": "^1.2.4", 33 33 "@radix-ui/react-tooltip": "^1.1.4", 34 34 "@tanstack/react-query": "^5.62.2", 35 35 "@tanstack/react-query-devtools": "^5.62.2", ··· 54 54 "@types/node": "^22.10.1", 55 55 "@types/react": "^19.0.0", 56 56 "@types/react-dom": "^19.0.0", 57 + "@vitejs/plugin-react": "^5.1.1", 57 58 "@vitejs/plugin-react-swc": "^3.5.0", 58 59 "autoprefixer": "^10.4.20", 60 + "babel-plugin-react-compiler": "^1.0.0", 59 61 "cssnano": "^7.0.6", 60 62 "eslint": "^9.15.0", 61 63 "eslint-plugin-react-hooks": "^5.0.0", ··· 66 68 "tailwindcss": "^3.4.16", 67 69 "typescript": "~5.6.2", 68 70 "typescript-eslint": "^8.15.0", 69 - "vite": "^6.0.1" 71 + "vite": "^7.2.4" 70 72 } 71 73 }
+3 -3
apps/web/src/components/query-placeholder.tsx
··· 3 3 import { Skeleton } from './ui/skeleton'; 4 4 import { Alert, AlertDescription, AlertTitle } from './ui/alert'; 5 5 import { AlertCircle } from 'lucide-react'; 6 - import { XRPCError } from '@atcute/client'; 6 + import { isXRPCErrorPayload } from '@atcute/client'; 7 7 8 8 type QueryPlaceholderProps<TData, TError> = PropsWithChildren<{ 9 9 query: UseQueryResult<TData, TError>; ··· 32 32 } else if (query.isError) { 33 33 const { error } = query; 34 34 let errMsg = 'Unknown'; 35 - if (error instanceof XRPCError) { 36 - errMsg = error.kind ?? `HTTP_${error.status}`; 35 + if (isXRPCErrorPayload(error)) { 36 + errMsg = error.message ?? `XRPC_${error.error}`; 37 37 } if (error instanceof Error) { 38 38 errMsg = `${error.message} (${error.name})`; 39 39 }
+242
apps/web/src/components/ui/field.tsx
··· 1 + import { useMemo } from "react" 2 + import { cva, type VariantProps } from "class-variance-authority" 3 + 4 + import { cn } from "@/lib/utils" 5 + import { Label } from "@/components/ui/label" 6 + import { Separator } from "@/components/ui/separator" 7 + 8 + function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) { 9 + return ( 10 + <fieldset 11 + data-slot="field-set" 12 + className={cn( 13 + "flex flex-col gap-6", 14 + "has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3", 15 + className 16 + )} 17 + {...props} 18 + /> 19 + ) 20 + } 21 + 22 + function FieldLegend({ 23 + className, 24 + variant = "legend", 25 + ...props 26 + }: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) { 27 + return ( 28 + <legend 29 + data-slot="field-legend" 30 + data-variant={variant} 31 + className={cn( 32 + "mb-3 font-medium", 33 + "data-[variant=legend]:text-base", 34 + "data-[variant=label]:text-sm", 35 + className 36 + )} 37 + {...props} 38 + /> 39 + ) 40 + } 41 + 42 + function FieldGroup({ className, ...props }: React.ComponentProps<"div">) { 43 + return ( 44 + <div 45 + data-slot="field-group" 46 + className={cn( 47 + "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4", 48 + className 49 + )} 50 + {...props} 51 + /> 52 + ) 53 + } 54 + 55 + const fieldVariants = cva( 56 + "group/field data-[invalid=true]:text-destructive flex w-full gap-3", 57 + { 58 + variants: { 59 + orientation: { 60 + vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"], 61 + horizontal: [ 62 + "flex-row items-center", 63 + "[&>[data-slot=field-label]]:flex-auto", 64 + "has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px has-[>[data-slot=field-content]]:items-start", 65 + ], 66 + responsive: [ 67 + "@md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto flex-col [&>*]:w-full [&>.sr-only]:w-auto", 68 + "@md/field-group:[&>[data-slot=field-label]]:flex-auto", 69 + "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px", 70 + ], 71 + }, 72 + }, 73 + defaultVariants: { 74 + orientation: "vertical", 75 + }, 76 + } 77 + ) 78 + 79 + function Field({ 80 + className, 81 + orientation = "vertical", 82 + ...props 83 + }: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) { 84 + return ( 85 + <div 86 + role="group" 87 + data-slot="field" 88 + data-orientation={orientation} 89 + className={cn(fieldVariants({ orientation }), className)} 90 + {...props} 91 + /> 92 + ) 93 + } 94 + 95 + function FieldContent({ className, ...props }: React.ComponentProps<"div">) { 96 + return ( 97 + <div 98 + data-slot="field-content" 99 + className={cn( 100 + "group/field-content flex flex-1 flex-col gap-1.5 leading-snug", 101 + className 102 + )} 103 + {...props} 104 + /> 105 + ) 106 + } 107 + 108 + function FieldLabel({ 109 + className, 110 + ...props 111 + }: React.ComponentProps<typeof Label>) { 112 + return ( 113 + <Label 114 + data-slot="field-label" 115 + className={cn( 116 + "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50", 117 + "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>[data-slot=field]]:p-4", 118 + "has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10", 119 + className 120 + )} 121 + {...props} 122 + /> 123 + ) 124 + } 125 + 126 + function FieldTitle({ className, ...props }: React.ComponentProps<"div">) { 127 + return ( 128 + <div 129 + data-slot="field-label" 130 + className={cn( 131 + "flex w-fit items-center gap-2 text-sm font-medium leading-snug group-data-[disabled=true]/field:opacity-50", 132 + className 133 + )} 134 + {...props} 135 + /> 136 + ) 137 + } 138 + 139 + function FieldDescription({ className, ...props }: React.ComponentProps<"p">) { 140 + return ( 141 + <p 142 + data-slot="field-description" 143 + className={cn( 144 + "text-muted-foreground text-sm font-normal leading-normal group-has-[[data-orientation=horizontal]]/field:text-balance", 145 + "nth-last-2:-mt-1 last:mt-0 [[data-variant=legend]+&]:-mt-1.5", 146 + "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4", 147 + className 148 + )} 149 + {...props} 150 + /> 151 + ) 152 + } 153 + 154 + function FieldSeparator({ 155 + children, 156 + className, 157 + ...props 158 + }: React.ComponentProps<"div"> & { 159 + children?: React.ReactNode 160 + }) { 161 + return ( 162 + <div 163 + data-slot="field-separator" 164 + data-content={!!children} 165 + className={cn( 166 + "relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2", 167 + className 168 + )} 169 + {...props} 170 + > 171 + <Separator className="absolute inset-0 top-1/2" /> 172 + {children && ( 173 + <span 174 + className="bg-background text-muted-foreground relative mx-auto block w-fit px-2" 175 + data-slot="field-separator-content" 176 + > 177 + {children} 178 + </span> 179 + )} 180 + </div> 181 + ) 182 + } 183 + 184 + function FieldError({ 185 + className, 186 + children, 187 + errors, 188 + ...props 189 + }: React.ComponentProps<"div"> & { 190 + errors?: Array<{ message?: string } | undefined> 191 + }) { 192 + const content = useMemo(() => { 193 + if (children) { 194 + return children 195 + } 196 + 197 + if (!errors) { 198 + return null 199 + } 200 + 201 + if (errors?.length === 1 && errors[0]?.message) { 202 + return errors[0].message 203 + } 204 + 205 + return ( 206 + <ul className="ml-4 flex list-disc flex-col gap-1"> 207 + {errors.map( 208 + (error, index) => 209 + error?.message && <li key={index}>{error.message}</li> 210 + )} 211 + </ul> 212 + ) 213 + }, [children, errors]) 214 + 215 + if (!content) { 216 + return null 217 + } 218 + 219 + return ( 220 + <div 221 + role="alert" 222 + data-slot="field-error" 223 + className={cn("text-destructive text-sm font-normal", className)} 224 + {...props} 225 + > 226 + {content} 227 + </div> 228 + ) 229 + } 230 + 231 + export { 232 + Field, 233 + FieldLabel, 234 + FieldDescription, 235 + FieldError, 236 + FieldGroup, 237 + FieldLegend, 238 + FieldSeparator, 239 + FieldSet, 240 + FieldContent, 241 + FieldTitle, 242 + }
+2
apps/web/src/components/ui/separator.tsx
··· 1 + "use client" 2 + 1 3 import * as React from "react" 2 4 import * as SeparatorPrimitive from "@radix-ui/react-separator" 3 5
+4 -17
apps/web/src/hooks/use-xrpc.tsx
··· 1 - import { SERVER_URL } from "@/lib/utils"; 2 - import { useAuth } from "@/state/auth"; 3 - import { Client, FetchHandler, FetchHandlerObject, ServiceProxyOptions, simpleFetchHandler } from "@atcute/client"; 1 + import { useClient } from "@/state/auth"; 4 2 3 + /** @deprecated Use `useClient` from `state/auth/client` instead. */ 5 4 export function useXrpc() { 6 - const { agent } = useAuth(); 7 - 8 - let handler: FetchHandler | FetchHandlerObject = simpleFetchHandler({ service: `https://${SERVER_URL}` }); 9 - let proxy: ServiceProxyOptions | null = null; 10 - 11 - if (agent) { 12 - handler = agent; 13 - proxy = { 14 - did: `did:web:${SERVER_URL}`, 15 - serviceId: '#recipes_blue', 16 - }; 17 - } 18 - 19 - return new Client({ handler, proxy }); 5 + const client = useClient(); 6 + return client; 20 7 }
+12 -8
apps/web/src/main.tsx
··· 6 6 import { ReactQueryDevtools } from '@tanstack/react-query-devtools' 7 7 import { configureOAuth, defaultIdentityResolver } from '@atcute/oauth-browser-client'; 8 8 import './index.css' 9 - import { AuthProvider, useAuth } from './state/auth'; 10 9 import { ThemeProvider } from './components/theme-provider'; 11 10 import { CompositeDidDocumentResolver, PlcDidDocumentResolver, WebDidDocumentResolver, XrpcHandleResolver } from '@atcute/identity-resolver'; 12 - import { SessionProvider } from './state/auth/session'; 11 + import { SessionProvider, useSession } from './state/auth/session'; 12 + import { ClientProvider, useClient } from './state/auth'; 13 13 14 14 const router = createRouter({ 15 15 routeTree, 16 16 context: { 17 - auth: undefined!, 17 + session: undefined!, 18 + client: undefined!, 18 19 }, 19 20 }); 20 21 ··· 27 28 configureOAuth({ 28 29 metadata: { 29 30 client_id: import.meta.env.VITE_OAUTH_CLIENT_ID, 30 - redirect_uri: import.meta.env.VITE_OAUTH_REDIRECT_URL, 31 + redirect_uri: import.meta.env.VITE_OAUTH_REDIRECT_URI, 31 32 }, 32 33 identityResolver: defaultIdentityResolver({ 33 34 handleResolver: new XrpcHandleResolver({ serviceUrl: 'https://slingshot.microcosm.blue' }), ··· 51 52 }); 52 53 53 54 const InnerApp = () => { 54 - const auth = useAuth(); 55 - return <RouterProvider router={router} context={{ auth }} /> 55 + const session = useSession(); 56 + const client = useClient(); 57 + return <RouterProvider router={router} context={{ session, client }} /> 56 58 }; 57 59 58 60 createRoot(document.getElementById('root')!).render( 59 61 <StrictMode> 60 62 <SessionProvider> 61 - <ThemeProvider defaultTheme="dark" storageKey="recipes-theme"> 63 + <ClientProvider> 64 + <ThemeProvider defaultTheme="dark" storageKey="recipes-theme"> 62 65 <QueryClientProvider client={queryClient}> 63 66 <InnerApp /> 64 67 <ReactQueryDevtools initialIsOpen={false} /> 65 68 </QueryClientProvider> 66 - </ThemeProvider> 69 + </ThemeProvider> 70 + </ClientProvider> 67 71 </SessionProvider> 68 72 </StrictMode>, 69 73 )
+3 -3
apps/web/src/queries/recipe.ts
··· 5 5 import { notFound } from "@tanstack/react-router"; 6 6 import { UseFormReturn } from "react-hook-form"; 7 7 import { TID } from '@atproto/common-web'; 8 - import { recipeSchema } from "@/forms/recipe"; 9 8 import { z } from "zod"; 10 9 import { ActorIdentifier, Did } from "@atcute/lexicons"; 11 10 12 11 import type {} from '@atcute/atproto'; 13 12 import type {} from '@cookware/lexicons'; 13 + import { useClient } from "../state/auth/client"; 14 14 15 15 const RQKEY_ROOT = 'posts'; 16 16 export const RQKEY = (cursor: string, did: string, rkey: string) => [RQKEY_ROOT, cursor, did, rkey]; 17 17 18 18 export const useRecipesQuery = (cursor: string, did?: Did) => { 19 - const rpc = useXrpc(); 19 + const client = useClient(); 20 20 return useQuery({ 21 21 queryKey: RQKEY(cursor, did ?? '', ''), 22 22 queryFn: async () => { 23 - const res = await rpc.get('blue.recipes.feed.getRecipes', { 23 + const res = await client.get('blue.recipes.feed.getRecipes', { 24 24 params: { cursor, did }, 25 25 }); 26 26 return res.data;
+48 -46
apps/web/src/routes/_.(auth)/login.tsx
··· 13 13 CardHeader, 14 14 CardTitle, 15 15 } from '@/components/ui/card' 16 + import { Field, FieldError, FieldGroup, FieldLabel } from '@/components/ui/field' 16 17 import { Input } from '@/components/ui/input' 17 18 import { Label } from '@/components/ui/label' 18 19 import { Separator } from '@/components/ui/separator' 19 20 import { SidebarTrigger } from '@/components/ui/sidebar' 20 - import { sleep } from '@/lib/utils' 21 21 import { useSession } from '@/state/auth/session' 22 - import { isHandle } from '@atcute/lexicons/syntax' 23 - import { createAuthorizationUrl } from '@atcute/oauth-browser-client' 24 22 import { useMutation } from '@tanstack/react-query' 25 23 import { createFileRoute } from '@tanstack/react-router' 26 24 import { useState } from 'react' ··· 57 55 </div> 58 56 </header> 59 57 <div className="flex flex-1 flex-col items-center justify-center gap-4 p-4 pt-0"> 60 - <Card className="max-w-sm w-full"> 61 - <CardHeader> 62 - <CardTitle>Log in</CardTitle> 63 - <CardDescription> 64 - Enter your handle below to sign in to your account. 65 - </CardDescription> 66 - </CardHeader> 67 - <CardContent> 68 - <div className="flex flex-col gap-2"> 69 - <Label htmlFor="handle">Handle</Label> 70 - <Input 71 - className={`${error ? 'border-destructive text-destructive' : ''}`} 72 - type="text" 73 - id="handle" 74 - name="handle" 75 - placeholder="johndoe.bsky.social" 76 - required 77 - value={handle} 78 - onChange={(e) => setHandle(e.currentTarget.value)} 79 - /> 80 - {error && ( 81 - <p className="text-sm font-medium text-destructive"> 82 - {error.message} 83 - </p> 84 - )} 85 - </div> 86 - </CardContent> 87 - <CardFooter className="grid gap-2"> 88 - <Button onClick={() => mutate()} disabled={isPending}> 89 - Log in 90 - </Button> 91 - <p className="text-sm text-muted-foreground text-center"> 92 - Don't have an account?{' '} 93 - <a 94 - className="font-bold text-primary" 95 - href="https://bsky.app/" 96 - target="_blank" 97 - > 98 - Sign up on Bluesky! 99 - </a> 100 - </p> 101 - </CardFooter> 102 - </Card> 58 + <form onSubmit={e => { 59 + e.preventDefault(); 60 + mutate(); 61 + }}> 62 + <Card className="max-w-sm w-full"> 63 + <CardHeader> 64 + <CardTitle>Log in</CardTitle> 65 + <CardDescription> 66 + Enter your Atmosphere handle below to sign in to your account. 67 + </CardDescription> 68 + </CardHeader> 69 + <CardContent> 70 + <FieldGroup> 71 + <Field data-invalid={error ? true : false}> 72 + <FieldLabel htmlFor="handle">Handle</FieldLabel> 73 + <Input 74 + id="handle" 75 + placeholder="johndoe.bsky.social" 76 + required 77 + autoComplete="username" 78 + aria-invalid={error ? 'true' : 'false'} 79 + tabIndex={0} 80 + autoFocus 81 + value={handle} 82 + onChange={(e) => setHandle(e.currentTarget.value)} 83 + /> 84 + {error && <FieldError>{error.message}</FieldError>} 85 + </Field> 86 + </FieldGroup> 87 + </CardContent> 88 + <CardFooter className="grid gap-2"> 89 + <Button type="submit" disabled={isPending}> 90 + Log in 91 + </Button> 92 + <p className="text-sm text-muted-foreground text-center"> 93 + Don't have an account?{' '} 94 + <a 95 + className="font-bold text-primary" 96 + href="https://bsky.app/" 97 + target="_blank" 98 + > 99 + Sign up on Bluesky! 100 + </a> 101 + </p> 102 + </CardFooter> 103 + </Card> 104 + </form> 103 105 </div> 104 106 </> 105 107 )
+3 -2
apps/web/src/routes/__root.tsx
··· 3 3 SidebarInset, 4 4 SidebarProvider, 5 5 } from '@/components/ui/sidebar' 6 - import { AuthContextType } from '@/state/auth'; 6 + import { ClientContext, SessionContext } from '@/state/auth'; 7 7 import { Outlet, createRootRouteWithContext } from '@tanstack/react-router' 8 8 9 9 type RootContext = { 10 - auth: AuthContextType; 10 + session: SessionContext; 11 + client: ClientContext['client']; 11 12 }; 12 13 13 14 export const Route = createRootRouteWithContext<RootContext>()({
-83
apps/web/src/state/auth.tsx
··· 1 - import { Did } from "@atcute/lexicons"; 2 - import { finalizeAuthorization, getSession, OAuthUserAgent, Session } from "@atcute/oauth-browser-client"; 3 - import { createContext, PropsWithChildren, useContext, useEffect, useState } from "react"; 4 - 5 - export type AuthContextType = { 6 - isLoggedIn: boolean; 7 - hasProfile: boolean; 8 - agent?: OAuthUserAgent; 9 - logOut: () => Promise<void>; 10 - }; 11 - 12 - const AuthContext = createContext<AuthContextType>({ 13 - isLoggedIn: false, 14 - hasProfile: false, 15 - logOut: async () => {}, 16 - }); 17 - 18 - export const AuthProvider = ({ children }: PropsWithChildren) => { 19 - const [isReady, setIsReady] = useState(false); 20 - const [isLoggedIn, setIsLoggedIn] = useState(false); 21 - const [hasProfile, setHasProfile] = useState(false); 22 - const [agent, setAgent] = useState<OAuthUserAgent | undefined>(undefined); 23 - 24 - useEffect(() => { 25 - const init = async () => { 26 - const params = new URLSearchParams(location.hash.slice(1)); 27 - let session: Session | null = null; 28 - 29 - if (params.has("state") && (params.has("code") || params.has("error"))) { 30 - history.replaceState(null, "", location.pathname + location.search); 31 - 32 - const session = await finalizeAuthorization(params); 33 - const did = session.info.sub; 34 - 35 - localStorage.setItem("lastSignedIn", did); 36 - } else { 37 - const lastSignedIn = localStorage.getItem("lastSignedIn"); 38 - 39 - if (lastSignedIn) { 40 - try { 41 - return await getSession(lastSignedIn as Did); 42 - } catch (err) { 43 - localStorage.removeItem("lastSignedIn"); 44 - throw err; 45 - } 46 - } 47 - } 48 - 49 - setAgent(new OAuthUserAgent(session!)); 50 - }; 51 - 52 - init() 53 - .then(session => { 54 - if (session) { 55 - setAgent(new OAuthUserAgent(session)); 56 - setIsLoggedIn(true); 57 - } 58 - 59 - setIsReady(true) 60 - }) 61 - .catch(() => {}); 62 - }, []); 63 - 64 - if (!isReady) return null; 65 - 66 - return ( 67 - <AuthContext.Provider value={{ 68 - isLoggedIn, 69 - hasProfile, 70 - agent, 71 - logOut: async () => { 72 - await agent?.signOut(); 73 - setIsLoggedIn(false); 74 - }, 75 - }}> 76 - {children} 77 - </AuthContext.Provider> 78 - ); 79 - }; 80 - 81 - export const useAuth = () => { 82 - return useContext(AuthContext); 83 - };
+38
apps/web/src/state/auth/client.tsx
··· 1 + import { Client, simpleFetchHandler } from "@atcute/client"; 2 + import { createContext, PropsWithChildren, useContext, useEffect, useState } from "react"; 3 + import { useSession } from "./session"; 4 + 5 + export type ClientContext = { 6 + client: Client; 7 + }; 8 + 9 + const clientContext = createContext<ClientContext>({ 10 + client: new Client({ handler: simpleFetchHandler({ service: import.meta.env.VITE_API_SERVICE }) }), 11 + }); 12 + 13 + export const ClientProvider = ({ children }: PropsWithChildren) => { 14 + const { agent } = useSession(); 15 + const [client, setClient] = useState<Client>( 16 + () => new Client({ handler: simpleFetchHandler({ service: import.meta.env.VITE_API_SERVICE }) }) 17 + ); 18 + 19 + useEffect(() => { 20 + setClient(new Client({ 21 + handler: agent ?? simpleFetchHandler({ service: import.meta.env.VITE_API_SERVICE }), 22 + proxy: { 23 + did: 'did:web:localhost', 24 + serviceId: '#api_service' 25 + }, 26 + })); 27 + }, [agent]); 28 + 29 + return ( 30 + <clientContext.Provider value={{ client: client }}> 31 + {children} 32 + </clientContext.Provider> 33 + ); 34 + } 35 + 36 + export const useClient = () => { 37 + return useContext(clientContext).client; 38 + }
+19 -2
apps/web/src/state/auth/session.tsx
··· 1 - import { Did, isActorIdentifier, isHandle } from "@atcute/lexicons/syntax"; 1 + import { isDid, isActorIdentifier } from "@atcute/lexicons/syntax"; 2 2 import { createAuthorizationUrl, deleteStoredSession, finalizeAuthorization, getSession, OAuthUserAgent, Session } from "@atcute/oauth-browser-client"; 3 - import { SessionState } from "node:http2"; 4 3 import { createContext, PropsWithChildren, useContext, useEffect, useState } from "react"; 5 4 6 5 export type SessionContext = { 7 6 session: null | Session; 7 + agent: null | OAuthUserAgent; 8 8 isLoading: boolean; 9 9 isLoggedIn: boolean; 10 10 signIn: (handle: string) => Promise<void>; ··· 13 13 14 14 const sessionContext = createContext<SessionContext>({ 15 15 session: null, 16 + agent: null, 16 17 isLoading: false, 17 18 isLoggedIn: false, 18 19 signIn: async () => { ··· 23 24 }, 24 25 }); 25 26 27 + const LS_LAST_SIGNED_IN = "recipes:last-signed-in"; 28 + 26 29 export const SessionProvider = ({ children }: PropsWithChildren<{}>) => { 27 30 const [initialized, setInitialized] = useState(false); 28 31 const [loading, setLoading] = useState(true); ··· 38 41 if (params.has("state") && params.has("iss") && params.has("code")) { 39 42 // If there is an active auth attempt: 40 43 history.replaceState(null, "", location.pathname + location.search); 44 + console.log("finalizing authorization..."); 41 45 finalizeAuthorization(params) 42 46 .then(val => { 43 47 setSession(val.session); ··· 51 55 setInitialized(true); 52 56 }); 53 57 } else { 58 + const lastSignedIn = localStorage.getItem(LS_LAST_SIGNED_IN); 59 + if (lastSignedIn && isDid(lastSignedIn)) { 60 + getSession(lastSignedIn, { allowStale: true }) 61 + .then((session) => { 62 + setSession(session); 63 + setAgent(new OAuthUserAgent(session)); 64 + }) 65 + .catch(err => { 66 + console.error("Failed to initialize session:", err); 67 + }) 68 + } 69 + 54 70 setLoading(false); 55 71 setInitialized(true); 56 72 } ··· 89 105 isLoading: loading, 90 106 isLoggedIn: session !== null, 91 107 session, 108 + agent, 92 109 signIn, 93 110 signOut, 94 111 }}>
+1 -1
apps/web/src/vite-env.d.ts
··· 5 5 readonly VITE_DEV_SERVER_PORT?: string; 6 6 readonly VITE_CLIENT_URI: string; 7 7 readonly VITE_OAUTH_CLIENT_ID: string; 8 - readonly VITE_OAUTH_REDIRECT_URL: string; 8 + readonly VITE_OAUTH_REDIRECT_URI: string; 9 9 readonly VITE_OAUTH_SCOPE: string; 10 10 } 11 11
+3 -2
apps/web/vite.config.ts
··· 1 1 import { defineConfig } from 'vite' 2 - import react from '@vitejs/plugin-react-swc' 2 + import react from '@vitejs/plugin-react' 3 3 import { tanstackRouter } from '@tanstack/router-plugin/vite' 4 4 import path from 'path' 5 5 import metadata from "./public/oauth-client-metadata.json" with { type: 'json' }; ··· 11 11 export default defineConfig({ 12 12 plugins: [ 13 13 tanstackRouter(), 14 - react(), 14 + react({ babel: { plugins: ['babel-plugin-react-compiler'] } }), 15 15 { 16 16 name: '_config', 17 17 config(_conf, { command }) { ··· 29 29 `?redirect_uri=${encodeURIComponent(redirectUri)}` + 30 30 `&scope=${encodeURIComponent(metadata.scope)}`; 31 31 32 + process.env.VITE_API_SERVICE = 'http://localhost:3000'; 32 33 process.env.VITE_DEV_SERVER_PORT = '' + SERVER_PORT; 33 34 process.env.VITE_OAUTH_CLIENT_ID = clientId; 34 35 process.env.VITE_OAUTH_REDIRECT_URI = redirectUri;
+28 -156
bun.lock
··· 76 76 "@radix-ui/react-dialog": "^1.1.4", 77 77 "@radix-ui/react-dropdown-menu": "^2.1.4", 78 78 "@radix-ui/react-icons": "^1.3.2", 79 - "@radix-ui/react-label": "^2.1.0", 80 - "@radix-ui/react-separator": "^1.1.0", 81 - "@radix-ui/react-slot": "^1.1.0", 79 + "@radix-ui/react-label": "^2.1.8", 80 + "@radix-ui/react-separator": "^1.1.8", 81 + "@radix-ui/react-slot": "^1.2.4", 82 82 "@radix-ui/react-tooltip": "^1.1.4", 83 83 "@tanstack/react-query": "^5.62.2", 84 84 "@tanstack/react-query-devtools": "^5.62.2", ··· 103 103 "@types/node": "^22.10.1", 104 104 "@types/react": "^19.0.0", 105 105 "@types/react-dom": "^19.0.0", 106 + "@vitejs/plugin-react": "^5.1.1", 106 107 "@vitejs/plugin-react-swc": "^3.5.0", 107 108 "autoprefixer": "^10.4.20", 109 + "babel-plugin-react-compiler": "^1.0.0", 108 110 "cssnano": "^7.0.6", 109 111 "eslint": "^9.15.0", 110 112 "eslint-plugin-react-hooks": "^5.0.0", ··· 115 117 "tailwindcss": "^3.4.16", 116 118 "typescript": "~5.6.2", 117 119 "typescript-eslint": "^8.15.0", 118 - "vite": "^6.0.1", 120 + "vite": "^7.2.4", 119 121 }, 120 122 }, 121 123 "libs/database": { ··· 294 296 "@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=="], 295 297 296 298 "@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=="], 299 + 300 + "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="], 301 + 302 + "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="], 297 303 298 304 "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@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-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="], 299 305 ··· 673 679 674 680 "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], 675 681 676 - "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="], 682 + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.47", "", {}, "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw=="], 677 683 678 684 "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.53.3", "", { "os": "android", "cpu": "arm" }, "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w=="], 679 685 ··· 791 797 792 798 "@typelex/emitter": ["@typelex/emitter@0.4.0", "", { "dependencies": { "@typespec/compiler": "^1.4.0" } }, "sha512-BaKny+8TA0yX5jZibkAodHHKLJ6l6xVe5ut7KeoUyTD63lSSuB9OXe8tWXrs2DbeR/hialCimHFZQ3xANleMow=="], 793 799 800 + "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], 801 + 802 + "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], 803 + 804 + "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], 805 + 806 + "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], 807 + 794 808 "@types/bun": ["@types/bun@1.3.3", "", { "dependencies": { "bun-types": "1.3.3" } }, "sha512-ogrKbJ2X5N0kWLLFKeytG0eHDleBYtngtlbu9cyBKFtNL3cnpDZkNdQj8flVf6WTZUX5ulI9AY1oa7ljhSrp+g=="], 795 809 796 810 "@types/connect": ["@types/connect@3.4.36", "", { "dependencies": { "@types/node": "*" } }, "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w=="], ··· 839 853 840 854 "@typespec/compiler": ["@typespec/compiler@1.6.0", "", { "dependencies": { "@babel/code-frame": "~7.27.1", "@inquirer/prompts": "^7.4.0", "ajv": "~8.17.1", "change-case": "~5.4.4", "env-paths": "^3.0.0", "globby": "~15.0.0", "is-unicode-supported": "^2.1.0", "mustache": "~4.2.0", "picocolors": "~1.1.1", "prettier": "~3.6.2", "semver": "^7.7.1", "tar": "^7.5.2", "temporal-polyfill": "^0.3.0", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.12", "yaml": "~2.8.0", "yargs": "~18.0.0" }, "bin": { "tsp": "cmd/tsp.js", "tsp-server": "cmd/tsp-server.js" } }, "sha512-yxyV+ch8tnqiuU2gClv/mQEESoFwpkjo6177UkYfV0nVA9PzTg4zVVc7+WIMZk04wiLRRT3H1uc11FB1cwLY3g=="], 841 855 856 + "@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.1", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.47", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-WQfkSw0QbQ5aJ2CHYw23ZGkqnRwqKHD/KYsMeTkZzPT4Jcf0DcBxBtwMJxnu6E7oxw5+JC6ZAiePgh28uJ1HBA=="], 857 + 842 858 "@vitejs/plugin-react-swc": ["@vitejs/plugin-react-swc@3.11.0", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-beta.27", "@swc/core": "^1.12.11" }, "peerDependencies": { "vite": "^4 || ^5 || ^6 || ^7" } }, "sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w=="], 843 859 844 860 "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], ··· 878 894 "axios": ["axios@1.13.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA=="], 879 895 880 896 "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=="], 897 + 898 + "babel-plugin-react-compiler": ["babel-plugin-react-compiler@1.0.0", "", { "dependencies": { "@babel/types": "^7.26.0" } }, "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw=="], 881 899 882 900 "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], 883 901 ··· 1439 1457 1440 1458 "react-hook-form": ["react-hook-form@7.66.1", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-2KnjpgG2Rhbi+CIiIBQQ9Df6sMGH5ExNyFl4Hw9qO7pIqMBR8Bvu9RQyjl3JM4vehzCh9soiNUM/xYMswb2EiA=="], 1441 1459 1460 + "react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="], 1461 + 1442 1462 "react-remove-scroll": ["react-remove-scroll@2.7.1", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA=="], 1443 1463 1444 1464 "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], ··· 1609 1629 1610 1630 "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], 1611 1631 1612 - "vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="], 1632 + "vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="], 1613 1633 1614 1634 "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], 1615 1635 ··· 1751 1771 1752 1772 "@radix-ui/react-visually-hidden/@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], 1753 1773 1754 - "@tanstack/react-router-devtools/vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="], 1755 - 1756 - "@tanstack/router-devtools/vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="], 1757 - 1758 - "@tanstack/router-devtools-core/vite": ["vite@7.2.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w=="], 1759 - 1760 1774 "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], 1761 1775 1762 1776 "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], 1777 + 1778 + "@vitejs/plugin-react-swc/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="], 1763 1779 1764 1780 "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 1765 1781 ··· 1898 1914 "@radix-ui/react-roving-focus/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], 1899 1915 1900 1916 "@radix-ui/react-visually-hidden/@radix-ui/react-primitive/@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], 1901 - 1902 - "@tanstack/react-router-devtools/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], 1903 - 1904 - "@tanstack/router-devtools-core/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], 1905 - 1906 - "@tanstack/router-devtools/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], 1907 1917 1908 1918 "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], 1909 1919 ··· 2020 2030 "@inquirer/core/wrap-ansi/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], 2021 2031 2022 2032 "@inquirer/core/wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], 2023 - 2024 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], 2025 - 2026 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], 2027 - 2028 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], 2029 - 2030 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], 2031 - 2032 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], 2033 - 2034 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], 2035 - 2036 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], 2037 - 2038 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], 2039 - 2040 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], 2041 - 2042 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], 2043 - 2044 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], 2045 - 2046 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], 2047 - 2048 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], 2049 - 2050 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], 2051 - 2052 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], 2053 - 2054 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], 2055 - 2056 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], 2057 - 2058 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], 2059 - 2060 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], 2061 - 2062 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], 2063 - 2064 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], 2065 - 2066 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], 2067 - 2068 - "@tanstack/react-router-devtools/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], 2069 - 2070 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], 2071 - 2072 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], 2073 - 2074 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], 2075 - 2076 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], 2077 - 2078 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], 2079 - 2080 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], 2081 - 2082 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], 2083 - 2084 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], 2085 - 2086 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], 2087 - 2088 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], 2089 - 2090 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], 2091 - 2092 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], 2093 - 2094 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], 2095 - 2096 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], 2097 - 2098 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], 2099 - 2100 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], 2101 - 2102 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], 2103 - 2104 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], 2105 - 2106 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], 2107 - 2108 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], 2109 - 2110 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], 2111 - 2112 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], 2113 - 2114 - "@tanstack/router-devtools-core/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], 2115 - 2116 - "@tanstack/router-devtools/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], 2117 - 2118 - "@tanstack/router-devtools/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], 2119 - 2120 - "@tanstack/router-devtools/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], 2121 - 2122 - "@tanstack/router-devtools/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], 2123 - 2124 - "@tanstack/router-devtools/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], 2125 - 2126 - "@tanstack/router-devtools/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], 2127 - 2128 - "@tanstack/router-devtools/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], 2129 - 2130 - "@tanstack/router-devtools/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], 2131 - 2132 - "@tanstack/router-devtools/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], 2133 - 2134 - "@tanstack/router-devtools/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], 2135 - 2136 - "@tanstack/router-devtools/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], 2137 - 2138 - "@tanstack/router-devtools/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], 2139 - 2140 - "@tanstack/router-devtools/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], 2141 - 2142 - "@tanstack/router-devtools/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], 2143 - 2144 - "@tanstack/router-devtools/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], 2145 - 2146 - "@tanstack/router-devtools/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], 2147 - 2148 - "@tanstack/router-devtools/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], 2149 - 2150 - "@tanstack/router-devtools/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], 2151 - 2152 - "@tanstack/router-devtools/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], 2153 - 2154 - "@tanstack/router-devtools/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], 2155 - 2156 - "@tanstack/router-devtools/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], 2157 - 2158 - "@tanstack/router-devtools/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], 2159 - 2160 - "@tanstack/router-devtools/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], 2161 2033 } 2162 2034 }