Openstatus www.openstatus.dev

Feat/incidents (#174)

* fix: transform slug to lowercase

* fix: build

* wip: incidents

* fix: build

* wip: incidents

* ๐Ÿ› page slug can't be empty (#169)

* ๐Ÿ› page slug can't be empty

* ๐Ÿ˜ pr checked

* update: className to absolute from fixed (#170)

* ๐Ÿ’Œ store user email (#167)

* ๐Ÿ’Œ store user email

* ๐Ÿš€ add photo url

* upd: use `import type` (#172)

* fix: pattern not repeating & screen overflow due to mouse effect (#171)

* update: className to absolute from fixed

* fix: overflow & background repetition

* fix: empty-screen

* update: removed not required z-index class

* wip: incidents db security

* fix: merge

* fix constraint

* improvment

* improvment

* improvment

* ๐Ÿš€ ready to push

* wip: incidents

* feat: add status-badge

* wip: incidents

---------

Co-authored-by: Thibault Le Ouay <thibaultleouay@gmail.Com>
Co-authored-by: Kartik Khorwal <88406357+kartikk-k@users.noreply.github.com>
Co-authored-by: #FF6000 <75097898+ff6k@users.noreply.github.com>

+2799 -1388
+4
apps/web/package.json
··· 27 27 "@radix-ui/react-hover-card": "1.0.6", 28 28 "@radix-ui/react-label": "2.0.2", 29 29 "@radix-ui/react-popover": "1.0.6", 30 + "@radix-ui/react-radio-group": "^1.1.3", 30 31 "@radix-ui/react-select": "1.2.2", 31 32 "@radix-ui/react-separator": "1.0.3", 32 33 "@radix-ui/react-slot": "1.0.2", 33 34 "@radix-ui/react-switch": "1.0.3", 35 + "@radix-ui/react-tabs": "^1.0.4", 34 36 "@radix-ui/react-toast": "1.1.4", 35 37 "@radix-ui/react-tooltip": "1.0.6", 36 38 "@t3-oss/env-nextjs": "0.4.1", ··· 49 51 "contentlayer": "0.3.4", 50 52 "date-fns": "2.30.0", 51 53 "lucide-react": "0.244.0", 54 + "luxon": "^3.3.0", 52 55 "micro": "10.0.1", 53 56 "nanoid": "4.0.2", 54 57 "next": "13.4.12", ··· 72 75 }, 73 76 "devDependencies": { 74 77 "@openstatus/eslint-config": "workspace:*", 78 + "@types/luxon": "^3.3.1", 75 79 "@types/node": "20.3.1", 76 80 "@types/react": "18.2.12", 77 81 "@types/react-dom": "18.2.5",
+101
apps/web/src/app/app/(dashboard)/[workspaceSlug]/incidents/_components/action-button.tsx
··· 1 + "use client"; 2 + 3 + import * as React from "react"; 4 + import Link from "next/link"; 5 + import { useRouter } from "next/navigation"; 6 + import { MoreVertical } from "lucide-react"; 7 + import type * as z from "zod"; 8 + 9 + import { 10 + insertIncidentSchema, 11 + // insertIncidentUpdateSchema, 12 + insertMonitorSchema, 13 + } from "@openstatus/db/src/schema"; 14 + 15 + import { LoadingAnimation } from "@/components/loading-animation"; 16 + import { 17 + AlertDialog, 18 + AlertDialogAction, 19 + AlertDialogCancel, 20 + AlertDialogContent, 21 + AlertDialogDescription, 22 + AlertDialogFooter, 23 + AlertDialogHeader, 24 + AlertDialogTitle, 25 + AlertDialogTrigger, 26 + } from "@/components/ui/alert-dialog"; 27 + import { Button } from "@/components/ui/button"; 28 + import { 29 + DropdownMenu, 30 + DropdownMenuContent, 31 + DropdownMenuItem, 32 + DropdownMenuTrigger, 33 + } from "@/components/ui/dropdown-menu"; 34 + import { api } from "@/trpc/client"; 35 + 36 + const temporary = insertIncidentSchema.pick({ id: true, workspaceSlug: true }); 37 + 38 + type Schema = z.infer<typeof temporary>; 39 + 40 + export function ActionButton(props: Schema) { 41 + const router = useRouter(); 42 + const [alertOpen, setAlertOpen] = React.useState(false); 43 + const [isPending, startTransition] = React.useTransition(); 44 + 45 + async function deleteIncident() { 46 + startTransition(async () => { 47 + if (!props.id) return; 48 + await api.incident.deleteIncident.mutate({ id: props.id }); 49 + router.refresh(); 50 + setAlertOpen(false); 51 + }); 52 + } 53 + 54 + return ( 55 + <AlertDialog open={alertOpen} onOpenChange={(value) => setAlertOpen(value)}> 56 + <DropdownMenu> 57 + <DropdownMenuTrigger asChild> 58 + <Button 59 + variant="ghost" 60 + className="data-[state=open]:bg-accent h-8 w-8 p-0" 61 + > 62 + <span className="sr-only">Open menu</span> 63 + <MoreVertical className="h-4 w-4" /> 64 + </Button> 65 + </DropdownMenuTrigger> 66 + <DropdownMenuContent align="end"> 67 + <Link href={`./incidents/edit?id=${props.id}`}> 68 + <DropdownMenuItem>Edit</DropdownMenuItem> 69 + </Link> 70 + <AlertDialogTrigger asChild> 71 + <DropdownMenuItem className="text-destructive focus:bg-destructive focus:text-background"> 72 + Delete 73 + </DropdownMenuItem> 74 + </AlertDialogTrigger> 75 + </DropdownMenuContent> 76 + </DropdownMenu> 77 + <AlertDialogContent> 78 + <AlertDialogHeader> 79 + <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle> 80 + <AlertDialogDescription> 81 + This action cannot be undone. This will permanently delete the 82 + incident. 83 + </AlertDialogDescription> 84 + </AlertDialogHeader> 85 + <AlertDialogFooter> 86 + <AlertDialogCancel>Cancel</AlertDialogCancel> 87 + <AlertDialogAction 88 + onClick={(e) => { 89 + e.preventDefault(); 90 + deleteIncident(); 91 + }} 92 + disabled={isPending} 93 + className="bg-destructive text-destructive-foreground hover:bg-destructive/90" 94 + > 95 + {!isPending ? "Delete" : <LoadingAnimation />} 96 + </AlertDialogAction> 97 + </AlertDialogFooter> 98 + </AlertDialogContent> 99 + </AlertDialog> 100 + ); 101 + }
+70
apps/web/src/app/app/(dashboard)/[workspaceSlug]/incidents/_components/delete-incident-update.tsx
··· 1 + "use client"; 2 + 3 + import * as React from "react"; 4 + import { useRouter } from "next/navigation"; 5 + 6 + import { Icons } from "@/components/icons"; 7 + import { LoadingAnimation } from "@/components/loading-animation"; 8 + import { 9 + AlertDialog, 10 + AlertDialogAction, 11 + AlertDialogCancel, 12 + AlertDialogContent, 13 + AlertDialogDescription, 14 + AlertDialogFooter, 15 + AlertDialogHeader, 16 + AlertDialogTitle, 17 + AlertDialogTrigger, 18 + } from "@/components/ui/alert-dialog"; 19 + import { Button } from "@/components/ui/button"; 20 + import { api } from "@/trpc/client"; 21 + 22 + export function DeleteIncidentUpdateButtonIcon({ id }: { id: number }) { 23 + const router = useRouter(); 24 + const [alertOpen, setAlertOpen] = React.useState(false); 25 + const [isPending, startTransition] = React.useTransition(); 26 + 27 + async function onDelete() { 28 + startTransition(async () => { 29 + await api.incident.deleteIncidentUpdate.mutate({ id }); 30 + router.refresh(); 31 + setAlertOpen(false); 32 + }); 33 + } 34 + 35 + return ( 36 + <AlertDialog open={alertOpen} onOpenChange={(value) => setAlertOpen(value)}> 37 + <AlertDialogTrigger asChild> 38 + <Button 39 + size="icon" 40 + variant="outline" 41 + className="border-destructive/50 text-destructive/80 hover:text-destructive hover:bg-destructive/10 h-7 w-7 p-0" 42 + > 43 + <Icons.trash className="h-4 w-4" /> 44 + </Button> 45 + </AlertDialogTrigger> 46 + <AlertDialogContent> 47 + <AlertDialogHeader> 48 + <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle> 49 + <AlertDialogDescription> 50 + This action cannot be undone. This will permanently delete the 51 + monitor. 52 + </AlertDialogDescription> 53 + </AlertDialogHeader> 54 + <AlertDialogFooter> 55 + <AlertDialogCancel>Cancel</AlertDialogCancel> 56 + <AlertDialogAction 57 + onClick={(e) => { 58 + e.preventDefault(); 59 + onDelete(); 60 + }} 61 + disabled={isPending} 62 + className="bg-destructive text-destructive-foreground hover:bg-destructive/90" 63 + > 64 + {!isPending ? "Delete" : <LoadingAnimation />} 65 + </AlertDialogAction> 66 + </AlertDialogFooter> 67 + </AlertDialogContent> 68 + </AlertDialog> 69 + ); 70 + }
+19
apps/web/src/app/app/(dashboard)/[workspaceSlug]/incidents/_components/empty-state.tsx
··· 1 + import Link from "next/link"; 2 + 3 + import { EmptyState as DefaultEmptyState } from "@/components/dashboard/empty-state"; 4 + import { Button } from "@/components/ui/button"; 5 + 6 + export function EmptyState() { 7 + return ( 8 + <DefaultEmptyState 9 + icon="siren" 10 + title="No incidents" 11 + description="Create your first incident" 12 + action={ 13 + <Button asChild> 14 + <Link href="./incidents/edit">Create</Link> 15 + </Button> 16 + } 17 + /> 18 + ); 19 + }
+18
apps/web/src/app/app/(dashboard)/[workspaceSlug]/incidents/edit/loading.tsx
··· 1 + import { Header } from "@/components/dashboard/header"; 2 + import { SkeletonForm } from "@/components/forms/skeleton-form"; 3 + import { Skeleton } from "@/components/ui/skeleton"; 4 + 5 + export default function Loading() { 6 + return ( 7 + <div className="grid gap-6 md:grid-cols-2 md:gap-8"> 8 + <div className="col-span-full flex w-full justify-between"> 9 + <Header.Skeleton> 10 + <Skeleton className="h-9 w-20" /> 11 + </Header.Skeleton> 12 + </div> 13 + <div className="col-span-full"> 14 + <SkeletonForm /> 15 + </div> 16 + </div> 17 + ); 18 + }
+62
apps/web/src/app/app/(dashboard)/[workspaceSlug]/incidents/edit/page.tsx
··· 1 + import { notFound } from "next/navigation"; 2 + import * as z from "zod"; 3 + 4 + import { Header } from "@/components/dashboard/header"; 5 + import { IncidentForm } from "@/components/forms/incident-form"; 6 + import { api } from "@/trpc/server"; 7 + 8 + /** 9 + * allowed URL search params 10 + */ 11 + const searchParamsSchema = z.object({ 12 + id: z.coerce.number().optional(), 13 + }); 14 + 15 + export default async function EditPage({ 16 + params, 17 + searchParams, 18 + }: { 19 + params: { workspaceSlug: string }; 20 + searchParams: { [key: string]: string | string[] | undefined }; 21 + }) { 22 + const search = searchParamsSchema.safeParse(searchParams); 23 + 24 + if (!search.success) { 25 + return notFound(); 26 + } 27 + 28 + const { id } = search.data; 29 + 30 + const incident = id 31 + ? await api.incident.getIncidentById.query({ 32 + id, 33 + }) 34 + : undefined; 35 + 36 + const monitors = await api.monitor.getMonitorsByWorkspace.query({ 37 + workspaceSlug: params.workspaceSlug, 38 + }); 39 + 40 + return ( 41 + <div className="grid gap-6 md:grid-cols-2 md:gap-8"> 42 + <Header title="Incident" description="Upsert your incident." /> 43 + <div className="col-span-full"> 44 + <IncidentForm 45 + workspaceSlug={params.workspaceSlug} 46 + monitors={monitors} 47 + defaultValues={ 48 + incident 49 + ? { 50 + ...incident, 51 + workspaceSlug: params.workspaceSlug, 52 + monitors: incident?.monitorsToIncidents.map( 53 + ({ monitorId }) => monitorId, 54 + ), 55 + } 56 + : undefined 57 + } 58 + /> 59 + </div> 60 + </div> 61 + ); 62 + }
+17
apps/web/src/app/app/(dashboard)/[workspaceSlug]/incidents/loading.tsx
··· 1 + import { Header } from "@/components/dashboard/header"; 2 + import { Skeleton } from "@/components/ui/skeleton"; 3 + 4 + export default function Loading() { 5 + return ( 6 + <div className="grid gap-6 md:grid-cols-1 md:gap-8"> 7 + <div className="col-span-full flex w-full justify-between"> 8 + <Header.Skeleton> 9 + <Skeleton className="h-9 w-20" /> 10 + </Header.Skeleton> 11 + </div> 12 + <Skeleton className="h-4 w-24" /> 13 + <Skeleton className="h-48 w-full" /> 14 + <Skeleton className="h-48 w-full" /> 15 + </div> 16 + ); 17 + }
+85 -2
apps/web/src/app/app/(dashboard)/[workspaceSlug]/incidents/page.tsx
··· 1 1 import * as React from "react"; 2 + import Link from "next/link"; 3 + import { formatDistance } from "date-fns"; 2 4 3 5 import { Container } from "@/components/dashboard/container"; 4 6 import { Header } from "@/components/dashboard/header"; 7 + import { Icons } from "@/components/icons"; 8 + import { AffectedMonitors } from "@/components/incidents/affected-monitors"; 9 + import { Events } from "@/components/incidents/events"; 10 + import { StatusBadge } from "@/components/incidents/status-badge"; 11 + import { Badge } from "@/components/ui/badge"; 12 + import { Button } from "@/components/ui/button"; 13 + import { statusDict } from "@/data/incidents-dictionary"; 14 + import { cn } from "@/lib/utils"; 5 15 import { api } from "@/trpc/server"; 16 + import { ActionButton } from "./_components/action-button"; 17 + import { EmptyState } from "./_components/empty-state"; 6 18 7 19 export default async function IncidentPage({ 8 20 params, ··· 13 25 workspaceSlug: params.workspaceSlug, 14 26 }); 15 27 return ( 16 - <div className="grid gap-6 md:grid-cols-2 md:gap-8"> 17 - <Header title="Incidents" description="Overview of all your incidents." /> 28 + <div className="grid gap-6 md:grid-cols-1 md:gap-8"> 29 + <Header title="Incidents" description="Overview of all your incidents."> 30 + <Button asChild> 31 + <Link href="./incidents/edit">Create</Link> 32 + </Button> 33 + </Header> 34 + {Boolean(incidents?.length) ? ( 35 + <div className="col-span-full grid sm:grid-cols-6"> 36 + <ul role="list" className="grid gap-4 sm:col-span-6"> 37 + {incidents?.map((incident, i) => { 38 + const { label, icon } = 39 + statusDict[incident.status as keyof typeof statusDict]; 40 + const Icon = Icons[icon]; 41 + return ( 42 + <li key={i} className="grid gap-2"> 43 + <time className="text-muted-foreground pl-3 text-xs"> 44 + {formatDistance(new Date(incident.createdAt!), new Date(), { 45 + addSuffix: true, 46 + })} 47 + </time> 48 + <Container 49 + title={ 50 + <> 51 + {incident.title} 52 + <StatusBadge status={incident.status} /> 53 + </> 54 + } 55 + actions={[ 56 + <Button key="status-button" variant="outline" size="sm"> 57 + <Link 58 + href={`./incidents/update/edit?incidentId=${incident.id}`} 59 + > 60 + New Update 61 + </Link> 62 + </Button>, 63 + <ActionButton 64 + key="action-button" 65 + id={incident.id} 66 + workspaceSlug={params.workspaceSlug} 67 + />, 68 + ]} 69 + > 70 + <div className="grid gap-4"> 71 + <div> 72 + <p className="text-muted-foreground mb-1.5 text-xs"> 73 + Affected Monitors 74 + </p> 75 + <AffectedMonitors 76 + monitors={incident.monitorsToIncidents.map( 77 + ({ monitor }) => monitor, 78 + )} 79 + /> 80 + </div> 81 + <div> 82 + <p className="text-muted-foreground mb-1.5 text-xs"> 83 + Last Updates 84 + </p> 85 + {/* Make it ordered by desc and make it toggable if you want the whole history! */} 86 + <Events 87 + incidentUpdates={incident.incidentUpdates} 88 + editable 89 + /> 90 + </div> 91 + </div> 92 + </Container> 93 + </li> 94 + ); 95 + })} 96 + </ul> 97 + </div> 98 + ) : ( 99 + <EmptyState /> 100 + )} 18 101 </div> 19 102 ); 20 103 }
+18
apps/web/src/app/app/(dashboard)/[workspaceSlug]/incidents/update/edit/loading.tsx
··· 1 + import { Header } from "@/components/dashboard/header"; 2 + import { SkeletonForm } from "@/components/forms/skeleton-form"; 3 + import { Skeleton } from "@/components/ui/skeleton"; 4 + 5 + export default function Loading() { 6 + return ( 7 + <div className="grid gap-6 md:grid-cols-2 md:gap-8"> 8 + <div className="col-span-full flex w-full justify-between"> 9 + <Header.Skeleton> 10 + <Skeleton className="h-9 w-20" /> 11 + </Header.Skeleton> 12 + </div> 13 + <div className="col-span-full"> 14 + <SkeletonForm /> 15 + </div> 16 + </div> 17 + ); 18 + }
+59
apps/web/src/app/app/(dashboard)/[workspaceSlug]/incidents/update/edit/page.tsx
··· 1 + import { notFound } from "next/navigation"; 2 + import * as z from "zod"; 3 + 4 + import { Header } from "@/components/dashboard/header"; 5 + import { IncidentUpdateForm } from "@/components/forms/incident-update-form"; 6 + import { api } from "@/trpc/server"; 7 + 8 + /** 9 + * allowed URL search params 10 + */ 11 + const searchParamsSchema = z.object({ 12 + id: z.coerce.number().optional(), 13 + incidentId: z.coerce.number(), 14 + }); 15 + 16 + export default async function EditPage({ 17 + params, 18 + searchParams, 19 + }: { 20 + params: { workspaceSlug: string }; 21 + searchParams: { [key: string]: string | string[] | undefined }; 22 + }) { 23 + const search = searchParamsSchema.safeParse(searchParams); 24 + 25 + if (!search.success) { 26 + return notFound(); 27 + } 28 + 29 + const { id, incidentId } = search.data; 30 + 31 + const incidentUpdate = id 32 + ? await api.incident.getIncidentUpdateById.query({ 33 + id, 34 + }) 35 + : undefined; 36 + 37 + return ( 38 + <div className="grid gap-6 md:grid-cols-2 md:gap-8"> 39 + <Header 40 + title="Incident Update" 41 + description="Upsert your incident update." 42 + /> 43 + <div className="col-span-full"> 44 + <IncidentUpdateForm 45 + workspaceSlug={params.workspaceSlug} 46 + incidentId={incidentId} 47 + defaultValues={ 48 + incidentUpdate 49 + ? { 50 + workspaceSlug: params.workspaceSlug, 51 + ...incidentUpdate, 52 + } 53 + : undefined 54 + } 55 + /> 56 + </div> 57 + </div> 58 + ); 59 + }
+1 -1
apps/web/src/app/app/(dashboard)/[workspaceSlug]/monitors/_components/action-button.tsx
··· 51 51 <DropdownMenuTrigger asChild> 52 52 <Button 53 53 variant="ghost" 54 - className="data-[state=open]:bg-accent absolute right-6 top-6 h-8 w-8 p-0" 54 + className="data-[state=open]:bg-accent h-8 w-8 p-0" 55 55 > 56 56 <span className="sr-only">Open menu</span> 57 57 <MoreVertical className="h-4 w-4" />
+3 -1
apps/web/src/app/app/(dashboard)/[workspaceSlug]/monitors/page.tsx
··· 39 39 key={index} 40 40 title={monitor.name} 41 41 description={monitor.description} 42 + actions={ 43 + <ActionButton {...monitor} workspaceSlug={params.workspaceSlug} /> 44 + } 42 45 > 43 - <ActionButton {...monitor} workspaceSlug={params.workspaceSlug} /> 44 46 <dl className="[&_dt]:text-muted-foreground grid gap-2 [&>*]:text-sm [&_dt]:font-light"> 45 47 <div className="flex min-w-0 items-center justify-between gap-3"> 46 48 <dt>Status</dt>
+1 -1
apps/web/src/app/app/(dashboard)/[workspaceSlug]/status-pages/_components/action-button.tsx
··· 55 55 <DropdownMenuTrigger asChild> 56 56 <Button 57 57 variant="ghost" 58 - className="data-[state=open]:bg-accent absolute right-6 top-6 h-8 w-8 p-0" 58 + className="data-[state=open]:bg-accent h-8 w-8 p-0" 59 59 > 60 60 <span className="sr-only">Open menu</span> 61 61 <MoreVertical className="h-4 w-4" />
+11 -7
apps/web/src/app/app/(dashboard)/[workspaceSlug]/status-pages/page.tsx
··· 49 49 key={index} 50 50 title={page.title} 51 51 description={page.description} 52 + actions={ 53 + <ActionButton 54 + page={{ 55 + ...page, 56 + workspaceSlug: params.workspaceSlug, 57 + monitors: page.monitorsToPages.map( 58 + ({ monitor }) => monitor.id, 59 + ), 60 + }} 61 + /> 62 + } 52 63 > 53 - <ActionButton 54 - page={{ 55 - ...page, 56 - workspaceSlug: params.workspaceSlug, 57 - monitors: page.monitorsToPages.map(({ monitor }) => monitor.id), 58 - }} 59 - /> 60 64 <dl className="[&_dt]:text-muted-foreground grid gap-2 [&>*]:text-sm [&_dt]:font-light"> 61 65 <div className="flex min-w-0 items-center justify-between gap-3"> 62 66 <dt>Slug</dt>
+3
apps/web/src/app/status-page/[domain]/loading.tsx
··· 11 11 <Container.Skeleton /> 12 12 <Container.Skeleton /> 13 13 </div> 14 + <div className="grid gap-4"> 15 + <Container.Skeleton /> 16 + </div> 14 17 </div> 15 18 </Shell> 16 19 );
+3
apps/web/src/app/status-page/[domain]/page.tsx
··· 3 3 4 4 import { Header } from "@/components/dashboard/header"; 5 5 import { Shell } from "@/components/dashboard/shell"; 6 + import { IncidentList } from "@/components/status-page/incident-list"; 6 7 import { MonitorList } from "@/components/status-page/monitor-list"; 7 8 import { api } from "@/trpc/server"; 8 9 ··· 27 28 description={page.description} 28 29 className="mx-auto max-w-lg lg:mx-auto" 29 30 /> 31 + {/* Think of having a tab to switch between monitors and incidents? */} 30 32 <MonitorList monitors={page.monitors} /> 33 + <IncidentList incidents={page.incidents} monitors={page.monitors} /> 31 34 </div> 32 35 </Shell> 33 36 );
+21 -8
apps/web/src/components/dashboard/container.tsx
··· 9 9 import { cn } from "@/lib/utils"; 10 10 import { Skeleton } from "../ui/skeleton"; 11 11 12 - interface CardProps extends React.HTMLAttributes<HTMLDivElement> { 13 - title: string; 12 + interface CardProps 13 + extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> { 14 + title: React.ReactNode; 14 15 description?: string; 16 + actions?: React.ReactNode | React.ReactNode[]; 15 17 } 16 18 17 - function Container({ title, description, className, children }: CardProps) { 19 + function Container({ 20 + title, 21 + description, 22 + actions, 23 + className, 24 + children, 25 + }: CardProps) { 18 26 return ( 19 27 <Card 20 28 className={cn("border-border/50 relative w-full shadow-none", className)} 21 29 > 22 - <CardHeader className="mr-12"> 23 - <CardTitle className="text-lg font-medium tracking-normal"> 24 - {title} 25 - </CardTitle> 26 - {description ? <CardDescription>{description}</CardDescription> : null} 30 + <CardHeader className="flex flex-row items-start justify-between gap-4 space-y-0"> 31 + <div className="space-y-1.5"> 32 + <CardTitle className="text-lg font-medium tracking-normal"> 33 + {title} 34 + </CardTitle> 35 + {description ? ( 36 + <CardDescription>{description}</CardDescription> 37 + ) : null} 38 + </div> 39 + {actions ? <div className="flex gap-2">{actions}</div> : null} 27 40 </CardHeader> 28 41 {/* potentially `asChild` */} 29 42 <CardContent>{children}</CardContent>
+279
apps/web/src/components/forms/incident-form.tsx
··· 1 + // move into @/components/forms/ later 2 + "use client"; 3 + 4 + import * as React from "react"; 5 + import { useRouter } from "next/navigation"; 6 + import { zodResolver } from "@hookform/resolvers/zod"; 7 + import { useForm } from "react-hook-form"; 8 + import * as z from "zod"; 9 + 10 + import type { allMonitorsSchema } from "@openstatus/db/src/schema"; 11 + import { 12 + availableStatus, 13 + insertIncidentSchema, 14 + StatusEnum, 15 + } from "@openstatus/db/src/schema"; 16 + 17 + import { Icons } from "@/components/icons"; 18 + import { LoadingAnimation } from "@/components/loading-animation"; 19 + import { Button } from "@/components/ui/button"; 20 + import { Checkbox } from "@/components/ui/checkbox"; 21 + import { DateTimePicker } from "@/components/ui/date-time-picker"; 22 + import { 23 + Form, 24 + FormControl, 25 + FormDescription, 26 + FormField, 27 + FormItem, 28 + FormLabel, 29 + FormMessage, 30 + } from "@/components/ui/form"; 31 + import { Input } from "@/components/ui/input"; 32 + import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; 33 + import { Textarea } from "@/components/ui/textarea"; 34 + import { useToast } from "@/components/ui/use-toast"; 35 + import { statusDict } from "@/data/incidents-dictionary"; 36 + import { api } from "@/trpc/client"; 37 + 38 + // include update on creation 39 + const insertSchema = insertIncidentSchema.extend({ 40 + message: z.string().optional(), 41 + date: z.date().optional().default(new Date()), 42 + }); 43 + 44 + type IncidentProps = z.infer<typeof insertSchema>; 45 + type MonitorsProps = z.infer<typeof allMonitorsSchema>; 46 + 47 + interface Props { 48 + defaultValues?: IncidentProps; 49 + monitors?: MonitorsProps; 50 + workspaceSlug: string; 51 + } 52 + 53 + export function IncidentForm({ 54 + defaultValues, 55 + monitors, 56 + workspaceSlug, 57 + }: Props) { 58 + const form = useForm<IncidentProps>({ 59 + resolver: zodResolver(insertSchema), 60 + defaultValues: { 61 + id: defaultValues?.id || 0, 62 + title: defaultValues?.title || "", 63 + status: defaultValues?.status || "investigating", 64 + monitors: defaultValues?.monitors || [], 65 + workspaceSlug, 66 + // include update on creation 67 + message: "", 68 + date: defaultValues?.date || new Date(), 69 + }, 70 + }); 71 + const router = useRouter(); 72 + const [isPending, startTransition] = React.useTransition(); 73 + const { toast } = useToast(); 74 + 75 + const onSubmit = ({ ...props }: IncidentProps) => { 76 + startTransition(async () => { 77 + try { 78 + if (defaultValues) { 79 + await api.incident.updateIncident.mutate({ ...props }); 80 + } else { 81 + // or use createIncident to create automaticaaly an IncidentUpdate? 82 + const { message, date, status, workspaceSlug, ...rest } = props; 83 + const incident = await api.incident.createIncident.mutate({ 84 + workspaceSlug, 85 + status, 86 + ...rest, 87 + }); 88 + // include update on creation 89 + if (incident?.id) { 90 + await api.incident.createIncidentUpdate.mutate({ 91 + message, 92 + date, 93 + status, 94 + workspaceSlug, 95 + incidentId: incident.id, 96 + }); 97 + } 98 + } 99 + router.push("./"); 100 + router.refresh(); 101 + } catch { 102 + toast({ 103 + title: "Something went wrong.", 104 + description: "Please try again.", 105 + }); 106 + } 107 + }); 108 + }; 109 + return ( 110 + <Form {...form}> 111 + <form 112 + onSubmit={async (e) => { 113 + e.preventDefault(); 114 + form.handleSubmit(onSubmit)(e); 115 + }} 116 + className="grid w-full grid-cols-1 items-center gap-6 sm:grid-cols-6" 117 + > 118 + <FormField 119 + control={form.control} 120 + name="title" 121 + render={({ field }) => ( 122 + <FormItem className="sm:col-span-4"> 123 + <FormLabel>Title</FormLabel> 124 + <FormControl> 125 + <Input placeholder="" {...field} /> 126 + </FormControl> 127 + <FormDescription>The title of your page.</FormDescription> 128 + <FormMessage /> 129 + </FormItem> 130 + )} 131 + /> 132 + <FormField 133 + control={form.control} 134 + name="status" 135 + render={({ field }) => ( 136 + <FormItem className="col-span-full space-y-1"> 137 + <FormLabel>Status</FormLabel> 138 + <FormDescription>Select the current status.</FormDescription> 139 + <FormMessage /> 140 + <RadioGroup 141 + onValueChange={(value) => 142 + field.onChange(StatusEnum.parse(value)) 143 + } // value is a string 144 + defaultValue={field.value} 145 + className="grid grid-cols-2 gap-4 sm:grid-cols-4 sm:gap-8" 146 + > 147 + {availableStatus.map((status) => { 148 + const { value, label, icon } = statusDict[status]; 149 + const Icon = Icons[icon]; 150 + return ( 151 + <FormItem key={value}> 152 + <FormLabel className="[&:has([data-state=checked])>div]:border-primary [&:has([data-state=checked])>div]:text-foreground"> 153 + <FormControl> 154 + <RadioGroupItem value={value} className="sr-only" /> 155 + </FormControl> 156 + <div className="border-border text-muted-foreground flex w-full items-center justify-center rounded-lg border p-2 px-6 py-3 text-center"> 157 + <Icon className="mr-2 h-4 w-4" /> 158 + {label} 159 + </div> 160 + </FormLabel> 161 + </FormItem> 162 + ); 163 + })} 164 + </RadioGroup> 165 + </FormItem> 166 + )} 167 + /> 168 + {/* include update on creation */} 169 + {!defaultValues ? ( 170 + <div className="bg-accent/40 border-border col-span-full -m-3 grid gap-6 rounded-lg border p-3 sm:grid-cols-6"> 171 + <FormField 172 + control={form.control} 173 + name="message" // TODO: support markdown and add a `Tabs` switch between "Write" and "Preview" 174 + render={({ field }) => ( 175 + <FormItem className="sm:col-span-4"> 176 + <FormLabel>Message</FormLabel> 177 + <FormControl> 178 + <Textarea 179 + placeholder="We are encountering..." 180 + className="w-full resize-none" 181 + rows={7} 182 + {...field} 183 + /> 184 + </FormControl> 185 + <FormDescription> 186 + Tell your user what&apos;s happening. 187 + </FormDescription> 188 + <FormMessage /> 189 + </FormItem> 190 + )} 191 + /> 192 + <FormField 193 + control={form.control} 194 + name="date" 195 + render={({ field }) => ( 196 + <FormItem className="flex flex-col sm:col-span-full"> 197 + <FormLabel>Date</FormLabel> 198 + <DateTimePicker 199 + date={field.value ? new Date(field.value) : new Date()} 200 + setDate={(date) => { 201 + field.onChange(date); 202 + }} 203 + /> 204 + <FormDescription> 205 + The date and time when the incident took place. 206 + </FormDescription> 207 + <FormMessage /> 208 + </FormItem> 209 + )} 210 + /> 211 + </div> 212 + ) : null} 213 + <FormField 214 + control={form.control} 215 + name="monitors" 216 + render={() => ( 217 + <FormItem className="sm:col-span-full"> 218 + <div className="mb-4"> 219 + <FormLabel>Monitors</FormLabel> 220 + <FormDescription> 221 + Select the monitors that you want to refer the incident to. 222 + </FormDescription> 223 + </div> 224 + <div className="grid grid-cols-2 gap-4 sm:grid-cols-4"> 225 + {monitors?.map((item) => ( 226 + <FormField 227 + key={item.id} 228 + control={form.control} 229 + name="monitors" 230 + render={({ field }) => { 231 + return ( 232 + <FormItem 233 + key={item.id} 234 + className="flex flex-row items-start space-x-3 space-y-0" 235 + > 236 + <FormControl> 237 + <Checkbox 238 + checked={field.value?.includes(item.id)} 239 + onCheckedChange={(checked) => { 240 + return checked 241 + ? field.onChange([ 242 + ...(field.value || []), 243 + item.id, 244 + ]) 245 + : field.onChange( 246 + field.value?.filter( 247 + (value) => value !== item.id, 248 + ), 249 + ); 250 + }} 251 + /> 252 + </FormControl> 253 + <div className="grid gap-1.5 leading-none"> 254 + <FormLabel className="font-normal"> 255 + {item.name} 256 + </FormLabel> 257 + <p className="text-muted-foreground truncate text-sm"> 258 + {item.description} 259 + </p> 260 + </div> 261 + </FormItem> 262 + ); 263 + }} 264 + /> 265 + ))} 266 + </div> 267 + <FormMessage /> 268 + </FormItem> 269 + )} 270 + /> 271 + <div className="sm:col-span-full"> 272 + <Button className="w-full sm:w-auto"> 273 + {!isPending ? "Confirm" : <LoadingAnimation />} 274 + </Button> 275 + </div> 276 + </form> 277 + </Form> 278 + ); 279 + }
+177
apps/web/src/components/forms/incident-update-form.tsx
··· 1 + // move into @/components/forms/ later 2 + "use client"; 3 + 4 + import * as React from "react"; 5 + import { useRouter } from "next/navigation"; 6 + import { zodResolver } from "@hookform/resolvers/zod"; 7 + import { useForm } from "react-hook-form"; 8 + import type * as z from "zod"; 9 + 10 + import { 11 + availableStatus, 12 + insertIncidentUpdateSchema, 13 + StatusEnum, 14 + } from "@openstatus/db/src/schema"; 15 + 16 + import { Icons } from "@/components/icons"; 17 + import { LoadingAnimation } from "@/components/loading-animation"; 18 + import { Button } from "@/components/ui/button"; 19 + import { DateTimePicker } from "@/components/ui/date-time-picker"; 20 + import { 21 + Form, 22 + FormControl, 23 + FormDescription, 24 + FormField, 25 + FormItem, 26 + FormLabel, 27 + FormMessage, 28 + } from "@/components/ui/form"; 29 + import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; 30 + import { Textarea } from "@/components/ui/textarea"; 31 + import { useToast } from "@/components/ui/use-toast"; 32 + import { statusDict } from "@/data/incidents-dictionary"; 33 + import { api } from "@/trpc/client"; 34 + 35 + // TODO: for UX, using the form inside of a Dialog feels more suitable 36 + 37 + type IncidentUpdateProps = z.infer<typeof insertIncidentUpdateSchema>; 38 + 39 + interface Props { 40 + defaultValues?: IncidentUpdateProps; 41 + workspaceSlug: string; 42 + incidentId: number; 43 + } 44 + 45 + export function IncidentUpdateForm({ 46 + defaultValues, 47 + workspaceSlug, 48 + incidentId, 49 + }: Props) { 50 + const form = useForm<IncidentUpdateProps>({ 51 + resolver: zodResolver(insertIncidentUpdateSchema), 52 + defaultValues: { 53 + id: defaultValues?.id || 0, 54 + status: defaultValues?.status || "investigating", 55 + message: defaultValues?.message || "", 56 + date: defaultValues?.date || new Date(), 57 + incidentId, 58 + workspaceSlug, 59 + }, 60 + }); 61 + const router = useRouter(); 62 + const [isPending, startTransition] = React.useTransition(); 63 + const { toast } = useToast(); 64 + 65 + const onSubmit = ({ ...props }: IncidentUpdateProps) => { 66 + startTransition(async () => { 67 + try { 68 + if (defaultValues) { 69 + await api.incident.updateIncidentUpdate.mutate({ ...props }); 70 + } else { 71 + await api.incident.createIncidentUpdate.mutate({ ...props }); 72 + } 73 + router.push("../"); 74 + router.refresh(); 75 + } catch { 76 + toast({ 77 + title: "Something went wrong.", 78 + description: "Please try again.", 79 + }); 80 + } 81 + }); 82 + }; 83 + 84 + return ( 85 + <Form {...form}> 86 + <form 87 + onSubmit={async (e) => { 88 + e.preventDefault(); 89 + form.handleSubmit(onSubmit)(e); 90 + }} 91 + className="grid w-full grid-cols-1 items-center gap-6 sm:grid-cols-6" 92 + > 93 + <FormField 94 + control={form.control} 95 + name="status" 96 + render={({ field }) => ( 97 + <FormItem className="col-span-full space-y-1"> 98 + <FormLabel>Status</FormLabel> 99 + <FormDescription>Select the current status.</FormDescription> 100 + <FormMessage /> 101 + <RadioGroup 102 + onValueChange={(value) => 103 + field.onChange(StatusEnum.parse(value)) 104 + } // value is a string 105 + defaultValue={field.value} 106 + className="grid grid-cols-2 gap-4 sm:grid-cols-4 sm:gap-8" 107 + > 108 + {availableStatus.map((status) => { 109 + const { value, label, icon } = statusDict[status]; 110 + const Icon = Icons[icon]; 111 + return ( 112 + <FormItem key={value}> 113 + <FormLabel className="[&:has([data-state=checked])>div]:border-primary [&:has([data-state=checked])>div]:text-foreground"> 114 + <FormControl> 115 + <RadioGroupItem value={value} className="sr-only" /> 116 + </FormControl> 117 + <div className="border-border text-muted-foreground flex w-full items-center justify-center rounded-lg border p-2 px-6 py-3 text-center"> 118 + <Icon className="mr-2 h-4 w-4" /> 119 + {label} 120 + </div> 121 + </FormLabel> 122 + </FormItem> 123 + ); 124 + })} 125 + </RadioGroup> 126 + </FormItem> 127 + )} 128 + /> 129 + <FormField 130 + control={form.control} 131 + name="message" // TODO: support markdown and add a `Tabs` switch between "Write" and "Preview" 132 + render={({ field }) => ( 133 + <FormItem className="sm:col-span-4"> 134 + <FormLabel>Message</FormLabel> 135 + <FormControl> 136 + <Textarea 137 + placeholder="We are encountering..." 138 + className="w-full resize-none" 139 + rows={7} 140 + {...field} 141 + /> 142 + </FormControl> 143 + <FormDescription> 144 + Tell your user what&apos;s happening. 145 + </FormDescription> 146 + <FormMessage /> 147 + </FormItem> 148 + )} 149 + /> 150 + <FormField 151 + control={form.control} 152 + name="date" 153 + render={({ field }) => ( 154 + <FormItem className="flex flex-col sm:col-span-full"> 155 + <FormLabel>Date</FormLabel> 156 + <DateTimePicker 157 + date={new Date(field.value)} 158 + setDate={(date) => { 159 + field.onChange(date); 160 + }} 161 + /> 162 + <FormDescription> 163 + The date and time when the incident took place. 164 + </FormDescription> 165 + <FormMessage /> 166 + </FormItem> 167 + )} 168 + /> 169 + <div className="sm:col-span-full"> 170 + <Button className="w-full sm:w-auto"> 171 + {!isPending ? "Confirm" : <LoadingAnimation />} 172 + </Button> 173 + </div> 174 + </form> 175 + </Form> 176 + ); 177 + }
+16
apps/web/src/components/icons.tsx
··· 1 1 import { 2 2 Activity, 3 + Calendar, 4 + Fingerprint, 3 5 LayoutDashboard, 4 6 Link, 7 + MessageCircle, 5 8 PanelTop, 9 + Pencil, 10 + Search, 11 + SearchCheck, 6 12 Siren, 7 13 Table, 14 + Tag, 8 15 ToyBrick, 16 + Trash, 9 17 } from "lucide-react"; 10 18 import type { Icon as LucideIcon, LucideProps } from "lucide-react"; 11 19 ··· 20 28 "panel-top": PanelTop, 21 29 table: Table, 22 30 "toy-brick": ToyBrick, 31 + search: Search, 32 + "search-check": SearchCheck, 33 + fingerprint: Fingerprint, 34 + pencil: Pencil, 35 + "message-circle": MessageCircle, 36 + calendar: Calendar, 37 + tag: Tag, 38 + trash: Trash, 23 39 discord: ({ ...props }: LucideProps) => ( 24 40 <svg viewBox="0 0 640 512" {...props}> 25 41 <path
+25
apps/web/src/components/incidents/affected-monitors.tsx
··· 1 + import type * as z from "zod"; 2 + 3 + import type { selectMonitorSchema } from "@openstatus/db/src/schema"; 4 + 5 + export function AffectedMonitors({ 6 + monitors, 7 + }: { 8 + monitors: z.infer<typeof selectMonitorSchema>[]; 9 + }) { 10 + return ( 11 + <ul role="list"> 12 + {monitors.length > 0 ? ( 13 + monitors.map(({ name, url }, i) => ( 14 + <li key={i} className="text-xs"> 15 + <span className="text-sm font-medium">{name}</span> 16 + <span className="text-muted-foreground/70 mx-1">&bull;</span> 17 + <span className="text-muted-foreground font-mono">{url}</span> 18 + </li> 19 + )) 20 + ) : ( 21 + <li className="text-muted-foreground text-sm">Monitor(s) missing</li> 22 + )} 23 + </ul> 24 + ); 25 + }
+95
apps/web/src/components/incidents/events.tsx
··· 1 + "use client"; 2 + 3 + import * as React from "react"; 4 + import { useRouter } from "next/navigation"; 5 + import { format } from "date-fns"; 6 + import type * as z from "zod"; 7 + 8 + import type { selectIncidentUpdateSchema } from "@openstatus/db/src/schema"; 9 + 10 + import { Icons } from "@/components/icons"; 11 + import { Badge } from "@/components/ui/badge"; 12 + import { Button } from "@/components/ui/button"; 13 + import { statusDict } from "@/data/incidents-dictionary"; 14 + import { cn } from "@/lib/utils"; 15 + import { DeleteIncidentUpdateButtonIcon } from "../../app/app/(dashboard)/[workspaceSlug]/incidents/_components/delete-incident-update"; 16 + 17 + type IncidentUpdateProps = z.infer<typeof selectIncidentUpdateSchema>; 18 + 19 + export function Events({ 20 + incidentUpdates, 21 + editable = false, 22 + }: { 23 + incidentUpdates: IncidentUpdateProps[]; 24 + editable?: boolean; 25 + }) { 26 + const [open, toggle] = React.useReducer((open) => !open, false); 27 + const router = useRouter(); 28 + 29 + // TODO: make it simpler.. 30 + const sortedArray = incidentUpdates.sort((a, b) => { 31 + const orderA = statusDict[a.status].order; 32 + const orderB = statusDict[b.status].order; 33 + return orderB - orderA; 34 + }); 35 + const slicedArray = open 36 + ? sortedArray 37 + : sortedArray.length > 0 38 + ? [sortedArray[0]] 39 + : []; 40 + // 41 + 42 + return ( 43 + <div className="grid gap-3"> 44 + {slicedArray?.map((update, i) => { 45 + const { icon, label } = statusDict[update.status]; 46 + const StatusIcon = Icons[icon]; 47 + return ( 48 + <div 49 + key={update.id} 50 + className={cn( 51 + "group relative -m-2 grid gap-2 border border-transparent p-2", 52 + editable && 53 + "hover:bg-accent/40 hover:border-border hover:rounded-lg", 54 + )} 55 + > 56 + {editable ? ( 57 + <div className="absolute right-2 top-2 hidden gap-2 group-hover:flex group-active:flex"> 58 + <Button 59 + size="icon" 60 + variant="outline" 61 + className="h-7 w-7 p-0" 62 + onClick={() => { 63 + router.push( 64 + `./incidents/update/edit?incidentId=${update.incidentId}&id=${update.id}`, 65 + ); 66 + }} 67 + > 68 + <Icons.pencil className="h-4 w-4" /> 69 + </Button> 70 + <DeleteIncidentUpdateButtonIcon id={update.id} /> 71 + </div> 72 + ) : undefined} 73 + <div className="text-muted-foreground flex items-center text-xs font-light"> 74 + {format(new Date(update.date), "LLL dd, y HH:mm")} 75 + <span className="text-muted-foreground/70 mx-1">&bull;</span> 76 + <Badge variant="secondary"> 77 + <StatusIcon className="mr-1 h-3 w-3" /> 78 + {label} 79 + </Badge> 80 + </div> 81 + <p className="max-w-3xl text-sm">{update.message}</p> 82 + </div> 83 + ); 84 + })} 85 + 86 + {incidentUpdates.length > 1 ? ( 87 + <div className="text-center"> 88 + <Button variant="ghost" onClick={toggle}> 89 + {open ? "Close all" : "All updates"} 90 + </Button> 91 + </div> 92 + ) : null} 93 + </div> 94 + ); 95 + }
+24
apps/web/src/components/incidents/status-badge.tsx
··· 1 + import { statusDict } from "@/data/incidents-dictionary"; 2 + import { cn } from "@/lib/utils"; 3 + import { Icons } from "../icons"; 4 + import { Badge } from "../ui/badge"; 5 + 6 + export function StatusBadge({ status }: { status: keyof typeof statusDict }) { 7 + const { label, icon } = statusDict[status]; 8 + const Icon = Icons[icon]; 9 + return ( 10 + <Badge 11 + variant="outline" 12 + className={cn("ml-2 font-normal", { 13 + "border-red-600/20 bg-red-50 text-red-600": status === "investigating", 14 + "border-yellow-600/20 bg-yellow-50 text-yellow-600": 15 + status === "identified", 16 + "border-blue-600/20 bg-blue-50 text-blue-600": status === "monitoring", 17 + "border-green-600/20 bg-green-50 text-green-600": status === "resolved", 18 + })} 19 + > 20 + <Icon className="mr-1 h-3 w-3" /> 21 + {label} 22 + </Badge> 23 + ); 24 + }
+73
apps/web/src/components/status-page/incident-list.tsx
··· 1 + import type { z } from "zod"; 2 + 3 + import type { 4 + selectIncidentsPageSchema, 5 + selectMonitorSchema, 6 + } from "@openstatus/db/src/schema"; 7 + 8 + import { notEmpty } from "@/lib/utils"; 9 + import { AffectedMonitors } from "../incidents/affected-monitors"; 10 + import { Events } from "../incidents/events"; 11 + import { StatusBadge } from "../incidents/status-badge"; 12 + 13 + // TODO: change layout - it is too packed with data rn 14 + 15 + export const IncidentList = ({ 16 + incidents, 17 + monitors, 18 + }: { 19 + incidents: z.infer<typeof selectIncidentsPageSchema>; 20 + monitors: z.infer<typeof selectMonitorSchema>[]; 21 + }) => { 22 + // TBD 23 + // const currentIncidents = incidents.filter( 24 + // ({ status }) => status !== "resolved", 25 + // ); 26 + 27 + return ( 28 + <> 29 + {incidents?.length > 0 ? ( 30 + <div className="grid gap-4"> 31 + <h2 className="text-muted-foreground text-lg font-light"> 32 + All Incidents 33 + </h2> 34 + {incidents.map((incident) => { 35 + return ( 36 + <div key={incident.id} className="grid gap-4 text-left"> 37 + <div className="max-w-3xl font-semibold"> 38 + {incident.title} 39 + <StatusBadge status={incident.status} /> 40 + </div> 41 + <div> 42 + <p className="text-muted-foreground mb-1 text-xs"> 43 + Affected Monitors 44 + </p> 45 + <AffectedMonitors 46 + monitors={incident.monitorsToIncidents 47 + .map(({ monitorId }) => { 48 + const monitor = monitors.find( 49 + ({ id }) => monitorId === id, 50 + ); 51 + return monitor || undefined; 52 + }) 53 + .filter(notEmpty)} 54 + /> 55 + </div> 56 + <div> 57 + <p className="text-muted-foreground mb-1 text-xs"> 58 + Latest Updates 59 + </p> 60 + <Events incidentUpdates={incident.incidentUpdates} /> 61 + </div> 62 + </div> 63 + ); 64 + })} 65 + </div> 66 + ) : ( 67 + <h2 className="text-muted-foreground text-lg font-light"> 68 + No Incidents 69 + </h2> 70 + )} 71 + </> 72 + ); 73 + };
+90
apps/web/src/components/ui/date-time-picker.tsx
··· 1 + // CREDITS: https://gist.github.com/fernandops26/da681c4b12e52191803b4fcb040cdebb 2 + "use client"; 3 + 4 + import * as React from "react"; 5 + import { Calendar as CalendarIcon } from "lucide-react"; 6 + import { DateTime } from "luxon"; 7 + import type { SelectSingleEventHandler } from "react-day-picker"; 8 + 9 + import { Button } from "@/components/ui/button"; 10 + import { Calendar } from "@/components/ui/calendar"; 11 + import { Input } from "@/components/ui/input"; 12 + import { Label } from "@/components/ui/label"; 13 + import { 14 + Popover, 15 + PopoverContent, 16 + PopoverTrigger, 17 + } from "@/components/ui/popover"; 18 + import { cn } from "@/lib/utils"; 19 + 20 + interface DateTimePickerProps { 21 + date: Date; 22 + setDate: (date: Date) => void; 23 + } 24 + 25 + export function DateTimePicker({ date, setDate }: DateTimePickerProps) { 26 + const [selectedDateTime, setSelectedDateTime] = React.useState<DateTime>( 27 + DateTime.fromJSDate(date), 28 + ); 29 + 30 + const handleSelect: SelectSingleEventHandler = (day, selected) => { 31 + const selectedDay = DateTime.fromJSDate(selected); 32 + const modifiedDay = selectedDay.set({ 33 + hour: selectedDateTime.hour, 34 + minute: selectedDateTime.minute, 35 + }); 36 + 37 + setSelectedDateTime(modifiedDay); 38 + setDate(modifiedDay.toJSDate()); 39 + }; 40 + 41 + const handleTimeChange: React.ChangeEventHandler<HTMLInputElement> = (e) => { 42 + const { value } = e.target; 43 + const hours = Number.parseInt(value.split(":")[0] || "00", 10); 44 + const minutes = Number.parseInt(value.split(":")[1] || "00", 10); 45 + const modifiedDay = selectedDateTime.set({ hour: hours, minute: minutes }); 46 + 47 + setSelectedDateTime(modifiedDay); 48 + setDate(modifiedDay.toJSDate()); 49 + }; 50 + 51 + return ( 52 + <Popover> 53 + <PopoverTrigger asChild className="z-10"> 54 + <Button 55 + variant={"outline"} 56 + className={cn( 57 + "w-[280px] justify-start text-left font-normal", 58 + !date && "text-muted-foreground", 59 + )} 60 + suppressHydrationWarning // because timestamp is not same, server and client 61 + > 62 + <CalendarIcon className="mr-2 h-4 w-4" /> 63 + {date ? ( 64 + selectedDateTime.toFormat("DDD HH:mm") 65 + ) : ( 66 + <span>Pick a date</span> 67 + )} 68 + </Button> 69 + </PopoverTrigger> 70 + <PopoverContent className="w-auto p-0"> 71 + <Calendar 72 + mode="single" 73 + selected={selectedDateTime.toJSDate()} 74 + onSelect={handleSelect} 75 + initialFocus 76 + /> 77 + <div className="px-4 pb-4 pt-0"> 78 + <Label>Time</Label> 79 + {/* TODO: style it properly! */} 80 + <Input 81 + type="time" 82 + onChange={handleTimeChange} 83 + value={selectedDateTime.toFormat("HH:mm")} 84 + /> 85 + </div> 86 + {!selectedDateTime && <p>Please pick a day.</p>} 87 + </PopoverContent> 88 + </Popover> 89 + ); 90 + }
+44
apps/web/src/components/ui/radio-group.tsx
··· 1 + "use client"; 2 + 3 + import * as React from "react"; 4 + import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"; 5 + import { Circle } from "lucide-react"; 6 + 7 + import { cn } from "@/lib/utils"; 8 + 9 + const RadioGroup = React.forwardRef< 10 + React.ElementRef<typeof RadioGroupPrimitive.Root>, 11 + React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> 12 + >(({ className, ...props }, ref) => { 13 + return ( 14 + <RadioGroupPrimitive.Root 15 + className={cn("grid gap-2", className)} 16 + {...props} 17 + ref={ref} 18 + /> 19 + ); 20 + }); 21 + RadioGroup.displayName = RadioGroupPrimitive.Root.displayName; 22 + 23 + const RadioGroupItem = React.forwardRef< 24 + React.ElementRef<typeof RadioGroupPrimitive.Item>, 25 + React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> 26 + >(({ className, children, ...props }, ref) => { 27 + return ( 28 + <RadioGroupPrimitive.Item 29 + ref={ref} 30 + className={cn( 31 + "border-primary text-primary ring-offset-background focus-visible:ring-ring aspect-square h-4 w-4 rounded-full border focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", 32 + className, 33 + )} 34 + {...props} 35 + > 36 + <RadioGroupPrimitive.Indicator className="flex items-center justify-center"> 37 + <Circle className="h-2.5 w-2.5 fill-current text-current" /> 38 + </RadioGroupPrimitive.Indicator> 39 + </RadioGroupPrimitive.Item> 40 + ); 41 + }); 42 + RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName; 43 + 44 + export { RadioGroup, RadioGroupItem };
+55
apps/web/src/components/ui/tabs.tsx
··· 1 + "use client"; 2 + 3 + import * as React from "react"; 4 + import * as TabsPrimitive from "@radix-ui/react-tabs"; 5 + 6 + import { cn } from "@/lib/utils"; 7 + 8 + const Tabs = TabsPrimitive.Root; 9 + 10 + const TabsList = React.forwardRef< 11 + React.ElementRef<typeof TabsPrimitive.List>, 12 + React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> 13 + >(({ className, ...props }, ref) => ( 14 + <TabsPrimitive.List 15 + ref={ref} 16 + className={cn( 17 + "bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1", 18 + className, 19 + )} 20 + {...props} 21 + /> 22 + )); 23 + TabsList.displayName = TabsPrimitive.List.displayName; 24 + 25 + const TabsTrigger = React.forwardRef< 26 + React.ElementRef<typeof TabsPrimitive.Trigger>, 27 + React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> 28 + >(({ className, ...props }, ref) => ( 29 + <TabsPrimitive.Trigger 30 + ref={ref} 31 + className={cn( 32 + "ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm", 33 + className, 34 + )} 35 + {...props} 36 + /> 37 + )); 38 + TabsTrigger.displayName = TabsPrimitive.Trigger.displayName; 39 + 40 + const TabsContent = React.forwardRef< 41 + React.ElementRef<typeof TabsPrimitive.Content>, 42 + React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content> 43 + >(({ className, ...props }, ref) => ( 44 + <TabsPrimitive.Content 45 + ref={ref} 46 + className={cn( 47 + "ring-offset-background focus-visible:ring-ring mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2", 48 + className, 49 + )} 50 + {...props} 51 + /> 52 + )); 53 + TabsContent.displayName = TabsPrimitive.Content.displayName; 54 + 55 + export { Tabs, TabsList, TabsTrigger, TabsContent };
+23
apps/web/src/components/ui/textarea.tsx
··· 1 + import * as React from "react"; 2 + 3 + import { cn } from "@/lib/utils"; 4 + 5 + export type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>; 6 + 7 + const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>( 8 + ({ className, ...props }, ref) => { 9 + return ( 10 + <textarea 11 + className={cn( 12 + "border-input ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[80px] w-full rounded-md border bg-transparent px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", 13 + className, 14 + )} 15 + ref={ref} 16 + {...props} 17 + /> 18 + ); 19 + }, 20 + ); 21 + Textarea.displayName = "Textarea"; 22 + 23 + export { Textarea };
-1
apps/web/src/config/pages.ts
··· 27 27 description: "War room where you handle the incidents.", 28 28 href: "/incidents", 29 29 icon: "siren", 30 - disabled: true, 31 30 }, 32 31 // ... 33 32 ];
+26
apps/web/src/data/incidents-dictionary.ts
··· 1 + export const statusDict = { 2 + investigating: { 3 + value: "investigating", 4 + label: "Investigating", 5 + icon: "search", 6 + order: 1, 7 + }, 8 + identified: { 9 + value: "identified", 10 + label: "Identified", 11 + icon: "fingerprint", 12 + order: 2, 13 + }, 14 + monitoring: { 15 + value: "monitoring", 16 + label: "Monitoring", 17 + icon: "activity", 18 + order: 3, 19 + }, 20 + resolved: { 21 + value: "resolved", 22 + label: "Resolved", 23 + icon: "search-check", 24 + order: 4, 25 + }, 26 + } as const;
+6
apps/web/src/lib/utils.ts
··· 14 14 export function formatDate(date: Date) { 15 15 return format(date, "LLL dd, y"); 16 16 } 17 + 18 + export function notEmpty<TValue>( 19 + value: TValue | null | undefined, 20 + ): value is TValue { 21 + return value !== null && value !== undefined; 22 + }
+349 -24
packages/api/src/router/incident.ts
··· 1 1 import { z } from "zod"; 2 2 3 - import { eq } from "@openstatus/db"; 3 + import { and, eq, inArray } from "@openstatus/db"; 4 4 import { 5 5 incident, 6 6 incidentUpdate, 7 7 insertIncidentSchema, 8 + insertIncidentSchemaWithMonitors, 8 9 insertIncidentUpdateSchema, 9 - page, 10 + monitor, 11 + monitorsToIncidents, 12 + selectIncidentSchema, 13 + selectIncidentUpdateSchema, 14 + selectMonitorSchema, 15 + StatusEnum, 16 + user, 17 + usersToWorkspaces, 10 18 workspace, 11 19 } from "@openstatus/db/src/schema"; 12 20 ··· 16 24 createIncident: protectedProcedure 17 25 .input(insertIncidentSchema) 18 26 .mutation(async (opts) => { 19 - // FIXME: SECURE THIS 20 - return opts.ctx.db.insert(incident).values(opts.input).returning().get(); 27 + const currentWorkspace = await opts.ctx.db 28 + .select() 29 + .from(workspace) 30 + .where(eq(workspace.slug, opts.input.workspaceSlug)) 31 + .get(); 32 + const currentUser = opts.ctx.db 33 + .select() 34 + .from(user) 35 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 36 + .as("currentUser"); 37 + const result = await opts.ctx.db 38 + .select() 39 + .from(usersToWorkspaces) 40 + .where(eq(usersToWorkspaces.workspaceId, currentWorkspace.id)) 41 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 42 + .get(); 43 + 44 + if (!result) return; 45 + const { id, workspaceSlug, monitors, date, ...incidentInput } = 46 + opts.input; 47 + 48 + const newIncident = await opts.ctx.db 49 + .insert(incident) 50 + .values({ 51 + workspaceId: currentWorkspace.id, 52 + ...incidentInput, 53 + }) 54 + .returning() 55 + .get(); 56 + 57 + // if (monitors && monitors.length > 0) { 58 + // // We should make sure the user has access to the monitors 59 + // const allMonitors = await opts.ctx.db.query.monitor.findMany({ 60 + // where: inArray(monitor.id, monitors), 61 + // }); 62 + // const values = allMonitors.map((monitor) => ({ 63 + // monitorId: monitor.id, 64 + // incidentId: newIncident.id, 65 + // })); 66 + // await opts.ctx.db.insert(monitorsToIncidents).values(values).run(); 67 + // } 68 + 69 + await opts.ctx.db 70 + .insert(monitorsToIncidents) 71 + .values( 72 + monitors.map((monitor) => ({ 73 + monitorId: monitor, 74 + incidentId: newIncident.id, 75 + })), 76 + ) 77 + .returning() 78 + .get(); 79 + 80 + return newIncident; 21 81 }), 22 82 23 83 createIncidentUpdate: protectedProcedure 24 84 .input(insertIncidentUpdateSchema) 25 85 .mutation(async (opts) => { 26 - // FIXME: SECURE THIS 86 + const currentWorkspace = await opts.ctx.db 87 + .select() 88 + .from(workspace) 89 + .where(eq(workspace.slug, opts.input.workspaceSlug)) 90 + .get(); 91 + const currentUser = opts.ctx.db 92 + .select() 93 + .from(user) 94 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 95 + .as("currentUser"); 96 + const result = await opts.ctx.db 97 + .select() 98 + .from(usersToWorkspaces) 99 + .where(eq(usersToWorkspaces.workspaceId, currentWorkspace.id)) 100 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 101 + .get(); 102 + 103 + if (!result) return; 104 + 105 + // update parent incident with latest status 106 + await opts.ctx.db 107 + .update(incident) 108 + .set({ status: opts.input.status }) 109 + .where(eq(incident.id, opts.input.incidentId)) 110 + .returning() 111 + .get(); 112 + 113 + const { workspaceSlug, ...incidentUpdateInput } = opts.input; 27 114 return await opts.ctx.db 28 115 .insert(incidentUpdate) 29 - .values(opts.input) 116 + .values(incidentUpdateInput) 30 117 .returning() 31 118 .get(); 32 119 }), 33 120 34 121 updateIncident: protectedProcedure 35 - .input( 36 - z.object({ 37 - incidentId: z.number(), 38 - status: insertIncidentSchema.pick({ status: true }), 39 - }), 40 - ) 122 + .input(insertIncidentSchemaWithMonitors) 41 123 .mutation(async (opts) => { 42 - return opts.ctx.db 124 + const currentWorkspace = await opts.ctx.db 125 + .select() 126 + .from(workspace) 127 + .where(eq(workspace.slug, opts.input.workspaceSlug)) 128 + .get(); 129 + const currentUser = opts.ctx.db 130 + .select() 131 + .from(user) 132 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 133 + .as("currentUser"); 134 + const result = await opts.ctx.db 135 + .select() 136 + .from(usersToWorkspaces) 137 + .where(eq(usersToWorkspaces.workspaceId, currentWorkspace.id)) 138 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 139 + .get(); 140 + 141 + if (!result) return; 142 + 143 + console.log(opts.input); 144 + const { monitors, workspaceSlug, ...incidentInput } = opts.input; 145 + console.log(incidentInput); 146 + 147 + if (!incidentInput.id) return; 148 + 149 + const { title, status } = incidentInput; 150 + 151 + const currentIncident = await opts.ctx.db 43 152 .update(incident) 44 - .set(opts.input.status) 45 - .where(eq(incident.id, opts.input.incidentId)) 153 + .set({ title, status, updatedAt: new Date() }) 154 + .where(eq(incident.id, incidentInput.id)) 155 + .returning() 156 + .get(); 157 + 158 + const currentMonitorToIncidents = await opts.ctx.db 159 + .select() 160 + .from(monitorsToIncidents) 161 + .where(eq(monitorsToIncidents.incidentId, currentIncident.id)) 162 + .all(); 163 + 164 + const currentMonitorToIncidentsIds = currentMonitorToIncidents.map( 165 + ({ monitorId }) => monitorId, 166 + ); 167 + 168 + const removedMonitors = currentMonitorToIncidentsIds.filter( 169 + (x) => !monitors?.includes(x), 170 + ); 171 + 172 + const addedMonitors = monitors?.filter( 173 + (x) => !currentMonitorToIncidentsIds?.includes(x), 174 + ); 175 + 176 + if (addedMonitors && addedMonitors.length > 0) { 177 + const values = addedMonitors.map((monitorId) => ({ 178 + monitorId: monitorId, 179 + incidentId: currentIncident.id, 180 + })); 181 + 182 + await opts.ctx.db.insert(monitorsToIncidents).values(values).run(); 183 + } 184 + 185 + if (removedMonitors && removedMonitors.length > 0) { 186 + await opts.ctx.db 187 + .delete(monitorsToIncidents) 188 + .where( 189 + and( 190 + eq(monitorsToIncidents.incidentId, currentIncident.id), 191 + inArray(monitorsToIncidents.monitorId, removedMonitors), 192 + ), 193 + ) 194 + .run(); 195 + } 196 + 197 + return currentIncident; 198 + }), 199 + 200 + updateIncidentUpdate: protectedProcedure 201 + .input(insertIncidentUpdateSchema) 202 + .mutation(async (opts) => { 203 + const currentWorkspace = await opts.ctx.db 204 + .select() 205 + .from(workspace) 206 + .where(eq(workspace.slug, opts.input.workspaceSlug)) 207 + .get(); 208 + const currentUser = opts.ctx.db 209 + .select() 210 + .from(user) 211 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 212 + .as("currentUser"); 213 + const result = await opts.ctx.db 214 + .select() 215 + .from(usersToWorkspaces) 216 + .where(eq(usersToWorkspaces.workspaceId, currentWorkspace.id)) 217 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 218 + .get(); 219 + 220 + if (!result) return; 221 + 222 + const { workspaceSlug, ...incidentUpdateInput } = opts.input; 223 + 224 + if (!incidentUpdateInput.id) return; 225 + 226 + const currentIncident = await opts.ctx.db 227 + .update(incidentUpdate) 228 + .set(incidentUpdateInput) 229 + .where(eq(incidentUpdate.id, incidentUpdateInput.id)) 46 230 .returning() 47 231 .get(); 232 + 233 + return currentIncident; 48 234 }), 49 - // FIXME: SECURE THIS 235 + 236 + deleteIncident: protectedProcedure 237 + .input(z.object({ id: z.number() })) 238 + .mutation(async (opts) => { 239 + // TODO: this looks not very affective 240 + const currentUser = await opts.ctx.db 241 + .select() 242 + .from(user) 243 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 244 + .get(); 245 + 246 + const result = await opts.ctx.db 247 + .select() 248 + .from(usersToWorkspaces) 249 + .where(eq(usersToWorkspaces.userId, currentUser.id)) 250 + .all(); 251 + 252 + const workspaceIds = result.map((workspace) => workspace.workspaceId); 253 + 254 + const incidentToDelete = await opts.ctx.db 255 + .select() 256 + .from(incident) 257 + .where( 258 + and( 259 + eq(incident.id, opts.input.id), 260 + inArray(incident.workspaceId, workspaceIds), 261 + ), 262 + ) 263 + .get(); 264 + if (!incidentToDelete) return; 265 + 266 + await opts.ctx.db 267 + .delete(incident) 268 + .where(eq(incident.id, incidentToDelete.id)) 269 + .run(); 270 + }), 271 + 272 + deleteIncidentUpdate: protectedProcedure 273 + .input(z.object({ id: z.number() })) 274 + .mutation(async (opts) => { 275 + const currentUser = await opts.ctx.db 276 + .select() 277 + .from(user) 278 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 279 + .get(); 280 + 281 + const result = await opts.ctx.db 282 + .select() 283 + .from(usersToWorkspaces) 284 + .where(eq(usersToWorkspaces.userId, currentUser.id)) 285 + .all(); 286 + 287 + const workspaceIds = result.map((workspace) => workspace.workspaceId); 288 + 289 + const incidentUpdateToDelete = await opts.ctx.db 290 + .select() 291 + .from(incidentUpdate) 292 + .where(and(eq(incidentUpdate.id, opts.input.id))) 293 + // FIXME: check if incident related to workspaceId 294 + // .innerJoin(incident, inArray(incident.workspaceId, workspaceIds)) 295 + .get(); 296 + 297 + if (!incidentUpdateToDelete) return; 298 + 299 + await opts.ctx.db 300 + .delete(incidentUpdate) 301 + .where(eq(incidentUpdate.id, opts.input.id)) 302 + .run(); 303 + }), 304 + 305 + getIncidentById: protectedProcedure 306 + .input(z.object({ id: z.number() })) 307 + .query(async (opts) => { 308 + const selectIncidentSchemaWithRelation = selectIncidentSchema.extend({ 309 + status: StatusEnum.default("investigating"), // TODO: remove! 310 + monitorsToIncidents: z 311 + .array(z.object({ incidentId: z.number(), monitorId: z.number() })) 312 + .default([]), 313 + incidentUpdates: z.array(selectIncidentUpdateSchema), 314 + date: z.date().default(new Date()), 315 + }); 316 + 317 + const data = await opts.ctx.db.query.incident.findFirst({ 318 + where: eq(incident.id, opts.input.id), 319 + with: { 320 + monitorsToIncidents: true, 321 + incidentUpdates: { 322 + orderBy: (incidentUpdate, { desc }) => [ 323 + desc(incidentUpdate.createdAt), 324 + ], 325 + }, 326 + }, 327 + }); 328 + 329 + return selectIncidentSchemaWithRelation.parse(data); 330 + }), 331 + 332 + getIncidentUpdateById: protectedProcedure 333 + .input(z.object({ id: z.number() })) 334 + .query(async (opts) => { 335 + const data = await opts.ctx.db.query.incidentUpdate.findFirst({ 336 + where: eq(incidentUpdate.id, opts.input.id), 337 + }); 338 + return selectIncidentUpdateSchema.parse(data); 339 + }), 340 + 50 341 getIncidentByWorkspace: protectedProcedure 51 342 .input(z.object({ workspaceSlug: z.string() })) 52 343 .query(async (opts) => { ··· 55 346 .from(workspace) 56 347 .where(eq(workspace.slug, opts.input.workspaceSlug)) 57 348 .get(); 58 - const pageQuery = opts.ctx.db 349 + 350 + const currentUser = opts.ctx.db 59 351 .select() 60 - .from(page) 61 - .where(eq(page.workspaceId, currentWorkspace.id)) 62 - .as("pageQuery"); 63 - return opts.ctx.db 352 + .from(user) 353 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 354 + .as("currentUser"); 355 + 356 + const result = await opts.ctx.db 64 357 .select() 65 - .from(incident) 66 - .innerJoin(pageQuery, eq(incident.pageId, pageQuery.id)) 67 - .all(); 358 + .from(usersToWorkspaces) 359 + .where(eq(usersToWorkspaces.workspaceId, currentWorkspace.id)) 360 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 361 + .get(); 362 + 363 + if (!result) return; 364 + 365 + const selectIncidentSchemaWithRelation = selectIncidentSchema.extend({ 366 + status: StatusEnum.default("investigating"), // TODO: remove! 367 + monitorsToIncidents: z 368 + .array( 369 + z.object({ 370 + incidentId: z.number(), 371 + monitorId: z.number(), 372 + monitor: selectMonitorSchema, 373 + }), 374 + ) 375 + .default([]), 376 + incidentUpdates: z.array(selectIncidentUpdateSchema), 377 + }); 378 + 379 + const data = await opts.ctx.db.query.incident.findMany({ 380 + where: eq(incident.workspaceId, currentWorkspace.id), 381 + with: { 382 + monitorsToIncidents: { with: { monitor: true } }, 383 + incidentUpdates: { 384 + orderBy: (incidentUpdate, { desc }) => [ 385 + desc(incidentUpdate.createdAt), 386 + ], 387 + }, 388 + }, 389 + orderBy: (incident, { desc }) => [desc(incident.createdAt)], 390 + }); 391 + 392 + return z.array(selectIncidentSchemaWithRelation).parse(data); 68 393 }), 69 394 });
+43 -17
packages/api/src/router/page.ts
··· 2 2 import { z } from "zod"; 3 3 4 4 import { analytics, trackAnalytics } from "@openstatus/analytics"; 5 - import { and, eq, inArray, sql } from "@openstatus/db"; 5 + import { and, eq, inArray, not, sql } from "@openstatus/db"; 6 6 import { 7 + incident, 8 + incidentUpdate, 7 9 insertPageSchemaWithMonitors, 8 10 monitor, 11 + monitorsToIncidents, 9 12 monitorsToPages, 10 13 page, 11 14 selectIncidentSchema, 15 + selectIncidentUpdateSchema, 12 16 selectMonitorSchema, 13 17 selectPageSchema, 18 + selectPageSchemaWithRelation, 14 19 user, 15 20 usersToWorkspaces, 16 21 workspace, ··· 109 114 eq(page.id, opts.input.id), 110 115 inArray(page.workspaceId, workspaceIds), 111 116 ), 112 - with: { monitorsToPages: { with: { monitor: true } }, incidents: true }, 117 + with: { 118 + monitorsToPages: { with: { monitor: true } }, 119 + // incidents: true 120 + }, 113 121 }); 114 122 }), 115 123 updatePage: protectedProcedure ··· 236 244 .query(async (opts) => { 237 245 const result = await opts.ctx.db.query.page.findFirst({ 238 246 where: sql`lower(${page.slug}) = ${opts.input.slug}`, 239 - with: { incidents: true }, 247 + // with: { incidents: true }, 240 248 }); 241 249 242 250 if (!result) { ··· 251 259 .all(); 252 260 253 261 const monitorsId = monitorsToPagesResult.map( 254 - (monitor) => monitor.monitorId, 262 + ({ monitorId }) => monitorId, 255 263 ); 256 264 257 - const selectPageSchemaWithRelation = selectPageSchema.extend({ 258 - monitors: z.array(selectMonitorSchema), 259 - incidents: z.array(selectIncidentSchema), 260 - }); 261 - 262 - if (monitorsId.length === 0) { 263 - return selectPageSchemaWithRelation.parse({ ...result, monitors: [] }); 264 - } // no monitors for that page 265 - 266 - const monitors = await opts.ctx.db 265 + const monitorsToIncidentsResult = await opts.ctx.db 267 266 .select() 268 - .from(monitor) 269 - .where(and(inArray(monitor.id, monitorsId), eq(monitor.active, true))) // REMINDER: this is hardcoded 267 + .from(monitorsToIncidents) 268 + .where(inArray(monitorsToIncidents.monitorId, monitorsId)) 270 269 .all(); 271 270 272 - return selectPageSchemaWithRelation.parse({ ...result, monitors }); 271 + const incidentsId = monitorsToIncidentsResult.map( 272 + ({ incidentId }) => incidentId, 273 + ); 274 + 275 + const incidents = 276 + incidentsId.length > 0 277 + ? await opts.ctx.db.query.incident.findMany({ 278 + where: and(inArray(incident.id, incidentsId)), 279 + with: { incidentUpdates: true, monitorsToIncidents: true }, 280 + }) 281 + : []; 282 + 283 + const monitors = 284 + monitorsId.length > 0 285 + ? await opts.ctx.db 286 + .select() 287 + .from(monitor) 288 + .where( 289 + and(inArray(monitor.id, monitorsId), eq(monitor.active, true)), // REMINDER: this is hardcoded 290 + ) 291 + .all() 292 + : []; 293 + 294 + return selectPageSchemaWithRelation.parse({ 295 + ...result, 296 + monitors, 297 + incidents, 298 + }); 273 299 }), 274 300 275 301 getSlugUniqueness: protectedProcedure
+42
packages/db/drizzle/0003_glamorous_living_mummy.sql
··· 1 + DROP INDEX IF EXISTS `incident_update_uuid_unique`;--> statement-breakpoint 2 + 3 + ALTER TABLE `incident` RENAME TO `incident_old`;--> statement-breakpoint 4 + ALTER TABLE `incident_update` RENAME TO `incident_update_old`;--> statement-breakpoint 5 + 6 + DROP TABLE `incident_old`;--> statement-breakpoint 7 + DROP TABLE `incident_update_old`;--> statement-breakpoint 8 + 9 + CREATE TABLE `incident` ( 10 + `id` integer PRIMARY KEY NOT NULL, 11 + `status` text(4) NOT NULL, 12 + `title` text(256) NOT NULL, 13 + `created_at` integer DEFAULT (strftime('%s', 'now')), 14 + `updated_at` integer DEFAULT (strftime('%s', 'now')), 15 + `workspace_id` integer NOT NULL, 16 + FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE cascade 17 + ); 18 + --> statement-breakpoint 19 + 20 + CREATE TABLE `incident_update` ( 21 + `id` integer PRIMARY KEY NOT NULL, 22 + `status` text(4) NOT NULL, 23 + `date` integer NOT NULL, 24 + `message` text NOT NULL, 25 + `created_at` integer DEFAULT (strftime('%s', 'now')), 26 + `updated_at` integer DEFAULT (strftime('%s', 'now')), 27 + `incident_id` integer NOT NULL, 28 + FOREIGN KEY (`incident_id`) REFERENCES `incident`(`id`) ON UPDATE no action ON DELETE cascade 29 + ); 30 + --> statement-breakpoint 31 + 32 + DROP INDEX IF EXISTS `incident_update_uuid_unique`; 33 + --> statement-breakpoint 34 + 35 + CREATE TABLE `incidents_to_monitors` ( 36 + `monitor_id` integer NOT NULL, 37 + `incident_id` integer NOT NULL, 38 + PRIMARY KEY(`incident_id`, `monitor_id`), 39 + FOREIGN KEY (`monitor_id`) REFERENCES `monitor`(`id`) ON UPDATE no action ON DELETE cascade, 40 + FOREIGN KEY (`incident_id`) REFERENCES `incident`(`id`) ON UPDATE no action ON DELETE cascade 41 + ); 42 +
+604
packages/db/drizzle/meta/0003_snapshot.json
··· 1 + { 2 + "version": "5", 3 + "dialect": "sqlite", 4 + "id": "f68fee05-786b-45d6-9e08-f793e7591577", 5 + "prevId": "84c77cb9-dca1-424b-8929-c31f24ad5144", 6 + "tables": { 7 + "incident": { 8 + "name": "incident", 9 + "columns": { 10 + "id": { 11 + "name": "id", 12 + "type": "integer", 13 + "primaryKey": true, 14 + "notNull": true, 15 + "autoincrement": false 16 + }, 17 + "status": { 18 + "name": "status", 19 + "type": "text(4)", 20 + "primaryKey": false, 21 + "notNull": true, 22 + "autoincrement": false 23 + }, 24 + "title": { 25 + "name": "title", 26 + "type": "text(256)", 27 + "primaryKey": false, 28 + "notNull": true, 29 + "autoincrement": false 30 + }, 31 + "workspace_id": { 32 + "name": "workspace_id", 33 + "type": "integer", 34 + "primaryKey": false, 35 + "notNull": false, 36 + "autoincrement": false 37 + }, 38 + "created_at": { 39 + "name": "created_at", 40 + "type": "integer", 41 + "primaryKey": false, 42 + "notNull": false, 43 + "autoincrement": false, 44 + "default": "(strftime('%s', 'now'))" 45 + }, 46 + "updated_at": { 47 + "name": "updated_at", 48 + "type": "integer", 49 + "primaryKey": false, 50 + "notNull": false, 51 + "autoincrement": false, 52 + "default": "(strftime('%s', 'now'))" 53 + } 54 + }, 55 + "indexes": {}, 56 + "foreignKeys": { 57 + "incident_workspace_id_workspace_id_fk": { 58 + "name": "incident_workspace_id_workspace_id_fk", 59 + "tableFrom": "incident", 60 + "tableTo": "workspace", 61 + "columnsFrom": ["workspace_id"], 62 + "columnsTo": ["id"], 63 + "onDelete": "no action", 64 + "onUpdate": "no action" 65 + } 66 + }, 67 + "compositePrimaryKeys": {}, 68 + "uniqueConstraints": {} 69 + }, 70 + "incident_update": { 71 + "name": "incident_update", 72 + "columns": { 73 + "id": { 74 + "name": "id", 75 + "type": "integer", 76 + "primaryKey": true, 77 + "notNull": true, 78 + "autoincrement": false 79 + }, 80 + "status": { 81 + "name": "status", 82 + "type": "text(4)", 83 + "primaryKey": false, 84 + "notNull": true, 85 + "autoincrement": false 86 + }, 87 + "date": { 88 + "name": "date", 89 + "type": "integer", 90 + "primaryKey": false, 91 + "notNull": true, 92 + "autoincrement": false 93 + }, 94 + "message": { 95 + "name": "message", 96 + "type": "text", 97 + "primaryKey": false, 98 + "notNull": true, 99 + "autoincrement": false 100 + }, 101 + "incident_id": { 102 + "name": "incident_id", 103 + "type": "integer", 104 + "primaryKey": false, 105 + "notNull": true, 106 + "autoincrement": false 107 + }, 108 + "created_at": { 109 + "name": "created_at", 110 + "type": "integer", 111 + "primaryKey": false, 112 + "notNull": false, 113 + "autoincrement": false, 114 + "default": "(strftime('%s', 'now'))" 115 + }, 116 + "updated_at": { 117 + "name": "updated_at", 118 + "type": "integer", 119 + "primaryKey": false, 120 + "notNull": false, 121 + "autoincrement": false, 122 + "default": "(strftime('%s', 'now'))" 123 + } 124 + }, 125 + "indexes": {}, 126 + "foreignKeys": { 127 + "incident_update_incident_id_incident_id_fk": { 128 + "name": "incident_update_incident_id_incident_id_fk", 129 + "tableFrom": "incident_update", 130 + "tableTo": "incident", 131 + "columnsFrom": ["incident_id"], 132 + "columnsTo": ["id"], 133 + "onDelete": "cascade", 134 + "onUpdate": "no action" 135 + } 136 + }, 137 + "compositePrimaryKeys": {}, 138 + "uniqueConstraints": {} 139 + }, 140 + "incidents_to_monitors": { 141 + "name": "incidents_to_monitors", 142 + "columns": { 143 + "monitor_id": { 144 + "name": "monitor_id", 145 + "type": "integer", 146 + "primaryKey": false, 147 + "notNull": true, 148 + "autoincrement": false 149 + }, 150 + "incident_id": { 151 + "name": "incident_id", 152 + "type": "integer", 153 + "primaryKey": false, 154 + "notNull": true, 155 + "autoincrement": false 156 + } 157 + }, 158 + "indexes": {}, 159 + "foreignKeys": { 160 + "incidents_to_monitors_monitor_id_monitor_id_fk": { 161 + "name": "incidents_to_monitors_monitor_id_monitor_id_fk", 162 + "tableFrom": "incidents_to_monitors", 163 + "tableTo": "monitor", 164 + "columnsFrom": ["monitor_id"], 165 + "columnsTo": ["id"], 166 + "onDelete": "cascade", 167 + "onUpdate": "no action" 168 + }, 169 + "incidents_to_monitors_incident_id_incident_id_fk": { 170 + "name": "incidents_to_monitors_incident_id_incident_id_fk", 171 + "tableFrom": "incidents_to_monitors", 172 + "tableTo": "incident", 173 + "columnsFrom": ["incident_id"], 174 + "columnsTo": ["id"], 175 + "onDelete": "cascade", 176 + "onUpdate": "no action" 177 + } 178 + }, 179 + "compositePrimaryKeys": { 180 + "incidents_to_monitors_monitor_id_incident_id_pk": { 181 + "columns": ["incident_id", "monitor_id"] 182 + } 183 + }, 184 + "uniqueConstraints": {} 185 + }, 186 + "page": { 187 + "name": "page", 188 + "columns": { 189 + "id": { 190 + "name": "id", 191 + "type": "integer", 192 + "primaryKey": true, 193 + "notNull": true, 194 + "autoincrement": false 195 + }, 196 + "workspace_id": { 197 + "name": "workspace_id", 198 + "type": "integer", 199 + "primaryKey": false, 200 + "notNull": true, 201 + "autoincrement": false 202 + }, 203 + "title": { 204 + "name": "title", 205 + "type": "text", 206 + "primaryKey": false, 207 + "notNull": true, 208 + "autoincrement": false 209 + }, 210 + "description": { 211 + "name": "description", 212 + "type": "text", 213 + "primaryKey": false, 214 + "notNull": true, 215 + "autoincrement": false 216 + }, 217 + "icon": { 218 + "name": "icon", 219 + "type": "text(256)", 220 + "primaryKey": false, 221 + "notNull": false, 222 + "autoincrement": false 223 + }, 224 + "slug": { 225 + "name": "slug", 226 + "type": "text(256)", 227 + "primaryKey": false, 228 + "notNull": true, 229 + "autoincrement": false 230 + }, 231 + "custom_domain": { 232 + "name": "custom_domain", 233 + "type": "text(256)", 234 + "primaryKey": false, 235 + "notNull": true, 236 + "autoincrement": false 237 + }, 238 + "published": { 239 + "name": "published", 240 + "type": "integer", 241 + "primaryKey": false, 242 + "notNull": false, 243 + "autoincrement": false, 244 + "default": false 245 + }, 246 + "updated_at": { 247 + "name": "updated_at", 248 + "type": "integer", 249 + "primaryKey": false, 250 + "notNull": false, 251 + "autoincrement": false, 252 + "default": "(strftime('%s', 'now'))" 253 + } 254 + }, 255 + "indexes": { 256 + "page_slug_unique": { 257 + "name": "page_slug_unique", 258 + "columns": ["slug"], 259 + "isUnique": true 260 + } 261 + }, 262 + "foreignKeys": { 263 + "page_workspace_id_workspace_id_fk": { 264 + "name": "page_workspace_id_workspace_id_fk", 265 + "tableFrom": "page", 266 + "tableTo": "workspace", 267 + "columnsFrom": ["workspace_id"], 268 + "columnsTo": ["id"], 269 + "onDelete": "cascade", 270 + "onUpdate": "no action" 271 + } 272 + }, 273 + "compositePrimaryKeys": {}, 274 + "uniqueConstraints": {} 275 + }, 276 + "monitor": { 277 + "name": "monitor", 278 + "columns": { 279 + "id": { 280 + "name": "id", 281 + "type": "integer", 282 + "primaryKey": true, 283 + "notNull": true, 284 + "autoincrement": false 285 + }, 286 + "job_type": { 287 + "name": "job_type", 288 + "type": "text(3)", 289 + "primaryKey": false, 290 + "notNull": true, 291 + "autoincrement": false, 292 + "default": "'other'" 293 + }, 294 + "periodicity": { 295 + "name": "periodicity", 296 + "type": "text(6)", 297 + "primaryKey": false, 298 + "notNull": true, 299 + "autoincrement": false, 300 + "default": "'other'" 301 + }, 302 + "status": { 303 + "name": "status", 304 + "type": "text(2)", 305 + "primaryKey": false, 306 + "notNull": true, 307 + "autoincrement": false, 308 + "default": "'inactive'" 309 + }, 310 + "active": { 311 + "name": "active", 312 + "type": "integer", 313 + "primaryKey": false, 314 + "notNull": false, 315 + "autoincrement": false, 316 + "default": false 317 + }, 318 + "regions": { 319 + "name": "regions", 320 + "type": "text", 321 + "primaryKey": false, 322 + "notNull": true, 323 + "autoincrement": false, 324 + "default": "''" 325 + }, 326 + "url": { 327 + "name": "url", 328 + "type": "text(512)", 329 + "primaryKey": false, 330 + "notNull": true, 331 + "autoincrement": false 332 + }, 333 + "name": { 334 + "name": "name", 335 + "type": "text(256)", 336 + "primaryKey": false, 337 + "notNull": true, 338 + "autoincrement": false, 339 + "default": "''" 340 + }, 341 + "description": { 342 + "name": "description", 343 + "type": "text", 344 + "primaryKey": false, 345 + "notNull": true, 346 + "autoincrement": false, 347 + "default": "''" 348 + }, 349 + "workspace_id": { 350 + "name": "workspace_id", 351 + "type": "integer", 352 + "primaryKey": false, 353 + "notNull": false, 354 + "autoincrement": false 355 + }, 356 + "updated_at": { 357 + "name": "updated_at", 358 + "type": "integer", 359 + "primaryKey": false, 360 + "notNull": false, 361 + "autoincrement": false, 362 + "default": "(strftime('%s', 'now'))" 363 + } 364 + }, 365 + "indexes": {}, 366 + "foreignKeys": { 367 + "monitor_workspace_id_workspace_id_fk": { 368 + "name": "monitor_workspace_id_workspace_id_fk", 369 + "tableFrom": "monitor", 370 + "tableTo": "workspace", 371 + "columnsFrom": ["workspace_id"], 372 + "columnsTo": ["id"], 373 + "onDelete": "no action", 374 + "onUpdate": "no action" 375 + } 376 + }, 377 + "compositePrimaryKeys": {}, 378 + "uniqueConstraints": {} 379 + }, 380 + "monitors_to_pages": { 381 + "name": "monitors_to_pages", 382 + "columns": { 383 + "monitor_id": { 384 + "name": "monitor_id", 385 + "type": "integer", 386 + "primaryKey": false, 387 + "notNull": true, 388 + "autoincrement": false 389 + }, 390 + "page_id": { 391 + "name": "page_id", 392 + "type": "integer", 393 + "primaryKey": false, 394 + "notNull": true, 395 + "autoincrement": false 396 + } 397 + }, 398 + "indexes": {}, 399 + "foreignKeys": { 400 + "monitors_to_pages_monitor_id_monitor_id_fk": { 401 + "name": "monitors_to_pages_monitor_id_monitor_id_fk", 402 + "tableFrom": "monitors_to_pages", 403 + "tableTo": "monitor", 404 + "columnsFrom": ["monitor_id"], 405 + "columnsTo": ["id"], 406 + "onDelete": "cascade", 407 + "onUpdate": "no action" 408 + }, 409 + "monitors_to_pages_page_id_page_id_fk": { 410 + "name": "monitors_to_pages_page_id_page_id_fk", 411 + "tableFrom": "monitors_to_pages", 412 + "tableTo": "page", 413 + "columnsFrom": ["page_id"], 414 + "columnsTo": ["id"], 415 + "onDelete": "cascade", 416 + "onUpdate": "no action" 417 + } 418 + }, 419 + "compositePrimaryKeys": { 420 + "monitors_to_pages_monitor_id_page_id_pk": { 421 + "columns": ["monitor_id", "page_id"] 422 + } 423 + }, 424 + "uniqueConstraints": {} 425 + }, 426 + "user": { 427 + "name": "user", 428 + "columns": { 429 + "id": { 430 + "name": "id", 431 + "type": "integer", 432 + "primaryKey": true, 433 + "notNull": true, 434 + "autoincrement": false 435 + }, 436 + "tenant_id": { 437 + "name": "tenant_id", 438 + "type": "text(256)", 439 + "primaryKey": false, 440 + "notNull": false, 441 + "autoincrement": false 442 + }, 443 + "first_name": { 444 + "name": "first_name", 445 + "type": "text", 446 + "primaryKey": false, 447 + "notNull": false, 448 + "autoincrement": false, 449 + "default": "''" 450 + }, 451 + "last_name": { 452 + "name": "last_name", 453 + "type": "text", 454 + "primaryKey": false, 455 + "notNull": false, 456 + "autoincrement": false, 457 + "default": "''" 458 + }, 459 + "email": { 460 + "name": "email", 461 + "type": "text", 462 + "primaryKey": false, 463 + "notNull": false, 464 + "autoincrement": false, 465 + "default": "''" 466 + }, 467 + "photo_url": { 468 + "name": "photo_url", 469 + "type": "text", 470 + "primaryKey": false, 471 + "notNull": false, 472 + "autoincrement": false, 473 + "default": "''" 474 + }, 475 + "updated_at": { 476 + "name": "updated_at", 477 + "type": "integer", 478 + "primaryKey": false, 479 + "notNull": false, 480 + "autoincrement": false, 481 + "default": "(strftime('%s', 'now'))" 482 + } 483 + }, 484 + "indexes": { 485 + "user_tenant_id_unique": { 486 + "name": "user_tenant_id_unique", 487 + "columns": ["tenant_id"], 488 + "isUnique": true 489 + } 490 + }, 491 + "foreignKeys": {}, 492 + "compositePrimaryKeys": {}, 493 + "uniqueConstraints": {} 494 + }, 495 + "users_to_workspaces": { 496 + "name": "users_to_workspaces", 497 + "columns": { 498 + "user_id": { 499 + "name": "user_id", 500 + "type": "integer", 501 + "primaryKey": false, 502 + "notNull": true, 503 + "autoincrement": false 504 + }, 505 + "workspace_id": { 506 + "name": "workspace_id", 507 + "type": "integer", 508 + "primaryKey": false, 509 + "notNull": true, 510 + "autoincrement": false 511 + } 512 + }, 513 + "indexes": {}, 514 + "foreignKeys": { 515 + "users_to_workspaces_user_id_user_id_fk": { 516 + "name": "users_to_workspaces_user_id_user_id_fk", 517 + "tableFrom": "users_to_workspaces", 518 + "tableTo": "user", 519 + "columnsFrom": ["user_id"], 520 + "columnsTo": ["id"], 521 + "onDelete": "no action", 522 + "onUpdate": "no action" 523 + }, 524 + "users_to_workspaces_workspace_id_workspace_id_fk": { 525 + "name": "users_to_workspaces_workspace_id_workspace_id_fk", 526 + "tableFrom": "users_to_workspaces", 527 + "tableTo": "workspace", 528 + "columnsFrom": ["workspace_id"], 529 + "columnsTo": ["id"], 530 + "onDelete": "no action", 531 + "onUpdate": "no action" 532 + } 533 + }, 534 + "compositePrimaryKeys": { 535 + "users_to_workspaces_user_id_workspace_id_pk": { 536 + "columns": ["user_id", "workspace_id"] 537 + } 538 + }, 539 + "uniqueConstraints": {} 540 + }, 541 + "workspace": { 542 + "name": "workspace", 543 + "columns": { 544 + "id": { 545 + "name": "id", 546 + "type": "integer", 547 + "primaryKey": true, 548 + "notNull": true, 549 + "autoincrement": false 550 + }, 551 + "slug": { 552 + "name": "slug", 553 + "type": "text", 554 + "primaryKey": false, 555 + "notNull": true, 556 + "autoincrement": false 557 + }, 558 + "stripe_id": { 559 + "name": "stripe_id", 560 + "type": "text(256)", 561 + "primaryKey": false, 562 + "notNull": false, 563 + "autoincrement": false 564 + }, 565 + "name": { 566 + "name": "name", 567 + "type": "text", 568 + "primaryKey": false, 569 + "notNull": false, 570 + "autoincrement": false 571 + }, 572 + "updated_at": { 573 + "name": "updated_at", 574 + "type": "integer", 575 + "primaryKey": false, 576 + "notNull": false, 577 + "autoincrement": false, 578 + "default": "(strftime('%s', 'now'))" 579 + } 580 + }, 581 + "indexes": { 582 + "workspace_slug_unique": { 583 + "name": "workspace_slug_unique", 584 + "columns": ["slug"], 585 + "isUnique": true 586 + }, 587 + "workspace_stripe_id_unique": { 588 + "name": "workspace_stripe_id_unique", 589 + "columns": ["stripe_id"], 590 + "isUnique": true 591 + } 592 + }, 593 + "foreignKeys": {}, 594 + "compositePrimaryKeys": {}, 595 + "uniqueConstraints": {} 596 + } 597 + }, 598 + "enums": {}, 599 + "_meta": { 600 + "schemas": {}, 601 + "tables": {}, 602 + "columns": {} 603 + } 604 + }
+7
packages/db/drizzle/meta/_journal.json
··· 22 22 "when": 1691573899721, 23 23 "tag": "0002_luxuriant_ser_duncan", 24 24 "breakpoints": true 25 + }, 26 + { 27 + "idx": 3, 28 + "version": "5", 29 + "when": 1691614487733, 30 + "tag": "0003_glamorous_living_mummy", 31 + "breakpoints": true 25 32 } 26 33 ] 27 34 }
+96 -22
packages/db/src/schema/incident.ts
··· 1 1 import { relations, sql } from "drizzle-orm"; 2 - import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core"; 2 + import { 3 + integer, 4 + primaryKey, 5 + sqliteTable, 6 + text, 7 + } from "drizzle-orm/sqlite-core"; 3 8 import { createInsertSchema, createSelectSchema } from "drizzle-zod"; 9 + import * as z from "zod"; 4 10 5 - import { page } from "./page"; 11 + import { monitor } from "./monitor"; 12 + import { workspace } from "./workspace"; 6 13 14 + export const availableStatus = [ 15 + "investigating", 16 + "identified", 17 + "monitoring", 18 + "resolved", 19 + ] as const; 20 + 21 + export const StatusEnum = z.enum(availableStatus); 22 + 23 + // We should have a self relation. Such that we show the parent. 7 24 export const incident = sqliteTable("incident", { 8 25 id: integer("id").primaryKey(), 9 - status: text("status", ["resolved", "investigating"]).notNull(), 26 + status: text("status", availableStatus).notNull(), // FIXME: delete from table! 27 + title: text("title", { length: 256 }).notNull(), 10 28 11 - pageId: text("page_id") 12 - .notNull() 13 - .references(() => page.id, { onDelete: "cascade" }), 29 + workspaceId: integer("workspace_id").references(() => workspace.id), 14 30 15 - createdAt: integer("updated_at", { mode: "timestamp" }).default( 31 + createdAt: integer("created_at", { mode: "timestamp" }).default( 16 32 sql`(strftime('%s', 'now'))`, 17 33 ), 18 34 updatedAt: integer("updated_at", { mode: "timestamp" }).default( 19 35 sql`(strftime('%s', 'now'))`, 20 36 ), 37 + // createdBy 21 38 }); 22 39 23 40 export const incidentUpdate = sqliteTable("incident_update", { 24 41 id: integer("id").primaryKey(), 25 - uuid: text("uuid").notNull().unique(), 26 42 27 - date: integer("incident_date"), 28 - title: text("title", { length: 256 }), // title of the incident 29 - message: text("message"), // where we can write the incident message 43 + status: text("status", availableStatus).notNull(), 44 + date: integer("date", { mode: "timestamp" }).notNull(), 45 + message: text("message").notNull(), 30 46 31 47 incidentId: integer("incident_id") 32 48 .references(() => incident.id, { onDelete: "cascade" }) 33 49 .notNull(), 34 - createdAt: integer("updated_at", { mode: "timestamp" }).default( 50 + createdAt: integer("created_at", { mode: "timestamp" }).default( 35 51 sql`(strftime('%s', 'now'))`, 36 52 ), 37 53 updatedAt: integer("updated_at", { mode: "timestamp" }).default( ··· 40 56 }); 41 57 42 58 export const incidentRelations = relations(incident, ({ one, many }) => ({ 43 - page: one(page, { 44 - fields: [incident.pageId], 45 - references: [page.id], 59 + monitorsToIncidents: many(monitorsToIncidents), 60 + incidentUpdates: many(incidentUpdate), 61 + workspace: one(workspace, { 62 + fields: [incident.workspaceId], 63 + references: [workspace.id], 46 64 }), 47 - incidentUpdates: many(incidentUpdate), 48 65 })); 49 66 50 67 export const incidentUpdateRelations = relations(incidentUpdate, ({ one }) => ({ ··· 54 71 }), 55 72 })); 56 73 57 - // Schema for inserting a Incident - can be used to validate API requests 58 - export const insertIncidentSchema = createInsertSchema(incident); 74 + export const monitorsToIncidents = sqliteTable( 75 + "incidents_to_monitors", 76 + { 77 + monitorId: integer("monitor_id") 78 + .notNull() 79 + .references(() => monitor.id, { onDelete: "cascade" }), 80 + incidentId: integer("incident_id") 81 + .notNull() 82 + .references(() => incident.id, { onDelete: "cascade" }), 83 + }, 84 + (t) => ({ 85 + pk: primaryKey(t.monitorId, t.incidentId), 86 + }), 87 + ); 59 88 60 - // Schema for selecting a Incident - can be used to validate API responses 61 - export const selectIncidentSchema = createSelectSchema(incident); 89 + export const monitorsToIncidentsRelations = relations( 90 + monitorsToIncidents, 91 + ({ one }) => ({ 92 + monitor: one(monitor, { 93 + fields: [monitorsToIncidents.monitorId], 94 + references: [monitor.id], 95 + }), 96 + incident: one(incident, { 97 + fields: [monitorsToIncidents.incidentId], 98 + references: [incident.id], 99 + }), 100 + }), 101 + ); 102 + 103 + // Schema for inserting a Incident - can be used to validate API requests 104 + export const insertIncidentSchema = createInsertSchema(incident).extend({ 105 + title: z.string().default(""), 106 + // message: z.string().optional().default(""), 107 + status: StatusEnum, 108 + date: z.date().optional().default(new Date()), 109 + // date: z.number().optional().default(new Date().getTime()), 110 + workspaceSlug: z.string(), 111 + monitors: z.number().array().min(1), 112 + }); 62 113 63 114 export const insertIncidentUpdateSchema = createInsertSchema( 64 115 incidentUpdate, 65 - ).omit({ id: true }); 116 + ).extend({ 117 + status: StatusEnum, 118 + message: z.string().optional().default(""), 119 + // date: z.number().optional().default(new Date().getTime()), 120 + workspaceSlug: z.string(), 121 + }); 122 + 123 + export const insertIncidentSchemaWithIncidentUpdates = 124 + insertIncidentSchema.extend({ 125 + incidentUpdates: insertIncidentUpdateSchema.array(), 126 + }); 127 + 128 + // TODO: remove! 129 + export const insertIncidentSchemaWithMonitors = insertIncidentSchema.extend({ 130 + monitors: z.number().array().min(1), 131 + }); 66 132 67 - export const selectIncidentUpdateSchema = createSelectSchema(incidentUpdate); 133 + export const selectIncidentSchema = createSelectSchema(incident).extend({ 134 + status: StatusEnum, 135 + }); 136 + 137 + export const selectIncidentUpdateSchema = createSelectSchema( 138 + incidentUpdate, 139 + ).extend({ 140 + status: StatusEnum, 141 + });
+1
packages/db/src/schema/index.ts
··· 3 3 export * from "./monitor"; 4 4 export * from "./user"; 5 5 export * from "./workspace"; 6 + export * from "./shared";
+2
packages/db/src/schema/monitor.ts
··· 8 8 import { createInsertSchema, createSelectSchema } from "drizzle-zod"; 9 9 import { z } from "zod"; 10 10 11 + import { monitorsToIncidents } from "./incident"; 11 12 import { page } from "./page"; 12 13 import { workspace } from "./workspace"; 13 14 ··· 65 66 66 67 export const monitorRelation = relations(monitor, ({ one, many }) => ({ 67 68 monitorsToPages: many(monitorsToPages), 69 + monitorsToIncidents: many(monitorsToIncidents), 68 70 workspace: one(workspace, { 69 71 fields: [monitor.workspaceId], 70 72 references: [workspace.id],
+6 -3
packages/db/src/schema/page.ts
··· 3 3 import { createInsertSchema, createSelectSchema } from "drizzle-zod"; 4 4 import { z } from "zod"; 5 5 6 - import { incident } from "./incident"; 7 - import { monitorsToPages } from "./monitor"; 6 + import { 7 + incident, 8 + selectIncidentSchema, 9 + selectIncidentUpdateSchema, 10 + } from "./incident"; 11 + import { monitorsToPages, selectMonitorSchema } from "./monitor"; 8 12 import { workspace } from "./workspace"; 9 13 10 14 export const page = sqliteTable("page", { ··· 31 35 32 36 export const pageRelations = relations(page, ({ many, one }) => ({ 33 37 monitorsToPages: many(monitorsToPages), 34 - incidents: many(incident), 35 38 workspace: one(workspace, { 36 39 fields: [page.workspaceId], 37 40 references: [workspace.id],
+18
packages/db/src/schema/shared.ts
··· 1 + import { z } from "zod"; 2 + 3 + import { selectIncidentSchema, selectIncidentUpdateSchema } from "./incident"; 4 + import { selectMonitorSchema } from "./monitor"; 5 + import { selectPageSchema } from "./page"; 6 + 7 + export const selectIncidentsPageSchema = z.array( 8 + selectIncidentSchema.extend({ 9 + incidentUpdates: z.array(selectIncidentUpdateSchema), 10 + monitorsToIncidents: z.array( 11 + z.object({ monitorId: z.number(), incidentId: z.number() }), 12 + ), 13 + }), 14 + ); 15 + export const selectPageSchemaWithRelation = selectPageSchema.extend({ 16 + monitors: z.array(selectMonitorSchema), 17 + incidents: selectIncidentsPageSchema, 18 + });
+202 -1301
pnpm-lock.yaml
··· 49 49 version: 1.0.1 50 50 next: 51 51 specifier: ^13.4.12 52 - version: 13.4.12(@babel/core@7.22.9)(react-dom@18.2.0)(react@18.2.0) 52 + version: 13.4.12(@babel/core@7.22.9)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) 53 53 nextra: 54 54 specifier: 2.10.0 55 55 version: 2.10.0(next@13.4.12)(react-dom@18.2.0)(react@18.2.0) ··· 126 126 '@radix-ui/react-popover': 127 127 specifier: 1.0.6 128 128 version: 1.0.6(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 129 + '@radix-ui/react-radio-group': 130 + specifier: ^1.1.3 131 + version: 1.1.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 129 132 '@radix-ui/react-select': 130 133 specifier: 1.2.2 131 134 version: 1.2.2(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) ··· 138 141 '@radix-ui/react-switch': 139 142 specifier: 1.0.3 140 143 version: 1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 144 + '@radix-ui/react-tabs': 145 + specifier: ^1.0.4 146 + version: 1.0.4(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 141 147 '@radix-ui/react-toast': 142 148 specifier: 1.1.4 143 149 version: 1.1.4(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) ··· 192 198 lucide-react: 193 199 specifier: 0.244.0 194 200 version: 0.244.0(react@18.2.0) 201 + luxon: 202 + specifier: ^3.3.0 203 + version: 3.3.0 195 204 micro: 196 205 specifier: 10.0.1 197 206 version: 10.0.1 ··· 256 265 '@openstatus/eslint-config': 257 266 specifier: workspace:* 258 267 version: link:../../packages/config/eslint 268 + '@types/luxon': 269 + specifier: ^3.3.1 270 + version: 3.3.1 259 271 '@types/node': 260 272 specifier: 20.3.1 261 273 version: 20.3.1 ··· 484 496 specifier: 5.1.6 485 497 version: 5.1.6 486 498 487 - packages/emails/.react-email: 488 - dependencies: 489 - '@radix-ui/colors': 490 - specifier: 0.1.8 491 - version: 0.1.8 492 - '@radix-ui/react-collapsible': 493 - specifier: 1.0.1 494 - version: 1.0.1(react-dom@18.2.0)(react@18.2.0) 495 - '@radix-ui/react-popover': 496 - specifier: 1.0.2 497 - version: 1.0.2(@types/react@18.0.25)(react-dom@18.2.0)(react@18.2.0) 498 - '@radix-ui/react-slot': 499 - specifier: 1.0.1 500 - version: 1.0.1(react@18.2.0) 501 - '@radix-ui/react-toggle-group': 502 - specifier: 1.0.1 503 - version: 1.0.1(react-dom@18.2.0)(react@18.2.0) 504 - '@radix-ui/react-tooltip': 505 - specifier: 1.0.2 506 - version: 1.0.2(@types/react@18.0.25)(react-dom@18.2.0)(react@18.2.0) 507 - '@react-email/button': 508 - specifier: 0.0.9 509 - version: 0.0.9 510 - '@react-email/components': 511 - specifier: 0.0.7 512 - version: 0.0.7 513 - '@react-email/head': 514 - specifier: 0.0.5 515 - version: 0.0.5 516 - '@react-email/html': 517 - specifier: 0.0.4 518 - version: 0.0.4 519 - '@react-email/render': 520 - specifier: 0.0.7 521 - version: 0.0.7 522 - '@react-email/tailwind': 523 - specifier: 0.0.8 524 - version: 0.0.8 525 - classnames: 526 - specifier: 2.3.2 527 - version: 2.3.2 528 - framer-motion: 529 - specifier: 8.4.6 530 - version: 8.4.6(react-dom@18.2.0)(react@18.2.0) 531 - next: 532 - specifier: 13.2.4 533 - version: 13.2.4(@babel/core@7.22.9)(react-dom@18.2.0)(react@18.2.0) 534 - prism-react-renderer: 535 - specifier: 1.3.5 536 - version: 1.3.5(react@18.2.0) 537 - react: 538 - specifier: 18.2.0 539 - version: 18.2.0 540 - react-dom: 541 - specifier: 18.2.0 542 - version: 18.2.0(react@18.2.0) 543 - react-email: 544 - specifier: 1.9.4 545 - version: 1.9.4 546 - devDependencies: 547 - '@types/classnames': 548 - specifier: 2.3.1 549 - version: 2.3.1 550 - '@types/node': 551 - specifier: 18.11.9 552 - version: 18.11.9 553 - '@types/react': 554 - specifier: 18.0.25 555 - version: 18.0.25 556 - '@types/react-dom': 557 - specifier: 18.0.9 558 - version: 18.0.9 559 - autoprefixer: 560 - specifier: 10.4.13 561 - version: 10.4.13(postcss@8.4.19) 562 - eslint: 563 - specifier: 8.36.0 564 - version: 8.36.0 565 - eslint-config-next: 566 - specifier: 13.2.4 567 - version: 13.2.4(eslint@8.36.0)(typescript@4.9.3) 568 - eslint-config-prettier: 569 - specifier: 8.7.0 570 - version: 8.7.0(eslint@8.36.0) 571 - eslint-plugin-simple-import-sort: 572 - specifier: 10.0.0 573 - version: 10.0.0(eslint@8.36.0) 574 - eslint-plugin-unused-imports: 575 - specifier: 2.0.0 576 - version: 2.0.0(eslint@8.36.0) 577 - postcss: 578 - specifier: 8.4.19 579 - version: 8.4.19 580 - prettier: 581 - specifier: 2.8.4 582 - version: 2.8.4 583 - tailwindcss: 584 - specifier: 3.2.4 585 - version: 3.2.4(postcss@8.4.19) 586 - typescript: 587 - specifier: 4.9.3 588 - version: 4.9.3 589 - 590 499 packages/plans: 591 500 dependencies: 592 501 '@openstatus/db': ··· 893 802 engines: {node: '>=6.9.0'} 894 803 dependencies: 895 804 regenerator-runtime: 0.13.11 805 + dev: false 896 806 897 807 /@babel/template@7.22.5: 898 808 resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} ··· 990 900 '@clerk/clerk-react': 4.23.1(react@18.2.0) 991 901 '@clerk/clerk-sdk-node': 4.12.1 992 902 '@clerk/types': 3.48.1 993 - next: 13.4.12(@babel/core@7.22.9)(react-dom@18.2.0)(react@18.2.0) 903 + next: 13.4.12(@babel/core@7.22.9)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) 994 904 path-to-regexp: 6.2.1 995 905 react: 18.2.0 996 906 react-dom: 18.2.0(react@18.2.0) ··· 1216 1126 /@effect-ts/system@0.57.5: 1217 1127 resolution: {integrity: sha512-/crHGujo0xnuHIYNc1VgP0HGJGFSoSqq88JFXe6FmFyXPpWt8Xu39LyLg7rchsxfXFeEdA9CrIZvLV5eswXV5g==} 1218 1128 dev: false 1219 - 1220 - /@emotion/is-prop-valid@0.8.8: 1221 - resolution: {integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==} 1222 - requiresBuild: true 1223 - dependencies: 1224 - '@emotion/memoize': 0.7.4 1225 - dev: false 1226 - optional: true 1227 - 1228 - /@emotion/memoize@0.7.4: 1229 - resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} 1230 - requiresBuild: true 1231 - dev: false 1232 - optional: true 1233 1129 1234 1130 /@esbuild-kit/core-utils@3.1.0: 1235 1131 resolution: {integrity: sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==} ··· 2051 1947 dev: false 2052 1948 optional: true 2053 1949 2054 - /@eslint-community/eslint-utils@4.4.0(eslint@8.36.0): 2055 - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} 2056 - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 2057 - peerDependencies: 2058 - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 2059 - dependencies: 2060 - eslint: 8.36.0 2061 - eslint-visitor-keys: 3.4.2 2062 - dev: true 2063 - 2064 1950 /@eslint-community/eslint-utils@4.4.0(eslint@8.43.0): 2065 1951 resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} 2066 1952 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} ··· 2100 1986 transitivePeerDependencies: 2101 1987 - supports-color 2102 1988 2103 - /@eslint/js@8.36.0: 2104 - resolution: {integrity: sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==} 2105 - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 2106 - dev: true 2107 - 2108 1989 /@eslint/js@8.43.0: 2109 1990 resolution: {integrity: sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==} 2110 1991 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} ··· 2118 1999 resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} 2119 2000 dev: false 2120 2001 2121 - /@floating-ui/core@0.7.3: 2122 - resolution: {integrity: sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==} 2123 - dev: false 2124 - 2125 2002 /@floating-ui/core@1.3.1: 2126 2003 resolution: {integrity: sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==} 2127 2004 dev: false 2128 2005 2129 - /@floating-ui/dom@0.5.4: 2130 - resolution: {integrity: sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==} 2131 - dependencies: 2132 - '@floating-ui/core': 0.7.3 2133 - dev: false 2134 - 2135 2006 /@floating-ui/dom@1.4.5: 2136 2007 resolution: {integrity: sha512-96KnRWkRnuBSSFbj0sFGwwOUd8EkiecINVl0O9wiZlZ64EkpyAOG3Xc2vKKNJmru0Z7RqWNymA+6b8OZqjgyyw==} 2137 2008 dependencies: 2138 2009 '@floating-ui/core': 1.3.1 2139 - dev: false 2140 - 2141 - /@floating-ui/react-dom@0.7.2(@types/react@18.0.25)(react-dom@18.2.0)(react@18.2.0): 2142 - resolution: {integrity: sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg==} 2143 - peerDependencies: 2144 - react: '>=16.8.0' 2145 - react-dom: '>=16.8.0' 2146 - dependencies: 2147 - '@floating-ui/dom': 0.5.4 2148 - react: 18.2.0 2149 - react-dom: 18.2.0(react@18.2.0) 2150 - use-isomorphic-layout-effect: 1.1.2(@types/react@18.0.25)(react@18.2.0) 2151 - transitivePeerDependencies: 2152 - - '@types/react' 2153 2010 dev: false 2154 2011 2155 2012 /@floating-ui/react-dom@2.0.1(react-dom@18.2.0)(react@18.2.0): ··· 2406 2263 react: 18.2.0 2407 2264 dev: false 2408 2265 2409 - /@motionone/animation@10.15.1: 2410 - resolution: {integrity: sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==} 2411 - dependencies: 2412 - '@motionone/easing': 10.15.1 2413 - '@motionone/types': 10.15.1 2414 - '@motionone/utils': 10.15.1 2415 - tslib: 2.6.1 2416 - dev: false 2417 - 2418 - /@motionone/dom@10.16.2: 2419 - resolution: {integrity: sha512-bnuHdNbge1FutZXv+k7xub9oPWcF0hsu8y1HTH/qg6av58YI0VufZ3ngfC7p2xhMJMnoh0LXFma2EGTgPeCkeg==} 2420 - dependencies: 2421 - '@motionone/animation': 10.15.1 2422 - '@motionone/generators': 10.15.1 2423 - '@motionone/types': 10.15.1 2424 - '@motionone/utils': 10.15.1 2425 - hey-listen: 1.0.8 2426 - tslib: 2.6.1 2427 - dev: false 2428 - 2429 - /@motionone/easing@10.15.1: 2430 - resolution: {integrity: sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==} 2431 - dependencies: 2432 - '@motionone/utils': 10.15.1 2433 - tslib: 2.6.1 2434 - dev: false 2435 - 2436 - /@motionone/generators@10.15.1: 2437 - resolution: {integrity: sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==} 2438 - dependencies: 2439 - '@motionone/types': 10.15.1 2440 - '@motionone/utils': 10.15.1 2441 - tslib: 2.6.1 2442 - dev: false 2443 - 2444 - /@motionone/types@10.15.1: 2445 - resolution: {integrity: sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==} 2446 - dev: false 2447 - 2448 - /@motionone/utils@10.15.1: 2449 - resolution: {integrity: sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==} 2450 - dependencies: 2451 - '@motionone/types': 10.15.1 2452 - hey-listen: 1.0.8 2453 - tslib: 2.6.1 2454 - dev: false 2455 - 2456 2266 /@napi-rs/simple-git-android-arm-eabi@0.1.8: 2457 2267 resolution: {integrity: sha512-JJCejHBB1G6O8nxjQLT4quWCcvLpC3oRdJJ9G3MFYSCoYS8i1bWCWeU+K7Br+xT+D6s1t9q8kNJAwJv9Ygpi0g==} 2458 2268 engines: {node: '>= 10'} ··· 2569 2379 '@napi-rs/simple-git-win32-x64-msvc': 0.1.8 2570 2380 dev: false 2571 2381 2572 - /@next/env@13.2.4: 2573 - resolution: {integrity: sha512-+Mq3TtpkeeKFZanPturjcXt+KHfKYnLlX6jMLyCrmpq6OOs4i1GqBOAauSkii9QeKCMTYzGppar21JU57b/GEA==} 2574 - dev: false 2575 - 2576 2382 /@next/env@13.4.12: 2577 2383 resolution: {integrity: sha512-RmHanbV21saP/6OEPBJ7yJMuys68cIf8OBBWd7+uj40LdpmswVAwe1uzeuFyUsd6SfeITWT3XnQfn6wULeKwDQ==} 2578 2384 dev: false 2579 2385 2580 - /@next/eslint-plugin-next@13.2.4: 2581 - resolution: {integrity: sha512-ck1lI+7r1mMJpqLNa3LJ5pxCfOB1lfJncKmRJeJxcJqcngaFwylreLP7da6Rrjr6u2gVRTfmnkSkjc80IiQCwQ==} 2582 - dependencies: 2583 - glob: 7.1.7 2584 - dev: true 2585 - 2586 2386 /@next/eslint-plugin-next@13.4.1: 2587 2387 resolution: {integrity: sha512-tVPS/2FKlA3ANCRCYZVT5jdbUKasBU8LG6bYqcNhyORDFTlDYa4cAWQJjZ7msIgLwMQIbL8CAsxrOL8maa/4Lg==} 2588 2388 dependencies: 2589 2389 glob: 7.1.7 2590 2390 dev: false 2591 2391 2592 - /@next/swc-android-arm-eabi@13.2.4: 2593 - resolution: {integrity: sha512-DWlalTSkLjDU11MY11jg17O1gGQzpRccM9Oes2yTqj2DpHndajrXHGxj9HGtJ+idq2k7ImUdJVWS2h2l/EDJOw==} 2594 - engines: {node: '>= 10'} 2595 - cpu: [arm] 2596 - os: [android] 2597 - requiresBuild: true 2598 - dev: false 2599 - optional: true 2600 - 2601 - /@next/swc-android-arm64@13.2.4: 2602 - resolution: {integrity: sha512-sRavmUImUCf332Gy+PjIfLkMhiRX1Ez4SI+3vFDRs1N5eXp+uNzjFUK/oLMMOzk6KFSkbiK/3Wt8+dHQR/flNg==} 2603 - engines: {node: '>= 10'} 2604 - cpu: [arm64] 2605 - os: [android] 2606 - requiresBuild: true 2607 - dev: false 2608 - optional: true 2609 - 2610 - /@next/swc-darwin-arm64@13.2.4: 2611 - resolution: {integrity: sha512-S6vBl+OrInP47TM3LlYx65betocKUUlTZDDKzTiRDbsRESeyIkBtZ6Qi5uT2zQs4imqllJznVjFd1bXLx3Aa6A==} 2612 - engines: {node: '>= 10'} 2613 - cpu: [arm64] 2614 - os: [darwin] 2615 - requiresBuild: true 2616 - dev: false 2617 - optional: true 2618 - 2619 2392 /@next/swc-darwin-arm64@13.4.12: 2620 2393 resolution: {integrity: sha512-deUrbCXTMZ6ZhbOoloqecnUeNpUOupi8SE2tx4jPfNS9uyUR9zK4iXBvH65opVcA/9F5I/p8vDXSYbUlbmBjZg==} 2621 2394 engines: {node: '>= 10'} ··· 2625 2398 dev: false 2626 2399 optional: true 2627 2400 2628 - /@next/swc-darwin-x64@13.2.4: 2629 - resolution: {integrity: sha512-a6LBuoYGcFOPGd4o8TPo7wmv5FnMr+Prz+vYHopEDuhDoMSHOnC+v+Ab4D7F0NMZkvQjEJQdJS3rqgFhlZmKlw==} 2630 - engines: {node: '>= 10'} 2631 - cpu: [x64] 2632 - os: [darwin] 2633 - requiresBuild: true 2634 - dev: false 2635 - optional: true 2636 - 2637 2401 /@next/swc-darwin-x64@13.4.12: 2638 2402 resolution: {integrity: sha512-WRvH7RxgRHlC1yb5oG0ZLx8F7uci9AivM5/HGGv9ZyG2Als8Ij64GC3d+mQ5sJhWjusyU6T6V1WKTUoTmOB0zQ==} 2639 2403 engines: {node: '>= 10'} ··· 2643 2407 dev: false 2644 2408 optional: true 2645 2409 2646 - /@next/swc-freebsd-x64@13.2.4: 2647 - resolution: {integrity: sha512-kkbzKVZGPaXRBPisoAQkh3xh22r+TD+5HwoC5bOkALraJ0dsOQgSMAvzMXKsN3tMzJUPS0tjtRf1cTzrQ0I5vQ==} 2648 - engines: {node: '>= 10'} 2649 - cpu: [x64] 2650 - os: [freebsd] 2651 - requiresBuild: true 2652 - dev: false 2653 - optional: true 2654 - 2655 - /@next/swc-linux-arm-gnueabihf@13.2.4: 2656 - resolution: {integrity: sha512-7qA1++UY0fjprqtjBZaOA6cas/7GekpjVsZn/0uHvquuITFCdKGFCsKNBx3S0Rpxmx6WYo0GcmhNRM9ru08BGg==} 2657 - engines: {node: '>= 10'} 2658 - cpu: [arm] 2659 - os: [linux] 2660 - requiresBuild: true 2661 - dev: false 2662 - optional: true 2663 - 2664 - /@next/swc-linux-arm64-gnu@13.2.4: 2665 - resolution: {integrity: sha512-xzYZdAeq883MwXgcwc72hqo/F/dwUxCukpDOkx/j1HTq/J0wJthMGjinN9wH5bPR98Mfeh1MZJ91WWPnZOedOg==} 2666 - engines: {node: '>= 10'} 2667 - cpu: [arm64] 2668 - os: [linux] 2669 - requiresBuild: true 2670 - dev: false 2671 - optional: true 2672 - 2673 2410 /@next/swc-linux-arm64-gnu@13.4.12: 2674 2411 resolution: {integrity: sha512-YEKracAWuxp54tKiAvvq73PUs9lok57cc8meYRibTWe/VdPB2vLgkTVWFcw31YDuRXdEhdX0fWS6Q+ESBhnEig==} 2675 2412 engines: {node: '>= 10'} ··· 2679 2416 dev: false 2680 2417 optional: true 2681 2418 2682 - /@next/swc-linux-arm64-musl@13.2.4: 2683 - resolution: {integrity: sha512-8rXr3WfmqSiYkb71qzuDP6I6R2T2tpkmf83elDN8z783N9nvTJf2E7eLx86wu2OJCi4T05nuxCsh4IOU3LQ5xw==} 2684 - engines: {node: '>= 10'} 2685 - cpu: [arm64] 2686 - os: [linux] 2687 - requiresBuild: true 2688 - dev: false 2689 - optional: true 2690 - 2691 2419 /@next/swc-linux-arm64-musl@13.4.12: 2692 2420 resolution: {integrity: sha512-LhJR7/RAjdHJ2Isl2pgc/JaoxNk0KtBgkVpiDJPVExVWA1c6gzY57+3zWuxuyWzTG+fhLZo2Y80pLXgIJv7g3g==} 2693 2421 engines: {node: '>= 10'} ··· 2697 2425 dev: false 2698 2426 optional: true 2699 2427 2700 - /@next/swc-linux-x64-gnu@13.2.4: 2701 - resolution: {integrity: sha512-Ngxh51zGSlYJ4EfpKG4LI6WfquulNdtmHg1yuOYlaAr33KyPJp4HeN/tivBnAHcZkoNy0hh/SbwDyCnz5PFJQQ==} 2702 - engines: {node: '>= 10'} 2703 - cpu: [x64] 2704 - os: [linux] 2705 - requiresBuild: true 2706 - dev: false 2707 - optional: true 2708 - 2709 2428 /@next/swc-linux-x64-gnu@13.4.12: 2710 2429 resolution: {integrity: sha512-1DWLL/B9nBNiQRng+1aqs3OaZcxC16Nf+mOnpcrZZSdyKHek3WQh6j/fkbukObgNGwmCoVevLUa/p3UFTTqgqg==} 2711 2430 engines: {node: '>= 10'} ··· 2715 2434 dev: false 2716 2435 optional: true 2717 2436 2718 - /@next/swc-linux-x64-musl@13.2.4: 2719 - resolution: {integrity: sha512-gOvwIYoSxd+j14LOcvJr+ekd9fwYT1RyMAHOp7znA10+l40wkFiMONPLWiZuHxfRk+Dy7YdNdDh3ImumvL6VwA==} 2720 - engines: {node: '>= 10'} 2721 - cpu: [x64] 2722 - os: [linux] 2723 - requiresBuild: true 2724 - dev: false 2725 - optional: true 2726 - 2727 2437 /@next/swc-linux-x64-musl@13.4.12: 2728 2438 resolution: {integrity: sha512-kEAJmgYFhp0VL+eRWmUkVxLVunn7oL9Mdue/FS8yzRBVj7Z0AnIrHpTIeIUl1bbdQq1VaoOztnKicAjfkLTRCQ==} 2729 2439 engines: {node: '>= 10'} ··· 2733 2443 dev: false 2734 2444 optional: true 2735 2445 2736 - /@next/swc-win32-arm64-msvc@13.2.4: 2737 - resolution: {integrity: sha512-q3NJzcfClgBm4HvdcnoEncmztxrA5GXqKeiZ/hADvC56pwNALt3ngDC6t6qr1YW9V/EPDxCYeaX4zYxHciW4Dw==} 2738 - engines: {node: '>= 10'} 2739 - cpu: [arm64] 2740 - os: [win32] 2741 - requiresBuild: true 2742 - dev: false 2743 - optional: true 2744 - 2745 2446 /@next/swc-win32-arm64-msvc@13.4.12: 2746 2447 resolution: {integrity: sha512-GMLuL/loR6yIIRTnPRY6UGbLL9MBdw2anxkOnANxvLvsml4F0HNIgvnU3Ej4BjbqMTNjD4hcPFdlEow4XHPdZA==} 2747 2448 engines: {node: '>= 10'} ··· 2751 2452 dev: false 2752 2453 optional: true 2753 2454 2754 - /@next/swc-win32-ia32-msvc@13.2.4: 2755 - resolution: {integrity: sha512-/eZ5ncmHUYtD2fc6EUmAIZlAJnVT2YmxDsKs1Ourx0ttTtvtma/WKlMV5NoUsyOez0f9ExLyOpeCoz5aj+MPXw==} 2756 - engines: {node: '>= 10'} 2757 - cpu: [ia32] 2758 - os: [win32] 2759 - requiresBuild: true 2760 - dev: false 2761 - optional: true 2762 - 2763 2455 /@next/swc-win32-ia32-msvc@13.4.12: 2764 2456 resolution: {integrity: sha512-PhgNqN2Vnkm7XaMdRmmX0ZSwZXQAtamBVSa9A/V1dfKQCV1rjIZeiy/dbBnVYGdj63ANfsOR/30XpxP71W0eww==} 2765 2457 engines: {node: '>= 10'} 2766 2458 cpu: [ia32] 2767 - os: [win32] 2768 - requiresBuild: true 2769 - dev: false 2770 - optional: true 2771 - 2772 - /@next/swc-win32-x64-msvc@13.2.4: 2773 - resolution: {integrity: sha512-0MffFmyv7tBLlji01qc0IaPP/LVExzvj7/R5x1Jph1bTAIj4Vu81yFQWHHQAP6r4ff9Ukj1mBK6MDNVXm7Tcvw==} 2774 - engines: {node: '>= 10'} 2775 - cpu: [x64] 2776 2459 os: [win32] 2777 2460 requiresBuild: true 2778 2461 dev: false ··· 3141 2824 open: 9.1.0 3142 2825 picocolors: 1.0.0 3143 2826 tslib: 2.6.1 2827 + dev: false 3144 2828 3145 2829 /@popperjs/core@2.11.8: 3146 2830 resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} ··· 3187 2871 3188 2872 /@protobufjs/utf8@1.1.0: 3189 2873 resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} 3190 - dev: false 3191 - 3192 - /@radix-ui/colors@0.1.8: 3193 - resolution: {integrity: sha512-jwRMXYwC0hUo0mv6wGpuw254Pd9p/R6Td5xsRpOmaWkUHlooNWqVcadgyzlRumMq3xfOTXwJReU0Jv+EIy4Jbw==} 3194 2874 dev: false 3195 2875 3196 2876 /@radix-ui/number@1.0.1: ··· 3266 2946 react-dom: 18.2.0(react@18.2.0) 3267 2947 dev: false 3268 2948 3269 - /@radix-ui/react-arrow@1.0.1(react-dom@18.2.0)(react@18.2.0): 3270 - resolution: {integrity: sha512-1yientwXqXcErDHEv8av9ZVNEBldH8L9scVR3is20lL+jOCfcJyMFZFEY5cgIrgexsq1qggSXqiEL/d/4f+QXA==} 3271 - peerDependencies: 3272 - react: ^16.8 || ^17.0 || ^18.0 3273 - react-dom: ^16.8 || ^17.0 || ^18.0 3274 - dependencies: 3275 - '@babel/runtime': 7.22.6 3276 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3277 - react: 18.2.0 3278 - react-dom: 18.2.0(react@18.2.0) 3279 - dev: false 3280 - 3281 2949 /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 3282 2950 resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} 3283 2951 peerDependencies: ··· 3327 2995 react-dom: 18.2.0(react@18.2.0) 3328 2996 dev: false 3329 2997 3330 - /@radix-ui/react-collapsible@1.0.1(react-dom@18.2.0)(react@18.2.0): 3331 - resolution: {integrity: sha512-0maX4q91iYa4gjt3PsNf7dq/yqSR+HGAE8I5p54dQ6gnveS+ETWlMoijxrhmgV1k8svxpm34mQAtqIrJt4XZmA==} 3332 - peerDependencies: 3333 - react: ^16.8 || ^17.0 || ^18.0 3334 - react-dom: ^16.8 || ^17.0 || ^18.0 3335 - dependencies: 3336 - '@babel/runtime': 7.22.6 3337 - '@radix-ui/primitive': 1.0.0 3338 - '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) 3339 - '@radix-ui/react-context': 1.0.0(react@18.2.0) 3340 - '@radix-ui/react-id': 1.0.0(react@18.2.0) 3341 - '@radix-ui/react-presence': 1.0.0(react-dom@18.2.0)(react@18.2.0) 3342 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3343 - '@radix-ui/react-use-controllable-state': 1.0.0(react@18.2.0) 3344 - '@radix-ui/react-use-layout-effect': 1.0.0(react@18.2.0) 3345 - react: 18.2.0 3346 - react-dom: 18.2.0(react@18.2.0) 3347 - dev: false 3348 - 3349 2998 /@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 3350 2999 resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==} 3351 3000 peerDependencies: ··· 3370 3019 '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3371 3020 '@types/react': 18.2.12 3372 3021 '@types/react-dom': 18.2.5 3373 - react: 18.2.0 3374 - react-dom: 18.2.0(react@18.2.0) 3375 - dev: false 3376 - 3377 - /@radix-ui/react-collection@1.0.1(react-dom@18.2.0)(react@18.2.0): 3378 - resolution: {integrity: sha512-uuiFbs+YCKjn3X1DTSx9G7BHApu4GHbi3kgiwsnFUbOKCrwejAJv4eE4Vc8C0Oaxt9T0aV4ox0WCOdx+39Xo+g==} 3379 - peerDependencies: 3380 - react: ^16.8 || ^17.0 || ^18.0 3381 - react-dom: ^16.8 || ^17.0 || ^18.0 3382 - dependencies: 3383 - '@babel/runtime': 7.22.6 3384 - '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) 3385 - '@radix-ui/react-context': 1.0.0(react@18.2.0) 3386 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3387 - '@radix-ui/react-slot': 1.0.1(react@18.2.0) 3388 3022 react: 18.2.0 3389 3023 react-dom: 18.2.0(react@18.2.0) 3390 3024 dev: false ··· 3520 3154 react-remove-scroll: 2.5.5(@types/react@18.2.12)(react@18.2.0) 3521 3155 dev: false 3522 3156 3523 - /@radix-ui/react-direction@1.0.0(react@18.2.0): 3524 - resolution: {integrity: sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==} 3525 - peerDependencies: 3526 - react: ^16.8 || ^17.0 || ^18.0 3527 - dependencies: 3528 - '@babel/runtime': 7.22.6 3529 - react: 18.2.0 3530 - dev: false 3531 - 3532 3157 /@radix-ui/react-direction@1.0.1(@types/react@18.2.12)(react@18.2.0): 3533 3158 resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} 3534 3159 peerDependencies: ··· 3555 3180 '@radix-ui/react-primitive': 1.0.0(react-dom@18.2.0)(react@18.2.0) 3556 3181 '@radix-ui/react-use-callback-ref': 1.0.0(react@18.2.0) 3557 3182 '@radix-ui/react-use-escape-keydown': 1.0.0(react@18.2.0) 3558 - react: 18.2.0 3559 - react-dom: 18.2.0(react@18.2.0) 3560 - dev: false 3561 - 3562 - /@radix-ui/react-dismissable-layer@1.0.2(react-dom@18.2.0)(react@18.2.0): 3563 - resolution: {integrity: sha512-WjJzMrTWROozDqLB0uRWYvj4UuXsM/2L19EmQ3Au+IJWqwvwq9Bwd+P8ivo0Deg9JDPArR1I6MbWNi1CmXsskg==} 3564 - peerDependencies: 3565 - react: ^16.8 || ^17.0 || ^18.0 3566 - react-dom: ^16.8 || ^17.0 || ^18.0 3567 - dependencies: 3568 - '@babel/runtime': 7.22.6 3569 - '@radix-ui/primitive': 1.0.0 3570 - '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) 3571 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3572 - '@radix-ui/react-use-callback-ref': 1.0.0(react@18.2.0) 3573 - '@radix-ui/react-use-escape-keydown': 1.0.2(react@18.2.0) 3574 3183 react: 18.2.0 3575 3184 react-dom: 18.2.0(react@18.2.0) 3576 3185 dev: false ··· 3664 3273 react-dom: 18.2.0(react@18.2.0) 3665 3274 dev: false 3666 3275 3667 - /@radix-ui/react-focus-scope@1.0.1(react-dom@18.2.0)(react@18.2.0): 3668 - resolution: {integrity: sha512-Ej2MQTit8IWJiS2uuujGUmxXjF/y5xZptIIQnyd2JHLwtV0R2j9NRVoRj/1j/gJ7e3REdaBw4Hjf4a1ImhkZcQ==} 3669 - peerDependencies: 3670 - react: ^16.8 || ^17.0 || ^18.0 3671 - react-dom: ^16.8 || ^17.0 || ^18.0 3672 - dependencies: 3673 - '@babel/runtime': 7.22.6 3674 - '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) 3675 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3676 - '@radix-ui/react-use-callback-ref': 1.0.0(react@18.2.0) 3677 - react: 18.2.0 3678 - react-dom: 18.2.0(react@18.2.0) 3679 - dev: false 3680 - 3681 3276 /@radix-ui/react-focus-scope@1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 3682 3277 resolution: {integrity: sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==} 3683 3278 peerDependencies: ··· 3814 3409 react-remove-scroll: 2.5.5(@types/react@18.2.12)(react@18.2.0) 3815 3410 dev: false 3816 3411 3817 - /@radix-ui/react-popover@1.0.2(@types/react@18.0.25)(react-dom@18.2.0)(react@18.2.0): 3818 - resolution: {integrity: sha512-4tqZEl9w95R5mlZ/sFdgBnfhCBOEPepLIurBA5kt/qaAhldJ1tNQd0ngr0ET0AHbPotT4mwxMPr7a+MA/wbK0g==} 3819 - peerDependencies: 3820 - react: ^16.8 || ^17.0 || ^18.0 3821 - react-dom: ^16.8 || ^17.0 || ^18.0 3822 - dependencies: 3823 - '@babel/runtime': 7.22.6 3824 - '@radix-ui/primitive': 1.0.0 3825 - '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) 3826 - '@radix-ui/react-context': 1.0.0(react@18.2.0) 3827 - '@radix-ui/react-dismissable-layer': 1.0.2(react-dom@18.2.0)(react@18.2.0) 3828 - '@radix-ui/react-focus-guards': 1.0.0(react@18.2.0) 3829 - '@radix-ui/react-focus-scope': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3830 - '@radix-ui/react-id': 1.0.0(react@18.2.0) 3831 - '@radix-ui/react-popper': 1.0.1(@types/react@18.0.25)(react-dom@18.2.0)(react@18.2.0) 3832 - '@radix-ui/react-portal': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3833 - '@radix-ui/react-presence': 1.0.0(react-dom@18.2.0)(react@18.2.0) 3834 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3835 - '@radix-ui/react-slot': 1.0.1(react@18.2.0) 3836 - '@radix-ui/react-use-controllable-state': 1.0.0(react@18.2.0) 3837 - aria-hidden: 1.2.3 3838 - react: 18.2.0 3839 - react-dom: 18.2.0(react@18.2.0) 3840 - react-remove-scroll: 2.5.5(@types/react@18.0.25)(react@18.2.0) 3841 - transitivePeerDependencies: 3842 - - '@types/react' 3843 - dev: false 3844 - 3845 3412 /@radix-ui/react-popover@1.0.6(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 3846 3413 resolution: {integrity: sha512-cZ4defGpkZ0qTRtlIBzJLSzL6ht7ofhhW4i1+pkemjV1IKXm0wgCRnee154qlV6r9Ttunmh2TNZhMfV2bavUyA==} 3847 3414 peerDependencies: ··· 3877 3444 react-remove-scroll: 2.5.5(@types/react@18.2.12)(react@18.2.0) 3878 3445 dev: false 3879 3446 3880 - /@radix-ui/react-popper@1.0.1(@types/react@18.0.25)(react-dom@18.2.0)(react@18.2.0): 3881 - resolution: {integrity: sha512-J4Vj7k3k+EHNWgcKrE+BLlQfpewxA7Zd76h5I0bIa+/EqaIZ3DuwrbPj49O3wqN+STnXsBuxiHLiF0iU3yfovw==} 3882 - peerDependencies: 3883 - react: ^16.8 || ^17.0 || ^18.0 3884 - react-dom: ^16.8 || ^17.0 || ^18.0 3885 - dependencies: 3886 - '@babel/runtime': 7.22.6 3887 - '@floating-ui/react-dom': 0.7.2(@types/react@18.0.25)(react-dom@18.2.0)(react@18.2.0) 3888 - '@radix-ui/react-arrow': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3889 - '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) 3890 - '@radix-ui/react-context': 1.0.0(react@18.2.0) 3891 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3892 - '@radix-ui/react-use-layout-effect': 1.0.0(react@18.2.0) 3893 - '@radix-ui/react-use-rect': 1.0.0(react@18.2.0) 3894 - '@radix-ui/react-use-size': 1.0.0(react@18.2.0) 3895 - '@radix-ui/rect': 1.0.0 3896 - react: 18.2.0 3897 - react-dom: 18.2.0(react@18.2.0) 3898 - transitivePeerDependencies: 3899 - - '@types/react' 3900 - dev: false 3901 - 3902 3447 /@radix-ui/react-popper@1.1.2(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 3903 3448 resolution: {integrity: sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==} 3904 3449 peerDependencies: ··· 3941 3486 react-dom: 18.2.0(react@18.2.0) 3942 3487 dev: false 3943 3488 3944 - /@radix-ui/react-portal@1.0.1(react-dom@18.2.0)(react@18.2.0): 3945 - resolution: {integrity: sha512-NY2vUWI5WENgAT1nfC6JS7RU5xRYBfjZVLq0HmgEN1Ezy3rk/UruMV4+Rd0F40PEaFC5SrLS1ixYvcYIQrb4Ig==} 3946 - peerDependencies: 3947 - react: ^16.8 || ^17.0 || ^18.0 3948 - react-dom: ^16.8 || ^17.0 || ^18.0 3949 - dependencies: 3950 - '@babel/runtime': 7.22.6 3951 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3952 - react: 18.2.0 3953 - react-dom: 18.2.0(react@18.2.0) 3954 - dev: false 3955 - 3956 3489 /@radix-ui/react-portal@1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 3957 3490 resolution: {integrity: sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==} 3958 3491 peerDependencies: ··· 4021 3554 react-dom: 18.2.0(react@18.2.0) 4022 3555 dev: false 4023 3556 4024 - /@radix-ui/react-primitive@1.0.1(react-dom@18.2.0)(react@18.2.0): 4025 - resolution: {integrity: sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==} 4026 - peerDependencies: 4027 - react: ^16.8 || ^17.0 || ^18.0 4028 - react-dom: ^16.8 || ^17.0 || ^18.0 4029 - dependencies: 4030 - '@babel/runtime': 7.22.6 4031 - '@radix-ui/react-slot': 1.0.1(react@18.2.0) 4032 - react: 18.2.0 4033 - react-dom: 18.2.0(react@18.2.0) 4034 - dev: false 4035 - 4036 3557 /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 4037 3558 resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} 4038 3559 peerDependencies: ··· 4054 3575 react-dom: 18.2.0(react@18.2.0) 4055 3576 dev: false 4056 3577 4057 - /@radix-ui/react-roving-focus@1.0.1(react-dom@18.2.0)(react@18.2.0): 4058 - resolution: {integrity: sha512-TB76u5TIxKpqMpUAuYH2VqMhHYKa+4Vs1NHygo/llLvlffN6mLVsFhz0AnSFlSBAvTBYVHYAkHAyEt7x1gPJOA==} 3578 + /@radix-ui/react-radio-group@1.1.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 3579 + resolution: {integrity: sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==} 4059 3580 peerDependencies: 3581 + '@types/react': '*' 3582 + '@types/react-dom': '*' 4060 3583 react: ^16.8 || ^17.0 || ^18.0 4061 3584 react-dom: ^16.8 || ^17.0 || ^18.0 3585 + peerDependenciesMeta: 3586 + '@types/react': 3587 + optional: true 3588 + '@types/react-dom': 3589 + optional: true 4062 3590 dependencies: 4063 3591 '@babel/runtime': 7.22.6 4064 - '@radix-ui/primitive': 1.0.0 4065 - '@radix-ui/react-collection': 1.0.1(react-dom@18.2.0)(react@18.2.0) 4066 - '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) 4067 - '@radix-ui/react-context': 1.0.0(react@18.2.0) 4068 - '@radix-ui/react-direction': 1.0.0(react@18.2.0) 4069 - '@radix-ui/react-id': 1.0.0(react@18.2.0) 4070 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 4071 - '@radix-ui/react-use-callback-ref': 1.0.0(react@18.2.0) 4072 - '@radix-ui/react-use-controllable-state': 1.0.0(react@18.2.0) 3592 + '@radix-ui/primitive': 1.0.1 3593 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3594 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3595 + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3596 + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 3597 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 3598 + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 3599 + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3600 + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3601 + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3602 + '@types/react': 18.2.12 3603 + '@types/react-dom': 18.2.5 4073 3604 react: 18.2.0 4074 3605 react-dom: 18.2.0(react@18.2.0) 4075 3606 dev: false ··· 4175 3706 react: 18.2.0 4176 3707 dev: false 4177 3708 4178 - /@radix-ui/react-slot@1.0.1(react@18.2.0): 4179 - resolution: {integrity: sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==} 4180 - peerDependencies: 4181 - react: ^16.8 || ^17.0 || ^18.0 4182 - dependencies: 4183 - '@babel/runtime': 7.22.6 4184 - '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) 4185 - react: 18.2.0 4186 - dev: false 4187 - 4188 3709 /@radix-ui/react-slot@1.0.2(@types/react@18.2.12)(react@18.2.0): 4189 3710 resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} 4190 3711 peerDependencies: ··· 4227 3748 react-dom: 18.2.0(react@18.2.0) 4228 3749 dev: false 4229 3750 4230 - /@radix-ui/react-toast@1.1.4(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 4231 - resolution: {integrity: sha512-wf+fc8DOywrpRK3jlPlWVe+ELYGHdKDaaARJZNuUTWyWYq7+ANCFLp4rTjZ/mcGkJJQ/vZ949Zis9xxEpfq9OA==} 3751 + /@radix-ui/react-tabs@1.0.4(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 3752 + resolution: {integrity: sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==} 4232 3753 peerDependencies: 4233 3754 '@types/react': '*' 4234 3755 '@types/react-dom': '*' ··· 4242 3763 dependencies: 4243 3764 '@babel/runtime': 7.22.6 4244 3765 '@radix-ui/primitive': 1.0.1 4245 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 4246 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.12)(react@18.2.0) 4247 3766 '@radix-ui/react-context': 1.0.1(@types/react@18.2.12)(react@18.2.0) 4248 - '@radix-ui/react-dismissable-layer': 1.0.4(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 4249 - '@radix-ui/react-portal': 1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 3767 + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3768 + '@radix-ui/react-id': 1.0.1(@types/react@18.2.12)(react@18.2.0) 4250 3769 '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 4251 3770 '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 4252 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3771 + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 4253 3772 '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.12)(react@18.2.0) 4254 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.12)(react@18.2.0) 4255 - '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 4256 3773 '@types/react': 18.2.12 4257 3774 '@types/react-dom': 18.2.5 4258 3775 react: 18.2.0 4259 3776 react-dom: 18.2.0(react@18.2.0) 4260 3777 dev: false 4261 3778 4262 - /@radix-ui/react-toggle-group@1.0.1(react-dom@18.2.0)(react@18.2.0): 4263 - resolution: {integrity: sha512-eye/gYvzy82xtoSSeu5Pwlzrh6N2rOcDIwAI7xMatu622Qjlg64LtwB0PSh3iWdmn6Wqy1Fjo5twNPQsp0guiw==} 3779 + /@radix-ui/react-toast@1.1.4(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 3780 + resolution: {integrity: sha512-wf+fc8DOywrpRK3jlPlWVe+ELYGHdKDaaARJZNuUTWyWYq7+ANCFLp4rTjZ/mcGkJJQ/vZ949Zis9xxEpfq9OA==} 4264 3781 peerDependencies: 3782 + '@types/react': '*' 3783 + '@types/react-dom': '*' 4265 3784 react: ^16.8 || ^17.0 || ^18.0 4266 3785 react-dom: ^16.8 || ^17.0 || ^18.0 3786 + peerDependenciesMeta: 3787 + '@types/react': 3788 + optional: true 3789 + '@types/react-dom': 3790 + optional: true 4267 3791 dependencies: 4268 3792 '@babel/runtime': 7.22.6 4269 - '@radix-ui/primitive': 1.0.0 4270 - '@radix-ui/react-context': 1.0.0(react@18.2.0) 4271 - '@radix-ui/react-direction': 1.0.0(react@18.2.0) 4272 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 4273 - '@radix-ui/react-roving-focus': 1.0.1(react-dom@18.2.0)(react@18.2.0) 4274 - '@radix-ui/react-toggle': 1.0.1(react-dom@18.2.0)(react@18.2.0) 4275 - '@radix-ui/react-use-controllable-state': 1.0.0(react@18.2.0) 4276 - react: 18.2.0 4277 - react-dom: 18.2.0(react@18.2.0) 4278 - dev: false 4279 - 4280 - /@radix-ui/react-toggle@1.0.1(react-dom@18.2.0)(react@18.2.0): 4281 - resolution: {integrity: sha512-hZIp9ZKnw4NwVqeB4evWBLa91ryaSJhAO0Ed82wkzRPgg/I29ypcY6SuBb3AMZW+GsuBZpIVujpCq+33TdEcyg==} 4282 - peerDependencies: 4283 - react: ^16.8 || ^17.0 || ^18.0 4284 - react-dom: ^16.8 || ^17.0 || ^18.0 4285 - dependencies: 4286 - '@babel/runtime': 7.22.6 4287 - '@radix-ui/primitive': 1.0.0 4288 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 4289 - '@radix-ui/react-use-controllable-state': 1.0.0(react@18.2.0) 4290 - react: 18.2.0 4291 - react-dom: 18.2.0(react@18.2.0) 4292 - dev: false 4293 - 4294 - /@radix-ui/react-tooltip@1.0.2(@types/react@18.0.25)(react-dom@18.2.0)(react@18.2.0): 4295 - resolution: {integrity: sha512-11gUlok2rv5mu+KBtxniOKKNKjqC/uTbgFHWoQdbF46vMV+zjDaBvCtVDK9+MTddlpmlisGPGvvojX7Qm0yr+g==} 4296 - peerDependencies: 4297 - react: ^16.8 || ^17.0 || ^18.0 4298 - react-dom: ^16.8 || ^17.0 || ^18.0 4299 - dependencies: 4300 - '@babel/runtime': 7.22.6 4301 - '@radix-ui/primitive': 1.0.0 4302 - '@radix-ui/react-compose-refs': 1.0.0(react@18.2.0) 4303 - '@radix-ui/react-context': 1.0.0(react@18.2.0) 4304 - '@radix-ui/react-dismissable-layer': 1.0.2(react-dom@18.2.0)(react@18.2.0) 4305 - '@radix-ui/react-id': 1.0.0(react@18.2.0) 4306 - '@radix-ui/react-popper': 1.0.1(@types/react@18.0.25)(react-dom@18.2.0)(react@18.2.0) 4307 - '@radix-ui/react-portal': 1.0.1(react-dom@18.2.0)(react@18.2.0) 4308 - '@radix-ui/react-presence': 1.0.0(react-dom@18.2.0)(react@18.2.0) 4309 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 4310 - '@radix-ui/react-slot': 1.0.1(react@18.2.0) 4311 - '@radix-ui/react-use-controllable-state': 1.0.0(react@18.2.0) 4312 - '@radix-ui/react-visually-hidden': 1.0.1(react-dom@18.2.0)(react@18.2.0) 3793 + '@radix-ui/primitive': 1.0.1 3794 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 3795 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3796 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3797 + '@radix-ui/react-dismissable-layer': 1.0.4(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 3798 + '@radix-ui/react-portal': 1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 3799 + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 3800 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 3801 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3802 + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3803 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.12)(react@18.2.0) 3804 + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0) 3805 + '@types/react': 18.2.12 3806 + '@types/react-dom': 18.2.5 4313 3807 react: 18.2.0 4314 3808 react-dom: 18.2.0(react@18.2.0) 4315 - transitivePeerDependencies: 4316 - - '@types/react' 4317 3809 dev: false 4318 3810 4319 3811 /@radix-ui/react-tooltip@1.0.6(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): ··· 4406 3898 react: 18.2.0 4407 3899 dev: false 4408 3900 4409 - /@radix-ui/react-use-escape-keydown@1.0.2(react@18.2.0): 4410 - resolution: {integrity: sha512-DXGim3x74WgUv+iMNCF+cAo8xUHHeqvjx8zs7trKf+FkQKPQXLk2sX7Gx1ysH7Q76xCpZuxIJE7HLPxRE+Q+GA==} 4411 - peerDependencies: 4412 - react: ^16.8 || ^17.0 || ^18.0 4413 - dependencies: 4414 - '@babel/runtime': 7.22.6 4415 - '@radix-ui/react-use-callback-ref': 1.0.0(react@18.2.0) 4416 - react: 18.2.0 4417 - dev: false 4418 - 4419 3901 /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.12)(react@18.2.0): 4420 3902 resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} 4421 3903 peerDependencies: ··· 4465 3947 dependencies: 4466 3948 '@babel/runtime': 7.22.6 4467 3949 '@types/react': 18.2.12 4468 - react: 18.2.0 4469 - dev: false 4470 - 4471 - /@radix-ui/react-use-rect@1.0.0(react@18.2.0): 4472 - resolution: {integrity: sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew==} 4473 - peerDependencies: 4474 - react: ^16.8 || ^17.0 || ^18.0 4475 - dependencies: 4476 - '@babel/runtime': 7.22.6 4477 - '@radix-ui/rect': 1.0.0 4478 3950 react: 18.2.0 4479 3951 dev: false 4480 3952 ··· 4493 3965 react: 18.2.0 4494 3966 dev: false 4495 3967 4496 - /@radix-ui/react-use-size@1.0.0(react@18.2.0): 4497 - resolution: {integrity: sha512-imZ3aYcoYCKhhgNpkNDh/aTiU05qw9hX+HHI1QDBTyIlcFjgeFlKKySNGMwTp7nYFLQg/j0VA2FmCY4WPDDHMg==} 4498 - peerDependencies: 4499 - react: ^16.8 || ^17.0 || ^18.0 4500 - dependencies: 4501 - '@babel/runtime': 7.22.6 4502 - '@radix-ui/react-use-layout-effect': 1.0.0(react@18.2.0) 4503 - react: 18.2.0 4504 - dev: false 4505 - 4506 3968 /@radix-ui/react-use-size@1.0.1(@types/react@18.2.12)(react@18.2.0): 4507 3969 resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} 4508 3970 peerDependencies: ··· 4518 3980 react: 18.2.0 4519 3981 dev: false 4520 3982 4521 - /@radix-ui/react-visually-hidden@1.0.1(react-dom@18.2.0)(react@18.2.0): 4522 - resolution: {integrity: sha512-K1hJcCMfWfiYUibRqf3V8r5Drpyf7rh44jnrwAbdvI5iCCijilBBeyQv9SKidYNZIopMdCyR9FnIjkHxHN0FcQ==} 4523 - peerDependencies: 4524 - react: ^16.8 || ^17.0 || ^18.0 4525 - react-dom: ^16.8 || ^17.0 || ^18.0 4526 - dependencies: 4527 - '@babel/runtime': 7.22.6 4528 - '@radix-ui/react-primitive': 1.0.1(react-dom@18.2.0)(react@18.2.0) 4529 - react: 18.2.0 4530 - react-dom: 18.2.0(react@18.2.0) 4531 - dev: false 4532 - 4533 3983 /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.5)(@types/react@18.2.12)(react-dom@18.2.0)(react@18.2.0): 4534 3984 resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} 4535 3985 peerDependencies: ··· 4551 4001 react-dom: 18.2.0(react@18.2.0) 4552 4002 dev: false 4553 4003 4554 - /@radix-ui/rect@1.0.0: 4555 - resolution: {integrity: sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg==} 4556 - dependencies: 4557 - '@babel/runtime': 7.22.6 4558 - dev: false 4559 - 4560 4004 /@radix-ui/rect@1.0.1: 4561 4005 resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==} 4562 4006 dependencies: ··· 4723 4167 4724 4168 /@rushstack/eslint-patch@1.3.2: 4725 4169 resolution: {integrity: sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==} 4170 + dev: false 4726 4171 4727 4172 /@selderee/plugin-htmlparser2@0.10.0: 4728 4173 resolution: {integrity: sha512-gW69MEamZ4wk1OsOq1nG1jcyhXIQcnrsX5JwixVw/9xaiav8TCyjESAruu1Rz9yyInhgBXxkNwMeygKnN2uxNA==} ··· 4733 4178 4734 4179 /@stablelib/base64@1.0.1: 4735 4180 resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} 4736 - dev: false 4737 - 4738 - /@swc/helpers@0.4.14: 4739 - resolution: {integrity: sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==} 4740 - dependencies: 4741 - tslib: 2.6.1 4742 4181 dev: false 4743 4182 4744 4183 /@swc/helpers@0.5.1: ··· 4947 4386 '@types/node': 20.3.1 4948 4387 dev: false 4949 4388 4950 - /@types/classnames@2.3.1: 4951 - resolution: {integrity: sha512-zeOWb0JGBoVmlQoznvqXbE0tEC/HONsnoUNH19Hc96NFsTAwTXbTqb8FMYkru1F/iqp7a18Ws3nWJvtA1sHD1A==} 4952 - deprecated: This is a stub types definition. classnames provides its own type definitions, so you do not need this installed. 4953 - dependencies: 4954 - classnames: 2.3.2 4955 - dev: true 4956 - 4957 4389 /@types/connect@3.4.35: 4958 4390 resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} 4959 4391 dependencies: ··· 5060 4492 5061 4493 /@types/json5@0.0.29: 5062 4494 resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} 4495 + dev: false 5063 4496 5064 4497 /@types/katex@0.14.0: 5065 4498 resolution: {integrity: sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==} ··· 5076 4509 /@types/long@4.0.2: 5077 4510 resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} 5078 4511 dev: false 4512 + 4513 + /@types/luxon@3.3.1: 4514 + resolution: {integrity: sha512-XOS5nBcgEeP2PpcqJHjCWhUCAzGfXIU8ILOSLpx2FhxqMW9KdxgCGXNOEKGVBfveKtIpztHzKK5vSRVLyW/NqA==} 4515 + dev: true 5079 4516 5080 4517 /@types/mdast@3.0.12: 5081 4518 resolution: {integrity: sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==} ··· 5127 4564 resolution: {integrity: sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==} 5128 4565 dev: true 5129 4566 5130 - /@types/node@18.11.9: 5131 - resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==} 5132 - dev: true 5133 - 5134 4567 /@types/node@20.3.1: 5135 4568 resolution: {integrity: sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==} 5136 4569 ··· 5153 4586 resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} 5154 4587 dev: false 5155 4588 5156 - /@types/react-dom@18.0.9: 5157 - resolution: {integrity: sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==} 5158 - dependencies: 5159 - '@types/react': 18.2.16 5160 - dev: true 5161 - 5162 4589 /@types/react-dom@18.2.5: 5163 4590 resolution: {integrity: sha512-sRQsOS/sCLnpQhR4DSKGTtWFE3FZjpQa86KPVbhUqdYMRZ9FEFcfAytKhR/vUG2rH1oFbOOej6cuD7MFSobDRQ==} 5164 4591 dependencies: ··· 5169 4596 dependencies: 5170 4597 '@types/react': 18.2.16 5171 4598 dev: true 5172 - 5173 - /@types/react@18.0.25: 5174 - resolution: {integrity: sha512-xD6c0KDT4m7n9uD4ZHi02lzskaiqcBxf4zi+tXZY98a04wvc0hi/TcCPC2FOESZi51Nd7tlUeOJY8RofL799/g==} 5175 - dependencies: 5176 - '@types/prop-types': 15.7.5 5177 - '@types/scheduler': 0.16.3 5178 - csstype: 3.1.2 5179 4599 5180 4600 /@types/react@18.2.12: 5181 4601 resolution: {integrity: sha512-ndmBMLCgn38v3SntMeoJaIrO6tGHYKMEBohCUmw8HoLLQdRMOIGXfeYaBTLe2lsFaSB3MOK1VXscYFnmLtTSmw==} ··· 5264 4684 - supports-color 5265 4685 dev: false 5266 4686 5267 - /@typescript-eslint/parser@5.59.9(eslint@8.36.0)(typescript@4.9.3): 5268 - resolution: {integrity: sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ==} 5269 - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 5270 - peerDependencies: 5271 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 5272 - typescript: '*' 5273 - peerDependenciesMeta: 5274 - typescript: 5275 - optional: true 5276 - dependencies: 5277 - '@typescript-eslint/scope-manager': 5.59.9 5278 - '@typescript-eslint/types': 5.59.9 5279 - '@typescript-eslint/typescript-estree': 5.59.9(typescript@4.9.3) 5280 - debug: 4.3.4 5281 - eslint: 8.36.0 5282 - typescript: 4.9.3 5283 - transitivePeerDependencies: 5284 - - supports-color 5285 - dev: true 5286 - 5287 4687 /@typescript-eslint/parser@5.59.9(eslint@8.43.0)(typescript@5.1.6): 5288 4688 resolution: {integrity: sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ==} 5289 4689 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} ··· 5310 4710 dependencies: 5311 4711 '@typescript-eslint/types': 5.59.9 5312 4712 '@typescript-eslint/visitor-keys': 5.59.9 4713 + dev: false 5313 4714 5314 4715 /@typescript-eslint/type-utils@5.59.9(eslint@8.43.0)(typescript@5.1.6): 5315 4716 resolution: {integrity: sha512-ksEsT0/mEHg9e3qZu98AlSrONAQtrSTljL3ow9CGej8eRo7pe+yaC/mvTjptp23Xo/xIf2mLZKC6KPv4Sji26Q==} ··· 5334 4735 /@typescript-eslint/types@5.59.9: 5335 4736 resolution: {integrity: sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==} 5336 4737 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 5337 - 5338 - /@typescript-eslint/typescript-estree@5.59.9(typescript@4.9.3): 5339 - resolution: {integrity: sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==} 5340 - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 5341 - peerDependencies: 5342 - typescript: '*' 5343 - peerDependenciesMeta: 5344 - typescript: 5345 - optional: true 5346 - dependencies: 5347 - '@typescript-eslint/types': 5.59.9 5348 - '@typescript-eslint/visitor-keys': 5.59.9 5349 - debug: 4.3.4 5350 - globby: 11.1.0 5351 - is-glob: 4.0.3 5352 - semver: 7.5.4 5353 - tsutils: 3.21.0(typescript@4.9.3) 5354 - typescript: 4.9.3 5355 - transitivePeerDependencies: 5356 - - supports-color 5357 - dev: true 4738 + dev: false 5358 4739 5359 4740 /@typescript-eslint/typescript-estree@5.59.9(typescript@5.1.6): 5360 4741 resolution: {integrity: sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==} ··· 5403 4784 dependencies: 5404 4785 '@typescript-eslint/types': 5.59.9 5405 4786 eslint-visitor-keys: 3.4.1 4787 + dev: false 5406 4788 5407 4789 /@upstash/core-analytics@0.0.6: 5408 4790 resolution: {integrity: sha512-cpPSR0XJAJs4Ddz9nq3tINlPS5aLfWVCqhhtHnXt4p7qr5+/Znlt1Es736poB/9rnl1hAHrOsOvVj46NEXcVqA==} ··· 5473 4855 acorn: 7.4.1 5474 4856 acorn-walk: 7.2.0 5475 4857 xtend: 4.0.2 4858 + dev: false 5476 4859 5477 4860 /acorn-walk@7.2.0: 5478 4861 resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} 5479 4862 engines: {node: '>=0.4.0'} 4863 + dev: false 5480 4864 5481 4865 /acorn-walk@8.2.0: 5482 4866 resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} ··· 5487 4871 resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} 5488 4872 engines: {node: '>=0.4.0'} 5489 4873 hasBin: true 4874 + dev: false 5490 4875 5491 4876 /acorn@8.10.0: 5492 4877 resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} ··· 5604 4989 resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} 5605 4990 dependencies: 5606 4991 dequal: 2.0.3 4992 + dev: false 5607 4993 5608 4994 /array-buffer-byte-length@1.0.0: 5609 4995 resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} 5610 4996 dependencies: 5611 4997 call-bind: 1.0.2 5612 4998 is-array-buffer: 3.0.2 4999 + dev: false 5613 5000 5614 5001 /array-includes@3.1.6: 5615 5002 resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} ··· 5620 5007 es-abstract: 1.22.1 5621 5008 get-intrinsic: 1.2.1 5622 5009 is-string: 1.0.7 5010 + dev: false 5623 5011 5624 5012 /array-timsort@1.0.3: 5625 5013 resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} ··· 5637 5025 define-properties: 1.2.0 5638 5026 es-abstract: 1.22.1 5639 5027 es-shim-unscopables: 1.0.0 5028 + dev: false 5640 5029 5641 5030 /array.prototype.flatmap@1.3.1: 5642 5031 resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} ··· 5646 5035 define-properties: 1.2.0 5647 5036 es-abstract: 1.22.1 5648 5037 es-shim-unscopables: 1.0.0 5038 + dev: false 5649 5039 5650 5040 /array.prototype.tosorted@1.1.1: 5651 5041 resolution: {integrity: sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==} ··· 5655 5045 es-abstract: 1.22.1 5656 5046 es-shim-unscopables: 1.0.0 5657 5047 get-intrinsic: 1.2.1 5048 + dev: false 5658 5049 5659 5050 /arraybuffer.prototype.slice@1.0.1: 5660 5051 resolution: {integrity: sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==} ··· 5666 5057 get-intrinsic: 1.2.1 5667 5058 is-array-buffer: 3.0.2 5668 5059 is-shared-array-buffer: 1.0.2 5060 + dev: false 5669 5061 5670 5062 /asn1js@3.0.5: 5671 5063 resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} ··· 5678 5070 5679 5071 /ast-types-flow@0.0.7: 5680 5072 resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} 5073 + dev: false 5681 5074 5682 5075 /astring@1.8.6: 5683 5076 resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} ··· 5688 5081 resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} 5689 5082 dev: false 5690 5083 5691 - /autoprefixer@10.4.13(postcss@8.4.19): 5692 - resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} 5693 - engines: {node: ^10 || ^12 || >=14} 5694 - hasBin: true 5695 - peerDependencies: 5696 - postcss: ^8.1.0 5697 - dependencies: 5698 - browserslist: 4.21.9 5699 - caniuse-lite: 1.0.30001519 5700 - fraction.js: 4.2.0 5701 - normalize-range: 0.1.2 5702 - picocolors: 1.0.0 5703 - postcss: 8.4.19 5704 - postcss-value-parser: 4.2.0 5705 - dev: true 5706 - 5707 5084 /autoprefixer@10.4.14(postcss@8.4.24): 5708 5085 resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} 5709 5086 engines: {node: ^10 || ^12 || >=14} ··· 5723 5100 /available-typed-arrays@1.0.5: 5724 5101 resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} 5725 5102 engines: {node: '>= 0.4'} 5103 + dev: false 5726 5104 5727 5105 /axe-core@4.7.2: 5728 5106 resolution: {integrity: sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==} 5729 5107 engines: {node: '>=4'} 5108 + dev: false 5730 5109 5731 5110 /axios@1.4.0: 5732 5111 resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==} ··· 5742 5121 resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} 5743 5122 dependencies: 5744 5123 dequal: 2.0.3 5124 + dev: false 5745 5125 5746 5126 /bail@2.0.2: 5747 5127 resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} ··· 5767 5147 /big-integer@1.6.51: 5768 5148 resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} 5769 5149 engines: {node: '>=0.6'} 5150 + dev: false 5770 5151 5771 5152 /binary-extensions@2.2.0: 5772 5153 resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} ··· 5801 5182 engines: {node: '>= 5.10.0'} 5802 5183 dependencies: 5803 5184 big-integer: 1.6.51 5185 + dev: false 5804 5186 5805 5187 /brace-expansion@1.1.11: 5806 5188 resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} ··· 5866 5248 engines: {node: '>=12'} 5867 5249 dependencies: 5868 5250 run-applescript: 5.0.0 5251 + dev: false 5869 5252 5870 5253 /bundle-require@4.0.1(esbuild@0.18.16): 5871 5254 resolution: {integrity: sha512-9NQkRHlNdNpDBGmLpngF3EFDcwodhMUuLz9PaWYciVcQF9SE4LFjM2DB/xV1Li5JiuDMv7ZUWuC3rGbqR0MAXQ==} ··· 5899 5282 dependencies: 5900 5283 function-bind: 1.1.1 5901 5284 get-intrinsic: 1.2.1 5285 + dev: false 5902 5286 5903 5287 /callsites@3.1.0: 5904 5288 resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} ··· 5943 5327 5944 5328 /caniuse-lite@1.0.30001517: 5945 5329 resolution: {integrity: sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==} 5330 + dev: true 5946 5331 5947 5332 /caniuse-lite@1.0.30001519: 5948 5333 resolution: {integrity: sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==} ··· 6056 5441 clsx: 1.2.1 6057 5442 typescript: 5.1.6 6058 5443 dev: false 6059 - 6060 - /classnames@2.3.2: 6061 - resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==} 6062 5444 6063 5445 /clean-stack@2.2.0: 6064 5446 resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} ··· 6654 6036 6655 6037 /damerau-levenshtein@1.0.8: 6656 6038 resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} 6039 + dev: false 6657 6040 6658 6041 /data-uri-to-buffer@4.0.1: 6659 6042 resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} ··· 6680 6063 optional: true 6681 6064 dependencies: 6682 6065 ms: 2.1.3 6066 + dev: false 6683 6067 6684 6068 /debug@4.3.4: 6685 6069 resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} ··· 6727 6111 dependencies: 6728 6112 bplist-parser: 0.2.0 6729 6113 untildify: 4.0.0 6114 + dev: false 6730 6115 6731 6116 /default-browser@4.0.0: 6732 6117 resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==} ··· 6736 6121 default-browser-id: 3.0.0 6737 6122 execa: 7.2.0 6738 6123 titleize: 3.0.0 6124 + dev: false 6739 6125 6740 6126 /defaults@1.0.4: 6741 6127 resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} ··· 6745 6131 /define-lazy-prop@3.0.0: 6746 6132 resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} 6747 6133 engines: {node: '>=12'} 6134 + dev: false 6748 6135 6749 6136 /define-properties@1.2.0: 6750 6137 resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} ··· 6752 6139 dependencies: 6753 6140 has-property-descriptors: 1.0.0 6754 6141 object-keys: 1.1.1 6142 + dev: false 6755 6143 6756 6144 /defined@1.0.1: 6757 6145 resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} 6146 + dev: false 6758 6147 6759 6148 /del@5.1.0: 6760 6149 resolution: {integrity: sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==} ··· 6818 6207 acorn-node: 1.8.2 6819 6208 defined: 1.0.1 6820 6209 minimist: 1.2.8 6210 + dev: false 6821 6211 6822 6212 /didyoumean@1.2.2: 6823 6213 resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} ··· 6851 6241 engines: {node: '>=0.10.0'} 6852 6242 dependencies: 6853 6243 esutils: 2.0.3 6244 + dev: false 6854 6245 6855 6246 /doctrine@3.0.0: 6856 6247 resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} ··· 7038 6429 7039 6430 /emoji-regex@9.2.2: 7040 6431 resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 6432 + dev: false 7041 6433 7042 6434 /encoding@0.1.13: 7043 6435 resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} ··· 7056 6448 dependencies: 7057 6449 graceful-fs: 4.2.11 7058 6450 tapable: 2.2.1 6451 + dev: false 7059 6452 7060 6453 /entities@4.5.0: 7061 6454 resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} ··· 7111 6504 typed-array-length: 1.0.4 7112 6505 unbox-primitive: 1.0.2 7113 6506 which-typed-array: 1.1.11 6507 + dev: false 7114 6508 7115 6509 /es-set-tostringtag@2.0.1: 7116 6510 resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} ··· 7119 6513 get-intrinsic: 1.2.1 7120 6514 has: 1.0.3 7121 6515 has-tostringtag: 1.0.0 6516 + dev: false 7122 6517 7123 6518 /es-shim-unscopables@1.0.0: 7124 6519 resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} 7125 6520 dependencies: 7126 6521 has: 1.0.3 6522 + dev: false 7127 6523 7128 6524 /es-to-primitive@1.2.1: 7129 6525 resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} ··· 7132 6528 is-callable: 1.2.7 7133 6529 is-date-object: 1.0.5 7134 6530 is-symbol: 1.0.4 6531 + dev: false 7135 6532 7136 6533 /es5-ext@0.10.62: 7137 6534 resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} ··· 7318 6715 resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} 7319 6716 engines: {node: '>=12'} 7320 6717 7321 - /eslint-config-next@13.2.4(eslint@8.36.0)(typescript@4.9.3): 7322 - resolution: {integrity: sha512-lunIBhsoeqw6/Lfkd6zPt25w1bn0znLA/JCL+au1HoEpSb4/PpsOYsYtgV/q+YPsoKIOzFyU5xnb04iZnXjUvg==} 7323 - peerDependencies: 7324 - eslint: ^7.23.0 || ^8.0.0 7325 - typescript: '>=3.3.1' 7326 - peerDependenciesMeta: 7327 - typescript: 7328 - optional: true 7329 - dependencies: 7330 - '@next/eslint-plugin-next': 13.2.4 7331 - '@rushstack/eslint-patch': 1.3.2 7332 - '@typescript-eslint/parser': 5.59.9(eslint@8.36.0)(typescript@4.9.3) 7333 - eslint: 8.36.0 7334 - eslint-import-resolver-node: 0.3.7 7335 - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.36.0) 7336 - eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.36.0) 7337 - eslint-plugin-jsx-a11y: 6.7.1(eslint@8.36.0) 7338 - eslint-plugin-react: 7.32.2(eslint@8.36.0) 7339 - eslint-plugin-react-hooks: 4.6.0(eslint@8.36.0) 7340 - typescript: 4.9.3 7341 - transitivePeerDependencies: 7342 - - eslint-import-resolver-webpack 7343 - - supports-color 7344 - dev: true 7345 - 7346 6718 /eslint-config-next@13.4.1(eslint@8.43.0)(typescript@5.1.6): 7347 6719 resolution: {integrity: sha512-ajuxjCkW1hvirr0EQZb3/B/bFH52Z7CT89uCtTcICFL9l30i5c8hN4p0LXvTjdOXNPV5fEDcxBgGHgXdzTj1/A==} 7348 6720 peerDependencies: ··· 7368 6740 - supports-color 7369 6741 dev: false 7370 6742 7371 - /eslint-config-prettier@8.7.0(eslint@8.36.0): 7372 - resolution: {integrity: sha512-HHVXLSlVUhMSmyW4ZzEuvjpwqamgmlfkutD53cYXLikh4pt/modINRcCIApJ84czDxM4GZInwUrromsDdTImTA==} 7373 - hasBin: true 7374 - peerDependencies: 7375 - eslint: '>=7.0.0' 7376 - dependencies: 7377 - eslint: 8.36.0 7378 - dev: true 7379 - 7380 6743 /eslint-config-prettier@8.8.0(eslint@8.43.0): 7381 6744 resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} 7382 6745 hasBin: true ··· 7403 6766 resolve: 1.22.2 7404 6767 transitivePeerDependencies: 7405 6768 - supports-color 7406 - 7407 - /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.36.0): 7408 - resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==} 7409 - engines: {node: ^14.18.0 || >=16.0.0} 7410 - peerDependencies: 7411 - eslint: '*' 7412 - eslint-plugin-import: '*' 7413 - dependencies: 7414 - debug: 4.3.4 7415 - enhanced-resolve: 5.15.0 7416 - eslint: 8.36.0 7417 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.36.0) 7418 - eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.36.0) 7419 - get-tsconfig: 4.6.2 7420 - globby: 13.2.2 7421 - is-core-module: 2.12.1 7422 - is-glob: 4.0.3 7423 - synckit: 0.8.5 7424 - transitivePeerDependencies: 7425 - - '@typescript-eslint/parser' 7426 - - eslint-import-resolver-node 7427 - - eslint-import-resolver-webpack 7428 - - supports-color 7429 - dev: true 6769 + dev: false 7430 6770 7431 6771 /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.43.0): 7432 6772 resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==} ··· 7452 6792 - supports-color 7453 6793 dev: false 7454 6794 7455 - /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.36.0): 7456 - resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} 7457 - engines: {node: '>=4'} 7458 - peerDependencies: 7459 - '@typescript-eslint/parser': '*' 7460 - eslint: '*' 7461 - eslint-import-resolver-node: '*' 7462 - eslint-import-resolver-typescript: '*' 7463 - eslint-import-resolver-webpack: '*' 7464 - peerDependenciesMeta: 7465 - '@typescript-eslint/parser': 7466 - optional: true 7467 - eslint: 7468 - optional: true 7469 - eslint-import-resolver-node: 7470 - optional: true 7471 - eslint-import-resolver-typescript: 7472 - optional: true 7473 - eslint-import-resolver-webpack: 7474 - optional: true 7475 - dependencies: 7476 - '@typescript-eslint/parser': 5.59.9(eslint@8.36.0)(typescript@4.9.3) 7477 - debug: 3.2.7 7478 - eslint: 8.36.0 7479 - eslint-import-resolver-node: 0.3.7 7480 - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-plugin-import@2.27.5)(eslint@8.36.0) 7481 - transitivePeerDependencies: 7482 - - supports-color 7483 - dev: true 7484 - 7485 6795 /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0): 7486 6796 resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} 7487 6797 engines: {node: '>=4'} ··· 7512 6822 - supports-color 7513 6823 dev: false 7514 6824 7515 - /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.36.0): 7516 - resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} 7517 - engines: {node: '>=4'} 7518 - peerDependencies: 7519 - '@typescript-eslint/parser': '*' 7520 - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 7521 - peerDependenciesMeta: 7522 - '@typescript-eslint/parser': 7523 - optional: true 7524 - dependencies: 7525 - '@typescript-eslint/parser': 5.59.9(eslint@8.36.0)(typescript@4.9.3) 7526 - array-includes: 3.1.6 7527 - array.prototype.flat: 1.3.1 7528 - array.prototype.flatmap: 1.3.1 7529 - debug: 3.2.7 7530 - doctrine: 2.1.0 7531 - eslint: 8.36.0 7532 - eslint-import-resolver-node: 0.3.7 7533 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.36.0) 7534 - has: 1.0.3 7535 - is-core-module: 2.12.1 7536 - is-glob: 4.0.3 7537 - minimatch: 3.1.2 7538 - object.values: 1.1.6 7539 - resolve: 1.22.2 7540 - semver: 6.3.1 7541 - tsconfig-paths: 3.14.2 7542 - transitivePeerDependencies: 7543 - - eslint-import-resolver-typescript 7544 - - eslint-import-resolver-webpack 7545 - - supports-color 7546 - dev: true 7547 - 7548 6825 /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.43.0): 7549 6826 resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} 7550 6827 engines: {node: '>=4'} ··· 7578 6855 - supports-color 7579 6856 dev: false 7580 6857 7581 - /eslint-plugin-jsx-a11y@6.7.1(eslint@8.36.0): 7582 - resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} 7583 - engines: {node: '>=4.0'} 7584 - peerDependencies: 7585 - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 7586 - dependencies: 7587 - '@babel/runtime': 7.22.6 7588 - aria-query: 5.3.0 7589 - array-includes: 3.1.6 7590 - array.prototype.flatmap: 1.3.1 7591 - ast-types-flow: 0.0.7 7592 - axe-core: 4.7.2 7593 - axobject-query: 3.2.1 7594 - damerau-levenshtein: 1.0.8 7595 - emoji-regex: 9.2.2 7596 - eslint: 8.36.0 7597 - has: 1.0.3 7598 - jsx-ast-utils: 3.3.4 7599 - language-tags: 1.0.5 7600 - minimatch: 3.1.2 7601 - object.entries: 1.1.6 7602 - object.fromentries: 2.0.6 7603 - semver: 6.3.1 7604 - dev: true 7605 - 7606 6858 /eslint-plugin-jsx-a11y@6.7.1(eslint@8.43.0): 7607 6859 resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} 7608 6860 engines: {node: '>=4.0'} ··· 7628 6880 semver: 6.3.1 7629 6881 dev: false 7630 6882 7631 - /eslint-plugin-react-hooks@4.6.0(eslint@8.36.0): 7632 - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} 7633 - engines: {node: '>=10'} 7634 - peerDependencies: 7635 - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 7636 - dependencies: 7637 - eslint: 8.36.0 7638 - dev: true 7639 - 7640 6883 /eslint-plugin-react-hooks@4.6.0(eslint@8.43.0): 7641 6884 resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} 7642 6885 engines: {node: '>=10'} ··· 7646 6889 eslint: 8.43.0 7647 6890 dev: false 7648 6891 7649 - /eslint-plugin-react@7.32.2(eslint@8.36.0): 7650 - resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==} 7651 - engines: {node: '>=4'} 7652 - peerDependencies: 7653 - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 7654 - dependencies: 7655 - array-includes: 3.1.6 7656 - array.prototype.flatmap: 1.3.1 7657 - array.prototype.tosorted: 1.1.1 7658 - doctrine: 2.1.0 7659 - eslint: 8.36.0 7660 - estraverse: 5.3.0 7661 - jsx-ast-utils: 3.3.4 7662 - minimatch: 3.1.2 7663 - object.entries: 1.1.6 7664 - object.fromentries: 2.0.6 7665 - object.hasown: 1.1.2 7666 - object.values: 1.1.6 7667 - prop-types: 15.8.1 7668 - resolve: 2.0.0-next.4 7669 - semver: 6.3.1 7670 - string.prototype.matchall: 4.0.8 7671 - dev: true 7672 - 7673 6892 /eslint-plugin-react@7.32.2(eslint@8.43.0): 7674 6893 resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==} 7675 6894 engines: {node: '>=4'} ··· 7694 6913 string.prototype.matchall: 4.0.8 7695 6914 dev: false 7696 6915 7697 - /eslint-plugin-simple-import-sort@10.0.0(eslint@8.36.0): 7698 - resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} 7699 - peerDependencies: 7700 - eslint: '>=5.0.0' 7701 - dependencies: 7702 - eslint: 8.36.0 7703 - dev: true 7704 - 7705 6916 /eslint-plugin-turbo@1.10.1(eslint@8.43.0): 7706 6917 resolution: {integrity: sha512-bScQeG42PhVPzSeJgCTk79hRqN8jFYY6Io7fw2qyuOtlff4QkSuBTot+BBooxk4BL11gJglWZUJk2nqumLJGOA==} 7707 6918 peerDependencies: ··· 7710 6921 eslint: 8.43.0 7711 6922 dev: false 7712 6923 7713 - /eslint-plugin-unused-imports@2.0.0(eslint@8.36.0): 7714 - resolution: {integrity: sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==} 7715 - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 7716 - peerDependencies: 7717 - '@typescript-eslint/eslint-plugin': ^5.0.0 7718 - eslint: ^8.0.0 7719 - peerDependenciesMeta: 7720 - '@typescript-eslint/eslint-plugin': 7721 - optional: true 7722 - dependencies: 7723 - eslint: 8.36.0 7724 - eslint-rule-composer: 0.3.0 7725 - dev: true 7726 - 7727 - /eslint-rule-composer@0.3.0: 7728 - resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} 7729 - engines: {node: '>=4.0.0'} 7730 - dev: true 7731 - 7732 6924 /eslint-scope@5.1.1: 7733 6925 resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} 7734 6926 engines: {node: '>=8.0.0'} ··· 7752 6944 resolution: {integrity: sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==} 7753 6945 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 7754 6946 7755 - /eslint@8.36.0: 7756 - resolution: {integrity: sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==} 7757 - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 7758 - hasBin: true 7759 - dependencies: 7760 - '@eslint-community/eslint-utils': 4.4.0(eslint@8.36.0) 7761 - '@eslint-community/regexpp': 4.6.1 7762 - '@eslint/eslintrc': 2.1.0 7763 - '@eslint/js': 8.36.0 7764 - '@humanwhocodes/config-array': 0.11.10 7765 - '@humanwhocodes/module-importer': 1.0.1 7766 - '@nodelib/fs.walk': 1.2.8 7767 - ajv: 6.12.6 7768 - chalk: 4.1.2 7769 - cross-spawn: 7.0.3 7770 - debug: 4.3.4 7771 - doctrine: 3.0.0 7772 - escape-string-regexp: 4.0.0 7773 - eslint-scope: 7.2.1 7774 - eslint-visitor-keys: 3.4.2 7775 - espree: 9.6.1 7776 - esquery: 1.5.0 7777 - esutils: 2.0.3 7778 - fast-deep-equal: 3.1.3 7779 - file-entry-cache: 6.0.1 7780 - find-up: 5.0.0 7781 - glob-parent: 6.0.2 7782 - globals: 13.20.0 7783 - grapheme-splitter: 1.0.4 7784 - ignore: 5.2.4 7785 - import-fresh: 3.3.0 7786 - imurmurhash: 0.1.4 7787 - is-glob: 4.0.3 7788 - is-path-inside: 3.0.3 7789 - js-sdsl: 4.4.2 7790 - js-yaml: 4.1.0 7791 - json-stable-stringify-without-jsonify: 1.0.1 7792 - levn: 0.4.1 7793 - lodash.merge: 4.6.2 7794 - minimatch: 3.1.2 7795 - natural-compare: 1.4.0 7796 - optionator: 0.9.3 7797 - strip-ansi: 6.0.1 7798 - strip-json-comments: 3.1.1 7799 - text-table: 0.2.0 7800 - transitivePeerDependencies: 7801 - - supports-color 7802 - dev: true 7803 - 7804 6947 /eslint@8.43.0: 7805 6948 resolution: {integrity: sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==} 7806 6949 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} ··· 8030 7173 onetime: 6.0.0 8031 7174 signal-exit: 3.0.7 8032 7175 strip-final-newline: 3.0.0 7176 + dev: false 8033 7177 8034 7178 /expand-template@2.0.3: 8035 7179 resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} ··· 8181 7325 resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} 8182 7326 dependencies: 8183 7327 is-callable: 1.2.7 7328 + dev: false 8184 7329 8185 7330 /form-data@3.0.1: 8186 7331 resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} ··· 8216 7361 resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} 8217 7362 dev: true 8218 7363 8219 - /framer-motion@8.4.6(react-dom@18.2.0)(react@18.2.0): 8220 - resolution: {integrity: sha512-0GkpTQnhDysG5SiD2VbANtAs8yCXVQLasynVABDTZYI+Qcx1krWg+rfyveM8W78q7AX+8RTsiMz/LJ7YIRZvFw==} 8221 - peerDependencies: 8222 - react: ^18.0.0 8223 - react-dom: ^18.0.0 8224 - dependencies: 8225 - '@motionone/dom': 10.16.2 8226 - hey-listen: 1.0.8 8227 - react: 18.2.0 8228 - react-dom: 18.2.0(react@18.2.0) 8229 - tslib: 2.6.1 8230 - optionalDependencies: 8231 - '@emotion/is-prop-valid': 0.8.8 8232 - dev: false 8233 - 8234 7364 /fs-constants@1.0.0: 8235 7365 resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} 8236 7366 dev: false ··· 8297 7427 define-properties: 1.2.0 8298 7428 es-abstract: 1.22.1 8299 7429 functions-have-names: 1.2.3 7430 + dev: false 8300 7431 8301 7432 /functions-have-names@1.2.3: 8302 7433 resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} 7434 + dev: false 8303 7435 8304 7436 /gensync@1.0.0-beta.2: 8305 7437 resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} ··· 8317 7449 has: 1.0.3 8318 7450 has-proto: 1.0.1 8319 7451 has-symbols: 1.0.3 7452 + dev: false 8320 7453 8321 7454 /get-nonce@1.0.1: 8322 7455 resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} ··· 8338 7471 dependencies: 8339 7472 call-bind: 1.0.2 8340 7473 get-intrinsic: 1.2.1 7474 + dev: false 8341 7475 8342 7476 /get-tsconfig@4.6.2: 8343 7477 resolution: {integrity: sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==} ··· 8399 7533 minimatch: 3.1.2 8400 7534 once: 1.4.0 8401 7535 path-is-absolute: 1.0.1 7536 + dev: false 8402 7537 8403 7538 /glob@7.2.3: 8404 7539 resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} ··· 8446 7581 engines: {node: '>= 0.4'} 8447 7582 dependencies: 8448 7583 define-properties: 1.2.0 7584 + dev: false 8449 7585 8450 7586 /globby@10.0.2: 8451 7587 resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==} ··· 8481 7617 ignore: 5.2.4 8482 7618 merge2: 1.4.1 8483 7619 slash: 4.0.0 7620 + dev: false 8484 7621 8485 7622 /gopd@1.0.1: 8486 7623 resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} 8487 7624 dependencies: 8488 7625 get-intrinsic: 1.2.1 7626 + dev: false 8489 7627 8490 7628 /graceful-fs@4.2.11: 8491 7629 resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 8492 7630 8493 7631 /grapheme-splitter@1.0.4: 8494 7632 resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} 7633 + dev: false 8495 7634 8496 7635 /graphemer@1.4.0: 8497 7636 resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} ··· 8528 7667 8529 7668 /has-bigints@1.0.2: 8530 7669 resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} 7670 + dev: false 8531 7671 8532 7672 /has-flag@2.0.0: 8533 7673 resolution: {integrity: sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==} ··· 8551 7691 resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} 8552 7692 dependencies: 8553 7693 get-intrinsic: 1.2.1 7694 + dev: false 8554 7695 8555 7696 /has-proto@1.0.1: 8556 7697 resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} 8557 7698 engines: {node: '>= 0.4'} 7699 + dev: false 8558 7700 8559 7701 /has-symbols@1.0.3: 8560 7702 resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} 8561 7703 engines: {node: '>= 0.4'} 7704 + dev: false 8562 7705 8563 7706 /has-tostringtag@1.0.0: 8564 7707 resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} 8565 7708 engines: {node: '>= 0.4'} 8566 7709 dependencies: 8567 7710 has-symbols: 1.0.3 7711 + dev: false 8568 7712 8569 7713 /has@1.0.3: 8570 7714 resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} ··· 8749 7893 /heap@0.2.7: 8750 7894 resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} 8751 7895 8752 - /hey-listen@1.0.8: 8753 - resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} 8754 - dev: false 8755 - 8756 7896 /hosted-git-info@2.8.9: 8757 7897 resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} 8758 7898 dev: false ··· 8827 7967 /human-signals@4.3.1: 8828 7968 resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} 8829 7969 engines: {node: '>=14.18.0'} 7970 + dev: false 8830 7971 8831 7972 /iconv-lite@0.4.24: 8832 7973 resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} ··· 8936 8077 get-intrinsic: 1.2.1 8937 8078 has: 1.0.3 8938 8079 side-channel: 1.0.4 8080 + dev: false 8939 8081 8940 8082 /internmap@1.0.1: 8941 8083 resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} ··· 8978 8120 call-bind: 1.0.2 8979 8121 get-intrinsic: 1.2.1 8980 8122 is-typed-array: 1.1.12 8123 + dev: false 8981 8124 8982 8125 /is-arrayish@0.2.1: 8983 8126 resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} ··· 8987 8130 resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} 8988 8131 dependencies: 8989 8132 has-bigints: 1.0.2 8133 + dev: false 8990 8134 8991 8135 /is-binary-path@2.1.0: 8992 8136 resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} ··· 9000 8144 dependencies: 9001 8145 call-bind: 1.0.2 9002 8146 has-tostringtag: 1.0.0 8147 + dev: false 9003 8148 9004 8149 /is-buffer@1.1.6: 9005 8150 resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} ··· 9012 8157 /is-callable@1.2.7: 9013 8158 resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} 9014 8159 engines: {node: '>= 0.4'} 8160 + dev: false 9015 8161 9016 8162 /is-core-module@2.12.1: 9017 8163 resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} ··· 9023 8169 engines: {node: '>= 0.4'} 9024 8170 dependencies: 9025 8171 has-tostringtag: 1.0.0 8172 + dev: false 9026 8173 9027 8174 /is-decimal@2.0.1: 9028 8175 resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} ··· 9032 8179 resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} 9033 8180 engines: {node: '>=8'} 9034 8181 hasBin: true 8182 + dev: false 9035 8183 9036 8184 /is-docker@3.0.0: 9037 8185 resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} 9038 8186 engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 9039 8187 hasBin: true 8188 + dev: false 9040 8189 9041 8190 /is-extendable@0.1.1: 9042 8191 resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} ··· 9067 8216 hasBin: true 9068 8217 dependencies: 9069 8218 is-docker: 3.0.0 8219 + dev: false 9070 8220 9071 8221 /is-interactive@1.0.0: 9072 8222 resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} ··· 9081 8231 /is-negative-zero@2.0.2: 9082 8232 resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} 9083 8233 engines: {node: '>= 0.4'} 8234 + dev: false 9084 8235 9085 8236 /is-number-object@1.0.7: 9086 8237 resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} 9087 8238 engines: {node: '>= 0.4'} 9088 8239 dependencies: 9089 8240 has-tostringtag: 1.0.0 8241 + dev: false 9090 8242 9091 8243 /is-number@7.0.0: 9092 8244 resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} ··· 9136 8288 dependencies: 9137 8289 call-bind: 1.0.2 9138 8290 has-tostringtag: 1.0.0 8291 + dev: false 9139 8292 9140 8293 /is-shared-array-buffer@1.0.2: 9141 8294 resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} 9142 8295 dependencies: 9143 8296 call-bind: 1.0.2 8297 + dev: false 9144 8298 9145 8299 /is-ssh@1.4.0: 9146 8300 resolution: {integrity: sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==} ··· 9160 8314 /is-stream@3.0.0: 9161 8315 resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} 9162 8316 engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 8317 + dev: false 9163 8318 9164 8319 /is-string@1.0.7: 9165 8320 resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} 9166 8321 engines: {node: '>= 0.4'} 9167 8322 dependencies: 9168 8323 has-tostringtag: 1.0.0 8324 + dev: false 9169 8325 9170 8326 /is-symbol@1.0.4: 9171 8327 resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} 9172 8328 engines: {node: '>= 0.4'} 9173 8329 dependencies: 9174 8330 has-symbols: 1.0.3 8331 + dev: false 9175 8332 9176 8333 /is-typed-array@1.1.12: 9177 8334 resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} 9178 8335 engines: {node: '>= 0.4'} 9179 8336 dependencies: 9180 8337 which-typed-array: 1.1.11 8338 + dev: false 9181 8339 9182 8340 /is-unicode-supported@0.1.0: 9183 8341 resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} ··· 9193 8351 resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} 9194 8352 dependencies: 9195 8353 call-bind: 1.0.2 8354 + dev: false 9196 8355 9197 8356 /is-what@4.1.15: 9198 8357 resolution: {integrity: sha512-uKua1wfy3Yt+YqsD6mTUEa2zSi3G1oPlqTflgaPJ7z63vUGN5pxFpnQfeSLMFnJDEsdvOtkp1rUWkYjB4YfhgA==} ··· 9209 8368 engines: {node: '>=8'} 9210 8369 dependencies: 9211 8370 is-docker: 2.2.1 8371 + dev: false 9212 8372 9213 8373 /isarray@1.0.0: 9214 8374 resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} ··· 9216 8376 9217 8377 /isarray@2.0.5: 9218 8378 resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} 8379 + dev: false 9219 8380 9220 8381 /isbinaryfile@4.0.10: 9221 8382 resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} ··· 9267 8428 engines: {node: '>=12'} 9268 8429 dev: false 9269 8430 9270 - /js-sdsl@4.4.2: 9271 - resolution: {integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==} 9272 - dev: true 9273 - 9274 8431 /js-tokens@4.0.0: 9275 8432 resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 9276 8433 ··· 9321 8478 hasBin: true 9322 8479 dependencies: 9323 8480 minimist: 1.2.8 8481 + dev: false 9324 8482 9325 8483 /json5@2.2.3: 9326 8484 resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} ··· 9352 8510 array.prototype.flat: 1.3.1 9353 8511 object.assign: 4.1.4 9354 8512 object.values: 1.1.6 8513 + dev: false 9355 8514 9356 8515 /katex@0.16.8: 9357 8516 resolution: {integrity: sha512-ftuDnJbcbOckGY11OO+zg3OofESlbR5DRl2cmN8HeWeeFIV7wTXvAOx8kEjZjobhA+9wh2fbKeO6cdcA9Mnovg==} ··· 9382 8541 9383 8542 /language-subtag-registry@0.3.22: 9384 8543 resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} 8544 + dev: false 9385 8545 9386 8546 /language-tags@1.0.5: 9387 8547 resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==} 9388 8548 dependencies: 9389 8549 language-subtag-registry: 0.3.22 8550 + dev: false 9390 8551 9391 8552 /layout-base@1.0.2: 9392 8553 resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} ··· 9539 8700 react: ^16.5.1 || ^17.0.0 || ^18.0.0 9540 8701 dependencies: 9541 8702 react: 18.2.0 8703 + dev: false 8704 + 8705 + /luxon@3.3.0: 8706 + resolution: {integrity: sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==} 8707 + engines: {node: '>=12'} 9542 8708 dev: false 9543 8709 9544 8710 /make-error@1.3.6: ··· 10193 9359 /mimic-fn@4.0.0: 10194 9360 resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} 10195 9361 engines: {node: '>=12'} 9362 + dev: false 10196 9363 10197 9364 /mimic-response@3.1.0: 10198 9365 resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} ··· 10253 9420 10254 9421 /ms@2.1.3: 10255 9422 resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 9423 + dev: false 10256 9424 10257 9425 /mute-stream@0.0.8: 10258 9426 resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} ··· 10348 9516 react: '>=16.0.0' 10349 9517 react-dom: '>=16.0.0' 10350 9518 dependencies: 10351 - next: 13.4.12(@babel/core@7.22.9)(react-dom@18.2.0)(react@18.2.0) 9519 + next: 13.4.12(@babel/core@7.22.9)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) 10352 9520 react: 18.2.0 10353 9521 react-dom: 18.2.0(react@18.2.0) 10354 9522 dev: false ··· 10360 9528 react: '*' 10361 9529 react-dom: '*' 10362 9530 dependencies: 10363 - next: 13.4.12(@babel/core@7.22.9)(react-dom@18.2.0)(react@18.2.0) 9531 + next: 13.4.12(@babel/core@7.22.9)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) 10364 9532 react: 18.2.0 10365 9533 react-dom: 18.2.0(react@18.2.0) 10366 9534 dev: false ··· 10369 9537 resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} 10370 9538 dev: true 10371 9539 10372 - /next@13.2.4(@babel/core@7.22.9)(react-dom@18.2.0)(react@18.2.0): 10373 - resolution: {integrity: sha512-g1I30317cThkEpvzfXujf0O4wtaQHtDCLhlivwlTJ885Ld+eOgcz7r3TGQzeU+cSRoNHtD8tsJgzxVdYojFssw==} 10374 - engines: {node: '>=14.6.0'} 10375 - hasBin: true 10376 - peerDependencies: 10377 - '@opentelemetry/api': ^1.4.0 10378 - fibers: '>= 3.1.0' 10379 - node-sass: ^6.0.0 || ^7.0.0 10380 - react: ^18.2.0 10381 - react-dom: ^18.2.0 10382 - sass: ^1.3.0 10383 - peerDependenciesMeta: 10384 - '@opentelemetry/api': 10385 - optional: true 10386 - fibers: 10387 - optional: true 10388 - node-sass: 10389 - optional: true 10390 - sass: 10391 - optional: true 10392 - dependencies: 10393 - '@next/env': 13.2.4 10394 - '@swc/helpers': 0.4.14 10395 - caniuse-lite: 1.0.30001519 10396 - postcss: 8.4.14 10397 - react: 18.2.0 10398 - react-dom: 18.2.0(react@18.2.0) 10399 - styled-jsx: 5.1.1(@babel/core@7.22.9)(react@18.2.0) 10400 - optionalDependencies: 10401 - '@next/swc-android-arm-eabi': 13.2.4 10402 - '@next/swc-android-arm64': 13.2.4 10403 - '@next/swc-darwin-arm64': 13.2.4 10404 - '@next/swc-darwin-x64': 13.2.4 10405 - '@next/swc-freebsd-x64': 13.2.4 10406 - '@next/swc-linux-arm-gnueabihf': 13.2.4 10407 - '@next/swc-linux-arm64-gnu': 13.2.4 10408 - '@next/swc-linux-arm64-musl': 13.2.4 10409 - '@next/swc-linux-x64-gnu': 13.2.4 10410 - '@next/swc-linux-x64-musl': 13.2.4 10411 - '@next/swc-win32-arm64-msvc': 13.2.4 10412 - '@next/swc-win32-ia32-msvc': 13.2.4 10413 - '@next/swc-win32-x64-msvc': 13.2.4 10414 - transitivePeerDependencies: 10415 - - '@babel/core' 10416 - - babel-plugin-macros 10417 - dev: false 10418 - 10419 9540 /next@13.4.12(@babel/core@7.22.9)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0): 10420 9541 resolution: {integrity: sha512-eHfnru9x6NRmTMcjQp6Nz0J4XH9OubmzOa7CkWL+AUrUxpibub3vWwttjduu9No16dug1kq04hiUUpo7J3m3Xw==} 10421 9542 engines: {node: '>=16.8.0'} ··· 10438 9559 '@opentelemetry/api': 1.4.1 10439 9560 '@swc/helpers': 0.5.1 10440 9561 busboy: 1.6.0 10441 - caniuse-lite: 1.0.30001517 10442 - postcss: 8.4.14 10443 - react: 18.2.0 10444 - react-dom: 18.2.0(react@18.2.0) 10445 - styled-jsx: 5.1.1(@babel/core@7.22.9)(react@18.2.0) 10446 - watchpack: 2.4.0 10447 - zod: 3.21.4 10448 - optionalDependencies: 10449 - '@next/swc-darwin-arm64': 13.4.12 10450 - '@next/swc-darwin-x64': 13.4.12 10451 - '@next/swc-linux-arm64-gnu': 13.4.12 10452 - '@next/swc-linux-arm64-musl': 13.4.12 10453 - '@next/swc-linux-x64-gnu': 13.4.12 10454 - '@next/swc-linux-x64-musl': 13.4.12 10455 - '@next/swc-win32-arm64-msvc': 13.4.12 10456 - '@next/swc-win32-ia32-msvc': 13.4.12 10457 - '@next/swc-win32-x64-msvc': 13.4.12 10458 - transitivePeerDependencies: 10459 - - '@babel/core' 10460 - - babel-plugin-macros 10461 - dev: false 10462 - 10463 - /next@13.4.12(@babel/core@7.22.9)(react-dom@18.2.0)(react@18.2.0): 10464 - resolution: {integrity: sha512-eHfnru9x6NRmTMcjQp6Nz0J4XH9OubmzOa7CkWL+AUrUxpibub3vWwttjduu9No16dug1kq04hiUUpo7J3m3Xw==} 10465 - engines: {node: '>=16.8.0'} 10466 - hasBin: true 10467 - peerDependencies: 10468 - '@opentelemetry/api': ^1.1.0 10469 - fibers: '>= 3.1.0' 10470 - react: ^18.2.0 10471 - react-dom: ^18.2.0 10472 - sass: ^1.3.0 10473 - peerDependenciesMeta: 10474 - '@opentelemetry/api': 10475 - optional: true 10476 - fibers: 10477 - optional: true 10478 - sass: 10479 - optional: true 10480 - dependencies: 10481 - '@next/env': 13.4.12 10482 - '@swc/helpers': 0.5.1 10483 - busboy: 1.6.0 10484 9562 caniuse-lite: 1.0.30001519 10485 9563 postcss: 8.4.14 10486 9564 react: 18.2.0 ··· 10519 9597 git-url-parse: 13.1.0 10520 9598 intersection-observer: 0.12.2 10521 9599 match-sorter: 6.3.1 10522 - next: 13.4.12(@babel/core@7.22.9)(react-dom@18.2.0)(react@18.2.0) 9600 + next: 13.4.12(@babel/core@7.22.9)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) 10523 9601 next-seo: 6.1.0(next@13.4.12)(react-dom@18.2.0)(react@18.2.0) 10524 9602 next-themes: 0.2.1(next@13.4.12)(react-dom@18.2.0)(react@18.2.0) 10525 9603 nextra: 2.10.0(next@13.4.12)(react-dom@18.2.0)(react@18.2.0) ··· 10549 9627 gray-matter: 4.0.3 10550 9628 katex: 0.16.8 10551 9629 lodash.get: 4.4.2 10552 - next: 13.4.12(@babel/core@7.22.9)(react-dom@18.2.0)(react@18.2.0) 9630 + next: 13.4.12(@babel/core@7.22.9)(@opentelemetry/api@1.4.1)(react-dom@18.2.0)(react@18.2.0) 10553 9631 next-mdx-remote: 4.4.1(react-dom@18.2.0)(react@18.2.0) 10554 9632 p-limit: 3.1.0 10555 9633 react: 18.2.0 ··· 10692 9770 engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 10693 9771 dependencies: 10694 9772 path-key: 4.0.0 9773 + dev: false 10695 9774 10696 9775 /npm-to-yarn@2.0.0: 10697 9776 resolution: {integrity: sha512-/IbjiJ7vqbxfxJxAZ+QI9CCRjnIbvGxn5KQcSY9xHh0lMKc/Sgqmm7yp7KPmd6TiTZX5/KiSBKlkGHo59ucZbg==} ··· 10708 9787 10709 9788 /object-inspect@1.12.3: 10710 9789 resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} 9790 + dev: false 10711 9791 10712 9792 /object-keys@1.1.1: 10713 9793 resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} 10714 9794 engines: {node: '>= 0.4'} 9795 + dev: false 10715 9796 10716 9797 /object.assign@4.1.4: 10717 9798 resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} ··· 10721 9802 define-properties: 1.2.0 10722 9803 has-symbols: 1.0.3 10723 9804 object-keys: 1.1.1 9805 + dev: false 10724 9806 10725 9807 /object.entries@1.1.6: 10726 9808 resolution: {integrity: sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==} ··· 10729 9811 call-bind: 1.0.2 10730 9812 define-properties: 1.2.0 10731 9813 es-abstract: 1.22.1 9814 + dev: false 10732 9815 10733 9816 /object.fromentries@2.0.6: 10734 9817 resolution: {integrity: sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==} ··· 10737 9820 call-bind: 1.0.2 10738 9821 define-properties: 1.2.0 10739 9822 es-abstract: 1.22.1 9823 + dev: false 10740 9824 10741 9825 /object.hasown@1.1.2: 10742 9826 resolution: {integrity: sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==} 10743 9827 dependencies: 10744 9828 define-properties: 1.2.0 10745 9829 es-abstract: 1.22.1 9830 + dev: false 10746 9831 10747 9832 /object.values@1.1.6: 10748 9833 resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} ··· 10751 9836 call-bind: 1.0.2 10752 9837 define-properties: 1.2.0 10753 9838 es-abstract: 1.22.1 9839 + dev: false 10754 9840 10755 9841 /once@1.4.0: 10756 9842 resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} ··· 10768 9854 engines: {node: '>=12'} 10769 9855 dependencies: 10770 9856 mimic-fn: 4.0.0 9857 + dev: false 10771 9858 10772 9859 /oo-ascii-tree@1.85.0: 10773 9860 resolution: {integrity: sha512-5QKNfCtTeW5rcdKbd0owoZFzMxJ7oJl9I+FycBJ0/i8UVJYcZOKctN9TA82unIRgf/BrSaa0X3Nw0RJuiAnMfQ==} ··· 10782 9869 define-lazy-prop: 3.0.0 10783 9870 is-inside-container: 1.0.0 10784 9871 is-wsl: 2.2.0 9872 + dev: false 10785 9873 10786 9874 /optionator@0.9.3: 10787 9875 resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} ··· 10964 10052 /path-key@4.0.0: 10965 10053 resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} 10966 10054 engines: {node: '>=12'} 10055 + dev: false 10967 10056 10968 10057 /path-parse@1.0.7: 10969 10058 resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} ··· 11019 10108 postcss: 8.4.21 11020 10109 dev: false 11021 10110 11022 - /postcss-import@14.1.0(postcss@8.4.19): 11023 - resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} 11024 - engines: {node: '>=10.0.0'} 11025 - peerDependencies: 11026 - postcss: ^8.0.0 11027 - dependencies: 11028 - postcss: 8.4.19 11029 - postcss-value-parser: 4.2.0 11030 - read-cache: 1.0.0 11031 - resolve: 1.22.2 11032 - dev: true 11033 - 11034 10111 /postcss-import@14.1.0(postcss@8.4.21): 11035 10112 resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} 11036 10113 engines: {node: '>=10.0.0'} ··· 11054 10131 read-cache: 1.0.0 11055 10132 resolve: 1.22.2 11056 10133 11057 - /postcss-js@4.0.1(postcss@8.4.19): 11058 - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} 11059 - engines: {node: ^12 || ^14 || >= 16} 11060 - peerDependencies: 11061 - postcss: ^8.4.21 11062 - dependencies: 11063 - camelcase-css: 2.0.1 11064 - postcss: 8.4.19 11065 - dev: true 11066 - 11067 10134 /postcss-js@4.0.1(postcss@8.4.21): 11068 10135 resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} 11069 10136 engines: {node: ^12 || ^14 || >= 16} ··· 11083 10150 camelcase-css: 2.0.1 11084 10151 postcss: 8.4.24 11085 10152 11086 - /postcss-load-config@3.1.4(postcss@8.4.19): 11087 - resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} 11088 - engines: {node: '>= 10'} 11089 - peerDependencies: 11090 - postcss: '>=8.0.9' 11091 - ts-node: '>=9.0.0' 11092 - peerDependenciesMeta: 11093 - postcss: 11094 - optional: true 11095 - ts-node: 11096 - optional: true 11097 - dependencies: 11098 - lilconfig: 2.1.0 11099 - postcss: 8.4.19 11100 - yaml: 1.10.2 11101 - dev: true 11102 - 11103 10153 /postcss-load-config@3.1.4(postcss@8.4.21): 11104 10154 resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} 11105 10155 engines: {node: '>= 10'} ··· 11132 10182 lilconfig: 2.1.0 11133 10183 postcss: 8.4.24 11134 10184 yaml: 2.3.1 11135 - 11136 - /postcss-nested@6.0.0(postcss@8.4.19): 11137 - resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} 11138 - engines: {node: '>=12.0'} 11139 - peerDependencies: 11140 - postcss: ^8.2.14 11141 - dependencies: 11142 - postcss: 8.4.19 11143 - postcss-selector-parser: 6.0.13 11144 - dev: true 11145 10185 11146 10186 /postcss-nested@6.0.0(postcss@8.4.21): 11147 10187 resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} ··· 11189 10229 source-map-js: 1.0.2 11190 10230 dev: false 11191 10231 11192 - /postcss@8.4.19: 11193 - resolution: {integrity: sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==} 11194 - engines: {node: ^10 || ^12 || >=14} 11195 - dependencies: 11196 - nanoid: 3.3.6 11197 - picocolors: 1.0.0 11198 - source-map-js: 1.0.2 11199 - dev: true 11200 - 11201 10232 /postcss@8.4.21: 11202 10233 resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} 11203 10234 engines: {node: ^10 || ^12 || >=14} ··· 11294 10325 prettier: 3.0.0 11295 10326 dev: true 11296 10327 11297 - /prettier@2.8.4: 11298 - resolution: {integrity: sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==} 11299 - engines: {node: '>=10.13.0'} 11300 - hasBin: true 11301 - dev: true 11302 - 11303 10328 /prettier@3.0.0: 11304 10329 resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==} 11305 10330 engines: {node: '>=14'} ··· 11320 10345 js-beautify: 1.14.9 11321 10346 dev: false 11322 10347 11323 - /prism-react-renderer@1.3.5(react@18.2.0): 11324 - resolution: {integrity: sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==} 11325 - peerDependencies: 11326 - react: '>=0.14.9' 11327 - dependencies: 11328 - react: 18.2.0 11329 - dev: false 11330 - 11331 10348 /process-nextick-args@2.0.1: 11332 10349 resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} 11333 10350 dev: false ··· 11338 10355 loose-envify: 1.4.0 11339 10356 object-assign: 4.1.1 11340 10357 react-is: 16.13.1 10358 + dev: false 11341 10359 11342 10360 /property-information@6.2.0: 11343 10361 resolution: {integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==} ··· 11415 10433 /quick-lru@5.1.1: 11416 10434 resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} 11417 10435 engines: {node: '>=10'} 10436 + dev: false 11418 10437 11419 10438 /random-word-slugs@0.1.7: 11420 10439 resolution: {integrity: sha512-8cyzxOIDeLFvwSPTgCItMXHGT5ZPkjhuFKUTww06Xg1dNMXuGxIKlARvS7upk6JXIm41ZKXmtlKR1iCRWklKmg==} ··· 11495 10514 11496 10515 /react-is@16.13.1: 11497 10516 resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} 10517 + dev: false 11498 10518 11499 10519 /react-property@2.0.0: 11500 10520 resolution: {integrity: sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==} 11501 10521 dev: false 11502 10522 11503 - /react-remove-scroll-bar@2.3.4(@types/react@18.0.25)(react@18.2.0): 11504 - resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} 11505 - engines: {node: '>=10'} 11506 - peerDependencies: 11507 - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 11508 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 11509 - peerDependenciesMeta: 11510 - '@types/react': 11511 - optional: true 11512 - dependencies: 11513 - '@types/react': 18.0.25 11514 - react: 18.2.0 11515 - react-style-singleton: 2.2.1(@types/react@18.0.25)(react@18.2.0) 11516 - tslib: 2.6.1 11517 - dev: false 11518 - 11519 10523 /react-remove-scroll-bar@2.3.4(@types/react@18.2.12)(react@18.2.0): 11520 10524 resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} 11521 10525 engines: {node: '>=10'} ··· 11551 10555 use-sidecar: 1.1.2(@types/react@18.2.12)(react@18.2.0) 11552 10556 dev: false 11553 10557 11554 - /react-remove-scroll@2.5.5(@types/react@18.0.25)(react@18.2.0): 11555 - resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} 11556 - engines: {node: '>=10'} 11557 - peerDependencies: 11558 - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 11559 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 11560 - peerDependenciesMeta: 11561 - '@types/react': 11562 - optional: true 11563 - dependencies: 11564 - '@types/react': 18.0.25 11565 - react: 18.2.0 11566 - react-remove-scroll-bar: 2.3.4(@types/react@18.0.25)(react@18.2.0) 11567 - react-style-singleton: 2.2.1(@types/react@18.0.25)(react@18.2.0) 11568 - tslib: 2.6.1 11569 - use-callback-ref: 1.3.0(@types/react@18.0.25)(react@18.2.0) 11570 - use-sidecar: 1.1.2(@types/react@18.0.25)(react@18.2.0) 11571 - dev: false 11572 - 11573 10558 /react-remove-scroll@2.5.5(@types/react@18.2.12)(react@18.2.0): 11574 10559 resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} 11575 10560 engines: {node: '>=10'} ··· 11597 10582 react: 18.2.0 11598 10583 dev: false 11599 10584 11600 - /react-style-singleton@2.2.1(@types/react@18.0.25)(react@18.2.0): 11601 - resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} 11602 - engines: {node: '>=10'} 11603 - peerDependencies: 11604 - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 11605 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 11606 - peerDependenciesMeta: 11607 - '@types/react': 11608 - optional: true 11609 - dependencies: 11610 - '@types/react': 18.0.25 11611 - get-nonce: 1.0.1 11612 - invariant: 2.2.4 11613 - react: 18.2.0 11614 - tslib: 2.6.1 11615 - dev: false 11616 - 11617 10585 /react-style-singleton@2.2.1(@types/react@18.2.12)(react@18.2.0): 11618 10586 resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} 11619 10587 engines: {node: '>=10'} ··· 11723 10691 call-bind: 1.0.2 11724 10692 define-properties: 1.2.0 11725 10693 functions-have-names: 1.2.3 10694 + dev: false 11726 10695 11727 10696 /registry-auth-token@3.3.2: 11728 10697 resolution: {integrity: sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==} ··· 11934 10903 is-core-module: 2.12.1 11935 10904 path-parse: 1.0.7 11936 10905 supports-preserve-symlinks-flag: 1.0.0 10906 + dev: false 11937 10907 11938 10908 /restore-cursor@3.1.0: 11939 10909 resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} ··· 11976 10946 engines: {node: '>=12'} 11977 10947 dependencies: 11978 10948 execa: 5.1.1 10949 + dev: false 11979 10950 11980 10951 /run-async@2.4.1: 11981 10952 resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} ··· 12018 10989 get-intrinsic: 1.2.1 12019 10990 has-symbols: 1.0.3 12020 10991 isarray: 2.0.5 10992 + dev: false 12021 10993 12022 10994 /safe-buffer@5.1.2: 12023 10995 resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} ··· 12032 11004 call-bind: 1.0.2 12033 11005 get-intrinsic: 1.2.1 12034 11006 is-regex: 1.1.4 11007 + dev: false 12035 11008 12036 11009 /safer-buffer@2.1.2: 12037 11010 resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} ··· 12140 11113 call-bind: 1.0.2 12141 11114 get-intrinsic: 1.2.1 12142 11115 object-inspect: 1.12.3 11116 + dev: false 12143 11117 12144 11118 /signal-exit@3.0.7: 12145 11119 resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} ··· 12167 11141 /slash@4.0.0: 12168 11142 resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} 12169 11143 engines: {node: '>=12'} 11144 + dev: false 12170 11145 12171 11146 /snake-case@2.1.0: 12172 11147 resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==} ··· 12290 11265 internal-slot: 1.0.5 12291 11266 regexp.prototype.flags: 1.5.0 12292 11267 side-channel: 1.0.4 11268 + dev: false 12293 11269 12294 11270 /string.prototype.trim@1.2.7: 12295 11271 resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} ··· 12298 11274 call-bind: 1.0.2 12299 11275 define-properties: 1.2.0 12300 11276 es-abstract: 1.22.1 11277 + dev: false 12301 11278 12302 11279 /string.prototype.trimend@1.0.6: 12303 11280 resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} ··· 12305 11282 call-bind: 1.0.2 12306 11283 define-properties: 1.2.0 12307 11284 es-abstract: 1.22.1 11285 + dev: false 12308 11286 12309 11287 /string.prototype.trimstart@1.0.6: 12310 11288 resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} ··· 12312 11290 call-bind: 1.0.2 12313 11291 define-properties: 1.2.0 12314 11292 es-abstract: 1.22.1 11293 + dev: false 12315 11294 12316 11295 /string_decoder@1.1.1: 12317 11296 resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} ··· 12345 11324 /strip-bom@3.0.0: 12346 11325 resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 12347 11326 engines: {node: '>=4'} 11327 + dev: false 12348 11328 12349 11329 /strip-eof@1.0.0: 12350 11330 resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} ··· 12358 11338 /strip-final-newline@3.0.0: 12359 11339 resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} 12360 11340 engines: {node: '>=12'} 11341 + dev: false 12361 11342 12362 11343 /strip-json-comments@2.0.1: 12363 11344 resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} ··· 12501 11482 dependencies: 12502 11483 '@pkgr/utils': 2.4.2 12503 11484 tslib: 2.6.1 11485 + dev: false 12504 11486 12505 11487 /tailwind-merge@1.13.2: 12506 11488 resolution: {integrity: sha512-R2/nULkdg1VR/EL4RXg4dEohdoxNUJGLMnWIQnPKL+O9Twu7Cn3Rxi4dlXkDzZrEGtR+G+psSXFouWlpTyLhCQ==} ··· 12514 11496 tailwindcss: 3.3.2 12515 11497 dev: false 12516 11498 12517 - /tailwindcss@3.2.4(postcss@8.4.19): 12518 - resolution: {integrity: sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==} 12519 - engines: {node: '>=12.13.0'} 12520 - hasBin: true 12521 - peerDependencies: 12522 - postcss: ^8.0.9 12523 - dependencies: 12524 - arg: 5.0.2 12525 - chokidar: 3.5.3 12526 - color-name: 1.1.4 12527 - detective: 5.2.1 12528 - didyoumean: 1.2.2 12529 - dlv: 1.1.3 12530 - fast-glob: 3.3.1 12531 - glob-parent: 6.0.2 12532 - is-glob: 4.0.3 12533 - lilconfig: 2.1.0 12534 - micromatch: 4.0.5 12535 - normalize-path: 3.0.0 12536 - object-hash: 3.0.0 12537 - picocolors: 1.0.0 12538 - postcss: 8.4.19 12539 - postcss-import: 14.1.0(postcss@8.4.19) 12540 - postcss-js: 4.0.1(postcss@8.4.19) 12541 - postcss-load-config: 3.1.4(postcss@8.4.19) 12542 - postcss-nested: 6.0.0(postcss@8.4.19) 12543 - postcss-selector-parser: 6.0.13 12544 - postcss-value-parser: 4.2.0 12545 - quick-lru: 5.1.1 12546 - resolve: 1.22.2 12547 - transitivePeerDependencies: 12548 - - ts-node 12549 - dev: true 12550 - 12551 11499 /tailwindcss@3.2.7(postcss@8.4.21): 12552 11500 resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==} 12553 11501 engines: {node: '>=12.13.0'} ··· 12616 11564 /tapable@2.2.1: 12617 11565 resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} 12618 11566 engines: {node: '>=6'} 11567 + dev: false 12619 11568 12620 11569 /tar-fs@2.1.1: 12621 11570 resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} ··· 12687 11636 /titleize@3.0.0: 12688 11637 resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} 12689 11638 engines: {node: '>=12'} 11639 + dev: false 12690 11640 12691 11641 /tmp@0.0.33: 12692 11642 resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} ··· 12815 11765 json5: 1.0.2 12816 11766 minimist: 1.2.8 12817 11767 strip-bom: 3.0.0 11768 + dev: false 12818 11769 12819 11770 /tslib@1.14.1: 12820 11771 resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} ··· 12862 11813 - ts-node 12863 11814 dev: true 12864 11815 12865 - /tsutils@3.21.0(typescript@4.9.3): 12866 - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} 12867 - engines: {node: '>= 6'} 12868 - peerDependencies: 12869 - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' 12870 - dependencies: 12871 - tslib: 1.14.1 12872 - typescript: 4.9.3 12873 - dev: true 12874 - 12875 11816 /tsutils@3.21.0(typescript@5.1.6): 12876 11817 resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} 12877 11818 engines: {node: '>= 6'} ··· 13014 11955 call-bind: 1.0.2 13015 11956 get-intrinsic: 1.2.1 13016 11957 is-typed-array: 1.1.12 11958 + dev: false 13017 11959 13018 11960 /typed-array-byte-length@1.0.0: 13019 11961 resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} ··· 13023 11965 for-each: 0.3.3 13024 11966 has-proto: 1.0.1 13025 11967 is-typed-array: 1.1.12 11968 + dev: false 13026 11969 13027 11970 /typed-array-byte-offset@1.0.0: 13028 11971 resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} ··· 13033 11976 for-each: 0.3.3 13034 11977 has-proto: 1.0.1 13035 11978 is-typed-array: 1.1.12 11979 + dev: false 13036 11980 13037 11981 /typed-array-length@1.0.4: 13038 11982 resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} ··· 13040 11984 call-bind: 1.0.2 13041 11985 for-each: 0.3.3 13042 11986 is-typed-array: 1.1.12 13043 - 13044 - /typescript@4.9.3: 13045 - resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} 13046 - engines: {node: '>=4.2.0'} 13047 - hasBin: true 13048 - dev: true 11987 + dev: false 13049 11988 13050 11989 /typescript@5.1.6: 13051 11990 resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} ··· 13067 12006 has-bigints: 1.0.2 13068 12007 has-symbols: 1.0.3 13069 12008 which-boxed-primitive: 1.0.2 12009 + dev: false 13070 12010 13071 12011 /unified@10.1.2: 13072 12012 resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} ··· 13197 12137 /untildify@4.0.0: 13198 12138 resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} 13199 12139 engines: {node: '>=8'} 12140 + dev: false 13200 12141 13201 12142 /unzipper@0.10.14: 13202 12143 resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==} ··· 13252 12193 requires-port: 1.0.0 13253 12194 dev: false 13254 12195 13255 - /use-callback-ref@1.3.0(@types/react@18.0.25)(react@18.2.0): 13256 - resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} 13257 - engines: {node: '>=10'} 13258 - peerDependencies: 13259 - '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 13260 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 13261 - peerDependenciesMeta: 13262 - '@types/react': 13263 - optional: true 13264 - dependencies: 13265 - '@types/react': 18.0.25 13266 - react: 18.2.0 13267 - tslib: 2.6.1 13268 - dev: false 13269 - 13270 12196 /use-callback-ref@1.3.0(@types/react@18.2.12)(react@18.2.0): 13271 12197 resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} 13272 12198 engines: {node: '>=10'} ··· 13278 12204 optional: true 13279 12205 dependencies: 13280 12206 '@types/react': 18.2.12 13281 - react: 18.2.0 13282 - tslib: 2.6.1 13283 - dev: false 13284 - 13285 - /use-isomorphic-layout-effect@1.1.2(@types/react@18.0.25)(react@18.2.0): 13286 - resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} 13287 - peerDependencies: 13288 - '@types/react': '*' 13289 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 13290 - peerDependenciesMeta: 13291 - '@types/react': 13292 - optional: true 13293 - dependencies: 13294 - '@types/react': 18.0.25 13295 - react: 18.2.0 13296 - dev: false 13297 - 13298 - /use-sidecar@1.1.2(@types/react@18.0.25)(react@18.2.0): 13299 - resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} 13300 - engines: {node: '>=10'} 13301 - peerDependencies: 13302 - '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 13303 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 13304 - peerDependenciesMeta: 13305 - '@types/react': 13306 - optional: true 13307 - dependencies: 13308 - '@types/react': 18.0.25 13309 - detect-node-es: 1.1.0 13310 12207 react: 18.2.0 13311 12208 tslib: 2.6.1 13312 12209 dev: false ··· 13491 12388 is-number-object: 1.0.7 13492 12389 is-string: 1.0.7 13493 12390 is-symbol: 1.0.4 12391 + dev: false 13494 12392 13495 12393 /which-typed-array@1.1.11: 13496 12394 resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} ··· 13501 12399 for-each: 0.3.3 13502 12400 gopd: 1.0.1 13503 12401 has-tostringtag: 1.0.0 12402 + dev: false 13504 12403 13505 12404 /which@1.3.1: 13506 12405 resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} ··· 13550 12449 /xtend@4.0.2: 13551 12450 resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} 13552 12451 engines: {node: '>=0.4'} 12452 + dev: false 13553 12453 13554 12454 /y18n@5.0.8: 13555 12455 resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} ··· 13569 12469 /yaml@1.10.2: 13570 12470 resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} 13571 12471 engines: {node: '>= 6'} 12472 + dev: false 13572 12473 13573 12474 /yaml@2.3.1: 13574 12475 resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==}