From facfba88e5ba0013389ca4b73ee6f209978d4cc5 Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 21:57:37 +0000 Subject: [PATCH 01/18] refactor(frontend): move Avatar to secondary-sidebar.tsx --- .../shared/components/navigation/topbars/app-topbar.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/frontend/src/app/features/shared/components/navigation/topbars/app-topbar.tsx b/frontend/src/app/features/shared/components/navigation/topbars/app-topbar.tsx index a77166aa..5bd52998 100644 --- a/frontend/src/app/features/shared/components/navigation/topbars/app-topbar.tsx +++ b/frontend/src/app/features/shared/components/navigation/topbars/app-topbar.tsx @@ -30,11 +30,6 @@ export function AppTopbar({ children, className, ...props }: AppTopbarProps) {
- - - - OK -
) From 01f4498e57bf70cea7cc246237636b98f842666c Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 21:57:51 +0000 Subject: [PATCH 02/18] feat(frontend): add FileDialog --- .../files/components/dialogs/file-dialog.tsx | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 frontend/src/app/features/files/components/dialogs/file-dialog.tsx diff --git a/frontend/src/app/features/files/components/dialogs/file-dialog.tsx b/frontend/src/app/features/files/components/dialogs/file-dialog.tsx new file mode 100644 index 00000000..18ff45f5 --- /dev/null +++ b/frontend/src/app/features/files/components/dialogs/file-dialog.tsx @@ -0,0 +1,30 @@ +import {Dialog, DialogContent, DialogTitle, DialogTrigger} from "@/components/ui/dialog.tsx"; +import type {Metadata} from "@/app/features/files/hooks/types.ts"; +import {useState} from "react"; +import {Button} from "@/components/ui/button.tsx"; +import {EllipsisVertical} from "lucide-react"; + +interface FileDialogProps{ + open: boolean, + onOpenChange: (open: boolean) => void, + metadata: Metadata, + ipfsLink: string, + spaceName: string, + spaceDid: string +} + +export function FileDialog({ + open, + onOpenChange, + metadata, + }: FileDialogProps) { + return ( + + + +

Last modified at: {metadata.modified_at}

+

Last modified at: {metadata.modified_at}

+
+
+ ) +} \ No newline at end of file From fd39a7d5a8cf472c029119ae5fb0aa78b5cd00cf Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 21:58:27 +0000 Subject: [PATCH 03/18] feat(frontend): add FileDropdown --- .../components/dropdowns/file-dropdown.tsx | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 frontend/src/app/features/files/components/dropdowns/file-dropdown.tsx diff --git a/frontend/src/app/features/files/components/dropdowns/file-dropdown.tsx b/frontend/src/app/features/files/components/dropdowns/file-dropdown.tsx new file mode 100644 index 00000000..18429690 --- /dev/null +++ b/frontend/src/app/features/files/components/dropdowns/file-dropdown.tsx @@ -0,0 +1,37 @@ +import {EllipsisVertical, Info, Moon, Settings, Sun, Trash2} from "lucide-react" + +import { Button } from "@/components/ui/button" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, DropdownMenuPortal, DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" +import { useTheme } from "@/components/theme-provider" + +export function FileDropdown() { + const { setTheme } = useTheme() + + return ( + + + + + + deleteFile(id)}> + {}{

Delete

} +
+ + + {}{

File Info

} +
+ + + {}{

File Settings

} +
+
+
+ ) +} \ No newline at end of file From 2bef93735c765e078f9b7d27099621a4e4d9a8e8 Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 21:59:27 +0000 Subject: [PATCH 04/18] feat(frontend): add file icons to favorites ScrollArea --- .../components/navigation/nav-favorites.tsx | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/features/shared/components/navigation/nav-favorites.tsx b/frontend/src/app/features/shared/components/navigation/nav-favorites.tsx index b32fa75e..8cee430e 100644 --- a/frontend/src/app/features/shared/components/navigation/nav-favorites.tsx +++ b/frontend/src/app/features/shared/components/navigation/nav-favorites.tsx @@ -22,6 +22,8 @@ import { SidebarMenuItem, useSidebar, } from "@/components/ui/sidebar.tsx" +import {getIconForFile } from "@react-symbols/icons/utils"; +import { FileIcon } from "@react-symbols/icons/utils"; export function NavFavorites({ favorites, @@ -40,12 +42,18 @@ export function NavFavorites({ {favorites.map((item) => ( - - - {item.emoji} - {item.name} - - + + + + + + {item.name} + + From f8a61893c3594224d2e9214d0285bdda6b68fbec Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:01:29 +0000 Subject: [PATCH 05/18] fix(frontend): resolve page flashing between redirect --- frontend/index.html | 77 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index b3319331..d166fdf4 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1,19 +1,70 @@ - + - + + + + + - Gestalto - - -
-
+ Gestalt - - - + + + +
+
+ +
+
+ + + \ No newline at end of file From 9021e1443829a0d5f0c969f1780b84b066aee4f7 Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:02:39 +0000 Subject: [PATCH 06/18] feat(frontend): add hardcoded spaghetti for demo --- .../src/app/features/shared/files/metadata.ts | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/features/shared/files/metadata.ts b/frontend/src/app/features/shared/files/metadata.ts index f9943a10..ed75c6cf 100644 --- a/frontend/src/app/features/shared/files/metadata.ts +++ b/frontend/src/app/features/shared/files/metadata.ts @@ -43,13 +43,16 @@ export async function extractMetadata(file: File): Promise { locateFile: (path) => `/mediainfo/dist/${path}`, }) - const result = await mediaInfo.analyzeData( - () => file.size, - async (chunkSize, offset) => { - const buffer = await file.slice(offset, offset + chunkSize).arrayBuffer() - return new Uint8Array(buffer) + const [result, checksum] = await Promise.all([ + mediaInfo.analyzeData( + () => file.size, + async (chunkSize, offset) => { + const buffer = await file.slice(offset, offset + chunkSize).arrayBuffer() + return new Uint8Array(buffer) } - ) + ), + getCheckSum(file) + ]); mediaInfo.close() @@ -59,6 +62,8 @@ export async function extractMetadata(file: File): Promise { //const media = JSON.parse(result); + console.log('Metadata:', result); + console.log('SHA-256:', checksum); return { path: file.name, relativePath: file.webkitRelativePath || file.name, @@ -70,7 +75,27 @@ export async function extractMetadata(file: File): Promise { //media, id: crypto.randomUUID(), - ownerId: crypto.randomUUID(), - checkSum: "a".repeat(256), + ownerId: "29b6f168-03f6-4801-81d5-603b52f2c932", + checkSum: checksum } +} + +function generateFileId(): string { + //TODO: Check UUID exist in db. + return crypto.randomUUID(); +} + +function getOwnerId(): string { + //TODO: Check UUID exist in db. + return crypto.randomUUID(); +} + +// TODO: Compute this in backend instead, bad security and also >100mb browser dies. +async function getCheckSum(file: File): Promise { + const arrayBuffer = await file.arrayBuffer(); + const hashBuffer = await crypto.subtle.digest('SHA-256', arrayBuffer); + + return Array.from(new Uint8Array(hashBuffer)) + .map(b => b.toString(16).padStart(2, '0')) + .join(''); } \ No newline at end of file From 3234b023d7e6e853023fc920b06b09743a56ba57 Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:03:23 +0000 Subject: [PATCH 07/18] feat(frontend): add FileDialog and FileDropdown to FileTable --- .../shared/components/tables/file-table.tsx | 51 +++++++++++++++---- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/frontend/src/app/features/shared/components/tables/file-table.tsx b/frontend/src/app/features/shared/components/tables/file-table.tsx index 3ba8da09..a561a9cf 100644 --- a/frontend/src/app/features/shared/components/tables/file-table.tsx +++ b/frontend/src/app/features/shared/components/tables/file-table.tsx @@ -19,8 +19,21 @@ import { import type { Metadata } from "@/app/features/files/hooks/types" import { useAuthStore } from "@/security/auth/authstore/auth-store" import { getIconForFile } from "@react-symbols/icons/utils" +import {DialogTrigger} from "@/components/ui/dialog.tsx"; +import {FileDialog} from "@/app/features/files/components/dialogs/file-dialog.tsx"; +import {FileDropdown} from "@/app/features/files/components/dropdowns/file-dropdown.tsx"; + + export function FileTable() { + const [dialogOpen, setDialogOpen] = useState(false) + const [activeFile, setActiveFile] = useState(null) + + function openDialog(file: Metadata) { + setActiveFile(file) + setDialogOpen(true) + } + const userId = useAuthStore((s) => s.userId) const cursor = useMemo( @@ -88,7 +101,7 @@ export function FileTable() { - +
@@ -101,9 +114,9 @@ export function FileTable() { /> - Name - Last Modified - + Name + Last Modified + @@ -117,25 +130,41 @@ export function FileTable() { /> - + openDialog(file)}>
{getIconForFile({ fileName: file.file_name })}
- {file.file_name} + openDialog(file)}> +

+ {file.file_name} +

+
- {formatDate(file.modified_at)} + openDialog(file)}> +

+ {formatDate(file.modified_at)} +

+
- - + + ))}
+ {activeFile && ( + + )} ) } From b0a6285da08404f055f9731634f19490dceb6108 Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:03:43 +0000 Subject: [PATCH 08/18] feat(frontend): add SecondarySidebar --- .../navigation/sidebars/secondary-sidebar.tsx | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 frontend/src/app/features/shared/components/navigation/sidebars/secondary-sidebar.tsx diff --git a/frontend/src/app/features/shared/components/navigation/sidebars/secondary-sidebar.tsx b/frontend/src/app/features/shared/components/navigation/sidebars/secondary-sidebar.tsx new file mode 100644 index 00000000..bdeeb032 --- /dev/null +++ b/frontend/src/app/features/shared/components/navigation/sidebars/secondary-sidebar.tsx @@ -0,0 +1,60 @@ +import { Button } from "@/components/ui/button" +import {Flame, FolderClosed, GitBranch, Settings2, Snowflake, SquareTerminal, Users} from "lucide-react" +import React from "react" +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" +import {Link} from "react-router-dom"; + +interface SecondarySidebarProps { + children?: React.ReactNode +} + +export function SecondarySidebar({ children }: SecondarySidebarProps) { + return ( + + ) +} From a58fc7d60793e451e018c422dc320fd692ed3687 Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:04:31 +0000 Subject: [PATCH 09/18] feat(frontend): add updated theme --- frontend/src/index.css | 231 ++++++++++++++++++++++++++++++----------- 1 file changed, 168 insertions(+), 63 deletions(-) diff --git a/frontend/src/index.css b/frontend/src/index.css index 0edf11e8..14fa3e11 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -39,75 +39,166 @@ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); + --font-sans: var(--font-sans); + --font-mono: var(--font-mono); + --font-serif: var(--font-serif); + --radius: var(--radius); + --shadow-xl: var(--shadow-xl); + --shadow-lg: var(--shadow-lg); + --shadow-md: var(--shadow-md); + --shadow: var(--shadow); + --shadow-sm: var(--shadow-sm); + --shadow-2xl: var(--shadow-2xl); + --shadow-xs: var(--shadow-xs); + --shadow-2xs: var(--shadow-2xs); + --radius-2xl: calc(var(--radius) + 8px); + --radius-3xl: calc(var(--radius) + 12px); + --radius-4xl: calc(var(--radius) + 16px); } :root { - --radius: 0.625rem; - --background: oklch(1 0 0); - --foreground: oklch(0.145 0 0); - --card: oklch(1 0 0); - --card-foreground: oklch(0.145 0 0); - --popover: oklch(1 0 0); - --popover-foreground: oklch(0.145 0 0); - --primary: oklch(0.205 0 0); - --primary-foreground: oklch(0.985 0 0); - --secondary: oklch(0.97 0 0); - --secondary-foreground: oklch(0.205 0 0); - --muted: oklch(0.97 0 0); - --muted-foreground: oklch(0.556 0 0); - --accent: oklch(0.97 0 0); - --accent-foreground: oklch(0.205 0 0); - --destructive: oklch(0.577 0.245 27.325); - --border: oklch(0.922 0 0); - --input: oklch(0.922 0 0); - --ring: oklch(0.708 0 0); - --chart-1: oklch(0.646 0.222 41.116); - --chart-2: oklch(0.6 0.118 184.704); - --chart-3: oklch(0.398 0.07 227.392); - --chart-4: oklch(0.828 0.189 84.429); - --chart-5: oklch(0.769 0.188 70.08); - --sidebar: oklch(0.985 0 0); - --sidebar-foreground: oklch(0.145 0 0); - --sidebar-primary: oklch(0.205 0 0); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.97 0 0); - --sidebar-accent-foreground: oklch(0.205 0 0); - --sidebar-border: oklch(0.922 0 0); - --sidebar-ring: oklch(0.708 0 0); + --background: oklch(0.98 0.01 93.48); + --foreground: oklch(0.34 0.03 94.42); + --card: oklch(0.98 0.01 93.48); + --card-foreground: oklch(0.19 0 0); + --popover: oklch(1.00 0 0); + --popover-foreground: oklch(0.27 0.02 99.70); + --primary: oklch(0.597 0.185 30.9); + --primary-foreground: oklch(1.00 0 0); + --secondary: oklch(0.92 0.01 87.42); + --secondary-foreground: oklch(0.43 0.02 99.33); + --muted: oklch(0.95 0.01 91.46); + --muted-foreground: oklch(0.61 0.01 91.49); + --accent: oklch(0.92 0.01 87.42); + --accent-foreground: oklch(0.27 0.02 99.70); + --destructive: oklch(0.19 0 0); + --border: oklch(0.91 0.01 106.47); + --input: oklch(0.76 0.02 96.91); + --ring: oklch(0.59 0.17 252.92); + --chart-1: oklch(0.56 0.13 42.95); + --chart-2: oklch(0.69 0.16 290.29); + --chart-3: oklch(0.88 0.03 91.64); + --chart-4: oklch(0.88 0.04 298.21); + --chart-5: oklch(0.56 0.13 41.94); + --sidebar: oklch(0.97 0.01 93.49); + --sidebar-foreground: oklch(0.36 0.01 106.85); + --sidebar-primary: oklch(0.62 0.14 39.15); + --sidebar-primary-foreground: oklch(0.99 0 0); + --sidebar-accent: oklch(0.922 0 89.876); + --sidebar-accent-foreground: oklch(0.33 0 0); + --sidebar-border: oklch(0.94 0 0); + --sidebar-ring: oklch(0.77 0 0); + + --font-sans: 'Geist', 'Geist Fallback', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + --font-serif: "Geist", "Geist Fallback", ui-serif, Georgia, Cambria, "Times New Roman", Times, serif; + --font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + + --radius: 0.5rem; + + --shadow-2xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05); + --shadow-xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05); + --shadow-sm: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10); + --shadow: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10); + --shadow-md: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 2px 4px -1px oklch(0.00 0 0 / 0.10); + --shadow-lg: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 4px 6px -1px oklch(0.00 0 0 / 0.10); + --shadow-xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 8px 10px -1px oklch(0.00 0 0 / 0.10); + --shadow-2xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.25); + } .dark { - --background: oklch(0.145 0 0); - --foreground: oklch(0.985 0 0); - --card: oklch(0.205 0 0); - --card-foreground: oklch(0.985 0 0); - --popover: oklch(0.205 0 0); - --popover-foreground: oklch(0.985 0 0); - --primary: oklch(0.922 0 0); - --primary-foreground: oklch(0.205 0 0); - --secondary: oklch(0.269 0 0); - --secondary-foreground: oklch(0.985 0 0); - --muted: oklch(0.269 0 0); - --muted-foreground: oklch(0.708 0 0); - --accent: oklch(0.269 0 0); - --accent-foreground: oklch(0.985 0 0); - --destructive: oklch(0.704 0.191 22.216); - --border: oklch(1 0 0 / 10%); - --input: oklch(1 0 0 / 15%); - --ring: oklch(0.556 0 0); - --chart-1: oklch(0.488 0.243 264.376); - --chart-2: oklch(0.696 0.17 162.48); - --chart-3: oklch(0.769 0.188 70.08); - --chart-4: oklch(0.627 0.265 303.9); - --chart-5: oklch(0.645 0.246 16.439); - --sidebar: oklch(0.205 0 0); - --sidebar-foreground: oklch(0.985 0 0); - --sidebar-primary: oklch(0.488 0.243 264.376); - --sidebar-primary-foreground: oklch(0.985 0 0); - --sidebar-accent: oklch(0.269 0 0); - --sidebar-accent-foreground: oklch(0.985 0 0); - --sidebar-border: oklch(1 0 0 / 10%); - --sidebar-ring: oklch(0.556 0 0); + --background: oklch(0.27 0 0); + --foreground: oklch(0.81 0.01 93.53); + --card: oklch(0.27 0 0); + --card-foreground: oklch(0.98 0.01 93.48); + --popover: oklch(0.31 0 0); + --popover-foreground: oklch(0.92 0 0); + --primary: oklch(0.524 0.15 29.973); + --primary-foreground: oklch(1.00 0 0); + --secondary: oklch(0.98 0.01 93.48); + --secondary-foreground: oklch(0.31 0 0); + --muted: oklch(0.22 0 0); + --muted-foreground: oklch(0.77 0.02 100.64); + --accent: oklch(0.21 0.01 88.79); + --accent-foreground: oklch(0.97 0.01 93.49); + --destructive: oklch(0.64 0.21 25.39); + --border: oklch(0.36 0.01 106.85); + --input: oklch(0.43 0.01 99.03); + --ring: oklch(0.59 0.17 252.92); + --chart-1: oklch(0.56 0.13 42.95); + --chart-2: oklch(0.69 0.16 290.29); + --chart-3: oklch(0.21 0.01 88.79); + --chart-4: oklch(0.31 0.05 289.74); + --chart-5: oklch(0.56 0.13 41.94); + --sidebar: oklch(0.24 0 0); + --sidebar-foreground: oklch(0.81 0.01 93.53); + --sidebar-primary: oklch(0.33 0 0); + --sidebar-primary-foreground: oklch(0.99 0 0); + --sidebar-accent: oklch(0.17 0 0); + --sidebar-accent-foreground: oklch(0.81 0.01 93.53); + --sidebar-border: oklch(0.94 0 0); + --sidebar-ring: oklch(0.77 0 0); + + --shadow-2xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05); + --shadow-xs: 0 1px 3px 0px oklch(0.00 0 0 / 0.05); + --shadow-sm: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10); + --shadow: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 1px 2px -1px oklch(0.00 0 0 / 0.10); + --shadow-md: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 2px 4px -1px oklch(0.00 0 0 / 0.10); + --shadow-lg: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 4px 6px -1px oklch(0.00 0 0 / 0.10); + --shadow-xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.10), 0 8px 10px -1px oklch(0.00 0 0 / 0.10); + --shadow-2xl: 0 1px 3px 0px oklch(0.00 0 0 / 0.25); +} + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); + + --font-sans: var(--font-sans); + --font-mono: var(--font-mono); + --font-serif: var(--font-serif); + + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + + --shadow-2xs: var(--shadow-2xs); + --shadow-xs: var(--shadow-xs); + --shadow-sm: var(--shadow-sm); + --shadow: var(--shadow); + --shadow-md: var(--shadow-md); + --shadow-lg: var(--shadow-lg); + --shadow-xl: var(--shadow-xl); + --shadow-2xl: var(--shadow-2xl); } @layer base { @@ -116,6 +207,7 @@ } body { @apply bg-background text-foreground; + letter-spacing: var(--tracking-normal); } } @@ -135,4 +227,17 @@ max-width: 200px; max-height: 200px; color: #1e1eef; +} + +.theme-scroll { + scrollbar-width: thin; + scrollbar-color: theme(colors.neutral.500) theme(colors.neutral.800); +} + +.theme-scroll::-webkit-scrollbar-thumb { + background-color: theme(colors.neutral.500); +} + +.theme-scroll::-webkit-scrollbar-thumb:hover { + background-color: theme(colors.neutral.500); } \ No newline at end of file From 23e472d49ea53e0904caadf2c58eea8dae227bd6 Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:04:55 +0000 Subject: [PATCH 10/18] chore(frontend): update package.json --- frontend/package-lock.json | 1135 +++++++++++++++++++++++++++++------- frontend/package.json | 1 + 2 files changed, 935 insertions(+), 201 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 6e2ac116..ca002e25 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -29,6 +29,7 @@ "keycloak-js": "^26.2.0", "lucide-react": "^0.525.0", "mediainfo.js": "^0.3.6", + "radix-ui": "^1.4.3", "react": "^19.1.0", "react-dom": "^19.1.0", "react-dropzone": "^14.3.8", @@ -1339,12 +1340,118 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "license": "BSD-3-Clause" }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT" + }, "node_modules/@radix-ui/primitive": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", - "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", "license": "MIT" }, + "node_modules/@radix-ui/react-accessible-icon": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.1.7.tgz", + "integrity": "sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz", + "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz", + "integrity": "sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dialog": "1.1.15", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-alert-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", @@ -1368,6 +1475,29 @@ } } }, + "node_modules/@radix-ui/react-aspect-ratio": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.7.tgz", + "integrity": "sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-avatar": { "version": "1.1.10", "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.1.10.tgz", @@ -1396,15 +1526,15 @@ } }, "node_modules/@radix-ui/react-checkbox": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.2.tgz", - "integrity": "sha512-yd+dI56KZqawxKZrJ31eENUwqc1QSqg4OZ15rybGjF2ZNwMO+wCyHzAVLRp9qoYJf7kYy0YpZ2b0JCzJ42HZpA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", @@ -1426,16 +1556,16 @@ } }, "node_modules/@radix-ui/react-collapsible": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.11.tgz", - "integrity": "sha512-2qrRsVGSCYasSz1RFOorXwl0H7g7J1frQtgpQgYrt+MOidtPAINHn9CPovQXb83r8ahapdx3Tu0fa/pdFFSdPg==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz", + "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1" @@ -1529,6 +1659,34 @@ } } }, + "node_modules/@radix-ui/react-context-menu": { + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.2.16.tgz", + "integrity": "sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-dialog": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", @@ -1564,41 +1722,29 @@ } } }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/primitive": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", - "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==" - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", - "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-escape-keydown": "1.1.1" + "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true - }, - "@types/react-dom": { - "optional": true } } }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", - "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -1609,13 +1755,17 @@ } } }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-presence": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", - "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", "dependencies": { + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1632,28 +1782,39 @@ } } }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", + "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-direction": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", - "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -1665,17 +1826,15 @@ } } }, - "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", - "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-escape-keydown": "1.1.1" + "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1692,19 +1851,18 @@ } } }, - "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.15.tgz", - "integrity": "sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==", + "node_modules/@radix-ui/react-form": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-form/-/react-form-0.1.8.tgz", + "integrity": "sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.15", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" + "@radix-ui/react-label": "2.1.7", + "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", @@ -1721,30 +1879,484 @@ } } }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", - "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "node_modules/@radix-ui/react-hover-card": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.1.15.tgz", + "integrity": "sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==", "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", - "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", + "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", + "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menubar": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.16.tgz", + "integrity": "sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.14.tgz", + "integrity": "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-one-time-password-field": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-one-time-password-field/-/react-one-time-password-field-0.1.8.tgz", + "integrity": "sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-password-toggle-field": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-password-toggle-field/-/react-password-toggle-field-0.1.3.tgz", + "integrity": "sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-is-hydrated": "0.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", + "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.7.tgz", + "integrity": "sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", + "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", "license": "MIT", "dependencies": { + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1" + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1761,31 +2373,52 @@ } } }, - "node_modules/@radix-ui/react-id": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-label": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", - "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", + "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1802,28 +2435,31 @@ } } }, - "node_modules/@radix-ui/react-menu": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.15.tgz", - "integrity": "sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==", + "node_modules/@radix-ui/react-select": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", + "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.10", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, @@ -1842,7 +2478,7 @@ } } }, - "node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", @@ -1860,27 +2496,46 @@ } } }, - "node_modules/@radix-ui/react-popover": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.14.tgz", - "integrity": "sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==", + "node_modules/@radix-ui/react-separator": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slider": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", + "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1897,10 +2552,10 @@ } } }, - "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "node_modules/@radix-ui/react-slot": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", + "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -1915,22 +2570,19 @@ } } }, - "node_modules/@radix-ui/react-popper": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", - "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", + "node_modules/@radix-ui/react-switch": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", + "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", "license": "MIT", "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-rect": "1.1.1", - "@radix-ui/react-use-size": "1.1.1", - "@radix-ui/rect": "1.1.1" + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", @@ -1947,14 +2599,20 @@ } } }, - "node_modules/@radix-ui/react-portal": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", - "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", "license": "MIT", "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -1971,14 +2629,24 @@ } } }, - "node_modules/@radix-ui/react-presence": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", - "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "node_modules/@radix-ui/react-toast": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.15.tgz", + "integrity": "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==", "license": "MIT", "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", @@ -1995,13 +2663,15 @@ } } }, - "node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "node_modules/@radix-ui/react-toggle": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", + "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.2.3" + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", @@ -2018,38 +2688,18 @@ } } }, - "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.10.tgz", - "integrity": "sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==", + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", + "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { @@ -2067,13 +2717,19 @@ } } }, - "node_modules/@radix-ui/react-separator": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", - "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", + "node_modules/@radix-ui/react-toolbar": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.1.11.tgz", + "integrity": "sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.1.3" + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-separator": "1.1.7", + "@radix-ui/react-toggle-group": "1.1.11" }, "peerDependencies": { "@types/react": "*", @@ -2090,38 +2746,20 @@ } } }, - "node_modules/@radix-ui/react-slot": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", - "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.7.tgz", - "integrity": "sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", @@ -6156,6 +6794,101 @@ "integrity": "sha512-5y72gAXPzIBsAMHcpxZP8eMDuDT98qMP1BqSDHRbHkJJXEgWIN1lA47LxUqzsK6jknOJtgfkQr9v+7qMlFDm6g==", "license": "(Apache-2.0 AND MIT)" }, + "node_modules/radix-ui": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/radix-ui/-/radix-ui-1.4.3.tgz", + "integrity": "sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-accessible-icon": "1.1.7", + "@radix-ui/react-accordion": "1.2.12", + "@radix-ui/react-alert-dialog": "1.1.15", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-aspect-ratio": "1.1.7", + "@radix-ui/react-avatar": "1.1.10", + "@radix-ui/react-checkbox": "1.3.3", + "@radix-ui/react-collapsible": "1.1.12", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-context-menu": "2.2.16", + "@radix-ui/react-dialog": "1.1.15", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-dropdown-menu": "2.1.16", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-form": "0.1.8", + "@radix-ui/react-hover-card": "1.1.15", + "@radix-ui/react-label": "2.1.7", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-menubar": "1.1.16", + "@radix-ui/react-navigation-menu": "1.2.14", + "@radix-ui/react-one-time-password-field": "0.1.8", + "@radix-ui/react-password-toggle-field": "0.1.3", + "@radix-ui/react-popover": "1.1.15", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-progress": "1.1.7", + "@radix-ui/react-radio-group": "1.3.8", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-scroll-area": "1.2.10", + "@radix-ui/react-select": "2.2.6", + "@radix-ui/react-separator": "1.1.7", + "@radix-ui/react-slider": "1.3.6", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-switch": "1.2.6", + "@radix-ui/react-tabs": "1.1.13", + "@radix-ui/react-toast": "1.2.15", + "@radix-ui/react-toggle": "1.1.10", + "@radix-ui/react-toggle-group": "1.1.11", + "@radix-ui/react-toolbar": "1.1.11", + "@radix-ui/react-tooltip": "1.2.8", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-escape-keydown": "1.1.1", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/radix-ui/node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react": { "version": "19.1.0", "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 81684d63..569ddd73 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -31,6 +31,7 @@ "keycloak-js": "^26.2.0", "lucide-react": "^0.525.0", "mediainfo.js": "^0.3.6", + "radix-ui": "^1.4.3", "react": "^19.1.0", "react-dom": "^19.1.0", "react-dropzone": "^14.3.8", From c5c5802d4165585442accd09933a04237fcccee0 Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:05:40 +0000 Subject: [PATCH 11/18] fix(frontend): stop page flashing between redirects --- frontend/src/main.tsx | 59 +++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 70c13f2b..2534bdae 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -1,43 +1,30 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import './index.css' -import App from './App.tsx' -import { initKeycloak } from '@/security/auth/keycloak/keycloak.ts'; -import { useAuthStore } from "@/security/auth/authstore/auth-store.ts"; + import { StrictMode } from 'react' + import { createRoot } from 'react-dom/client' + import './index.css' + import App from './App.tsx' + import { initKeycloak } from '@/security/auth/keycloak/keycloak.ts'; + import { useAuthStore } from "@/security/auth/authstore/auth-store.ts"; -const rootElement = document.getElementById("root")!; -rootElement.innerHTML = ` -
- loading... -
-`; + const root = createRoot(document.getElementById('root')!); -async function auth() { - const kc = await initKeycloak(); + async function bootstrap() { + const kc = await initKeycloak(); + + // If Keycloak determines user not signed in, redirect to login page. + // The spinner in index.html stays visible until the browser actually leaves the page. + if (!kc || !kc.authenticated) { + kc?.login(); + return; + } - if (kc) { useAuthStore.getState().setToken(kc.token ?? null); - console.log('Token:', kc.token); - console.log('User:', kc.tokenParsed?.preferred_username); - } + useAuthStore.getState().setUserId(kc.tokenParsed?.sub ?? null); - if (kc?.tokenParsed) { - const userId = kc.tokenParsed.sub; - useAuthStore.getState().setUserId(userId ?? null); + root.render( + + + + ); } - const isAuthenticated = !!kc; - - createRoot(document.getElementById('root')!).render( - - - , - ); - -} - -auth(); \ No newline at end of file + bootstrap(); \ No newline at end of file From 6411dd14eaebfd25d0ca05f56e670080afb82084 Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:06:15 +0000 Subject: [PATCH 12/18] refactor(backend): add Pool interface --- backend/src/internal/{ => db}/metadb/db.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) rename backend/src/internal/{ => db}/metadb/db.go (69%) diff --git a/backend/src/internal/metadb/db.go b/backend/src/internal/db/metadb/db.go similarity index 69% rename from backend/src/internal/metadb/db.go rename to backend/src/internal/db/metadb/db.go index e783a6d6..da74524e 100644 --- a/backend/src/internal/metadb/db.go +++ b/backend/src/internal/db/metadb/db.go @@ -6,11 +6,19 @@ import ( "log" "os" + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" "github.com/jackc/pgx/v5/pgxpool" ) +type Pool interface { + Begin(context.Context) (pgx.Tx, error) + Exec(context.Context, string, ...any) (pgconn.CommandTag, error) + Query(context.Context, string, ...any) (pgx.Rows, error) +} + type MetadataDatabase struct { - Pool *pgxpool.Pool + Pool Pool } func New(ctx context.Context, envVar string) (*MetadataDatabase, error) { From 14041fcea864f7d3542a794e7aa8f452b232b78d Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:07:00 +0000 Subject: [PATCH 13/18] refactor(backend): add json mapping --- backend/src/usecase/files/data/metadata.go | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/backend/src/usecase/files/data/metadata.go b/backend/src/usecase/files/data/metadata.go index 60e58a27..d85ace23 100644 --- a/backend/src/usecase/files/data/metadata.go +++ b/backend/src/usecase/files/data/metadata.go @@ -11,18 +11,18 @@ import ( // Metadata Model - need ContentCID string for IPFS type MetaData struct { - ID uuid.UUID - FileName string - Path string - Size uint64 - FileType string - ModifiedAt time.Time - UploadedAt time.Time - Owner uuid.UUID - AccessTo []uuid.UUID - Group []uuid.UUID - CheckSum []byte - Version time.Time + ID uuid.UUID `json:"uuid"` + FileName string `json:"file_name"` + Path string `json:"path"` + Size uint64 `json:"size"` + FileType string `json:"file_type"` + ModifiedAt time.Time `json:"modified_at"` + UploadedAt time.Time `json:"created_at"` + Owner uuid.UUID `json:"owner_id"` + AccessTo []uuid.UUID `json:"access_to"` + Group []uuid.UUID `json:"group_id"` + CheckSum []byte `json:"checksum"` + Version time.Time `json:"version"` } func (m *MetaData) ToResponse() MetaDataResponse { From 40f9b0307a6551996de74f3a5203b19fbca84dea Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:07:36 +0000 Subject: [PATCH 14/18] chore(frontend): add alert components --- frontend/src/components/ui/alert.tsx | 66 ++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 frontend/src/components/ui/alert.tsx diff --git a/frontend/src/components/ui/alert.tsx b/frontend/src/components/ui/alert.tsx new file mode 100644 index 00000000..14213546 --- /dev/null +++ b/frontend/src/components/ui/alert.tsx @@ -0,0 +1,66 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const alertVariants = cva( + "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", + { + variants: { + variant: { + default: "bg-card text-card-foreground", + destructive: + "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function Alert({ + className, + variant, + ...props +}: React.ComponentProps<"div"> & VariantProps) { + return ( +
+ ) +} + +function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ) +} + +function AlertDescription({ + className, + ...props +}: React.ComponentProps<"div">) { + return ( +
+ ) +} + +export { Alert, AlertTitle, AlertDescription } From 0a9149ad6bd625010459f0176cb5a0242a2601ae Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:08:16 +0000 Subject: [PATCH 15/18] feat(frontend): add favicons --- backend/tempfiles/react-1618799214.svg | 1 + frontend/public/apple-touch-icon.png | Bin 0 -> 9285 bytes frontend/public/favicon-96x96.png | Bin 0 -> 4077 bytes frontend/public/favicon.ico | Bin 0 -> 15086 bytes frontend/public/favicon.svg | 38 +++++++++++++++++++ frontend/public/web-app-manifest-192x192.png | Bin 0 -> 9950 bytes frontend/public/web-app-manifest-512x512.png | Bin 0 -> 36958 bytes 7 files changed, 39 insertions(+) create mode 100644 backend/tempfiles/react-1618799214.svg create mode 100644 frontend/public/apple-touch-icon.png create mode 100644 frontend/public/favicon-96x96.png create mode 100644 frontend/public/favicon.ico create mode 100644 frontend/public/favicon.svg create mode 100644 frontend/public/web-app-manifest-192x192.png create mode 100644 frontend/public/web-app-manifest-512x512.png diff --git a/backend/tempfiles/react-1618799214.svg b/backend/tempfiles/react-1618799214.svg new file mode 100644 index 00000000..6c87de9b --- /dev/null +++ b/backend/tempfiles/react-1618799214.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/public/apple-touch-icon.png b/frontend/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..816f3700f337bed08afa6cb14a070f404bb51138 GIT binary patch literal 9285 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 literal 0 HcmV?d00001 diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..aad3e8cbd273a093398602bd2a1bbd229e65e82c GIT binary patch literal 15086 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 IZiCeS0VsGs*#H0l literal 0 HcmV?d00001 diff --git a/frontend/public/favicon.svg b/frontend/public/favicon.svg new file mode 100644 index 00000000..afcf830f --- /dev/null +++ b/frontend/public/favicon.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/public/web-app-manifest-192x192.png b/frontend/public/web-app-manifest-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..648a4737b314a5c5a0e468f67cb3c2fc478d77ee GIT binary patch literal 9950 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 Date: Tue, 10 Feb 2026 22:08:42 +0000 Subject: [PATCH 16/18] chore(frontend): add ScrollArea component --- frontend/src/components/ui/scroll-area.tsx | 56 ++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 frontend/src/components/ui/scroll-area.tsx diff --git a/frontend/src/components/ui/scroll-area.tsx b/frontend/src/components/ui/scroll-area.tsx new file mode 100644 index 00000000..f71026ba --- /dev/null +++ b/frontend/src/components/ui/scroll-area.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import { ScrollArea as ScrollAreaPrimitive } from "radix-ui" + +import { cn } from "@/lib/utils" + +function ScrollArea({ + className, + children, + ...props +}: React.ComponentProps) { + return ( + + + {children} + + + + + ) +} + +function ScrollBar({ + className, + orientation = "vertical", + ...props +}: React.ComponentProps) { + return ( + + + + ) +} + +export { ScrollArea, ScrollBar } From d2ce97e0dc5bbbfefc33ed8c607f837f8bbdf77d Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:09:20 +0000 Subject: [PATCH 17/18] chore(frontend): add site manifest --- frontend/public/site.webmanifest | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 frontend/public/site.webmanifest diff --git a/frontend/public/site.webmanifest b/frontend/public/site.webmanifest new file mode 100644 index 00000000..cad068fb --- /dev/null +++ b/frontend/public/site.webmanifest @@ -0,0 +1,21 @@ +{ + "name": "gestalt.ws", + "short_name": "gestalt", + "icons": [ + { + "src": "/public/./web-app-manifest-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/public/./web-app-manifest-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#450909", + "background_color": "#450909", + "display": "standalone" +} \ No newline at end of file From 82b787e5757cb28d7a8996cf668a754e901aa3f8 Mon Sep 17 00:00:00 2001 From: OliverKeefe <104454089+OliverKeefe@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:09:36 +0000 Subject: [PATCH 18/18] chore(frontend): remove vite.svg --- frontend/public/vite.svg | 1 - 1 file changed, 1 deletion(-) delete mode 100644 frontend/public/vite.svg diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/frontend/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file