From 924865be5002aa93b276c9aa4f8945e952b6cb7d Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Mon, 1 Jun 2026 19:02:24 +0200 Subject: [PATCH 01/12] feat: added frontend for one mono repo --- {frontend => app}/.gitignore | 3 + {frontend => app}/.npmrc | 0 app/.vscode/extensions.json | 3 + app/README.md | 42 + app/components.json | 20 + app/package-lock.json | 2861 +++++++ app/package.json | 38 + app/src/app.d.ts | 13 + app/src/app.html | 12 + {frontend => app}/src/lib/assets/favicon.svg | 0 app/src/lib/auth/right-panel.svelte | 116 + .../lib/components/sidebar/app-sidebar.svelte | 127 + .../lib/components/sidebar/icon-bucket.svelte | 8 + .../lib/components/sidebar/nav-main.svelte | 41 + .../components/sidebar/nav-projects.svelte | 33 + .../lib/components/sidebar/nav-user.svelte | 87 + .../components/sidebar/team-switcher.svelte | 86 + .../components/ui/avatar/avatar-badge.svelte | 26 + .../ui/avatar/avatar-fallback.svelte | 20 + .../ui/avatar/avatar-group-count.svelte | 23 + .../components/ui/avatar/avatar-group.svelte | 23 + .../components/ui/avatar/avatar-image.svelte | 17 + .../lib/components/ui/avatar/avatar.svelte | 26 + app/src/lib/components/ui/avatar/index.ts | 22 + .../ui/breadcrumb/breadcrumb-ellipsis.svelte | 23 + .../ui/breadcrumb/breadcrumb-item.svelte | 20 + .../ui/breadcrumb/breadcrumb-link.svelte | 31 + .../ui/breadcrumb/breadcrumb-list.svelte | 20 + .../ui/breadcrumb/breadcrumb-page.svelte | 23 + .../ui/breadcrumb/breadcrumb-separator.svelte | 27 + .../ui/breadcrumb/breadcrumb.svelte | 22 + app/src/lib/components/ui/breadcrumb/index.ts | 25 + .../lib/components/ui/button/button.svelte | 82 + app/src/lib/components/ui/button/index.ts | 17 + .../lib/components/ui/card/card-action.svelte | 23 + .../components/ui/card/card-content.svelte | 20 + .../ui/card/card-description.svelte | 20 + .../lib/components/ui/card/card-footer.svelte | 20 + .../lib/components/ui/card/card-header.svelte | 23 + .../lib/components/ui/card/card-title.svelte | 20 + app/src/lib/components/ui/card/card.svelte | 22 + app/src/lib/components/ui/card/index.ts | 25 + .../components/ui/checkbox/checkbox.svelte | 39 + app/src/lib/components/ui/checkbox/index.ts | 6 + .../ui/collapsible/collapsible-content.svelte | 7 + .../ui/collapsible/collapsible-trigger.svelte | 7 + .../ui/collapsible/collapsible.svelte | 11 + .../lib/components/ui/collapsible/index.ts | 13 + .../dropdown-menu-checkbox-group.svelte | 16 + .../dropdown-menu-checkbox-item.svelte | 44 + .../dropdown-menu-content.svelte | 31 + .../dropdown-menu-group-heading.svelte | 22 + .../dropdown-menu/dropdown-menu-group.svelte | 7 + .../dropdown-menu/dropdown-menu-item.svelte | 27 + .../dropdown-menu/dropdown-menu-label.svelte | 24 + .../dropdown-menu/dropdown-menu-portal.svelte | 7 + .../dropdown-menu-radio-group.svelte | 16 + .../dropdown-menu-radio-item.svelte | 34 + .../dropdown-menu-separator.svelte | 17 + .../dropdown-menu-shortcut.svelte | 20 + .../dropdown-menu-sub-content.svelte | 17 + .../dropdown-menu-sub-trigger.svelte | 29 + .../ui/dropdown-menu/dropdown-menu-sub.svelte | 7 + .../dropdown-menu-trigger.svelte | 7 + .../ui/dropdown-menu/dropdown-menu.svelte | 7 + .../lib/components/ui/dropdown-menu/index.ts | 54 + app/src/lib/components/ui/input/index.ts | 7 + app/src/lib/components/ui/input/input.svelte | 48 + app/src/lib/components/ui/label/index.ts | 7 + app/src/lib/components/ui/label/label.svelte | 20 + app/src/lib/components/ui/separator/index.ts | 7 + .../components/ui/separator/separator.svelte | 23 + app/src/lib/components/ui/sheet/index.ts | 34 + .../components/ui/sheet/sheet-close.svelte | 7 + .../components/ui/sheet/sheet-content.svelte | 55 + .../ui/sheet/sheet-description.svelte | 17 + .../components/ui/sheet/sheet-footer.svelte | 20 + .../components/ui/sheet/sheet-header.svelte | 20 + .../components/ui/sheet/sheet-overlay.svelte | 17 + .../components/ui/sheet/sheet-portal.svelte | 7 + .../components/ui/sheet/sheet-title.svelte | 17 + .../components/ui/sheet/sheet-trigger.svelte | 7 + app/src/lib/components/ui/sheet/sheet.svelte | 7 + .../lib/components/ui/sidebar/constants.ts | 6 + .../components/ui/sidebar/context.svelte.ts | 81 + app/src/lib/components/ui/sidebar/index.ts | 75 + .../ui/sidebar/sidebar-content.svelte | 24 + .../ui/sidebar/sidebar-footer.svelte | 21 + .../ui/sidebar/sidebar-group-action.svelte | 33 + .../ui/sidebar/sidebar-group-content.svelte | 21 + .../ui/sidebar/sidebar-group-label.svelte | 33 + .../ui/sidebar/sidebar-group.svelte | 21 + .../ui/sidebar/sidebar-header.svelte | 21 + .../ui/sidebar/sidebar-input.svelte | 21 + .../ui/sidebar/sidebar-inset.svelte | 20 + .../ui/sidebar/sidebar-menu-action.svelte | 37 + .../ui/sidebar/sidebar-menu-badge.svelte | 24 + .../ui/sidebar/sidebar-menu-button.svelte | 102 + .../ui/sidebar/sidebar-menu-item.svelte | 21 + .../ui/sidebar/sidebar-menu-skeleton.svelte | 36 + .../ui/sidebar/sidebar-menu-sub-button.svelte | 39 + .../ui/sidebar/sidebar-menu-sub-item.svelte | 21 + .../ui/sidebar/sidebar-menu-sub.svelte | 21 + .../components/ui/sidebar/sidebar-menu.svelte | 21 + .../ui/sidebar/sidebar-provider.svelte | 53 + .../components/ui/sidebar/sidebar-rail.svelte | 36 + .../ui/sidebar/sidebar-separator.svelte | 19 + .../ui/sidebar/sidebar-trigger.svelte | 36 + .../lib/components/ui/sidebar/sidebar.svelte | 108 + app/src/lib/components/ui/skeleton/index.ts | 7 + .../components/ui/skeleton/skeleton.svelte | 17 + app/src/lib/components/ui/tooltip/index.ts | 19 + .../ui/tooltip/tooltip-content.svelte | 52 + .../ui/tooltip/tooltip-portal.svelte | 7 + .../ui/tooltip/tooltip-provider.svelte | 7 + .../ui/tooltip/tooltip-trigger.svelte | 7 + .../lib/components/ui/tooltip/tooltip.svelte | 7 + app/src/lib/hooks/is-mobile.svelte.ts | 9 + {frontend => app}/src/lib/index.ts | 0 {frontend => app}/src/lib/utils.ts | 10 +- app/src/routes/(app)/+layout.svelte | 13 + app/src/routes/(app)/+page.svelte | 11 + app/src/routes/+layout.svelte | 17 + app/src/routes/layout.css | 139 + app/src/routes/login/+page.svelte | 90 + app/static/fonts/Geist-Variable.woff2 | Bin 0 -> 69436 bytes app/static/gradients/Gradient-dark.svg | 1 + .../static/gradients/Gradient-light.svg | 0 app/static/logo/logo-csfx.svg | 17 + {frontend => app}/static/robots.txt | 0 app/svelte.config.js | 21 + app/tsconfig.json | 20 + app/vite.config.ts | 5 + frontend/.dockerignore | 14 - frontend/.env.example | 6 - frontend/.prettierignore | 8 - frontend/.prettierrc | 16 - frontend/Dockerfile.dev | 8 - frontend/Dockerfile.prod | 27 - frontend/components.json | 16 - frontend/package-lock.json | 6997 ----------------- frontend/package.json | 65 - frontend/src/app.css | 132 - frontend/src/app.d.ts | 13 - frontend/src/app.html | 41 - .../DeployDockerContainerDialog.svelte | 341 - .../lib/components/UpdateNotification.svelte | 140 - .../components/auth/login-form-client.svelte | 228 - .../components/auth/otp-form-client.svelte | 282 - .../lib/components/navbar/app-sidebar.svelte | 132 - .../components/navbar/nav-favorites.svelte | 43 - .../src/lib/components/navbar/nav-main.svelte | 34 - .../lib/components/navbar/nav-projects.svelte | 76 - .../src/lib/components/navbar/nav-user.svelte | 124 - .../components/navbar/team-switcher.svelte | 31 - .../settings/OrganizationSettings.svelte | 153 - .../components/settings/UpdateSettings.svelte | 311 - .../alert-dialog/alert-dialog-action.svelte | 18 - .../alert-dialog/alert-dialog-cancel.svelte | 18 - .../alert-dialog/alert-dialog-content.svelte | 29 - .../alert-dialog-description.svelte | 17 - .../alert-dialog/alert-dialog-footer.svelte | 20 - .../alert-dialog/alert-dialog-header.svelte | 20 - .../alert-dialog/alert-dialog-overlay.svelte | 20 - .../alert-dialog/alert-dialog-portal.svelte | 7 - .../ui/alert-dialog/alert-dialog-title.svelte | 17 - .../alert-dialog/alert-dialog-trigger.svelte | 7 - .../ui/alert-dialog/alert-dialog.svelte | 7 - .../lib/components/ui/alert-dialog/index.ts | 37 - .../ui/alert/alert-description.svelte | 23 - .../components/ui/alert/alert-title.svelte | 20 - .../src/lib/components/ui/alert/alert.svelte | 44 - frontend/src/lib/components/ui/alert/index.ts | 14 - .../ui/avatar/avatar-fallback.svelte | 17 - .../components/ui/avatar/avatar-image.svelte | 17 - .../lib/components/ui/avatar/avatar.svelte | 19 - .../src/lib/components/ui/avatar/index.ts | 13 - .../src/lib/components/ui/badge/badge.svelte | 49 - frontend/src/lib/components/ui/badge/index.ts | 2 - .../ui/breadcrumb/breadcrumb-ellipsis.svelte | 23 - .../ui/breadcrumb/breadcrumb-item.svelte | 20 - .../ui/breadcrumb/breadcrumb-link.svelte | 31 - .../ui/breadcrumb/breadcrumb-list.svelte | 23 - .../ui/breadcrumb/breadcrumb-page.svelte | 23 - .../ui/breadcrumb/breadcrumb-separator.svelte | 27 - .../ui/breadcrumb/breadcrumb.svelte | 21 - .../src/lib/components/ui/breadcrumb/index.ts | 25 - .../lib/components/ui/button/button.svelte | 82 - .../src/lib/components/ui/button/index.ts | 17 - .../ui/calendar/calendar-caption.svelte | 76 - .../ui/calendar/calendar-cell.svelte | 19 - .../ui/calendar/calendar-day.svelte | 35 - .../ui/calendar/calendar-grid-body.svelte | 12 - .../ui/calendar/calendar-grid-head.svelte | 12 - .../ui/calendar/calendar-grid-row.svelte | 12 - .../ui/calendar/calendar-grid.svelte | 16 - .../ui/calendar/calendar-head-cell.svelte | 19 - .../ui/calendar/calendar-header.svelte | 19 - .../ui/calendar/calendar-heading.svelte | 16 - .../ui/calendar/calendar-month-select.svelte | 44 - .../ui/calendar/calendar-month.svelte | 15 - .../ui/calendar/calendar-months.svelte | 19 - .../ui/calendar/calendar-nav.svelte | 19 - .../ui/calendar/calendar-next-button.svelte | 31 - .../ui/calendar/calendar-prev-button.svelte | 31 - .../ui/calendar/calendar-year-select.svelte | 43 - .../components/ui/calendar/calendar.svelte | 115 - .../src/lib/components/ui/calendar/index.ts | 40 - .../lib/components/ui/card/card-action.svelte | 20 - .../components/ui/card/card-content.svelte | 15 - .../ui/card/card-description.svelte | 20 - .../lib/components/ui/card/card-footer.svelte | 20 - .../lib/components/ui/card/card-header.svelte | 23 - .../lib/components/ui/card/card-title.svelte | 20 - .../src/lib/components/ui/card/card.svelte | 23 - frontend/src/lib/components/ui/card/index.ts | 25 - .../ui/chart/chart-container.svelte | 80 - .../components/ui/chart/chart-style.svelte | 37 - .../components/ui/chart/chart-tooltip.svelte | 155 - .../lib/components/ui/chart/chart-utils.ts | 66 - frontend/src/lib/components/ui/chart/index.ts | 6 - .../components/ui/checkbox/checkbox.svelte | 36 - .../src/lib/components/ui/checkbox/index.ts | 6 - .../ui/collapsible/collapsible-content.svelte | 7 - .../ui/collapsible/collapsible-trigger.svelte | 7 - .../ui/collapsible/collapsible.svelte | 11 - .../lib/components/ui/collapsible/index.ts | 13 - .../ui/data-table/data-table.svelte.ts | 142 - .../ui/data-table/flex-render.svelte | 40 - .../src/lib/components/ui/data-table/index.ts | 3 - .../ui/data-table/render-helpers.ts | 111 - .../components/ui/dialog/dialog-close.svelte | 7 - .../ui/dialog/dialog-content.svelte | 43 - .../ui/dialog/dialog-description.svelte | 17 - .../components/ui/dialog/dialog-footer.svelte | 20 - .../components/ui/dialog/dialog-header.svelte | 20 - .../ui/dialog/dialog-overlay.svelte | 20 - .../components/ui/dialog/dialog-title.svelte | 17 - .../ui/dialog/dialog-trigger.svelte | 7 - .../src/lib/components/ui/dialog/index.ts | 37 - .../dropdown-menu-checkbox-item.svelte | 41 - .../dropdown-menu-content.svelte | 27 - .../dropdown-menu-group-heading.svelte | 22 - .../dropdown-menu/dropdown-menu-group.svelte | 7 - .../dropdown-menu/dropdown-menu-item.svelte | 27 - .../dropdown-menu/dropdown-menu-label.svelte | 24 - .../dropdown-menu-radio-group.svelte | 16 - .../dropdown-menu-radio-item.svelte | 31 - .../dropdown-menu-separator.svelte | 17 - .../dropdown-menu-shortcut.svelte | 20 - .../dropdown-menu-sub-content.svelte | 20 - .../dropdown-menu-sub-trigger.svelte | 29 - .../dropdown-menu-trigger.svelte | 7 - .../lib/components/ui/dropdown-menu/index.ts | 49 - .../components/ui/field/field-content.svelte | 20 - .../ui/field/field-description.svelte | 25 - .../components/ui/field/field-error.svelte | 58 - .../components/ui/field/field-group.svelte | 23 - .../components/ui/field/field-label.svelte | 26 - .../components/ui/field/field-legend.svelte | 29 - .../ui/field/field-separator.svelte | 35 - .../lib/components/ui/field/field-set.svelte | 24 - .../components/ui/field/field-title.svelte | 23 - .../src/lib/components/ui/field/field.svelte | 53 - frontend/src/lib/components/ui/field/index.ts | 33 - .../src/lib/components/ui/input-otp/index.ts | 15 - .../ui/input-otp/input-otp-group.svelte | 20 - .../ui/input-otp/input-otp-separator.svelte | 19 - .../ui/input-otp/input-otp-slot.svelte | 31 - .../components/ui/input-otp/input-otp.svelte | 22 - frontend/src/lib/components/ui/input/index.ts | 7 - .../src/lib/components/ui/input/input.svelte | 52 - frontend/src/lib/components/ui/label/index.ts | 7 - .../src/lib/components/ui/label/label.svelte | 20 - .../lib/components/ui/native-select/index.ts | 12 - .../native-select-opt-group.svelte | 14 - .../native-select/native-select-option.svelte | 14 - .../ui/native-select/native-select.svelte | 38 - .../src/lib/components/ui/progress/index.ts | 7 - .../components/ui/progress/progress.svelte | 27 - .../src/lib/components/ui/select/index.ts | 37 - .../ui/select/select-content.svelte | 40 - .../ui/select/select-group-heading.svelte | 21 - .../components/ui/select/select-group.svelte | 7 - .../components/ui/select/select-item.svelte | 38 - .../components/ui/select/select-label.svelte | 20 - .../select/select-scroll-down-button.svelte | 20 - .../ui/select/select-scroll-up-button.svelte | 20 - .../ui/select/select-separator.svelte | 18 - .../ui/select/select-trigger.svelte | 29 - .../src/lib/components/ui/separator/index.ts | 7 - .../components/ui/separator/separator.svelte | 21 - .../src/lib/components/ui/service-icon.svelte | 95 - frontend/src/lib/components/ui/sheet/index.ts | 36 - .../components/ui/sheet/sheet-close.svelte | 7 - .../components/ui/sheet/sheet-content.svelte | 60 - .../ui/sheet/sheet-description.svelte | 17 - .../components/ui/sheet/sheet-footer.svelte | 20 - .../components/ui/sheet/sheet-header.svelte | 20 - .../components/ui/sheet/sheet-overlay.svelte | 20 - .../components/ui/sheet/sheet-title.svelte | 17 - .../components/ui/sheet/sheet-trigger.svelte | 7 - .../lib/components/ui/sidebar/constants.ts | 6 - .../components/ui/sidebar/context.svelte.ts | 79 - .../src/lib/components/ui/sidebar/index.ts | 75 - .../ui/sidebar/sidebar-content.svelte | 24 - .../ui/sidebar/sidebar-footer.svelte | 21 - .../ui/sidebar/sidebar-group-action.svelte | 36 - .../ui/sidebar/sidebar-group-content.svelte | 21 - .../ui/sidebar/sidebar-group-label.svelte | 34 - .../ui/sidebar/sidebar-group.svelte | 21 - .../ui/sidebar/sidebar-header.svelte | 21 - .../ui/sidebar/sidebar-input.svelte | 21 - .../ui/sidebar/sidebar-inset.svelte | 24 - .../ui/sidebar/sidebar-menu-action.svelte | 43 - .../ui/sidebar/sidebar-menu-badge.svelte | 29 - .../ui/sidebar/sidebar-menu-button.svelte | 101 - .../ui/sidebar/sidebar-menu-item.svelte | 21 - .../ui/sidebar/sidebar-menu-skeleton.svelte | 36 - .../ui/sidebar/sidebar-menu-sub-button.svelte | 43 - .../ui/sidebar/sidebar-menu-sub-item.svelte | 21 - .../ui/sidebar/sidebar-menu-sub.svelte | 25 - .../components/ui/sidebar/sidebar-menu.svelte | 21 - .../ui/sidebar/sidebar-provider.svelte | 53 - .../components/ui/sidebar/sidebar-rail.svelte | 36 - .../ui/sidebar/sidebar-separator.svelte | 19 - .../ui/sidebar/sidebar-trigger.svelte | 35 - .../lib/components/ui/sidebar/sidebar.svelte | 101 - .../src/lib/components/ui/skeleton/index.ts | 7 - .../components/ui/skeleton/skeleton.svelte | 17 - .../src/lib/components/ui/switch/index.ts | 7 - .../lib/components/ui/switch/switch.svelte | 29 - frontend/src/lib/components/ui/table/index.ts | 28 - .../lib/components/ui/table/table-body.svelte | 20 - .../components/ui/table/table-caption.svelte | 20 - .../lib/components/ui/table/table-cell.svelte | 23 - .../components/ui/table/table-footer.svelte | 20 - .../lib/components/ui/table/table-head.svelte | 23 - .../components/ui/table/table-header.svelte | 20 - .../lib/components/ui/table/table-row.svelte | 23 - .../src/lib/components/ui/table/table.svelte | 22 - frontend/src/lib/components/ui/tabs/index.ts | 16 - .../components/ui/tabs/tabs-content.svelte | 17 - .../lib/components/ui/tabs/tabs-list.svelte | 16 - .../components/ui/tabs/tabs-trigger.svelte | 20 - .../src/lib/components/ui/tabs/tabs.svelte | 19 - .../src/lib/components/ui/textarea/index.ts | 7 - .../components/ui/textarea/textarea.svelte | 23 - .../src/lib/components/ui/tooltip/index.ts | 21 - .../ui/tooltip/tooltip-content.svelte | 47 - .../ui/tooltip/tooltip-trigger.svelte | 7 - frontend/src/lib/hooks/is-mobile.svelte.ts | 9 - frontend/src/lib/services/agents.ts | 69 - frontend/src/lib/services/api-client.ts | 174 - frontend/src/lib/services/auth.ts | 132 - frontend/src/lib/services/budget.ts | 78 - frontend/src/lib/services/expenses.ts | 87 - frontend/src/lib/services/invoice.ts | 129 - frontend/src/lib/services/marketplace.ts | 60 - frontend/src/lib/services/organization.ts | 103 - frontend/src/lib/services/resource-groups.ts | 67 - frontend/src/lib/services/resources.ts | 100 - frontend/src/lib/services/settings.ts | 106 - frontend/src/lib/services/subscriptions.ts | 95 - frontend/src/lib/services/system.ts | 67 - frontend/src/lib/services/updates.ts | 60 - frontend/src/lib/stores/auth.ts | 70 - frontend/src/lib/stores/theme.ts | 74 - frontend/src/lib/stores/updates.ts | 103 - frontend/src/lib/types/agent.ts | 35 - frontend/src/lib/types/index.ts | 120 - frontend/src/lib/types/organization.ts | 47 - frontend/src/lib/types/resource-group.ts | 25 - frontend/src/lib/types/resource.ts | 204 - frontend/src/lib/utils/logger.ts | 66 - frontend/src/routes/+layout.server.ts | 45 - frontend/src/routes/+layout.svelte | 77 - frontend/src/routes/+page.server.ts | 12 - frontend/src/routes/+page.svelte | 12 - frontend/src/routes/admin/+layout.server.ts | 18 - frontend/src/routes/admin/+layout.svelte | 64 - frontend/src/routes/admin/+page.svelte | 58 - .../routes/admin/organization/+page.server.ts | 16 - .../routes/admin/organization/+page.svelte | 190 - .../src/routes/admin/users/+page.server.ts | 16 - frontend/src/routes/admin/users/+page.svelte | 389 - .../src/routes/api/set-auth-cookie/+server.ts | 23 - .../routes/change-password/+page.server.ts | 14 - .../src/routes/change-password/+page.svelte | 107 - frontend/src/routes/local-system/+page.svelte | 320 - frontend/src/routes/marketplace/+page.svelte | 424 - frontend/src/routes/otp/+page.svelte | 5 - .../src/routes/physical-servers/+page.svelte | 223 - .../routes/physical-servers/[id]/+page.svelte | 600 -- .../src/routes/resource-groups/+page.svelte | 256 - .../routes/resource-groups/[id]/+page.svelte | 594 -- .../resource-groups/[id]/edit/+page.svelte | 196 - .../resource-groups/create/+page.svelte | 159 - frontend/src/routes/resources/+page.svelte | 354 - .../src/routes/resources/[id]/+page.svelte | 774 -- frontend/src/routes/settings/+page.server.ts | 14 - frontend/src/routes/settings/+page.svelte | 499 -- frontend/src/routes/signin/+page.server.ts | 76 - frontend/src/routes/signin/+page.svelte | 5 - frontend/static/logos/CSF_Logo.png | Bin 93686 -> 0 bytes frontend/svelte.config.js | 24 - frontend/tsconfig.json | 19 - frontend/vite.config.ts | 10 - 408 files changed, 6321 insertions(+), 22297 deletions(-) rename {frontend => app}/.gitignore (90%) rename {frontend => app}/.npmrc (100%) create mode 100644 app/.vscode/extensions.json create mode 100644 app/README.md create mode 100644 app/components.json create mode 100644 app/package-lock.json create mode 100644 app/package.json create mode 100644 app/src/app.d.ts create mode 100644 app/src/app.html rename {frontend => app}/src/lib/assets/favicon.svg (100%) create mode 100644 app/src/lib/auth/right-panel.svelte create mode 100644 app/src/lib/components/sidebar/app-sidebar.svelte create mode 100644 app/src/lib/components/sidebar/icon-bucket.svelte create mode 100644 app/src/lib/components/sidebar/nav-main.svelte create mode 100644 app/src/lib/components/sidebar/nav-projects.svelte create mode 100644 app/src/lib/components/sidebar/nav-user.svelte create mode 100644 app/src/lib/components/sidebar/team-switcher.svelte create mode 100644 app/src/lib/components/ui/avatar/avatar-badge.svelte create mode 100644 app/src/lib/components/ui/avatar/avatar-fallback.svelte create mode 100644 app/src/lib/components/ui/avatar/avatar-group-count.svelte create mode 100644 app/src/lib/components/ui/avatar/avatar-group.svelte create mode 100644 app/src/lib/components/ui/avatar/avatar-image.svelte create mode 100644 app/src/lib/components/ui/avatar/avatar.svelte create mode 100644 app/src/lib/components/ui/avatar/index.ts create mode 100644 app/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte create mode 100644 app/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte create mode 100644 app/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte create mode 100644 app/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte create mode 100644 app/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte create mode 100644 app/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte create mode 100644 app/src/lib/components/ui/breadcrumb/breadcrumb.svelte create mode 100644 app/src/lib/components/ui/breadcrumb/index.ts create mode 100644 app/src/lib/components/ui/button/button.svelte create mode 100644 app/src/lib/components/ui/button/index.ts create mode 100644 app/src/lib/components/ui/card/card-action.svelte create mode 100644 app/src/lib/components/ui/card/card-content.svelte create mode 100644 app/src/lib/components/ui/card/card-description.svelte create mode 100644 app/src/lib/components/ui/card/card-footer.svelte create mode 100644 app/src/lib/components/ui/card/card-header.svelte create mode 100644 app/src/lib/components/ui/card/card-title.svelte create mode 100644 app/src/lib/components/ui/card/card.svelte create mode 100644 app/src/lib/components/ui/card/index.ts create mode 100644 app/src/lib/components/ui/checkbox/checkbox.svelte create mode 100644 app/src/lib/components/ui/checkbox/index.ts create mode 100644 app/src/lib/components/ui/collapsible/collapsible-content.svelte create mode 100644 app/src/lib/components/ui/collapsible/collapsible-trigger.svelte create mode 100644 app/src/lib/components/ui/collapsible/collapsible.svelte create mode 100644 app/src/lib/components/ui/collapsible/index.ts create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte create mode 100644 app/src/lib/components/ui/dropdown-menu/index.ts create mode 100644 app/src/lib/components/ui/input/index.ts create mode 100644 app/src/lib/components/ui/input/input.svelte create mode 100644 app/src/lib/components/ui/label/index.ts create mode 100644 app/src/lib/components/ui/label/label.svelte create mode 100644 app/src/lib/components/ui/separator/index.ts create mode 100644 app/src/lib/components/ui/separator/separator.svelte create mode 100644 app/src/lib/components/ui/sheet/index.ts create mode 100644 app/src/lib/components/ui/sheet/sheet-close.svelte create mode 100644 app/src/lib/components/ui/sheet/sheet-content.svelte create mode 100644 app/src/lib/components/ui/sheet/sheet-description.svelte create mode 100644 app/src/lib/components/ui/sheet/sheet-footer.svelte create mode 100644 app/src/lib/components/ui/sheet/sheet-header.svelte create mode 100644 app/src/lib/components/ui/sheet/sheet-overlay.svelte create mode 100644 app/src/lib/components/ui/sheet/sheet-portal.svelte create mode 100644 app/src/lib/components/ui/sheet/sheet-title.svelte create mode 100644 app/src/lib/components/ui/sheet/sheet-trigger.svelte create mode 100644 app/src/lib/components/ui/sheet/sheet.svelte create mode 100644 app/src/lib/components/ui/sidebar/constants.ts create mode 100644 app/src/lib/components/ui/sidebar/context.svelte.ts create mode 100644 app/src/lib/components/ui/sidebar/index.ts create mode 100644 app/src/lib/components/ui/sidebar/sidebar-content.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-footer.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-group-action.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-group-content.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-group-label.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-group.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-header.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-input.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-inset.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-menu-action.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-menu-button.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-menu-item.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-menu.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-provider.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-rail.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-separator.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar-trigger.svelte create mode 100644 app/src/lib/components/ui/sidebar/sidebar.svelte create mode 100644 app/src/lib/components/ui/skeleton/index.ts create mode 100644 app/src/lib/components/ui/skeleton/skeleton.svelte create mode 100644 app/src/lib/components/ui/tooltip/index.ts create mode 100644 app/src/lib/components/ui/tooltip/tooltip-content.svelte create mode 100644 app/src/lib/components/ui/tooltip/tooltip-portal.svelte create mode 100644 app/src/lib/components/ui/tooltip/tooltip-provider.svelte create mode 100644 app/src/lib/components/ui/tooltip/tooltip-trigger.svelte create mode 100644 app/src/lib/components/ui/tooltip/tooltip.svelte create mode 100644 app/src/lib/hooks/is-mobile.svelte.ts rename {frontend => app}/src/lib/index.ts (100%) rename {frontend => app}/src/lib/utils.ts (74%) create mode 100644 app/src/routes/(app)/+layout.svelte create mode 100644 app/src/routes/(app)/+page.svelte create mode 100644 app/src/routes/+layout.svelte create mode 100644 app/src/routes/layout.css create mode 100644 app/src/routes/login/+page.svelte create mode 100644 app/static/fonts/Geist-Variable.woff2 create mode 100644 app/static/gradients/Gradient-dark.svg rename frontend/static/Gradientsv2.svg => app/static/gradients/Gradient-light.svg (100%) create mode 100644 app/static/logo/logo-csfx.svg rename {frontend => app}/static/robots.txt (100%) create mode 100644 app/svelte.config.js create mode 100644 app/tsconfig.json create mode 100644 app/vite.config.ts delete mode 100644 frontend/.dockerignore delete mode 100644 frontend/.env.example delete mode 100644 frontend/.prettierignore delete mode 100644 frontend/.prettierrc delete mode 100644 frontend/Dockerfile.dev delete mode 100644 frontend/Dockerfile.prod delete mode 100644 frontend/components.json delete mode 100644 frontend/package-lock.json delete mode 100644 frontend/package.json delete mode 100644 frontend/src/app.css delete mode 100644 frontend/src/app.d.ts delete mode 100644 frontend/src/app.html delete mode 100644 frontend/src/lib/components/DeployDockerContainerDialog.svelte delete mode 100644 frontend/src/lib/components/UpdateNotification.svelte delete mode 100644 frontend/src/lib/components/auth/login-form-client.svelte delete mode 100644 frontend/src/lib/components/auth/otp-form-client.svelte delete mode 100644 frontend/src/lib/components/navbar/app-sidebar.svelte delete mode 100644 frontend/src/lib/components/navbar/nav-favorites.svelte delete mode 100644 frontend/src/lib/components/navbar/nav-main.svelte delete mode 100644 frontend/src/lib/components/navbar/nav-projects.svelte delete mode 100644 frontend/src/lib/components/navbar/nav-user.svelte delete mode 100644 frontend/src/lib/components/navbar/team-switcher.svelte delete mode 100644 frontend/src/lib/components/settings/OrganizationSettings.svelte delete mode 100644 frontend/src/lib/components/settings/UpdateSettings.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/alert-dialog.svelte delete mode 100644 frontend/src/lib/components/ui/alert-dialog/index.ts delete mode 100644 frontend/src/lib/components/ui/alert/alert-description.svelte delete mode 100644 frontend/src/lib/components/ui/alert/alert-title.svelte delete mode 100644 frontend/src/lib/components/ui/alert/alert.svelte delete mode 100644 frontend/src/lib/components/ui/alert/index.ts delete mode 100644 frontend/src/lib/components/ui/avatar/avatar-fallback.svelte delete mode 100644 frontend/src/lib/components/ui/avatar/avatar-image.svelte delete mode 100644 frontend/src/lib/components/ui/avatar/avatar.svelte delete mode 100644 frontend/src/lib/components/ui/avatar/index.ts delete mode 100644 frontend/src/lib/components/ui/badge/badge.svelte delete mode 100644 frontend/src/lib/components/ui/badge/index.ts delete mode 100644 frontend/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte delete mode 100644 frontend/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte delete mode 100644 frontend/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte delete mode 100644 frontend/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte delete mode 100644 frontend/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte delete mode 100644 frontend/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte delete mode 100644 frontend/src/lib/components/ui/breadcrumb/breadcrumb.svelte delete mode 100644 frontend/src/lib/components/ui/breadcrumb/index.ts delete mode 100644 frontend/src/lib/components/ui/button/button.svelte delete mode 100644 frontend/src/lib/components/ui/button/index.ts delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-caption.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-cell.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-day.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-grid-body.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-grid-head.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-grid-row.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-grid.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-head-cell.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-header.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-heading.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-month-select.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-month.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-months.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-nav.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-next-button.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-prev-button.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar-year-select.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/calendar.svelte delete mode 100644 frontend/src/lib/components/ui/calendar/index.ts delete mode 100644 frontend/src/lib/components/ui/card/card-action.svelte delete mode 100644 frontend/src/lib/components/ui/card/card-content.svelte delete mode 100644 frontend/src/lib/components/ui/card/card-description.svelte delete mode 100644 frontend/src/lib/components/ui/card/card-footer.svelte delete mode 100644 frontend/src/lib/components/ui/card/card-header.svelte delete mode 100644 frontend/src/lib/components/ui/card/card-title.svelte delete mode 100644 frontend/src/lib/components/ui/card/card.svelte delete mode 100644 frontend/src/lib/components/ui/card/index.ts delete mode 100644 frontend/src/lib/components/ui/chart/chart-container.svelte delete mode 100644 frontend/src/lib/components/ui/chart/chart-style.svelte delete mode 100644 frontend/src/lib/components/ui/chart/chart-tooltip.svelte delete mode 100644 frontend/src/lib/components/ui/chart/chart-utils.ts delete mode 100644 frontend/src/lib/components/ui/chart/index.ts delete mode 100644 frontend/src/lib/components/ui/checkbox/checkbox.svelte delete mode 100644 frontend/src/lib/components/ui/checkbox/index.ts delete mode 100644 frontend/src/lib/components/ui/collapsible/collapsible-content.svelte delete mode 100644 frontend/src/lib/components/ui/collapsible/collapsible-trigger.svelte delete mode 100644 frontend/src/lib/components/ui/collapsible/collapsible.svelte delete mode 100644 frontend/src/lib/components/ui/collapsible/index.ts delete mode 100644 frontend/src/lib/components/ui/data-table/data-table.svelte.ts delete mode 100644 frontend/src/lib/components/ui/data-table/flex-render.svelte delete mode 100644 frontend/src/lib/components/ui/data-table/index.ts delete mode 100644 frontend/src/lib/components/ui/data-table/render-helpers.ts delete mode 100644 frontend/src/lib/components/ui/dialog/dialog-close.svelte delete mode 100644 frontend/src/lib/components/ui/dialog/dialog-content.svelte delete mode 100644 frontend/src/lib/components/ui/dialog/dialog-description.svelte delete mode 100644 frontend/src/lib/components/ui/dialog/dialog-footer.svelte delete mode 100644 frontend/src/lib/components/ui/dialog/dialog-header.svelte delete mode 100644 frontend/src/lib/components/ui/dialog/dialog-overlay.svelte delete mode 100644 frontend/src/lib/components/ui/dialog/dialog-title.svelte delete mode 100644 frontend/src/lib/components/ui/dialog/dialog-trigger.svelte delete mode 100644 frontend/src/lib/components/ui/dialog/index.ts delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte delete mode 100644 frontend/src/lib/components/ui/dropdown-menu/index.ts delete mode 100644 frontend/src/lib/components/ui/field/field-content.svelte delete mode 100644 frontend/src/lib/components/ui/field/field-description.svelte delete mode 100644 frontend/src/lib/components/ui/field/field-error.svelte delete mode 100644 frontend/src/lib/components/ui/field/field-group.svelte delete mode 100644 frontend/src/lib/components/ui/field/field-label.svelte delete mode 100644 frontend/src/lib/components/ui/field/field-legend.svelte delete mode 100644 frontend/src/lib/components/ui/field/field-separator.svelte delete mode 100644 frontend/src/lib/components/ui/field/field-set.svelte delete mode 100644 frontend/src/lib/components/ui/field/field-title.svelte delete mode 100644 frontend/src/lib/components/ui/field/field.svelte delete mode 100644 frontend/src/lib/components/ui/field/index.ts delete mode 100644 frontend/src/lib/components/ui/input-otp/index.ts delete mode 100644 frontend/src/lib/components/ui/input-otp/input-otp-group.svelte delete mode 100644 frontend/src/lib/components/ui/input-otp/input-otp-separator.svelte delete mode 100644 frontend/src/lib/components/ui/input-otp/input-otp-slot.svelte delete mode 100644 frontend/src/lib/components/ui/input-otp/input-otp.svelte delete mode 100644 frontend/src/lib/components/ui/input/index.ts delete mode 100644 frontend/src/lib/components/ui/input/input.svelte delete mode 100644 frontend/src/lib/components/ui/label/index.ts delete mode 100644 frontend/src/lib/components/ui/label/label.svelte delete mode 100644 frontend/src/lib/components/ui/native-select/index.ts delete mode 100644 frontend/src/lib/components/ui/native-select/native-select-opt-group.svelte delete mode 100644 frontend/src/lib/components/ui/native-select/native-select-option.svelte delete mode 100644 frontend/src/lib/components/ui/native-select/native-select.svelte delete mode 100644 frontend/src/lib/components/ui/progress/index.ts delete mode 100644 frontend/src/lib/components/ui/progress/progress.svelte delete mode 100644 frontend/src/lib/components/ui/select/index.ts delete mode 100644 frontend/src/lib/components/ui/select/select-content.svelte delete mode 100644 frontend/src/lib/components/ui/select/select-group-heading.svelte delete mode 100644 frontend/src/lib/components/ui/select/select-group.svelte delete mode 100644 frontend/src/lib/components/ui/select/select-item.svelte delete mode 100644 frontend/src/lib/components/ui/select/select-label.svelte delete mode 100644 frontend/src/lib/components/ui/select/select-scroll-down-button.svelte delete mode 100644 frontend/src/lib/components/ui/select/select-scroll-up-button.svelte delete mode 100644 frontend/src/lib/components/ui/select/select-separator.svelte delete mode 100644 frontend/src/lib/components/ui/select/select-trigger.svelte delete mode 100644 frontend/src/lib/components/ui/separator/index.ts delete mode 100644 frontend/src/lib/components/ui/separator/separator.svelte delete mode 100644 frontend/src/lib/components/ui/service-icon.svelte delete mode 100644 frontend/src/lib/components/ui/sheet/index.ts delete mode 100644 frontend/src/lib/components/ui/sheet/sheet-close.svelte delete mode 100644 frontend/src/lib/components/ui/sheet/sheet-content.svelte delete mode 100644 frontend/src/lib/components/ui/sheet/sheet-description.svelte delete mode 100644 frontend/src/lib/components/ui/sheet/sheet-footer.svelte delete mode 100644 frontend/src/lib/components/ui/sheet/sheet-header.svelte delete mode 100644 frontend/src/lib/components/ui/sheet/sheet-overlay.svelte delete mode 100644 frontend/src/lib/components/ui/sheet/sheet-title.svelte delete mode 100644 frontend/src/lib/components/ui/sheet/sheet-trigger.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/constants.ts delete mode 100644 frontend/src/lib/components/ui/sidebar/context.svelte.ts delete mode 100644 frontend/src/lib/components/ui/sidebar/index.ts delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-content.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-footer.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-group-action.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-group-content.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-group-label.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-group.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-header.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-input.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-inset.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-menu-action.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-menu-button.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-menu-item.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-menu.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-provider.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-rail.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-separator.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar-trigger.svelte delete mode 100644 frontend/src/lib/components/ui/sidebar/sidebar.svelte delete mode 100644 frontend/src/lib/components/ui/skeleton/index.ts delete mode 100644 frontend/src/lib/components/ui/skeleton/skeleton.svelte delete mode 100644 frontend/src/lib/components/ui/switch/index.ts delete mode 100644 frontend/src/lib/components/ui/switch/switch.svelte delete mode 100644 frontend/src/lib/components/ui/table/index.ts delete mode 100644 frontend/src/lib/components/ui/table/table-body.svelte delete mode 100644 frontend/src/lib/components/ui/table/table-caption.svelte delete mode 100644 frontend/src/lib/components/ui/table/table-cell.svelte delete mode 100644 frontend/src/lib/components/ui/table/table-footer.svelte delete mode 100644 frontend/src/lib/components/ui/table/table-head.svelte delete mode 100644 frontend/src/lib/components/ui/table/table-header.svelte delete mode 100644 frontend/src/lib/components/ui/table/table-row.svelte delete mode 100644 frontend/src/lib/components/ui/table/table.svelte delete mode 100644 frontend/src/lib/components/ui/tabs/index.ts delete mode 100644 frontend/src/lib/components/ui/tabs/tabs-content.svelte delete mode 100644 frontend/src/lib/components/ui/tabs/tabs-list.svelte delete mode 100644 frontend/src/lib/components/ui/tabs/tabs-trigger.svelte delete mode 100644 frontend/src/lib/components/ui/tabs/tabs.svelte delete mode 100644 frontend/src/lib/components/ui/textarea/index.ts delete mode 100644 frontend/src/lib/components/ui/textarea/textarea.svelte delete mode 100644 frontend/src/lib/components/ui/tooltip/index.ts delete mode 100644 frontend/src/lib/components/ui/tooltip/tooltip-content.svelte delete mode 100644 frontend/src/lib/components/ui/tooltip/tooltip-trigger.svelte delete mode 100644 frontend/src/lib/hooks/is-mobile.svelte.ts delete mode 100644 frontend/src/lib/services/agents.ts delete mode 100644 frontend/src/lib/services/api-client.ts delete mode 100644 frontend/src/lib/services/auth.ts delete mode 100644 frontend/src/lib/services/budget.ts delete mode 100644 frontend/src/lib/services/expenses.ts delete mode 100644 frontend/src/lib/services/invoice.ts delete mode 100644 frontend/src/lib/services/marketplace.ts delete mode 100644 frontend/src/lib/services/organization.ts delete mode 100644 frontend/src/lib/services/resource-groups.ts delete mode 100644 frontend/src/lib/services/resources.ts delete mode 100644 frontend/src/lib/services/settings.ts delete mode 100644 frontend/src/lib/services/subscriptions.ts delete mode 100644 frontend/src/lib/services/system.ts delete mode 100644 frontend/src/lib/services/updates.ts delete mode 100644 frontend/src/lib/stores/auth.ts delete mode 100644 frontend/src/lib/stores/theme.ts delete mode 100644 frontend/src/lib/stores/updates.ts delete mode 100644 frontend/src/lib/types/agent.ts delete mode 100644 frontend/src/lib/types/index.ts delete mode 100644 frontend/src/lib/types/organization.ts delete mode 100644 frontend/src/lib/types/resource-group.ts delete mode 100644 frontend/src/lib/types/resource.ts delete mode 100644 frontend/src/lib/utils/logger.ts delete mode 100644 frontend/src/routes/+layout.server.ts delete mode 100644 frontend/src/routes/+layout.svelte delete mode 100644 frontend/src/routes/+page.server.ts delete mode 100644 frontend/src/routes/+page.svelte delete mode 100644 frontend/src/routes/admin/+layout.server.ts delete mode 100644 frontend/src/routes/admin/+layout.svelte delete mode 100644 frontend/src/routes/admin/+page.svelte delete mode 100644 frontend/src/routes/admin/organization/+page.server.ts delete mode 100644 frontend/src/routes/admin/organization/+page.svelte delete mode 100644 frontend/src/routes/admin/users/+page.server.ts delete mode 100644 frontend/src/routes/admin/users/+page.svelte delete mode 100644 frontend/src/routes/api/set-auth-cookie/+server.ts delete mode 100644 frontend/src/routes/change-password/+page.server.ts delete mode 100644 frontend/src/routes/change-password/+page.svelte delete mode 100644 frontend/src/routes/local-system/+page.svelte delete mode 100644 frontend/src/routes/marketplace/+page.svelte delete mode 100644 frontend/src/routes/otp/+page.svelte delete mode 100644 frontend/src/routes/physical-servers/+page.svelte delete mode 100644 frontend/src/routes/physical-servers/[id]/+page.svelte delete mode 100644 frontend/src/routes/resource-groups/+page.svelte delete mode 100644 frontend/src/routes/resource-groups/[id]/+page.svelte delete mode 100644 frontend/src/routes/resource-groups/[id]/edit/+page.svelte delete mode 100644 frontend/src/routes/resource-groups/create/+page.svelte delete mode 100644 frontend/src/routes/resources/+page.svelte delete mode 100644 frontend/src/routes/resources/[id]/+page.svelte delete mode 100644 frontend/src/routes/settings/+page.server.ts delete mode 100644 frontend/src/routes/settings/+page.svelte delete mode 100644 frontend/src/routes/signin/+page.server.ts delete mode 100644 frontend/src/routes/signin/+page.svelte delete mode 100644 frontend/static/logos/CSF_Logo.png delete mode 100644 frontend/svelte.config.js delete mode 100644 frontend/tsconfig.json delete mode 100644 frontend/vite.config.ts diff --git a/frontend/.gitignore b/app/.gitignore similarity index 90% rename from frontend/.gitignore rename to app/.gitignore index 3b462cb..f8d7fc2 100644 --- a/frontend/.gitignore +++ b/app/.gitignore @@ -21,3 +21,6 @@ Thumbs.db # Vite vite.config.js.timestamp-* vite.config.ts.timestamp-* + +.DS_Store +.Thumbs.db diff --git a/frontend/.npmrc b/app/.npmrc similarity index 100% rename from frontend/.npmrc rename to app/.npmrc diff --git a/app/.vscode/extensions.json b/app/.vscode/extensions.json new file mode 100644 index 0000000..28d1e67 --- /dev/null +++ b/app/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["svelte.svelte-vscode"] +} diff --git a/app/README.md b/app/README.md new file mode 100644 index 0000000..54732be --- /dev/null +++ b/app/README.md @@ -0,0 +1,42 @@ +# sv + +Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```sh +# create a new project +npx sv create my-app +``` + +To recreate this project with the same configuration: + +```sh +# recreate this project +npx sv@0.15.1 create --template minimal --types ts --add tailwindcss="plugins:none" --install npm app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```sh +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```sh +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. diff --git a/app/components.json b/app/components.json new file mode 100644 index 0000000..5e6e1e6 --- /dev/null +++ b/app/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://shadcn-svelte.com/schema.json", + "tailwind": { + "css": "src/routes/layout.css", + "baseColor": "neutral" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils", + "ui": "$lib/components/ui", + "hooks": "$lib/hooks", + "lib": "$lib" + }, + "typescript": true, + "registry": "https://shadcn-svelte.com/registry", + "style": "vega", + "iconLibrary": "lucide", + "menuColor": "default", + "menuAccent": "subtle" +} diff --git a/app/package-lock.json b/app/package-lock.json new file mode 100644 index 0000000..43d53af --- /dev/null +++ b/app/package-lock.json @@ -0,0 +1,2861 @@ +{ + "name": "app", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "app", + "version": "0.0.1", + "dependencies": { + "@iconify/svelte": "^5.2.1", + "geist": "^1.7.0" + }, + "devDependencies": { + "@fontsource-variable/inter": "^5.2.8", + "@internationalized/date": "^3.12.1", + "@lucide/svelte": "^1.14.0", + "@sveltejs/adapter-auto": "^7.0.1", + "@sveltejs/kit": "^2.57.0", + "@sveltejs/vite-plugin-svelte": "^7.0.0", + "@tailwindcss/vite": "^4.2.2", + "bits-ui": "^2.18.0", + "clsx": "^2.1.1", + "shadcn-svelte": "^1.2.7", + "svelte": "^5.55.2", + "svelte-check": "^4.4.6", + "tailwind-merge": "^3.5.0", + "tailwind-variants": "^3.2.2", + "tailwindcss": "^4.2.2", + "tw-animate-css": "^1.4.0", + "typescript": "^6.0.2", + "vite": "^8.0.7" + } + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz", + "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz", + "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.5", + "@floating-ui/utils": "^0.2.11" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz", + "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@fontsource-variable/inter": { + "version": "5.2.8", + "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.2.8.tgz", + "integrity": "sha512-kOfP2D+ykbcX/P3IFnokOhVRNoTozo5/JxhAIVYLpea/UBmCQ/YWPBfWIDuBImXX/15KH+eKh4xpEUyS2sQQGQ==", + "dev": true, + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@iconify/svelte": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@iconify/svelte/-/svelte-5.2.1.tgz", + "integrity": "sha512-zHmsIPmnIhGd5gc95bNN5FL+GifwMZv7M2rlZEpa7IXYGFJm/XGHdWf6PWQa6OBoC+R69WyiPO9NAj5wjfjbow==", + "license": "MIT", + "dependencies": { + "@iconify/types": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/cyberalien" + }, + "peerDependencies": { + "svelte": ">5.0.0" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "peer": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@internationalized/date": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.12.1.tgz", + "integrity": "sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lucide/svelte": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-1.14.0.tgz", + "integrity": "sha512-MVuP5VRCBQa2OaIpaRbuEV4k5OV2dy9MyxA6Tf4Sz/IN0v3zzUU72ObHc9r2Zn/wSMXDg6lLrHrczqI7w7gCzQ==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "svelte": "^5" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@next/env": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.4.tgz", + "integrity": "sha512-dKkkOzOSwFYe5RX6y26fZgkSpVAlIOJKQHIiydQcrWH6y/97+RceSOAdjZ14Qa3zLduVUy0TXcn+EiM6t4rPgw==", + "license": "MIT", + "peer": true + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.4.tgz", + "integrity": "sha512-OXTFFox5EKN1Ym08vfrz+OXxmCcEjT4SFMbNRsWZE99dMqt2Kcusl5MqPXcW232RYkMLQTy0hqgAMEsfEd/l2A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.4.tgz", + "integrity": "sha512-XhpVnUfmYWvD3YrXu55XdcAkQtOnvaI6wtQa8fuF5fGoKoxIUZ0kWPtcOfqJEWngFF/lOS9l3+O9CcownhiQxQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.4.tgz", + "integrity": "sha512-Mx/tjlNA3G8kg14QvuGAJ4xBwPk1tUHq56JxZ8CXnZwz1Etz714soCEzGQQzVMz4bEnGPowzkV6Xrp6wAkEWOQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.4.tgz", + "integrity": "sha512-iVMMp14514u7Nup2umQS03nT/bN9HurK8ufylC3FZNykrwjtx7V1A7+4kvhbDSCeonTVqV3Txnv0Lu+m2oDXNg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.4.tgz", + "integrity": "sha512-EZOvm1aQWgnI/N/xcWOlnS3RQBk0VtVav5Zo7n4p0A7UKyTDx047k8opDbXgBpHl4CulRqRfbw3QrX2w5UOXMQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.4.tgz", + "integrity": "sha512-h9FxsngCm9cTBf71AR4fGznDEDx1hS7+kSEiIRjq5kO1oXWm07DxVGZjCvk0SGx7TSjlUqhI8oOyz7NfwAdPoA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.4.tgz", + "integrity": "sha512-3NdJV5OXMSOeJYijX+bjaLge3mJBlh4ybydbT4GFoB/2hAojWHtMhl3CYlYoMrjPuodp0nzFVi4Tj2+WaMg+Ow==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.4.tgz", + "integrity": "sha512-kMVGgsqhO5YTYODD9IPGGhA6iprWidQckK3LmPeW08PIFENRmgfb4MjXHO+p//d+ts2rpjvK5gXWzXSMrPl9cw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.127.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.127.0.tgz", + "integrity": "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz", + "integrity": "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz", + "integrity": "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz", + "integrity": "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz", + "integrity": "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz", + "integrity": "sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz", + "integrity": "sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz", + "integrity": "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz", + "integrity": "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz", + "integrity": "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz", + "integrity": "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz", + "integrity": "sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sveltejs/acorn-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.9.tgz", + "integrity": "sha512-lVJX6qEgs/4DOcRTpo56tmKzVPtoWAaVbL4hfO7t7NVwl9AAXzQR6cihesW1BmNMPl+bK6dreu2sOKBP2Q9CIA==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8.9.0" + } + }, + "node_modules/@sveltejs/adapter-auto": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-7.0.1.tgz", + "integrity": "sha512-dvuPm1E7M9NI/+canIQ6KKQDU2AkEefEZ2Dp7cY6uKoPq9Z/PhOXABe526UdW2mN986gjVkuSLkOYIBnS/M2LQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.58.0", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.58.0.tgz", + "integrity": "sha512-kT9GCN8yJTkCK1W+Gi/bvGooWAM7y7WXP+yd+rf6QOIjyoK1ERPrMwSufXJUNu2pMWIqruhFvmz+LbOqsEmKmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/cookie": "^0.6.0", + "acorn": "^8.14.1", + "cookie": "^0.6.0", + "devalue": "^5.6.4", + "esm-env": "^1.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "set-cookie-parser": "^3.0.0", + "sirv": "^3.0.0" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": "^5.3.3 || ^6.0.0", + "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-7.0.0.tgz", + "integrity": "sha512-ILXmxC7HAsnkK2eslgPetrqqW1BKSL7LktsFgqzNj83MaivMGZzluWq32m25j2mDOjmSKX7GGWahePhuEs7P/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deepmerge": "^4.3.1", + "magic-string": "^0.30.21", + "obug": "^2.1.0", + "vitefu": "^1.1.2" + }, + "engines": { + "node": "^20.19 || ^22.12 || >=24" + }, + "peerDependencies": { + "svelte": "^5.46.4", + "vite": "^8.0.0-beta.7 || ^8.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.21.tgz", + "integrity": "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.4.tgz", + "integrity": "sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", + "jiti": "^2.6.1", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.2.4" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.4.tgz", + "integrity": "sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.2.4", + "@tailwindcss/oxide-darwin-arm64": "4.2.4", + "@tailwindcss/oxide-darwin-x64": "4.2.4", + "@tailwindcss/oxide-freebsd-x64": "4.2.4", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.4", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.4", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.4", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.4", + "@tailwindcss/oxide-linux-x64-musl": "4.2.4", + "@tailwindcss/oxide-wasm32-wasi": "4.2.4", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.4", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.4" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.4.tgz", + "integrity": "sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.4.tgz", + "integrity": "sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.4.tgz", + "integrity": "sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.4.tgz", + "integrity": "sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.4.tgz", + "integrity": "sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.4.tgz", + "integrity": "sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.4.tgz", + "integrity": "sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.4.tgz", + "integrity": "sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.4.tgz", + "integrity": "sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.4.tgz", + "integrity": "sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.4.tgz", + "integrity": "sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.4.tgz", + "integrity": "sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.4.tgz", + "integrity": "sha512-pCvohwOCspk3ZFn6eJzrrX3g4n2JY73H6MmYC87XfGPyTty4YsCjYTMArRZm/zOI8dIt3+EcrLHAFPe5A4bgtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.2.4", + "@tailwindcss/oxide": "4.2.4", + "tailwindcss": "4.2.4" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.24", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.24.tgz", + "integrity": "sha512-I2NkZOOrj2XuguvWCK6OVh9GavsNjZjK908Rq3mIBK25+GD8vPX5w2WdxVqnQ7xx3SrZJiCiZFu+/Oz50oSYSA==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/bits-ui": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.18.0.tgz", + "integrity": "sha512-GLOBZRVy3hxNHIQ2MpD/+5aK9KcBFZRhUJtZ1UDABXdlVR4K6zFpgt4T+Rwuhf2sQzlc6yK1q/DprHPjwT4Pjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.1", + "@floating-ui/dom": "^1.7.1", + "esm-env": "^1.1.2", + "runed": "^0.35.1", + "svelte-toolbelt": "^0.10.6", + "tabbable": "^6.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/huntabyte" + }, + "peerDependencies": { + "@internationalized/date": "^3.8.1", + "svelte": "^5.33.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001791", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz", + "integrity": "sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0", + "peer": true + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT", + "peer": true + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/devalue": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.7.1.tgz", + "integrity": "sha512-MUbZ586EgQqdRnC4yDrlod3BEdyvE4TapGYHMW2CiaW+KkkFmWEFqBUaLltEZCGi0iFXCEjRF0OjF0DV2QHjOA==", + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz", + "integrity": "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esm-env": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", + "license": "MIT" + }, + "node_modules/esrap": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.5.tgz", + "integrity": "sha512-/yLB1538mag+dn0wsePTe8C0rDIjUOaJpMs2McodSzmM2msWcZsBSdRtg6HOBt0A/r82BN+Md3pgwSc/uWt2Ig==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "peerDependencies": { + "@typescript-eslint/types": "^8.2.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/types": { + "optional": true + } + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/geist": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/geist/-/geist-1.7.0.tgz", + "integrity": "sha512-ZaoiZwkSf0DwwB1ncdLKp+ggAldqxl5L1+SXaNIBGkPAqcu+xjVJLxlf3/S8vLt9UHx1xu5fz3lbzKCj5iOVdQ==", + "license": "SIL OPEN FONT LICENSE", + "peerDependencies": { + "next": ">=13.2.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "license": "MIT" + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "16.2.4", + "resolved": "https://registry.npmjs.org/next/-/next-16.2.4.tgz", + "integrity": "sha512-kPvz56wF5frc+FxlHI5qnklCzbq53HTwORaWBGdT0vNoKh1Aya9XC8aPauH4NJxqtzbWsS5mAbctm4cr+EkQ2Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@next/env": "16.2.4", + "@swc/helpers": "0.5.15", + "baseline-browser-mapping": "^2.9.19", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.2.4", + "@next/swc-darwin-x64": "16.2.4", + "@next/swc-linux-arm64-gnu": "16.2.4", + "@next/swc-linux-arm64-musl": "16.2.4", + "@next/swc-linux-x64-gnu": "16.2.4", + "@next/swc-linux-x64-musl": "16.2.4", + "@next/swc-win32-arm64-msvc": "16.2.4", + "@next/swc-win32-x64-msvc": "16.2.4", + "sharp": "^0.34.5" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.12.tgz", + "integrity": "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", + "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.5", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", + "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.5" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rolldown": { + "version": "1.0.0-rc.17", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.17.tgz", + "integrity": "sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.127.0", + "@rolldown/pluginutils": "1.0.0-rc.17" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.17", + "@rolldown/binding-darwin-x64": "1.0.0-rc.17", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.17", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.17", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.17", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.17", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.17", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.17", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.17", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.17" + } + }, + "node_modules/runed": { + "version": "0.35.1", + "resolved": "https://registry.npmjs.org/runed/-/runed-0.35.1.tgz", + "integrity": "sha512-2F4Q/FZzbeJTFdIS/PuOoPRSm92sA2LhzTnv6FXhCoENb3huf5+fDuNOg1LNvGOouy3u/225qxmuJvcV3IZK5Q==", + "dev": true, + "funding": [ + "https://github.com/sponsors/huntabyte", + "https://github.com/sponsors/tglide" + ], + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "esm-env": "^1.0.0", + "lz-string": "^1.5.0" + }, + "peerDependencies": { + "@sveltejs/kit": "^2.21.0", + "svelte": "^5.7.0" + }, + "peerDependenciesMeta": { + "@sveltejs/kit": { + "optional": true + } + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT", + "peer": true + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-cookie-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.0.tgz", + "integrity": "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/shadcn-svelte": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/shadcn-svelte/-/shadcn-svelte-1.2.7.tgz", + "integrity": "sha512-mWuQk4H4gtV+J2wJQ7nEPKNnB/v86AALFryZU0SSM7ChHmJJMZ1kH+qIuxYKrXm9vOOOcSWHRsWzPDB71DnjYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^14.0.0", + "node-fetch-native": "^1.6.4", + "postcss": "^8.5.5", + "tailwind-merge": "^3.0.0" + }, + "bin": { + "shadcn-svelte": "dist/index.mjs" + }, + "peerDependencies": { + "svelte": "^5.0.0" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/sirv": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "peer": true, + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/svelte": { + "version": "5.55.5", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.55.5.tgz", + "integrity": "sha512-2uCs/LZ9us+AktdzYJM8OcxQ8qnPS1kpaO7syGT/MgO+6Qr1Ybl+TqPq+97u7PHqmmMlye5ZkoyXONy5mjjAbw==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.5", + "@types/estree": "^1.0.5", + "@types/trusted-types": "^2.0.7", + "acorn": "^8.12.1", + "aria-query": "5.3.1", + "axobject-query": "^4.1.0", + "clsx": "^2.1.1", + "devalue": "^5.6.4", + "esm-env": "^1.2.1", + "esrap": "^2.2.4", + "is-reference": "^3.0.3", + "locate-character": "^3.0.0", + "magic-string": "^0.30.11", + "zimmerframe": "^1.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/svelte-check": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.4.6.tgz", + "integrity": "sha512-kP1zG81EWaFe9ZyTv4ZXv44Csi6Pkdpb7S3oj6m+K2ec/IcDg/a8LsFsnVLqm2nxtkSwsd5xPj/qFkTBgXHXjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "chokidar": "^4.0.1", + "fdir": "^6.2.0", + "picocolors": "^1.0.0", + "sade": "^1.7.4" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": ">=5.0.0" + } + }, + "node_modules/svelte-toolbelt": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.10.6.tgz", + "integrity": "sha512-YWuX+RE+CnWYx09yseAe4ZVMM7e7GRFZM6OYWpBKOb++s+SQ8RBIMMe+Bs/CznBMc0QPLjr+vDBxTAkozXsFXQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/huntabyte" + ], + "dependencies": { + "clsx": "^2.1.1", + "runed": "^0.35.1", + "style-to-object": "^1.0.8" + }, + "engines": { + "node": ">=18", + "pnpm": ">=8.7.0" + }, + "peerDependencies": { + "svelte": "^5.30.2" + } + }, + "node_modules/tabbable": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", + "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tailwind-merge": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.5.0.tgz", + "integrity": "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwind-variants": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-3.2.2.tgz", + "integrity": "sha512-Mi4kHeMTLvKlM98XPnK+7HoBPmf4gygdFmqQPaDivc3DpYS6aIY6KiG/PgThrGvii5YZJqRsPz0aPyhoFzmZgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.x", + "pnpm": ">=7.x" + }, + "peerDependencies": { + "tailwind-merge": ">=3.0.0", + "tailwindcss": "*" + }, + "peerDependenciesMeta": { + "tailwind-merge": { + "optional": true + } + } + }, + "node_modules/tailwindcss": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.4.tgz", + "integrity": "sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", + "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "8.0.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.10.tgz", + "integrity": "sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.10", + "rolldown": "1.0.0-rc.17", + "tinyglobby": "^0.2.16" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz", + "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==", + "dev": true, + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/zimmerframe": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "license": "MIT" + } + } +} diff --git a/app/package.json b/app/package.json new file mode 100644 index 0000000..3066d8f --- /dev/null +++ b/app/package.json @@ -0,0 +1,38 @@ +{ + "name": "app", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "prepare": "svelte-kit sync || echo ''", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + }, + "devDependencies": { + "@fontsource-variable/inter": "^5.2.8", + "@internationalized/date": "^3.12.1", + "@lucide/svelte": "^1.14.0", + "@sveltejs/adapter-auto": "^7.0.1", + "@sveltejs/kit": "^2.57.0", + "@sveltejs/vite-plugin-svelte": "^7.0.0", + "@tailwindcss/vite": "^4.2.2", + "bits-ui": "^2.18.0", + "clsx": "^2.1.1", + "shadcn-svelte": "^1.2.7", + "svelte": "^5.55.2", + "svelte-check": "^4.4.6", + "tailwind-merge": "^3.5.0", + "tailwind-variants": "^3.2.2", + "tailwindcss": "^4.2.2", + "tw-animate-css": "^1.4.0", + "typescript": "^6.0.2", + "vite": "^8.0.7" + }, + "dependencies": { + "@iconify/svelte": "^5.2.1", + "geist": "^1.7.0" + } +} diff --git a/app/src/app.d.ts b/app/src/app.d.ts new file mode 100644 index 0000000..da08e6d --- /dev/null +++ b/app/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://svelte.dev/docs/kit/types#app.d.ts +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/app/src/app.html b/app/src/app.html new file mode 100644 index 0000000..6a2bb58 --- /dev/null +++ b/app/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/frontend/src/lib/assets/favicon.svg b/app/src/lib/assets/favicon.svg similarity index 100% rename from frontend/src/lib/assets/favicon.svg rename to app/src/lib/assets/favicon.svg diff --git a/app/src/lib/auth/right-panel.svelte b/app/src/lib/auth/right-panel.svelte new file mode 100644 index 0000000..b1b6a02 --- /dev/null +++ b/app/src/lib/auth/right-panel.svelte @@ -0,0 +1,116 @@ + + + diff --git a/app/src/lib/components/sidebar/app-sidebar.svelte b/app/src/lib/components/sidebar/app-sidebar.svelte new file mode 100644 index 0000000..7cda9db --- /dev/null +++ b/app/src/lib/components/sidebar/app-sidebar.svelte @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/lib/components/sidebar/icon-bucket.svelte b/app/src/lib/components/sidebar/icon-bucket.svelte new file mode 100644 index 0000000..7fc159b --- /dev/null +++ b/app/src/lib/components/sidebar/icon-bucket.svelte @@ -0,0 +1,8 @@ + + + diff --git a/app/src/lib/components/sidebar/nav-main.svelte b/app/src/lib/components/sidebar/nav-main.svelte new file mode 100644 index 0000000..31c3d99 --- /dev/null +++ b/app/src/lib/components/sidebar/nav-main.svelte @@ -0,0 +1,41 @@ + + + + {#if label} + {label} + {/if} + + {#each items as item (item.title)} + + + {#snippet child({ props })} + + {#if item.icon} + + {/if} + {item.title} + + {/snippet} + + + {/each} + + diff --git a/app/src/lib/components/sidebar/nav-projects.svelte b/app/src/lib/components/sidebar/nav-projects.svelte new file mode 100644 index 0000000..8fc99be --- /dev/null +++ b/app/src/lib/components/sidebar/nav-projects.svelte @@ -0,0 +1,33 @@ + + + + Resources + + {#each projects as item (item.name)} + + + {#snippet child({ props })} + + + {item.name} + + {/snippet} + + + {/each} + + diff --git a/app/src/lib/components/sidebar/nav-user.svelte b/app/src/lib/components/sidebar/nav-user.svelte new file mode 100644 index 0000000..3f8cef0 --- /dev/null +++ b/app/src/lib/components/sidebar/nav-user.svelte @@ -0,0 +1,87 @@ + + + + + + + {#snippet child({ props })} + + + + CN + +
+ {user.name} + {user.email} +
+ +
+ {/snippet} +
+ + +
+ + + CN + +
+ {user.name} + {user.email} +
+
+
+ + + + + Upgrade to Pro + + + + + + + Account + + + + Billing + + + + Notifications + + + + + + Log out + +
+
+
+
diff --git a/app/src/lib/components/sidebar/team-switcher.svelte b/app/src/lib/components/sidebar/team-switcher.svelte new file mode 100644 index 0000000..e9e7ecf --- /dev/null +++ b/app/src/lib/components/sidebar/team-switcher.svelte @@ -0,0 +1,86 @@ + + + + + + + {#snippet child({ props })} + +
+ +
+
+ + {activeTeam.name} + + {activeTeam.plan} +
+ +
+ {/snippet} +
+ + Teams + {#each teams as team, index (team.name)} + (activeTeam = team)} + class="gap-2 p-2" + > +
+ +
+ {team.name} + ⌘{index + 1} +
+ {/each} + + +
+ +
+
+ Add team +
+
+
+
+
+
diff --git a/app/src/lib/components/ui/avatar/avatar-badge.svelte b/app/src/lib/components/ui/avatar/avatar-badge.svelte new file mode 100644 index 0000000..ca9d9ed --- /dev/null +++ b/app/src/lib/components/ui/avatar/avatar-badge.svelte @@ -0,0 +1,26 @@ + + +svg]:hidden", + "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2", + "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2", + className + )} + {...restProps} +> + {@render children?.()} + diff --git a/app/src/lib/components/ui/avatar/avatar-fallback.svelte b/app/src/lib/components/ui/avatar/avatar-fallback.svelte new file mode 100644 index 0000000..63c8b02 --- /dev/null +++ b/app/src/lib/components/ui/avatar/avatar-fallback.svelte @@ -0,0 +1,20 @@ + + + diff --git a/app/src/lib/components/ui/avatar/avatar-group-count.svelte b/app/src/lib/components/ui/avatar/avatar-group-count.svelte new file mode 100644 index 0000000..c89684a --- /dev/null +++ b/app/src/lib/components/ui/avatar/avatar-group-count.svelte @@ -0,0 +1,23 @@ + + +
svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3 ring-background relative flex shrink-0 items-center justify-center ring-2", + className + )} + {...restProps} +> + {@render children?.()} +
diff --git a/app/src/lib/components/ui/avatar/avatar-group.svelte b/app/src/lib/components/ui/avatar/avatar-group.svelte new file mode 100644 index 0000000..78714fc --- /dev/null +++ b/app/src/lib/components/ui/avatar/avatar-group.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/app/src/lib/components/ui/avatar/avatar-image.svelte b/app/src/lib/components/ui/avatar/avatar-image.svelte new file mode 100644 index 0000000..f41cf8f --- /dev/null +++ b/app/src/lib/components/ui/avatar/avatar-image.svelte @@ -0,0 +1,17 @@ + + + diff --git a/app/src/lib/components/ui/avatar/avatar.svelte b/app/src/lib/components/ui/avatar/avatar.svelte new file mode 100644 index 0000000..ea6fde5 --- /dev/null +++ b/app/src/lib/components/ui/avatar/avatar.svelte @@ -0,0 +1,26 @@ + + + diff --git a/app/src/lib/components/ui/avatar/index.ts b/app/src/lib/components/ui/avatar/index.ts new file mode 100644 index 0000000..38ccef8 --- /dev/null +++ b/app/src/lib/components/ui/avatar/index.ts @@ -0,0 +1,22 @@ +import Root from "./avatar.svelte"; +import Image from "./avatar-image.svelte"; +import Fallback from "./avatar-fallback.svelte"; +import Badge from "./avatar-badge.svelte"; +import Group from "./avatar-group.svelte"; +import GroupCount from "./avatar-group-count.svelte"; + +export { + Root, + Image, + Fallback, + Badge, + Group, + GroupCount, + // + Root as Avatar, + Image as AvatarImage, + Fallback as AvatarFallback, + Badge as AvatarBadge, + Group as AvatarGroup, + GroupCount as AvatarGroupCount, +}; diff --git a/app/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte b/app/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte new file mode 100644 index 0000000..9e1e22c --- /dev/null +++ b/app/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte @@ -0,0 +1,23 @@ + + + diff --git a/app/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte b/app/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte new file mode 100644 index 0000000..684d9fd --- /dev/null +++ b/app/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte @@ -0,0 +1,20 @@ + + +
  • + {@render children?.()} +
  • diff --git a/app/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte b/app/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte new file mode 100644 index 0000000..e6bc17d --- /dev/null +++ b/app/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte @@ -0,0 +1,31 @@ + + +{#if child} + {@render child({ props: attrs })} +{:else} + + {@render children?.()} + +{/if} diff --git a/app/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte b/app/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte new file mode 100644 index 0000000..5c3257b --- /dev/null +++ b/app/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte @@ -0,0 +1,20 @@ + + +
      + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte b/app/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte new file mode 100644 index 0000000..5fb6979 --- /dev/null +++ b/app/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/app/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte b/app/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte new file mode 100644 index 0000000..0f62fba --- /dev/null +++ b/app/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte @@ -0,0 +1,27 @@ + + + diff --git a/app/src/lib/components/ui/breadcrumb/breadcrumb.svelte b/app/src/lib/components/ui/breadcrumb/breadcrumb.svelte new file mode 100644 index 0000000..29ea3f5 --- /dev/null +++ b/app/src/lib/components/ui/breadcrumb/breadcrumb.svelte @@ -0,0 +1,22 @@ + + + diff --git a/app/src/lib/components/ui/breadcrumb/index.ts b/app/src/lib/components/ui/breadcrumb/index.ts new file mode 100644 index 0000000..dc914ec --- /dev/null +++ b/app/src/lib/components/ui/breadcrumb/index.ts @@ -0,0 +1,25 @@ +import Root from "./breadcrumb.svelte"; +import Ellipsis from "./breadcrumb-ellipsis.svelte"; +import Item from "./breadcrumb-item.svelte"; +import Separator from "./breadcrumb-separator.svelte"; +import Link from "./breadcrumb-link.svelte"; +import List from "./breadcrumb-list.svelte"; +import Page from "./breadcrumb-page.svelte"; + +export { + Root, + Ellipsis, + Item, + Separator, + Link, + List, + Page, + // + Root as Breadcrumb, + Ellipsis as BreadcrumbEllipsis, + Item as BreadcrumbItem, + Separator as BreadcrumbSeparator, + Link as BreadcrumbLink, + List as BreadcrumbList, + Page as BreadcrumbPage, +}; diff --git a/app/src/lib/components/ui/button/button.svelte b/app/src/lib/components/ui/button/button.svelte new file mode 100644 index 0000000..c38862e --- /dev/null +++ b/app/src/lib/components/ui/button/button.svelte @@ -0,0 +1,82 @@ + + + + +{#if href} + + {@render children?.()} + +{:else} + +{/if} diff --git a/app/src/lib/components/ui/button/index.ts b/app/src/lib/components/ui/button/index.ts new file mode 100644 index 0000000..fb585d7 --- /dev/null +++ b/app/src/lib/components/ui/button/index.ts @@ -0,0 +1,17 @@ +import Root, { + type ButtonProps, + type ButtonSize, + type ButtonVariant, + buttonVariants, +} from "./button.svelte"; + +export { + Root, + type ButtonProps as Props, + // + Root as Button, + buttonVariants, + type ButtonProps, + type ButtonSize, + type ButtonVariant, +}; diff --git a/app/src/lib/components/ui/card/card-action.svelte b/app/src/lib/components/ui/card/card-action.svelte new file mode 100644 index 0000000..7c48844 --- /dev/null +++ b/app/src/lib/components/ui/card/card-action.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/card/card-content.svelte b/app/src/lib/components/ui/card/card-content.svelte new file mode 100644 index 0000000..082a786 --- /dev/null +++ b/app/src/lib/components/ui/card/card-content.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/card/card-description.svelte b/app/src/lib/components/ui/card/card-description.svelte new file mode 100644 index 0000000..9b20ac7 --- /dev/null +++ b/app/src/lib/components/ui/card/card-description.svelte @@ -0,0 +1,20 @@ + + +

    + {@render children?.()} +

    diff --git a/app/src/lib/components/ui/card/card-footer.svelte b/app/src/lib/components/ui/card/card-footer.svelte new file mode 100644 index 0000000..591c3f7 --- /dev/null +++ b/app/src/lib/components/ui/card/card-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/card/card-header.svelte b/app/src/lib/components/ui/card/card-header.svelte new file mode 100644 index 0000000..21e9a17 --- /dev/null +++ b/app/src/lib/components/ui/card/card-header.svelte @@ -0,0 +1,23 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/card/card-title.svelte b/app/src/lib/components/ui/card/card-title.svelte new file mode 100644 index 0000000..7d20243 --- /dev/null +++ b/app/src/lib/components/ui/card/card-title.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/card/card.svelte b/app/src/lib/components/ui/card/card.svelte new file mode 100644 index 0000000..329a6c7 --- /dev/null +++ b/app/src/lib/components/ui/card/card.svelte @@ -0,0 +1,22 @@ + + +
    img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col", className)} + {...restProps} +> + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/card/index.ts b/app/src/lib/components/ui/card/index.ts new file mode 100644 index 0000000..4d3fce4 --- /dev/null +++ b/app/src/lib/components/ui/card/index.ts @@ -0,0 +1,25 @@ +import Root from "./card.svelte"; +import Content from "./card-content.svelte"; +import Description from "./card-description.svelte"; +import Footer from "./card-footer.svelte"; +import Header from "./card-header.svelte"; +import Title from "./card-title.svelte"; +import Action from "./card-action.svelte"; + +export { + Root, + Content, + Description, + Footer, + Header, + Title, + Action, + // + Root as Card, + Content as CardContent, + Description as CardDescription, + Footer as CardFooter, + Header as CardHeader, + Title as CardTitle, + Action as CardAction, +}; diff --git a/app/src/lib/components/ui/checkbox/checkbox.svelte b/app/src/lib/components/ui/checkbox/checkbox.svelte new file mode 100644 index 0000000..3c84a08 --- /dev/null +++ b/app/src/lib/components/ui/checkbox/checkbox.svelte @@ -0,0 +1,39 @@ + + + + {#snippet children({ checked, indeterminate })} +
    + {#if checked} + + {:else if indeterminate} + + {/if} +
    + {/snippet} +
    diff --git a/app/src/lib/components/ui/checkbox/index.ts b/app/src/lib/components/ui/checkbox/index.ts new file mode 100644 index 0000000..6d92d94 --- /dev/null +++ b/app/src/lib/components/ui/checkbox/index.ts @@ -0,0 +1,6 @@ +import Root from "./checkbox.svelte"; +export { + Root, + // + Root as Checkbox, +}; diff --git a/app/src/lib/components/ui/collapsible/collapsible-content.svelte b/app/src/lib/components/ui/collapsible/collapsible-content.svelte new file mode 100644 index 0000000..bdabb55 --- /dev/null +++ b/app/src/lib/components/ui/collapsible/collapsible-content.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/collapsible/collapsible-trigger.svelte b/app/src/lib/components/ui/collapsible/collapsible-trigger.svelte new file mode 100644 index 0000000..ece7ad6 --- /dev/null +++ b/app/src/lib/components/ui/collapsible/collapsible-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/collapsible/collapsible.svelte b/app/src/lib/components/ui/collapsible/collapsible.svelte new file mode 100644 index 0000000..39cdd4e --- /dev/null +++ b/app/src/lib/components/ui/collapsible/collapsible.svelte @@ -0,0 +1,11 @@ + + + diff --git a/app/src/lib/components/ui/collapsible/index.ts b/app/src/lib/components/ui/collapsible/index.ts new file mode 100644 index 0000000..169b479 --- /dev/null +++ b/app/src/lib/components/ui/collapsible/index.ts @@ -0,0 +1,13 @@ +import Root from "./collapsible.svelte"; +import Trigger from "./collapsible-trigger.svelte"; +import Content from "./collapsible-content.svelte"; + +export { + Root, + Content, + Trigger, + // + Root as Collapsible, + Content as CollapsibleContent, + Trigger as CollapsibleTrigger, +}; diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte new file mode 100644 index 0000000..e0e1971 --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..c04d294 --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,44 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else if checked} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..369bab1 --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 0000000..433540f --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,22 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte new file mode 100644 index 0000000..aca1f7b --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..0fec5f5 --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..ad6947a --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte new file mode 100644 index 0000000..274cfef --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..189aef4 --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..d3888cc --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,34 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..90f1b6f --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..ed7cc85 --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..254de66 --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,17 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..a390e2d --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte new file mode 100644 index 0000000..f044581 --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte new file mode 100644 index 0000000..cb05344 --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte b/app/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte new file mode 100644 index 0000000..cb4bc62 --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/dropdown-menu/index.ts b/app/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..7850c6a --- /dev/null +++ b/app/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,54 @@ +import Root from "./dropdown-menu.svelte"; +import Sub from "./dropdown-menu-sub.svelte"; +import CheckboxGroup from "./dropdown-menu-checkbox-group.svelte"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import Group from "./dropdown-menu-group.svelte"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import RadioGroup from "./dropdown-menu-radio-group.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import Trigger from "./dropdown-menu-trigger.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; +import GroupHeading from "./dropdown-menu-group-heading.svelte"; +import Portal from "./dropdown-menu-portal.svelte"; + +export { + CheckboxGroup, + CheckboxItem, + Content, + Portal, + Root as DropdownMenu, + CheckboxGroup as DropdownMenuCheckboxGroup, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + Portal as DropdownMenuPortal, + Group as DropdownMenuGroup, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + RadioGroup as DropdownMenuRadioGroup, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + Shortcut as DropdownMenuShortcut, + Sub as DropdownMenuSub, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + Trigger as DropdownMenuTrigger, + GroupHeading as DropdownMenuGroupHeading, + Group, + GroupHeading, + Item, + Label, + RadioGroup, + RadioItem, + Root, + Separator, + Shortcut, + Sub, + SubContent, + SubTrigger, + Trigger, +}; diff --git a/app/src/lib/components/ui/input/index.ts b/app/src/lib/components/ui/input/index.ts new file mode 100644 index 0000000..f47b6d3 --- /dev/null +++ b/app/src/lib/components/ui/input/index.ts @@ -0,0 +1,7 @@ +import Root from "./input.svelte"; + +export { + Root, + // + Root as Input, +}; diff --git a/app/src/lib/components/ui/input/input.svelte b/app/src/lib/components/ui/input/input.svelte new file mode 100644 index 0000000..9978bcb --- /dev/null +++ b/app/src/lib/components/ui/input/input.svelte @@ -0,0 +1,48 @@ + + +{#if type === "file"} + +{:else} + +{/if} diff --git a/app/src/lib/components/ui/label/index.ts b/app/src/lib/components/ui/label/index.ts new file mode 100644 index 0000000..8bfca0b --- /dev/null +++ b/app/src/lib/components/ui/label/index.ts @@ -0,0 +1,7 @@ +import Root from "./label.svelte"; + +export { + Root, + // + Root as Label, +}; diff --git a/app/src/lib/components/ui/label/label.svelte b/app/src/lib/components/ui/label/label.svelte new file mode 100644 index 0000000..d5e3086 --- /dev/null +++ b/app/src/lib/components/ui/label/label.svelte @@ -0,0 +1,20 @@ + + + diff --git a/app/src/lib/components/ui/separator/index.ts b/app/src/lib/components/ui/separator/index.ts new file mode 100644 index 0000000..82442d2 --- /dev/null +++ b/app/src/lib/components/ui/separator/index.ts @@ -0,0 +1,7 @@ +import Root from "./separator.svelte"; + +export { + Root, + // + Root as Separator, +}; diff --git a/app/src/lib/components/ui/separator/separator.svelte b/app/src/lib/components/ui/separator/separator.svelte new file mode 100644 index 0000000..5fd8a42 --- /dev/null +++ b/app/src/lib/components/ui/separator/separator.svelte @@ -0,0 +1,23 @@ + + + diff --git a/app/src/lib/components/ui/sheet/index.ts b/app/src/lib/components/ui/sheet/index.ts new file mode 100644 index 0000000..28d7da1 --- /dev/null +++ b/app/src/lib/components/ui/sheet/index.ts @@ -0,0 +1,34 @@ +import Root from "./sheet.svelte"; +import Portal from "./sheet-portal.svelte"; +import Trigger from "./sheet-trigger.svelte"; +import Close from "./sheet-close.svelte"; +import Overlay from "./sheet-overlay.svelte"; +import Content from "./sheet-content.svelte"; +import Header from "./sheet-header.svelte"; +import Footer from "./sheet-footer.svelte"; +import Title from "./sheet-title.svelte"; +import Description from "./sheet-description.svelte"; + +export { + Root, + Close, + Trigger, + Portal, + Overlay, + Content, + Header, + Footer, + Title, + Description, + // + Root as Sheet, + Close as SheetClose, + Trigger as SheetTrigger, + Portal as SheetPortal, + Overlay as SheetOverlay, + Content as SheetContent, + Header as SheetHeader, + Footer as SheetFooter, + Title as SheetTitle, + Description as SheetDescription, +}; diff --git a/app/src/lib/components/ui/sheet/sheet-close.svelte b/app/src/lib/components/ui/sheet/sheet-close.svelte new file mode 100644 index 0000000..ae382c1 --- /dev/null +++ b/app/src/lib/components/ui/sheet/sheet-close.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/sheet/sheet-content.svelte b/app/src/lib/components/ui/sheet/sheet-content.svelte new file mode 100644 index 0000000..afdea92 --- /dev/null +++ b/app/src/lib/components/ui/sheet/sheet-content.svelte @@ -0,0 +1,55 @@ + + + + + + + + {@render children?.()} + {#if showCloseButton} + + {#snippet child({ props })} + + {/snippet} + + {/if} + + diff --git a/app/src/lib/components/ui/sheet/sheet-description.svelte b/app/src/lib/components/ui/sheet/sheet-description.svelte new file mode 100644 index 0000000..333b17a --- /dev/null +++ b/app/src/lib/components/ui/sheet/sheet-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/app/src/lib/components/ui/sheet/sheet-footer.svelte b/app/src/lib/components/ui/sheet/sheet-footer.svelte new file mode 100644 index 0000000..ad9e07b --- /dev/null +++ b/app/src/lib/components/ui/sheet/sheet-footer.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sheet/sheet-header.svelte b/app/src/lib/components/ui/sheet/sheet-header.svelte new file mode 100644 index 0000000..6e51470 --- /dev/null +++ b/app/src/lib/components/ui/sheet/sheet-header.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sheet/sheet-overlay.svelte b/app/src/lib/components/ui/sheet/sheet-overlay.svelte new file mode 100644 index 0000000..8d33847 --- /dev/null +++ b/app/src/lib/components/ui/sheet/sheet-overlay.svelte @@ -0,0 +1,17 @@ + + + diff --git a/app/src/lib/components/ui/sheet/sheet-portal.svelte b/app/src/lib/components/ui/sheet/sheet-portal.svelte new file mode 100644 index 0000000..f3085a3 --- /dev/null +++ b/app/src/lib/components/ui/sheet/sheet-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/sheet/sheet-title.svelte b/app/src/lib/components/ui/sheet/sheet-title.svelte new file mode 100644 index 0000000..13d9443 --- /dev/null +++ b/app/src/lib/components/ui/sheet/sheet-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/app/src/lib/components/ui/sheet/sheet-trigger.svelte b/app/src/lib/components/ui/sheet/sheet-trigger.svelte new file mode 100644 index 0000000..e266975 --- /dev/null +++ b/app/src/lib/components/ui/sheet/sheet-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/sheet/sheet.svelte b/app/src/lib/components/ui/sheet/sheet.svelte new file mode 100644 index 0000000..5bf9783 --- /dev/null +++ b/app/src/lib/components/ui/sheet/sheet.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/sidebar/constants.ts b/app/src/lib/components/ui/sidebar/constants.ts new file mode 100644 index 0000000..4de4435 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/constants.ts @@ -0,0 +1,6 @@ +export const SIDEBAR_COOKIE_NAME = "sidebar:state"; +export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; +export const SIDEBAR_WIDTH = "16rem"; +export const SIDEBAR_WIDTH_MOBILE = "18rem"; +export const SIDEBAR_WIDTH_ICON = "3rem"; +export const SIDEBAR_KEYBOARD_SHORTCUT = "b"; diff --git a/app/src/lib/components/ui/sidebar/context.svelte.ts b/app/src/lib/components/ui/sidebar/context.svelte.ts new file mode 100644 index 0000000..15248ad --- /dev/null +++ b/app/src/lib/components/ui/sidebar/context.svelte.ts @@ -0,0 +1,81 @@ +import { IsMobile } from "$lib/hooks/is-mobile.svelte.js"; +import { getContext, setContext } from "svelte"; +import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js"; + +type Getter = () => T; + +export type SidebarStateProps = { + /** + * A getter function that returns the current open state of the sidebar. + * We use a getter function here to support `bind:open` on the `Sidebar.Provider` + * component. + */ + open: Getter; + + /** + * A function that sets the open state of the sidebar. To support `bind:open`, we need + * a source of truth for changing the open state to ensure it will be synced throughout + * the sub-components and any `bind:` references. + */ + setOpen: (open: boolean) => void; +}; + +class SidebarState { + readonly props: SidebarStateProps; + open = $derived.by(() => this.props.open()); + openMobile = $state(false); + setOpen: SidebarStateProps["setOpen"]; + #isMobile: IsMobile; + state = $derived.by(() => (this.open ? "expanded" : "collapsed")); + + constructor(props: SidebarStateProps) { + this.setOpen = props.setOpen; + this.#isMobile = new IsMobile(); + this.props = props; + } + + // Convenience getter for checking if the sidebar is mobile + // without this, we would need to use `sidebar.isMobile.current` everywhere + get isMobile() { + return this.#isMobile.current; + } + + // Event handler to apply to the `` + handleShortcutKeydown = (e: KeyboardEvent) => { + if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) { + e.preventDefault(); + this.toggle(); + } + }; + + setOpenMobile = (value: boolean) => { + this.openMobile = value; + }; + + toggle = () => { + return this.#isMobile.current + ? (this.openMobile = !this.openMobile) + : this.setOpen(!this.open); + }; +} + +const SYMBOL_KEY = "scn-sidebar"; + +/** + * Instantiates a new `SidebarState` instance and sets it in the context. + * + * @param props The constructor props for the `SidebarState` class. + * @returns The `SidebarState` instance. + */ +export function setSidebar(props: SidebarStateProps): SidebarState { + return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props)); +} + +/** + * Retrieves the `SidebarState` instance from the context. This is a class instance, + * so you cannot destructure it. + * @returns The `SidebarState` instance. + */ +export function useSidebar(): SidebarState { + return getContext(Symbol.for(SYMBOL_KEY)); +} diff --git a/app/src/lib/components/ui/sidebar/index.ts b/app/src/lib/components/ui/sidebar/index.ts new file mode 100644 index 0000000..318a341 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/index.ts @@ -0,0 +1,75 @@ +import { useSidebar } from "./context.svelte.js"; +import Content from "./sidebar-content.svelte"; +import Footer from "./sidebar-footer.svelte"; +import GroupAction from "./sidebar-group-action.svelte"; +import GroupContent from "./sidebar-group-content.svelte"; +import GroupLabel from "./sidebar-group-label.svelte"; +import Group from "./sidebar-group.svelte"; +import Header from "./sidebar-header.svelte"; +import Input from "./sidebar-input.svelte"; +import Inset from "./sidebar-inset.svelte"; +import MenuAction from "./sidebar-menu-action.svelte"; +import MenuBadge from "./sidebar-menu-badge.svelte"; +import MenuButton from "./sidebar-menu-button.svelte"; +import MenuItem from "./sidebar-menu-item.svelte"; +import MenuSkeleton from "./sidebar-menu-skeleton.svelte"; +import MenuSubButton from "./sidebar-menu-sub-button.svelte"; +import MenuSubItem from "./sidebar-menu-sub-item.svelte"; +import MenuSub from "./sidebar-menu-sub.svelte"; +import Menu from "./sidebar-menu.svelte"; +import Provider from "./sidebar-provider.svelte"; +import Rail from "./sidebar-rail.svelte"; +import Separator from "./sidebar-separator.svelte"; +import Trigger from "./sidebar-trigger.svelte"; +import Root from "./sidebar.svelte"; + +export { + Content, + Footer, + Group, + GroupAction, + GroupContent, + GroupLabel, + Header, + Input, + Inset, + Menu, + MenuAction, + MenuBadge, + MenuButton, + MenuItem, + MenuSkeleton, + MenuSub, + MenuSubButton, + MenuSubItem, + Provider, + Rail, + Root, + Separator, + // + Root as Sidebar, + Content as SidebarContent, + Footer as SidebarFooter, + Group as SidebarGroup, + GroupAction as SidebarGroupAction, + GroupContent as SidebarGroupContent, + GroupLabel as SidebarGroupLabel, + Header as SidebarHeader, + Input as SidebarInput, + Inset as SidebarInset, + Menu as SidebarMenu, + MenuAction as SidebarMenuAction, + MenuBadge as SidebarMenuBadge, + MenuButton as SidebarMenuButton, + MenuItem as SidebarMenuItem, + MenuSkeleton as SidebarMenuSkeleton, + MenuSub as SidebarMenuSub, + MenuSubButton as SidebarMenuSubButton, + MenuSubItem as SidebarMenuSubItem, + Provider as SidebarProvider, + Rail as SidebarRail, + Separator as SidebarSeparator, + Trigger as SidebarTrigger, + Trigger, + useSidebar, +}; diff --git a/app/src/lib/components/ui/sidebar/sidebar-content.svelte b/app/src/lib/components/ui/sidebar/sidebar-content.svelte new file mode 100644 index 0000000..c4111aa --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-content.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-footer.svelte b/app/src/lib/components/ui/sidebar/sidebar-footer.svelte new file mode 100644 index 0000000..496c6c0 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-footer.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-group-action.svelte b/app/src/lib/components/ui/sidebar/sidebar-group-action.svelte new file mode 100644 index 0000000..1d07b97 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-group-action.svelte @@ -0,0 +1,33 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + +{/if} diff --git a/app/src/lib/components/ui/sidebar/sidebar-group-content.svelte b/app/src/lib/components/ui/sidebar/sidebar-group-content.svelte new file mode 100644 index 0000000..7835b0e --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-group-content.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-group-label.svelte b/app/src/lib/components/ui/sidebar/sidebar-group-label.svelte new file mode 100644 index 0000000..518216c --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-group-label.svelte @@ -0,0 +1,33 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} +
    + {@render children?.()} +
    +{/if} diff --git a/app/src/lib/components/ui/sidebar/sidebar-group.svelte b/app/src/lib/components/ui/sidebar/sidebar-group.svelte new file mode 100644 index 0000000..b5880d7 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-group.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-header.svelte b/app/src/lib/components/ui/sidebar/sidebar-header.svelte new file mode 100644 index 0000000..b54754a --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-header.svelte @@ -0,0 +1,21 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-input.svelte b/app/src/lib/components/ui/sidebar/sidebar-input.svelte new file mode 100644 index 0000000..19b3666 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-input.svelte @@ -0,0 +1,21 @@ + + + diff --git a/app/src/lib/components/ui/sidebar/sidebar-inset.svelte b/app/src/lib/components/ui/sidebar/sidebar-inset.svelte new file mode 100644 index 0000000..19a787c --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-inset.svelte @@ -0,0 +1,20 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-menu-action.svelte b/app/src/lib/components/ui/sidebar/sidebar-menu-action.svelte new file mode 100644 index 0000000..26c81ed --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-menu-action.svelte @@ -0,0 +1,37 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + +{/if} diff --git a/app/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte b/app/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte new file mode 100644 index 0000000..6cecdb4 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte @@ -0,0 +1,24 @@ + + +
    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-menu-button.svelte b/app/src/lib/components/ui/sidebar/sidebar-menu-button.svelte new file mode 100644 index 0000000..8e1668b --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-menu-button.svelte @@ -0,0 +1,102 @@ + + + + +{#snippet Button({ props }: { props?: Record })} + {@const mergedProps = mergeProps(buttonProps, props)} + {#if child} + {@render child({ props: mergedProps })} + {:else} + + {/if} +{/snippet} + +{#if !tooltipContent} + {@render Button({})} +{:else} + + + {#snippet child({ props })} + {@render Button({ props })} + {/snippet} + + + +{/if} diff --git a/app/src/lib/components/ui/sidebar/sidebar-menu-item.svelte b/app/src/lib/components/ui/sidebar/sidebar-menu-item.svelte new file mode 100644 index 0000000..4db4453 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-menu-item.svelte @@ -0,0 +1,21 @@ + + +
  • + {@render children?.()} +
  • diff --git a/app/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte b/app/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte new file mode 100644 index 0000000..1e1249b --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte @@ -0,0 +1,36 @@ + + +
    + {#if showIcon} + + {/if} + + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte b/app/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte new file mode 100644 index 0000000..09ff228 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte @@ -0,0 +1,39 @@ + + +{#if child} + {@render child({ props: mergedProps })} +{:else} + + {@render children?.()} + +{/if} diff --git a/app/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte b/app/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte new file mode 100644 index 0000000..681d0f1 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte @@ -0,0 +1,21 @@ + + +
  • + {@render children?.()} +
  • diff --git a/app/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte b/app/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte new file mode 100644 index 0000000..29614ee --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte @@ -0,0 +1,21 @@ + + +
      + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-menu.svelte b/app/src/lib/components/ui/sidebar/sidebar-menu.svelte new file mode 100644 index 0000000..44d6870 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-menu.svelte @@ -0,0 +1,21 @@ + + +
      + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-provider.svelte b/app/src/lib/components/ui/sidebar/sidebar-provider.svelte new file mode 100644 index 0000000..5b0d0aa --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-provider.svelte @@ -0,0 +1,53 @@ + + + + + +
    + {@render children?.()} +
    +
    diff --git a/app/src/lib/components/ui/sidebar/sidebar-rail.svelte b/app/src/lib/components/ui/sidebar/sidebar-rail.svelte new file mode 100644 index 0000000..f65c869 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-rail.svelte @@ -0,0 +1,36 @@ + + + diff --git a/app/src/lib/components/ui/sidebar/sidebar-separator.svelte b/app/src/lib/components/ui/sidebar/sidebar-separator.svelte new file mode 100644 index 0000000..18d791b --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-separator.svelte @@ -0,0 +1,19 @@ + + + diff --git a/app/src/lib/components/ui/sidebar/sidebar-trigger.svelte b/app/src/lib/components/ui/sidebar/sidebar-trigger.svelte new file mode 100644 index 0000000..dd2dc50 --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar-trigger.svelte @@ -0,0 +1,36 @@ + + + diff --git a/app/src/lib/components/ui/sidebar/sidebar.svelte b/app/src/lib/components/ui/sidebar/sidebar.svelte new file mode 100644 index 0000000..9c90d4f --- /dev/null +++ b/app/src/lib/components/ui/sidebar/sidebar.svelte @@ -0,0 +1,108 @@ + + +{#if collapsible === "none"} +
    + {@render children?.()} +
    +{:else if sidebar.isMobile} + sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} + {...restProps} + > + button]:hidden", + className + )} + style="--sidebar-width: {SIDEBAR_WIDTH_MOBILE};" + {side} + > + + Sidebar + Displays the mobile sidebar. + +
    + {@render children?.()} +
    +
    +
    +{:else} + +{/if} diff --git a/app/src/lib/components/ui/skeleton/index.ts b/app/src/lib/components/ui/skeleton/index.ts new file mode 100644 index 0000000..186db21 --- /dev/null +++ b/app/src/lib/components/ui/skeleton/index.ts @@ -0,0 +1,7 @@ +import Root from "./skeleton.svelte"; + +export { + Root, + // + Root as Skeleton, +}; diff --git a/app/src/lib/components/ui/skeleton/skeleton.svelte b/app/src/lib/components/ui/skeleton/skeleton.svelte new file mode 100644 index 0000000..1a940ee --- /dev/null +++ b/app/src/lib/components/ui/skeleton/skeleton.svelte @@ -0,0 +1,17 @@ + + +
    diff --git a/app/src/lib/components/ui/tooltip/index.ts b/app/src/lib/components/ui/tooltip/index.ts new file mode 100644 index 0000000..1718604 --- /dev/null +++ b/app/src/lib/components/ui/tooltip/index.ts @@ -0,0 +1,19 @@ +import Root from "./tooltip.svelte"; +import Trigger from "./tooltip-trigger.svelte"; +import Content from "./tooltip-content.svelte"; +import Provider from "./tooltip-provider.svelte"; +import Portal from "./tooltip-portal.svelte"; + +export { + Root, + Trigger, + Content, + Provider, + Portal, + // + Root as Tooltip, + Content as TooltipContent, + Trigger as TooltipTrigger, + Provider as TooltipProvider, + Portal as TooltipPortal, +}; diff --git a/app/src/lib/components/ui/tooltip/tooltip-content.svelte b/app/src/lib/components/ui/tooltip/tooltip-content.svelte new file mode 100644 index 0000000..0cf0694 --- /dev/null +++ b/app/src/lib/components/ui/tooltip/tooltip-content.svelte @@ -0,0 +1,52 @@ + + + + + {@render children?.()} + + {#snippet child({ props })} +
    + {/snippet} +
    +
    +
    diff --git a/app/src/lib/components/ui/tooltip/tooltip-portal.svelte b/app/src/lib/components/ui/tooltip/tooltip-portal.svelte new file mode 100644 index 0000000..d234f7d --- /dev/null +++ b/app/src/lib/components/ui/tooltip/tooltip-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/tooltip/tooltip-provider.svelte b/app/src/lib/components/ui/tooltip/tooltip-provider.svelte new file mode 100644 index 0000000..6dba9a6 --- /dev/null +++ b/app/src/lib/components/ui/tooltip/tooltip-provider.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/tooltip/tooltip-trigger.svelte b/app/src/lib/components/ui/tooltip/tooltip-trigger.svelte new file mode 100644 index 0000000..1acdaa4 --- /dev/null +++ b/app/src/lib/components/ui/tooltip/tooltip-trigger.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/components/ui/tooltip/tooltip.svelte b/app/src/lib/components/ui/tooltip/tooltip.svelte new file mode 100644 index 0000000..0b0f9ce --- /dev/null +++ b/app/src/lib/components/ui/tooltip/tooltip.svelte @@ -0,0 +1,7 @@ + + + diff --git a/app/src/lib/hooks/is-mobile.svelte.ts b/app/src/lib/hooks/is-mobile.svelte.ts new file mode 100644 index 0000000..4829c00 --- /dev/null +++ b/app/src/lib/hooks/is-mobile.svelte.ts @@ -0,0 +1,9 @@ +import { MediaQuery } from "svelte/reactivity"; + +const DEFAULT_MOBILE_BREAKPOINT = 768; + +export class IsMobile extends MediaQuery { + constructor(breakpoint: number = DEFAULT_MOBILE_BREAKPOINT) { + super(`max-width: ${breakpoint - 1}px`); + } +} diff --git a/frontend/src/lib/index.ts b/app/src/lib/index.ts similarity index 100% rename from frontend/src/lib/index.ts rename to app/src/lib/index.ts diff --git a/frontend/src/lib/utils.ts b/app/src/lib/utils.ts similarity index 74% rename from frontend/src/lib/utils.ts rename to app/src/lib/utils.ts index ee33998..55b3a91 100644 --- a/frontend/src/lib/utils.ts +++ b/app/src/lib/utils.ts @@ -1,13 +1,13 @@ -import { clsx, type ClassValue } from 'clsx'; -import { twMerge } from 'tailwind-merge'; +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); + return twMerge(clsx(inputs)); } // eslint-disable-next-line @typescript-eslint/no-explicit-any -export type WithoutChild = T extends { child?: any } ? Omit : T; +export type WithoutChild = T extends { child?: any } ? Omit : T; // eslint-disable-next-line @typescript-eslint/no-explicit-any -export type WithoutChildren = T extends { children?: any } ? Omit : T; +export type WithoutChildren = T extends { children?: any } ? Omit : T; export type WithoutChildrenOrChild = WithoutChildren>; export type WithElementRef = T & { ref?: U | null }; diff --git a/app/src/routes/(app)/+layout.svelte b/app/src/routes/(app)/+layout.svelte new file mode 100644 index 0000000..11a66eb --- /dev/null +++ b/app/src/routes/(app)/+layout.svelte @@ -0,0 +1,13 @@ + + + + + + {@render children()} + + diff --git a/app/src/routes/(app)/+page.svelte b/app/src/routes/(app)/+page.svelte new file mode 100644 index 0000000..ae2319b --- /dev/null +++ b/app/src/routes/(app)/+page.svelte @@ -0,0 +1,11 @@ + + +
    + +
    + +
    +

    Dashboard

    +
    diff --git a/app/src/routes/+layout.svelte b/app/src/routes/+layout.svelte new file mode 100644 index 0000000..316fbb7 --- /dev/null +++ b/app/src/routes/+layout.svelte @@ -0,0 +1,17 @@ + + + +{@render children()} diff --git a/app/src/routes/layout.css b/app/src/routes/layout.css new file mode 100644 index 0000000..cf53eeb --- /dev/null +++ b/app/src/routes/layout.css @@ -0,0 +1,139 @@ +@import "tailwindcss"; +@import "tw-animate-css"; +@import "shadcn-svelte/tailwind.css"; + +@font-face { + font-family: "Geist"; + src: url("/fonts/Geist-Variable.woff2") format("woff2"); + font-weight: 100 900; + font-style: normal; + font-display: swap; +} + +@custom-variant dark (&:is(.dark *)); + +:root { + --panel-foreground: oklch(0.985 0 0); + --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.87 0 0); + --chart-2: oklch(0.556 0 0); + --chart-3: oklch(0.439 0 0); + --chart-4: oklch(0.371 0 0); + --chart-5: oklch(0.269 0 0); + --radius: 0.4rem; + --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); +} + +.dark { + --panel-foreground: oklch(0.985 0 0); + --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.87 0 0); + --chart-2: oklch(0.556 0 0); + --chart-3: oklch(0.439 0 0); + --chart-4: oklch(0.371 0 0); + --chart-5: oklch(0.269 0 0); + --sidebar: oklch(0.16 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.21 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 6%); + --sidebar-ring: oklch(0.556 0 0); +} + +@theme inline { + --font-sans: "Geist", sans-serif; + --color-panel-foreground: var(--panel-foreground); + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar: var(--sidebar); + --color-chart-5: var(--chart-5); + --color-chart-4: var(--chart-4); + --color-chart-3: var(--chart-3); + --color-chart-2: var(--chart-2); + --color-chart-1: var(--chart-1); + --color-ring: var(--ring); + --color-input: var(--input); + --color-border: var(--border); + --color-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-card-foreground: var(--card-foreground); + --color-card: var(--card); + --color-foreground: var(--foreground); + --color-background: var(--background); + --radius-sm: calc(var(--radius) * 0.6); + --radius-md: calc(var(--radius) * 0.8); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) * 1.4); + --radius-2xl: calc(var(--radius) * 1.8); + --radius-3xl: calc(var(--radius) * 2.2); + --radius-4xl: calc(var(--radius) * 2.6); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } + html { + @apply font-sans; + } +} diff --git a/app/src/routes/login/+page.svelte b/app/src/routes/login/+page.svelte new file mode 100644 index 0000000..9f693d3 --- /dev/null +++ b/app/src/routes/login/+page.svelte @@ -0,0 +1,90 @@ + + +
    +
    +
    + CSFX Logo +

    Sign in

    + +
    +
    + +
    + + +
    +
    + +
    + +
    + + +
    +
    + +
    + + +
    + + {#if error} +
    {error}
    + {/if} + + +
    +
    +
    + +
    diff --git a/app/static/fonts/Geist-Variable.woff2 b/app/static/fonts/Geist-Variable.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..b2f01210625c8cc9939508fb1f7214d21eb41357 GIT binary patch literal 69436 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

    <+} zV(L`CrggiU`%1^h`2fp|);K%cr#pjrYN|84Ty|#K+U8qieH+@h+QHlRMqAxW{>;z& z@lR_QLLbU)Pgz=$MKerrz=beNo5?4na#1gtkh;r0Q7L!0!ZKSeypCt=?&geW6r&u& zj;?&sP5cYzGXM==$1v?`F?bXn|Kl3vj(_tvZVFV@loTKs0xrEk)@_P!7juWMyCL*G zVNXhV#?5D>JSXsFO|N+I8U(+u=tCVJLd8c)J~sR@qiRUXuqrar-L*Pp#xQqE$b;wIHV% z>=$X9qpEkN1n1^>Lg!%iZlDb_d9xcJ3d6nP?7zIF_vM*e667lJ^ppb>^0 u|F(! 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 \ No newline at end of file diff --git a/frontend/static/Gradientsv2.svg b/app/static/gradients/Gradient-light.svg similarity index 100% rename from frontend/static/Gradientsv2.svg rename to app/static/gradients/Gradient-light.svg diff --git a/app/static/logo/logo-csfx.svg b/app/static/logo/logo-csfx.svg new file mode 100644 index 0000000..e888572 --- /dev/null +++ b/app/static/logo/logo-csfx.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/frontend/static/robots.txt b/app/static/robots.txt similarity index 100% rename from frontend/static/robots.txt rename to app/static/robots.txt diff --git a/app/svelte.config.js b/app/svelte.config.js new file mode 100644 index 0000000..ba04497 --- /dev/null +++ b/app/svelte.config.js @@ -0,0 +1,21 @@ +import adapter from "@sveltejs/adapter-auto"; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + compilerOptions: { + // Force runes mode for the project, except for libraries. Can be removed in svelte 6. + runes: ({ filename }) => + filename.split(/[/\\]/).includes("node_modules") ? undefined : true, + }, + kit: { + adapter: adapter(), + alias: { + $components: "src/components", + $lib: "src/lib", + $stores: "src/stores", + $utils: "src/utils", + }, + }, +}; + +export default config; diff --git a/app/tsconfig.json b/app/tsconfig.json new file mode 100644 index 0000000..2c2ed3c --- /dev/null +++ b/app/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "rewriteRelativeImportExtensions": true, + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias + // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files + // + // To make changes to top-level options such as include and exclude, we recommend extending + // the generated config; see https://svelte.dev/docs/kit/configuration#typescript +} diff --git a/app/vite.config.ts b/app/vite.config.ts new file mode 100644 index 0000000..56f40c7 --- /dev/null +++ b/app/vite.config.ts @@ -0,0 +1,5 @@ +import tailwindcss from '@tailwindcss/vite'; +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig } from 'vite'; + +export default defineConfig({ plugins: [tailwindcss(), sveltekit()] }); diff --git a/frontend/.dockerignore b/frontend/.dockerignore deleted file mode 100644 index 120e4a0..0000000 --- a/frontend/.dockerignore +++ /dev/null @@ -1,14 +0,0 @@ -node_modules -.svelte-kit -build -.output -.vercel -.netlify -.wrangler -.DS_Store -Thumbs.db -.env -.env.* -!.env.example -*.log -npm-debug.log* diff --git a/frontend/.env.example b/frontend/.env.example deleted file mode 100644 index e23059b..0000000 --- a/frontend/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -# Frontend Environment Variables - -# API Base URL - used by SvelteKit at build time -# For production: /api (relative path, backend proxies) -# For development: http://localhost:8000/api (direct backend URL) -PUBLIC_API_BASE_URL=/api diff --git a/frontend/.prettierignore b/frontend/.prettierignore deleted file mode 100644 index 75ba31a..0000000 --- a/frontend/.prettierignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules -.svelte-kit -build -dist -.env -.env.* -!.env.example -package-lock.json diff --git a/frontend/.prettierrc b/frontend/.prettierrc deleted file mode 100644 index 5065015..0000000 --- a/frontend/.prettierrc +++ /dev/null @@ -1,16 +0,0 @@ -{ - "useTabs": false, - "tabWidth": 2, - "singleQuote": true, - "trailingComma": "es5", - "printWidth": 100, - "plugins": ["prettier-plugin-svelte"], - "overrides": [ - { - "files": "*.svelte", - "options": { - "parser": "svelte" - } - } - ] -} diff --git a/frontend/Dockerfile.dev b/frontend/Dockerfile.dev deleted file mode 100644 index 37bb7b7..0000000 --- a/frontend/Dockerfile.dev +++ /dev/null @@ -1,8 +0,0 @@ -FROM node:20-alpine - -WORKDIR /app - -COPY package*.json ./ -RUN npm install - -EXPOSE 3000 \ No newline at end of file diff --git a/frontend/Dockerfile.prod b/frontend/Dockerfile.prod deleted file mode 100644 index 9efa6f7..0000000 --- a/frontend/Dockerfile.prod +++ /dev/null @@ -1,27 +0,0 @@ -FROM node:20-alpine AS build - -WORKDIR /app - -COPY package*.json ./ -RUN npm ci - -COPY . . - -# Setenv variables during build if necessary -ENV PUBLIC_API_BASE_URL=http://localhost:8000 - -RUN npm run build - -# Runtime Stage -FROM node:20-alpine - -WORKDIR /app - -COPY --from=build /app/build ./build -COPY --from=build /app/package.json ./package.json -COPY --from=build /app/node_modules ./node_modules - -EXPOSE 3000 - -ENV PORT=3000 -CMD ["node", "build/index.js"] \ No newline at end of file diff --git a/frontend/components.json b/frontend/components.json deleted file mode 100644 index 298e869..0000000 --- a/frontend/components.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "https://shadcn-svelte.com/schema.json", - "tailwind": { - "css": "src/app.css", - "baseColor": "slate" - }, - "aliases": { - "components": "$lib/components", - "utils": "$lib/utils", - "ui": "$lib/components/ui", - "hooks": "$lib/hooks", - "lib": "$lib" - }, - "typescript": true, - "registry": "https://shadcn-svelte.com/registry" -} diff --git a/frontend/package-lock.json b/frontend/package-lock.json deleted file mode 100644 index c2f272b..0000000 --- a/frontend/package-lock.json +++ /dev/null @@ -1,6997 +0,0 @@ -{ - "name": "frontend", - "version": "0.2.2", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "frontend", - "version": "0.2.2", - "dependencies": { - "@icons-pack/svelte-simple-icons": "^6.5.0", - "@tailwindcss/typography": "0.5.19", - "@tailwindcss/vite": "^4.1.13", - "jsonwebtoken": "^9.0.2", - "node-forge": "^1.3.1", - "tailwindcss": "^4.1.13", - "tw-animate-css": "^1.3.8" - }, - "devDependencies": { - "@iconify/svelte": "^5.1.0", - "@internationalized/date": "^3.10.0", - "@lucide/svelte": "^0.561.0", - "@sveltejs/adapter-node": "^5.3.2", - "@sveltejs/kit": "2.47.2", - "@sveltejs/vite-plugin-svelte": "6.2.1", - "@tanstack/table-core": "^8.21.3", - "@types/d3-scale": "^4.0.9", - "@types/d3-shape": "^3.1.7", - "@types/jsonwebtoken": "^9.0.10", - "bits-ui": "^2.14.4", - "layerchart": "^2.0.0-next.27", - "positron-components": "1.7.0", - "prettier": "^3.4.2", - "prettier-plugin-svelte": "^3.3.2", - "svelte": "5.41.0", - "svelte-check": "4.3.3", - "tailwind-merge": "^3.3.1", - "tailwind-variants": "^3.2.2", - "tslib": "2.8.1", - "typescript": "5.9.3", - "vite": "7.1.11", - "zod": "4.1.12" - }, - "optionalDependencies": { - "@esbuild/linux-arm64": "^0.25.10", - "@rollup/rollup-darwin-arm64": "^4.50.2", - "@rollup/rollup-darwin-x64": "^4.50.2", - "@rollup/rollup-linux-arm64-gnu": "^4.50.2", - "@rollup/rollup-linux-arm64-musl": "^4.50.2", - "@rollup/rollup-linux-x64-gnu": "^4.50.2", - "@rollup/rollup-win32-x64-msvc": "^4.50.2", - "lightningcss-darwin-arm64": "^1.30.1", - "lightningcss-darwin-x64": "^1.30.1", - "lightningcss-linux-arm64-gnu": "^1.30.1", - "lightningcss-linux-arm64-musl": "^1.30.1", - "lightningcss-linux-x64-gnu": "^1.30.1", - "lightningcss-win32-x64-msvc": "^1.30.1" - } - }, - "node_modules/@ark/regex": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/@ark/regex/-/regex-0.0.0.tgz", - "integrity": "sha512-p4vsWnd/LRGOdGQglbwOguIVhPmCAf5UzquvnDoxqhhPWTP84wWgi1INea8MgJ4SnI2gp37f13oA4Waz9vwNYg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@ark/util": "0.50.0" - } - }, - "node_modules/@ark/schema": { - "version": "0.50.0", - "resolved": "https://registry.npmjs.org/@ark/schema/-/schema-0.50.0.tgz", - "integrity": "sha512-hfmP82GltBZDadIOeR3argKNlYYyB2wyzHp0eeAqAOFBQguglMV/S7Ip2q007bRtKxIMLDqFY6tfPie1dtssaQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@ark/util": "0.50.0" - } - }, - "node_modules/@ark/util": { - "version": "0.50.0", - "resolved": "https://registry.npmjs.org/@ark/util/-/util-0.50.0.tgz", - "integrity": "sha512-tIkgIMVRpkfXRQIEf0G2CJryZVtHVrqcWHMDa5QKo0OEEBu0tHkRSIMm4Ln8cd8Bn9TPZtvc/kE2Gma8RESPSg==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@asamuzakjp/css-color": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.0.5.tgz", - "integrity": "sha512-lMrXidNhPGsDjytDy11Vwlb6OIGrT3CmLg3VWNFyWkLWtijKl7xjvForlh8vuj0SHGjgl4qZEQzUmYTeQA2JFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@csstools/css-calc": "^2.1.4", - "@csstools/css-color-parser": "^3.1.0", - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "lru-cache": "^11.2.1" - } - }, - "node_modules/@asamuzakjp/dom-selector": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.3.tgz", - "integrity": "sha512-kiGFeY+Hxf5KbPpjRLf+ffWbkos1aGo8MBfd91oxS3O57RgU3XhZrt/6UzoVF9VMpWbC3v87SRc9jxGrc9qHtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@asamuzakjp/nwsapi": "^2.3.9", - "bidi-js": "^1.0.3", - "css-tree": "^3.1.0", - "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.2.2" - } - }, - "node_modules/@asamuzakjp/nwsapi": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", - "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/runtime": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.14.tgz", - "integrity": "sha512-zSlIxa20WvMojjpCSy8WrNpcZ61RqfTfX3XTaOeVlGJrt/8HF3YbzgFZa01yTbT4GWQLwfTcC3EB8i3XnB647Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@dagrejs/dagre": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@dagrejs/dagre/-/dagre-1.1.5.tgz", - "integrity": "sha512-Ghgrh08s12DCL5SeiR6AoyE80mQELTWhJBRmXfFoqDiFkR458vPEdgTbbjA0T+9ETNxUblnD0QW55tfdvi5pjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@dagrejs/graphlib": "2.2.4" - } - }, - "node_modules/@dagrejs/graphlib": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-2.2.4.tgz", - "integrity": "sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">17.0.0" - } - }, - "node_modules/@emoji-mart/data": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emoji-mart/data/-/data-1.2.1.tgz", - "integrity": "sha512-no2pQMWiBy6gpBEiqGeU77/bFejDqUTRY7KX+0+iur13op3bqUsXdnwoZs6Xb1zbv0gAj5VvS1PWoUUckSr5Dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", - "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", - "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", - "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", - "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", - "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", - "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", - "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", - "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", - "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", - "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", - "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", - "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", - "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", - "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", - "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", - "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", - "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", - "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", - "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", - "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", - "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", - "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", - "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", - "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", - "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@exodus/schemasafe": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", - "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@floating-ui/core": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", - "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/utils": "^0.2.10" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", - "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/core": "^1.7.3", - "@floating-ui/utils": "^0.2.10" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", - "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@gcornut/valibot-json-schema": { - "version": "0.42.0", - "resolved": "https://registry.npmjs.org/@gcornut/valibot-json-schema/-/valibot-json-schema-0.42.0.tgz", - "integrity": "sha512-4Et4AN6wmqeA0PfU5Clkv/IS27wiefsWf6TemAZrb75uzkClYEFavim7SboeKwbll9Nbsn2Iv0LT/HS5H7orZg==", - "dev": true, - "optional": true, - "dependencies": { - "valibot": "~0.42.0" - }, - "bin": { - "valibot-json-schema": "bin/index.js" - }, - "optionalDependencies": { - "@types/json-schema": ">= 7.0.14", - "esbuild-runner": ">= 2.2.2" - } - }, - "node_modules/@gcornut/valibot-json-schema/node_modules/valibot": { - "version": "0.42.1", - "resolved": "https://registry.npmjs.org/valibot/-/valibot-0.42.1.tgz", - "integrity": "sha512-3keXV29Ar5b//Hqi4MbSdV7lfVp6zuYLZuA9V1PvQUsXqogr+u5lvLPLk3A4f74VUXDnf/JfWMN6sB+koJ/FFw==", - "dev": true, - "license": "MIT", - "optional": true, - "peerDependencies": { - "typescript": ">=5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@iconify/svelte": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@iconify/svelte/-/svelte-5.1.0.tgz", - "integrity": "sha512-I14nSqo0pNXO5OKsT61ZO3XIPF4yRHA2ErgPsaZ1sPJdKXn80o7o8jOe1xpWphbb9FihdX6by9zlKKBss61mFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@iconify/types": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/cyberalien" - }, - "peerDependencies": { - "svelte": ">4.0.0" - } - }, - "node_modules/@iconify/types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", - "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@icons-pack/svelte-simple-icons": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@icons-pack/svelte-simple-icons/-/svelte-simple-icons-6.5.0.tgz", - "integrity": "sha512-Xj3PTioiV3TJ1NTKsXY95NFG8FUqw90oeyDZIlslWHs1KkuCheu1HOPrlHb0/IM0b4cldPgx/0TldzxzBlM8Cw==", - "license": "MIT", - "engines": { - "node": ">=20", - "pnpm": ">=9" - }, - "peerDependencies": { - "@sveltejs/kit": "^2.5.0", - "svelte": "^4.2.0 || ^5.0.0" - } - }, - "node_modules/@internationalized/date": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.10.0.tgz", - "integrity": "sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - } - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@layerstack/svelte-actions": { - "version": "1.0.1-next.12", - "resolved": "https://registry.npmjs.org/@layerstack/svelte-actions/-/svelte-actions-1.0.1-next.12.tgz", - "integrity": "sha512-dndWTlYu8b1u6vw2nrO7NssccoACArGG75WoNlyVC13KuENZlWdKE9Q79/wlnbq00NeQMNKMjJwRMsrKQj2ULA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/dom": "^1.7.0", - "@layerstack/utils": "2.0.0-next.12", - "d3-scale": "^4.0.2" - } - }, - "node_modules/@layerstack/svelte-state": { - "version": "0.1.0-next.17", - "resolved": "https://registry.npmjs.org/@layerstack/svelte-state/-/svelte-state-0.1.0-next.17.tgz", - "integrity": "sha512-z7e6mPJnypD80LEI/UDuH0bI6s8/nut06MB7rEkRcEfHJekhKSJgFhMnrYzLED7Mc2gTTD0X/wcYlakauWlU8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@layerstack/utils": "2.0.0-next.12" - } - }, - "node_modules/@layerstack/tailwind": { - "version": "2.0.0-next.15", - "resolved": "https://registry.npmjs.org/@layerstack/tailwind/-/tailwind-2.0.0-next.15.tgz", - "integrity": "sha512-7tqKE3OV7/ybeDOORX++USYYCBJa7IgTya2czFpzbgXGo7CQDVyuv+0J1DggjRcEqhhXQA4MUhgnhcRaZvHxWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@layerstack/utils": "^2.0.0-next.12", - "clsx": "^2.1.1", - "d3-array": "^3.2.4", - "lodash-es": "^4.17.21", - "tailwind-merge": "^3.2.0" - } - }, - "node_modules/@layerstack/utils": { - "version": "2.0.0-next.12", - "resolved": "https://registry.npmjs.org/@layerstack/utils/-/utils-2.0.0-next.12.tgz", - "integrity": "sha512-fhGZUlSr3N+D44BYm37WKMGSEFyZBW+dwIqtGU8Cl54mR4TLQ/UwyGhdpgIHyH/x/8q1abE0fP0Dn6ZsrDE3BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "d3-array": "^3.2.4", - "d3-time": "^3.1.0", - "d3-time-format": "^4.1.0", - "lodash-es": "^4.17.21" - } - }, - "node_modules/@lucide/svelte": { - "version": "0.561.0", - "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-0.561.0.tgz", - "integrity": "sha512-vofKV2UFVrKE6I4ewKJ3dfCXSV6iP6nWVmiM83MLjsU91EeJcEg7LoWUABLp/aOTxj1HQNbJD1f3g3L0JQgH9A==", - "dev": true, - "license": "ISC", - "peerDependencies": { - "svelte": "^5" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", - "license": "MIT" - }, - "node_modules/@poppinss/macroable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@poppinss/macroable/-/macroable-1.1.0.tgz", - "integrity": "sha512-y/YKzZDuG8XrpXpM7Z1RdQpiIc0MAKyva24Ux1PB4aI7RiSI/79K8JVDcdyubriTm7vJ1LhFs8CrZpmPnx/8Pw==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@publint/pack": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@publint/pack/-/pack-0.1.2.tgz", - "integrity": "sha512-S+9ANAvUmjutrshV4jZjaiG8XQyuJIZ8a4utWmN/vW1sgQ9IfBnPndwkmQYw53QmouOIytT874u65HEmu6H5jw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://bjornlu.com/sponsor" - } - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "28.0.9", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.9.tgz", - "integrity": "sha512-PIR4/OHZ79romx0BVVll/PkwWpJ7e5lsqFa3gFfcrFPWwLXLV39JVUzQV9RKjWerE7B845Hqjj9VYlQeieZ2dA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "fdir": "^6.2.0", - "is-reference": "1.2.1", - "magic-string": "^0.30.3", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=16.0.0 || 14 >= 14.17" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-json": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-6.1.0.tgz", - "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.1.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.3.tgz", - "integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", - "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", - "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", - "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", - "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.5.tgz", - "integrity": "sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", - "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", - "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", - "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", - "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.5.tgz", - "integrity": "sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.5.tgz", - "integrity": "sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", - "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", - "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", - "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", - "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", - "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.5.tgz", - "integrity": "sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", - "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", - "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", - "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", - "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", - "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.5.tgz", - "integrity": "sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@shikijs/core": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.13.0.tgz", - "integrity": "sha512-3P8rGsg2Eh2qIHekwuQjzWhKI4jV97PhvYjYUzGqjvJfqdQPz+nMlfWahU24GZAyW1FxFI1sYjyhfh5CoLmIUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.13.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4", - "hast-util-to-html": "^9.0.5" - } - }, - "node_modules/@shikijs/core/node_modules/@shikijs/types": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.13.0.tgz", - "integrity": "sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/engine-javascript": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.13.0.tgz", - "integrity": "sha512-Ty7xv32XCp8u0eQt8rItpMs6rU9Ki6LJ1dQOW3V/56PKDcpvfHPnYFbsx5FFUP2Yim34m/UkazidamMNVR4vKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.13.0", - "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^4.3.3" - } - }, - "node_modules/@shikijs/engine-javascript/node_modules/@shikijs/types": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.13.0.tgz", - "integrity": "sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.13.0.tgz", - "integrity": "sha512-O42rBGr4UDSlhT2ZFMxqM7QzIU+IcpoTMzb3W7AlziI1ZF7R8eS2M0yt5Ry35nnnTX/LTLXFPUjRFCIW+Operg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.13.0", - "@shikijs/vscode-textmate": "^10.0.2" - } - }, - "node_modules/@shikijs/engine-oniguruma/node_modules/@shikijs/types": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.13.0.tgz", - "integrity": "sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/langs": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.14.0.tgz", - "integrity": "sha512-DIB2EQY7yPX1/ZH7lMcwrK5pl+ZkP/xoSpUzg9YC8R+evRCCiSQ7yyrvEyBsMnfZq4eBzLzBlugMyTAf13+pzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.14.0" - } - }, - "node_modules/@shikijs/themes": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.14.0.tgz", - "integrity": "sha512-fAo/OnfWckNmv4uBoUu6dSlkcBc+SA1xzj5oUSaz5z3KqHtEbUypg/9xxgJARtM6+7RVm0Q6Xnty41xA1ma1IA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.14.0" - } - }, - "node_modules/@shikijs/types": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.14.0.tgz", - "integrity": "sha512-bQGgC6vrY8U/9ObG1Z/vTro+uclbjjD/uG58RvfxKZVD5p9Yc1ka3tVyEFy7BNJLzxuWyHH5NWynP9zZZS59eQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true - }, - "node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@standard-schema/spec": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", - "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", - "license": "MIT" - }, - "node_modules/@sveltejs/acorn-typescript": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.6.tgz", - "integrity": "sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^8.9.0" - } - }, - "node_modules/@sveltejs/adapter-auto": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-6.1.0.tgz", - "integrity": "sha512-shOuLI5D2s+0zTv2ab5M5PqfknXqWbKi+0UwB9yLTRIdzsK1R93JOO8jNhIYSHdW+IYXIYnLniu+JZqXs7h9Wg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@sveltejs/kit": "^2.0.0" - } - }, - "node_modules/@sveltejs/adapter-node": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-5.4.0.tgz", - "integrity": "sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/plugin-commonjs": "^28.0.1", - "@rollup/plugin-json": "^6.1.0", - "@rollup/plugin-node-resolve": "^16.0.0", - "rollup": "^4.9.5" - }, - "peerDependencies": { - "@sveltejs/kit": "^2.4.0" - } - }, - "node_modules/@sveltejs/kit": { - "version": "2.47.2", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.47.2.tgz", - "integrity": "sha512-mbUomaJTiADTrq6GT4ZvQ7v1rs0S+wXGMzrjFwjARAKMEF8FpOUmz2uEJ4M9WMJMQOXCMHpKFzJfdjo9O7M22A==", - "license": "MIT", - "dependencies": { - "@standard-schema/spec": "^1.0.0", - "@sveltejs/acorn-typescript": "^1.0.5", - "@types/cookie": "^0.6.0", - "acorn": "^8.14.1", - "cookie": "^0.6.0", - "devalue": "^5.3.2", - "esm-env": "^1.2.2", - "kleur": "^4.1.5", - "magic-string": "^0.30.5", - "mrmime": "^2.0.0", - "sade": "^1.8.1", - "set-cookie-parser": "^2.6.0", - "sirv": "^3.0.0" - }, - "bin": { - "svelte-kit": "svelte-kit.js" - }, - "engines": { - "node": ">=18.13" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.0", - "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - } - } - }, - "node_modules/@sveltejs/package": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/@sveltejs/package/-/package-2.5.4.tgz", - "integrity": "sha512-8+1hccAt0M3PPkHVPKH54Wc+cc1PNxRqCrICZiv/hEEto8KwbQVRghxNgTB4htIPyle+4CIB8RayTQH5zRQh9A==", - "dev": true, - "license": "MIT", - "dependencies": { - "chokidar": "^4.0.3", - "kleur": "^4.1.5", - "sade": "^1.8.1", - "semver": "^7.5.4", - "svelte2tsx": "~0.7.33" - }, - "bin": { - "svelte-package": "svelte-package.js" - }, - "engines": { - "node": "^16.14 || >=18" - }, - "peerDependencies": { - "svelte": "^3.44.0 || ^4.0.0 || ^5.0.0-next.1" - } - }, - "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.1.tgz", - "integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", - "license": "MIT", - "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", - "debug": "^4.4.1", - "deepmerge": "^4.3.1", - "magic-string": "^0.30.17", - "vitefu": "^1.1.1" - }, - "engines": { - "node": "^20.19 || ^22.12 || >=24" - }, - "peerDependencies": { - "svelte": "^5.0.0", - "vite": "^6.3.0 || ^7.0.0" - } - }, - "node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.1.tgz", - "integrity": "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.1" - }, - "engines": { - "node": "^20.19 || ^22.12 || >=24" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", - "svelte": "^5.0.0", - "vite": "^6.3.0 || ^7.0.0" - } - }, - "node_modules/@swc/helpers": { - "version": "0.5.17", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", - "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@tailwindcss/node": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.16.tgz", - "integrity": "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==", - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "enhanced-resolve": "^5.18.3", - "jiti": "^2.6.1", - "lightningcss": "1.30.2", - "magic-string": "^0.30.19", - "source-map-js": "^1.2.1", - "tailwindcss": "4.1.16" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.16.tgz", - "integrity": "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg==", - "license": "MIT", - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.16", - "@tailwindcss/oxide-darwin-arm64": "4.1.16", - "@tailwindcss/oxide-darwin-x64": "4.1.16", - "@tailwindcss/oxide-freebsd-x64": "4.1.16", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", - "@tailwindcss/oxide-linux-x64-musl": "4.1.16", - "@tailwindcss/oxide-wasm32-wasi": "4.1.16", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.16.tgz", - "integrity": "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.16.tgz", - "integrity": "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.16.tgz", - "integrity": "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.16.tgz", - "integrity": "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.16.tgz", - "integrity": "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.16.tgz", - "integrity": "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.16.tgz", - "integrity": "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.16.tgz", - "integrity": "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.16.tgz", - "integrity": "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.16.tgz", - "integrity": "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.5.0", - "@emnapi/runtime": "^1.5.0", - "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.0.7", - "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.16.tgz", - "integrity": "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.16.tgz", - "integrity": "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/typography": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.19.tgz", - "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "6.0.10" - }, - "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" - } - }, - "node_modules/@tailwindcss/vite": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.16.tgz", - "integrity": "sha512-bbguNBcDxsRmi9nnlWJxhfDWamY3lmcyACHcdO1crxfzuLpOhHLLtEIN/nCbbAtj5rchUgQD17QVAKi1f7IsKg==", - "license": "MIT", - "dependencies": { - "@tailwindcss/node": "4.1.16", - "@tailwindcss/oxide": "4.1.16", - "tailwindcss": "4.1.16" - }, - "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" - } - }, - "node_modules/@tanstack/table-core": { - "version": "8.21.3", - "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.21.3.tgz", - "integrity": "sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@types/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "license": "MIT" - }, - "node_modules/@types/d3-path": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", - "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/d3-scale": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", - "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@types/d3-shape": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", - "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/d3-path": "*" - } - }, - "node_modules/@types/d3-time": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", - "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT" - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@types/jsonwebtoken": { - "version": "9.0.10", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz", - "integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/ms": "*", - "@types/node": "*" - } - }, - "node_modules/@types/luxon": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.7.1.tgz", - "integrity": "sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.9.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz", - "integrity": "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/validator": { - "version": "13.15.3", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.3.tgz", - "integrity": "sha512-7bcUmDyS6PN3EuD9SlGGOxM77F8WLVsrwkxyWxKnxzmXoequ6c7741QBrANq6htVRGOITJ7z72mTP6Z4XyuG+Q==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@typeschema/class-validator": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@typeschema/class-validator/-/class-validator-0.3.0.tgz", - "integrity": "sha512-OJSFeZDIQ8EK1HTljKLT5CItM2wsbgczLN8tMEfz3I1Lmhc5TBfkZ0eikFzUC16tI3d1Nag7um6TfCgp2I2Bww==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@typeschema/core": "0.14.0" - }, - "peerDependencies": { - "class-validator": "^0.14.1" - }, - "peerDependenciesMeta": { - "class-validator": { - "optional": true - } - } - }, - "node_modules/@typeschema/core": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@typeschema/core/-/core-0.14.0.tgz", - "integrity": "sha512-Ia6PtZHcL3KqsAWXjMi5xIyZ7XMH4aSnOQes8mfMLx+wGFGtGRNlwe6Y7cYvX+WfNK67OL0/HSe9t8QDygV0/w==", - "dev": true, - "license": "MIT", - "optional": true, - "peerDependencies": { - "@types/json-schema": "^7.0.15" - }, - "peerDependenciesMeta": { - "@types/json-schema": { - "optional": true - } - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@vinejs/compiler": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@vinejs/compiler/-/compiler-3.0.0.tgz", - "integrity": "sha512-v9Lsv59nR56+bmy2p0+czjZxsLHwaibJ+SV5iK9JJfehlJMa501jUJQqqz4X/OqKXrxtE3uTQmSqjUqzF3B2mw==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@vinejs/vine": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@vinejs/vine/-/vine-3.0.1.tgz", - "integrity": "sha512-ZtvYkYpZOYdvbws3uaOAvTFuvFXoQGAtmzeiXu+XSMGxi5GVsODpoI9Xu9TplEMuD/5fmAtBbKb9cQHkWkLXDQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@poppinss/macroable": "^1.0.4", - "@types/validator": "^13.12.2", - "@vinejs/compiler": "^3.0.0", - "camelcase": "^8.0.0", - "dayjs": "^1.11.13", - "dlv": "^1.1.3", - "normalize-url": "^8.0.1", - "validator": "^13.12.0" - }, - "engines": { - "node": ">=18.16.0" - } - }, - "node_modules/@zxcvbn-ts/core": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@zxcvbn-ts/core/-/core-3.0.4.tgz", - "integrity": "sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==", - "dev": true, - "license": "MIT", - "dependencies": { - "fastest-levenshtein": "1.0.16" - } - }, - "node_modules/@zxcvbn-ts/language-common": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-common/-/language-common-3.0.4.tgz", - "integrity": "sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@zxcvbn-ts/language-en": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@zxcvbn-ts/language-en/-/language-en-3.0.2.tgz", - "integrity": "sha512-Zp+zL+I6Un2Bj0tRXNs6VUBq3Djt+hwTwUz4dkt2qgsQz47U0/XthZ4ULrT/RxjwJRl5LwiaKOOZeOtmixHnjg==", - "dev": true, - "license": "MIT" - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/arktype": { - "version": "2.1.23", - "resolved": "https://registry.npmjs.org/arktype/-/arktype-2.1.23.tgz", - "integrity": "sha512-tyxNWX6xJVMb2EPJJ3OjgQS1G/vIeQRrZuY4DeBNQmh8n7geS+czgbauQWB6Pr+RXiOO8ChEey44XdmxsqGmfQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@ark/regex": "0.0.0", - "@ark/schema": "0.50.0", - "@ark/util": "0.50.0" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/bidi-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", - "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "require-from-string": "^2.0.2" - } - }, - "node_modules/bits-ui": { - "version": "2.14.4", - "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.14.4.tgz", - "integrity": "sha512-W6kenhnbd/YVvur+DKkaVJ6GldE53eLewur5AhUCqslYQ0vjZr8eWlOfwZnMiPB+PF5HMVqf61vXBvmyrAmPWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/core": "^1.7.1", - "@floating-ui/dom": "^1.7.1", - "esm-env": "^1.1.2", - "runed": "^0.35.1", - "svelte-toolbelt": "^0.10.6", - "tabbable": "^6.2.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/huntabyte" - }, - "peerDependencies": { - "@internationalized/date": "^3.8.1", - "svelte": "^5.33.0" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", - "license": "BSD-3-Clause" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/camelcase": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", - "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/chrono-node": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/chrono-node/-/chrono-node-2.9.0.tgz", - "integrity": "sha512-glI4YY2Jy6JII5l3d5FN6rcrIbKSQqKPhWsIRYPK2IK8Mm4Q1ZZFdYIaDqglUNf7gNwG+kWIzTn0omzzE0VkvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/class-validator": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.3.tgz", - "integrity": "sha512-rXXekcjofVN1LTOSw+u4u9WXVEUvNBVjORW154q/IdmYWy1nMbOU9aNtZB0t8m+FJQ9q91jlr2f9CwwUFdFMRA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/validator": "^13.15.3", - "libphonenumber-js": "^1.11.1", - "validator": "^13.15.20" - } - }, - "node_modules/class-validator/node_modules/libphonenumber-js": { - "version": "1.12.33", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.33.tgz", - "integrity": "sha512-r9kw4OA6oDO4dPXkOrXTkArQAafIKAU71hChInV4FxZ69dxCfbwQGDPzqR5/vea94wU705/3AZroEbSoeVWrQw==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/country-flag-icons": { - "version": "1.5.21", - "resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.5.21.tgz", - "integrity": "sha512-0KmU4oeiyAM+F+atzK99ghQDQJKxEY3tiDhnRraVFL4o65rZgrmrx7xKi0b+hxcVpcEpuUbu+KCC6TKTZQTDcA==", - "dev": true, - "license": "MIT" - }, - "node_modules/css-tree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "mdn-data": "2.12.2", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssstyle": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.1.tgz", - "integrity": "sha512-g5PC9Aiph9eiczFpcgUhd9S4UUO3F+LHGRIi5NUMZ+4xtoIYbHNZwZnWA2JsFGe8OU8nl4WyaEFiZuGuxlutJQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@asamuzakjp/css-color": "^4.0.3", - "@csstools/css-syntax-patches-for-csstree": "^1.0.14", - "css-tree": "^3.1.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", - "dev": true, - "license": "ISC", - "dependencies": { - "internmap": "1 - 2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", - "dev": true, - "license": "ISC", - "dependencies": { - "delaunator": "5" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dispatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dsv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "commander": "7", - "iconv-lite": "0.6", - "rw": "1" - }, - "bin": { - "csv2json": "bin/dsv2json.js", - "csv2tsv": "bin/dsv2dsv.js", - "dsv2dsv": "bin/dsv2dsv.js", - "dsv2json": "bin/dsv2json.js", - "json2csv": "bin/json2dsv.js", - "json2dsv": "bin/json2dsv.js", - "json2tsv": "bin/json2dsv.js", - "tsv2csv": "bin/dsv2dsv.js", - "tsv2json": "bin/dsv2json.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-force": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", - "dev": true, - "license": "ISC", - "dependencies": { - "d3-dispatch": "1 - 3", - "d3-quadtree": "1 - 3", - "d3-timer": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-geo": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", - "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "d3-array": "2.5.0 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-geo-voronoi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/d3-geo-voronoi/-/d3-geo-voronoi-2.1.0.tgz", - "integrity": "sha512-kqE4yYuOjPbKdBXG0xztCacPwkVSK2REF1opSNrnqqtXJmNcM++UbwQ8SxvwP6IQTj9RvIjjK4qeiVsEfj0Z2Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "d3-array": "3", - "d3-delaunay": "6", - "d3-geo": "3", - "d3-tricontour": "1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-hierarchy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", - "dev": true, - "license": "ISC", - "dependencies": { - "d3-color": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-interpolate-path": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/d3-interpolate-path/-/d3-interpolate-path-2.3.0.tgz", - "integrity": "sha512-tZYtGXxBmbgHsIc9Wms6LS5u4w6KbP8C09a4/ZYc4KLMYYqub57rRBUgpUr2CIarIrJEpdAWWxWQvofgaMpbKQ==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-quadtree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-random": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-sankey": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", - "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "d3-array": "1 - 2", - "d3-shape": "^1.2.0" - } - }, - "node_modules/d3-sankey/node_modules/d3-array": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "internmap": "^1.0.0" - } - }, - "node_modules/d3-sankey/node_modules/d3-path": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/d3-sankey/node_modules/d3-shape": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", - "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "d3-path": "1" - } - }, - "node_modules/d3-sankey/node_modules/internmap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", - "dev": true, - "license": "ISC" - }, - "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-scale-chromatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "d3-color": "1 - 3", - "d3-interpolate": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "dev": true, - "license": "ISC", - "dependencies": { - "d3-path": "^3.1.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-tile": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d3-tile/-/d3-tile-1.0.0.tgz", - "integrity": "sha512-79fnTKpPMPDS5xQ0xuS9ir0165NEwwkFpe/DSOmc2Gl9ldYzKKRDWogmTTE8wAJ8NA7PMapNfEcyKhI9Lxdu5Q==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "d3-array": "2 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "dev": true, - "license": "ISC", - "dependencies": { - "d3-time": "1 - 3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-tricontour": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-tricontour/-/d3-tricontour-1.1.0.tgz", - "integrity": "sha512-G7gHKj89n2owmkGb6WX6ixcnQ0Kf/0wpa9VIh9DGdbHu8wdrlaHU4ir3/bFNERl8N8nn4G7e7qbtBG8N9caihQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "d3-delaunay": "6", - "d3-scale": "4" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/data-urls": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.0.tgz", - "integrity": "sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^15.0.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/dayjs": { - "version": "1.11.18", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", - "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "dev": true, - "license": "MIT" - }, - "node_modules/dedent-js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz", - "integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delaunator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", - "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", - "dev": true, - "license": "ISC", - "dependencies": { - "robust-predicates": "^3.0.2" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/devalue": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.4.2.tgz", - "integrity": "sha512-MwPZTKEPK2k8Qgfmqrd48ZKVvzSQjgW0lXLxiIBA8dQjtf/6mw6pggHNLcyDKyf+fI6eXxlQwPsfaCMTU5U+Bw==", - "license": "MIT" - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/dompurify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.0.tgz", - "integrity": "sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ==", - "dev": true, - "license": "(MPL-2.0 OR Apache-2.0)", - "optionalDependencies": { - "@types/trusted-types": "^2.0.7" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/effect": { - "version": "3.18.4", - "resolved": "https://registry.npmjs.org/effect/-/effect-3.18.4.tgz", - "integrity": "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@standard-schema/spec": "^1.0.0", - "fast-check": "^3.23.1" - } - }, - "node_modules/embla-carousel": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", - "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==", - "dev": true, - "license": "MIT" - }, - "node_modules/embla-carousel-reactive-utils": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz", - "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "embla-carousel": "8.6.0" - } - }, - "node_modules/embla-carousel-svelte": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/embla-carousel-svelte/-/embla-carousel-svelte-8.6.0.tgz", - "integrity": "sha512-ZDsKk8Sdv+AUTygMYcwZjfRd1DTh+JSUzxkOo8b9iKAkYjg+39mzbY/lwHsE3jXSpKxdKWS69hPSNuzlOGtR2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "embla-carousel": "8.6.0", - "embla-carousel-reactive-utils": "8.6.0" - }, - "peerDependencies": { - "svelte": "^3.49.0 || ^4.0.0 || ^5.0.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.18.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", - "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/esbuild": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", - "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.11", - "@esbuild/android-arm": "0.25.11", - "@esbuild/android-arm64": "0.25.11", - "@esbuild/android-x64": "0.25.11", - "@esbuild/darwin-arm64": "0.25.11", - "@esbuild/darwin-x64": "0.25.11", - "@esbuild/freebsd-arm64": "0.25.11", - "@esbuild/freebsd-x64": "0.25.11", - "@esbuild/linux-arm": "0.25.11", - "@esbuild/linux-arm64": "0.25.11", - "@esbuild/linux-ia32": "0.25.11", - "@esbuild/linux-loong64": "0.25.11", - "@esbuild/linux-mips64el": "0.25.11", - "@esbuild/linux-ppc64": "0.25.11", - "@esbuild/linux-riscv64": "0.25.11", - "@esbuild/linux-s390x": "0.25.11", - "@esbuild/linux-x64": "0.25.11", - "@esbuild/netbsd-arm64": "0.25.11", - "@esbuild/netbsd-x64": "0.25.11", - "@esbuild/openbsd-arm64": "0.25.11", - "@esbuild/openbsd-x64": "0.25.11", - "@esbuild/openharmony-arm64": "0.25.11", - "@esbuild/sunos-x64": "0.25.11", - "@esbuild/win32-arm64": "0.25.11", - "@esbuild/win32-ia32": "0.25.11", - "@esbuild/win32-x64": "0.25.11" - } - }, - "node_modules/esbuild-runner": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/esbuild-runner/-/esbuild-runner-2.2.2.tgz", - "integrity": "sha512-fRFVXcmYVmSmtYm2mL8RlUASt2TDkGh3uRcvHFOKNr/T58VrfVeKD9uT9nlgxk96u0LS0ehS/GY7Da/bXWKkhw==", - "dev": true, - "license": "Apache License 2.0", - "optional": true, - "dependencies": { - "source-map-support": "0.5.21", - "tslib": "2.4.0" - }, - "bin": { - "esr": "bin/esr.js" - }, - "peerDependencies": { - "esbuild": "*" - } - }, - "node_modules/esbuild-runner/node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true, - "license": "0BSD", - "optional": true - }, - "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", - "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/esm-env": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", - "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", - "license": "MIT" - }, - "node_modules/esrap": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.1.tgz", - "integrity": "sha512-ebTT9B6lOtZGMgJ3o5r12wBacHctG7oEWazIda8UlPfA3HD/Wrv8FdXoVo73vzdpwCxNyXjPauyN2bbJzMkB9A==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-check": { - "version": "3.23.2", - "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz", - "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT", - "optional": true, - "dependencies": { - "pure-rand": "^6.1.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/formsnap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/formsnap/-/formsnap-2.0.1.tgz", - "integrity": "sha512-iJSe4YKd/W6WhLwKDVJU9FQeaJRpEFuolhju7ZXlRpUVyDdqFdMP8AUBICgnVvQPyP41IPAlBa/v0Eo35iE6wQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "svelte-toolbelt": "^0.5.0" - }, - "engines": { - "node": ">=18", - "pnpm": ">=8.7.0" - }, - "funding": { - "url": "https://github.com/sponsors/huntabyte" - }, - "peerDependencies": { - "svelte": "^5.0.0", - "sveltekit-superforms": "^2.19.0" - } - }, - "node_modules/formsnap/node_modules/svelte-toolbelt": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.5.0.tgz", - "integrity": "sha512-t3tenZcnfQoIeRuQf/jBU7bvTeT3TGkcEE+1EUr5orp0lR7NEpprflpuie3x9Dn0W9nOKqs3HwKGJeeN5Ok1sQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte" - ], - "dependencies": { - "clsx": "^2.1.1", - "style-to-object": "^1.0.8" - }, - "engines": { - "node": ">=18", - "pnpm": ">=8.7.0" - }, - "peerDependencies": { - "svelte": "^5.0.0-next.126" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hast-util-to-html": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", - "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-encoding": "^3.1.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/inline-style-parser": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.6.tgz", - "integrity": "sha512-gtGXVaBdl5mAes3rPcMedEBm12ibjt1kDMFfheul1wUAOVEJW60voNdMVzVkfLN06O7ZaD/rxhfKgtlgtTbMjg==", - "dev": true, - "license": "MIT" - }, - "node_modules/internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/isomorphic-dompurify": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.30.1.tgz", - "integrity": "sha512-VJFbthRrns7BE+q3qSUJ5zxGNjuq4FqiaWXKCwnMoJbumnoQJoeOeOzP/oejKLPPtENckLWoDxGQiv5OkEFC+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "dompurify": "^3.3.0", - "jsdom": "^27.0.1" - }, - "engines": { - "node": ">=20.19.5" - } - }, - "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, - "node_modules/jsdom": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.0.1.tgz", - "integrity": "sha512-SNSQteBL1IlV2zqhwwolaG9CwhIhTvVHWg3kTss/cLE7H/X4644mtPQqYvCfsSrGQWt9hSZcgOXX8bOZaMN+kA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@asamuzakjp/dom-selector": "^6.7.2", - "cssstyle": "^5.3.1", - "data-urls": "^6.0.0", - "decimal.js": "^10.6.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.6", - "is-potential-custom-element-name": "^1.0.1", - "parse5": "^8.0.0", - "rrweb-cssom": "^0.8.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^6.0.0", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^8.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^15.1.0", - "ws": "^8.18.3", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=20" - }, - "peerDependencies": { - "canvas": "^3.0.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/json-schema-to-ts": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", - "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@babel/runtime": "^7.18.3", - "ts-algebra": "^2.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", - "license": "MIT", - "dependencies": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jwa": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", - "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", - "license": "MIT", - "dependencies": { - "buffer-equal-constant-time": "^1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "license": "MIT", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/layerchart": { - "version": "2.0.0-next.27", - "resolved": "https://registry.npmjs.org/layerchart/-/layerchart-2.0.0-next.27.tgz", - "integrity": "sha512-yt28xU8WzXq0AliX7eiC0JKZGQtO8M9FmHvt8sESNitSc/yC+fYeTghaO9lMRwcYCmi6D1NjbFyD9mWFeazNIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@dagrejs/dagre": "^1.1.4", - "@layerstack/svelte-actions": "1.0.1-next.12", - "@layerstack/svelte-state": "0.1.0-next.17", - "@layerstack/tailwind": "2.0.0-next.15", - "@layerstack/utils": "2.0.0-next.12", - "d3-array": "^3.2.4", - "d3-color": "^3.1.0", - "d3-delaunay": "^6.0.4", - "d3-dsv": "^3.0.1", - "d3-force": "^3.0.0", - "d3-geo": "^3.1.1", - "d3-geo-voronoi": "^2.1.0", - "d3-hierarchy": "^3.1.2", - "d3-interpolate": "^3.0.1", - "d3-interpolate-path": "^2.3.0", - "d3-path": "^3.1.0", - "d3-quadtree": "^3.0.1", - "d3-random": "^3.0.1", - "d3-sankey": "^0.12.3", - "d3-scale": "^4.0.2", - "d3-scale-chromatic": "^3.1.0", - "d3-shape": "^3.2.0", - "d3-tile": "^1.0.0", - "d3-time": "^3.1.0", - "lodash-es": "^4.17.21", - "memoize": "^10.1.0", - "runed": "^0.28.0" - }, - "peerDependencies": { - "svelte": "^5.0.0" - } - }, - "node_modules/layerchart/node_modules/runed": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.28.0.tgz", - "integrity": "sha512-k2xx7RuO9hWcdd9f+8JoBeqWtYrm5CALfgpkg2YDB80ds/QE4w0qqu34A7fqiAwiBBSBQOid7TLxwxVC27ymWQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "license": "MIT", - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, - "node_modules/libphonenumber-js": { - "version": "1.10.43", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.43.tgz", - "integrity": "sha512-M/iPACJGsTvEy8QmUY4K0SoIFB71X2j7y2JvUMYzUXUxCNmiU+NTfHdz7gt+dC48BVfBzZi2oO6s9TDGllCfxA==", - "dev": true, - "license": "MIT" - }, - "node_modules/lightningcss": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", - "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.30.2", - "lightningcss-darwin-arm64": "1.30.2", - "lightningcss-darwin-x64": "1.30.2", - "lightningcss-freebsd-x64": "1.30.2", - "lightningcss-linux-arm-gnueabihf": "1.30.2", - "lightningcss-linux-arm64-gnu": "1.30.2", - "lightningcss-linux-arm64-musl": "1.30.2", - "lightningcss-linux-x64-gnu": "1.30.2", - "lightningcss-linux-x64-musl": "1.30.2", - "lightningcss-win32-arm64-msvc": "1.30.2", - "lightningcss-win32-x64-msvc": "1.30.2" - } - }, - "node_modules/lightningcss-android-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", - "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", - "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", - "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", - "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", - "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", - "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", - "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", - "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", - "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", - "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", - "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/locate-character": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", - "license": "MIT" - }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", - "license": "MIT" - }, - "node_modules/lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", - "license": "MIT" - }, - "node_modules/lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", - "license": "MIT" - }, - "node_modules/lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", - "license": "MIT" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "license": "MIT" - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "license": "MIT" - }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", - "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/luxon": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", - "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "dev": true, - "license": "MIT", - "bin": { - "lz-string": "bin/bin.js" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", - "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/memoize": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/memoize/-/memoize-10.2.0.tgz", - "integrity": "sha512-DeC6b7QBrZsRs3Y02A6A7lQyzFbsQbqgjI6UW0GigGWV+u1s25TycMr0XHZE4cJce7rY/vyw2ctMQqfDkIhUEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sindresorhus/memoize?sponsor=1" - } - }, - "node_modules/memoize-weak": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/memoize-weak/-/memoize-weak-1.0.2.tgz", - "integrity": "sha512-gj39xkrjEw7nCn4nJ1M5ms6+MyMlyiGmttzsqAUsAKn6bYKwuTHh/AO3cKPF8IBrTIYTxb0wWXFs3E//Y8VoWQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mode-watcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mode-watcher/-/mode-watcher-1.1.0.tgz", - "integrity": "sha512-mUT9RRGPDYenk59qJauN1rhsIMKBmWA3xMF+uRwE8MW/tjhaDSCCARqkSuDTq8vr4/2KcAxIGVjACxTjdk5C3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "runed": "^0.25.0", - "svelte-toolbelt": "^0.7.1" - }, - "peerDependencies": { - "svelte": "^5.27.0" - } - }, - "node_modules/mode-watcher/node_modules/runed": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.25.0.tgz", - "integrity": "sha512-7+ma4AG9FT2sWQEA0Egf6mb7PBT2vHyuHail1ie8ropfSjvZGtEAx8YTmUjv/APCsdRRxEVvArNjALk9zFSOrg==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, - "node_modules/mode-watcher/node_modules/svelte-toolbelt": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.7.1.tgz", - "integrity": "sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte" - ], - "dependencies": { - "clsx": "^2.1.1", - "runed": "^0.23.2", - "style-to-object": "^1.0.8" - }, - "engines": { - "node": ">=18", - "pnpm": ">=8.7.0" - }, - "peerDependencies": { - "svelte": "^5.0.0" - } - }, - "node_modules/mode-watcher/node_modules/svelte-toolbelt/node_modules/runed": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.23.4.tgz", - "integrity": "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/normalize-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.0.tgz", - "integrity": "sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/oniguruma-parser": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", - "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/oniguruma-to-es": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.3.tgz", - "integrity": "sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "oniguruma-parser": "^0.12.1", - "regex": "^6.0.1", - "regex-recursion": "^6.0.2" - } - }, - "node_modules/package-manager-detector": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.5.0.tgz", - "integrity": "sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==", - "dev": true, - "license": "MIT" - }, - "node_modules/paneforge": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/paneforge/-/paneforge-1.0.2.tgz", - "integrity": "sha512-KzmIXQH1wCfwZ4RsMohD/IUtEjVhteR+c+ulb/CHYJHX8SuDXoJmChtsc/Xs5Wl8NHS4L5Q7cxL8MG40gSU1bA==", - "dev": true, - "license": "MIT", - "dependencies": { - "runed": "^0.23.4", - "svelte-toolbelt": "^0.9.2" - }, - "peerDependencies": { - "svelte": "^5.29.0" - } - }, - "node_modules/paneforge/node_modules/runed": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.23.4.tgz", - "integrity": "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, - "node_modules/paneforge/node_modules/svelte-toolbelt": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.9.3.tgz", - "integrity": "sha512-HCSWxCtVmv+c6g1ACb8LTwHVbDqLKJvHpo6J8TaqwUme2hj9ATJCpjCPNISR1OCq2Q4U1KT41if9ON0isINQZw==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte" - ], - "dependencies": { - "clsx": "^2.1.1", - "runed": "^0.29.0", - "style-to-object": "^1.0.8" - }, - "engines": { - "node": ">=18", - "pnpm": ">=8.7.0" - }, - "peerDependencies": { - "svelte": "^5.30.2" - } - }, - "node_modules/paneforge/node_modules/svelte-toolbelt/node_modules/runed": { - "version": "0.29.2", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.29.2.tgz", - "integrity": "sha512-0cq6cA6sYGZwl/FvVqjx9YN+1xEBu9sDDyuWdDW1yWX7JF2wmvmVKfH+hVCZs+csW+P3ARH92MjI3H9QTagOQA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "license": "MIT", - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, - "node_modules/parse5": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", - "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", - "dev": true, - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/positron-components": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/positron-components/-/positron-components-1.7.0.tgz", - "integrity": "sha512-qw67lNgfALtvahkd04tsTfZFFU+Bv/lrvjYr1RMhxWN2kgt717es9ZZJiowuxTblM6B0Y1PbHbi8PQrc8fYh7A==", - "dev": true, - "dependencies": { - "@emoji-mart/data": "^1.2.1", - "@internationalized/date": "3.9.0", - "@lucide/svelte": "^0.544.0", - "@shikijs/langs": "^3.13.0", - "@shikijs/themes": "^3.13.0", - "@sveltejs/adapter-auto": "6.1.0", - "@sveltejs/kit": "2.43.4", - "@sveltejs/package": "2.5.4", - "@sveltejs/vite-plugin-svelte": "6.2.1", - "@tailwindcss/typography": "0.5.19", - "@tailwindcss/vite": "4.1.13", - "@tanstack/table-core": "8.21.3", - "@types/luxon": "3.7.1", - "@zxcvbn-ts/core": "^3.0.4", - "@zxcvbn-ts/language-common": "^3.0.4", - "@zxcvbn-ts/language-en": "^3.0.2", - "bits-ui": "^2.11.3", - "clsx": "^2.1.1", - "country-flag-icons": "^1.5.21", - "embla-carousel-svelte": "^8.6.0", - "formsnap": "2.0.1", - "isomorphic-dompurify": "^2.28.0", - "layerchart": "^2.0.0-next.38", - "luxon": "3.7.2", - "mode-watcher": "^1.1.0", - "package-manager-detector": "^1.3.0", - "paneforge": "^1.0.2", - "prettier": "3.6.2", - "prettier-plugin-svelte": "3.4.0", - "prettier-plugin-tailwindcss": "0.6.14", - "publint": "0.3.13", - "runed": "^0.34.0", - "shiki": "3.13.0", - "svelte": "5.39.6", - "svelte-check": "4.3.2", - "svelte-easy-crop": "^5.0.0", - "svelte-sonner": "^1.0.5", - "svelte-tel-input": "^3.6.0", - "svelte-toolbelt": "^0.10.5", - "sveltekit-superforms": "2.27.1", - "tailwind-merge": "^3.3.1", - "tailwind-variants": "^3.1.1", - "tailwindcss": "4.1.13", - "tw-animate-css": "1.4.0", - "typescript": "5.9.2", - "vaul-svelte": "^1.0.0-next.7", - "vite": "7.1.7", - "yeezy-dates": "^1.0.1", - "zod": "4.1.11" - } - }, - "node_modules/positron-components/node_modules/@internationalized/date": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.9.0.tgz", - "integrity": "sha512-yaN3brAnHRD+4KyyOsJyk49XUvj2wtbNACSqg0bz3u8t2VuzhC8Q5dfRnrSxjnnbDb+ienBnkn1TzQfE154vyg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/helpers": "^0.5.0" - } - }, - "node_modules/positron-components/node_modules/@layerstack/svelte-actions": { - "version": "1.0.1-next.14", - "resolved": "https://registry.npmjs.org/@layerstack/svelte-actions/-/svelte-actions-1.0.1-next.14.tgz", - "integrity": "sha512-MPBmVaB+GfNHvBkg5nJkPG18smoXKvsvJRpsdWnrUBfca+TieZLoaEzNxDH+9LG11dIXP9gghsXt1mUqbbyAsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/dom": "^1.7.0", - "@layerstack/utils": "2.0.0-next.14", - "d3-scale": "^4.0.2" - } - }, - "node_modules/positron-components/node_modules/@layerstack/svelte-state": { - "version": "0.1.0-next.19", - "resolved": "https://registry.npmjs.org/@layerstack/svelte-state/-/svelte-state-0.1.0-next.19.tgz", - "integrity": "sha512-yCYoQAIbeP8y1xmOB/r0+UundgP4JFnpNURgMki+26TotzoqrZ5oLpHvhPSVm60ks+buR3ebDBTeUFdHzxwzQQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@layerstack/utils": "2.0.0-next.14" - } - }, - "node_modules/positron-components/node_modules/@layerstack/tailwind": { - "version": "2.0.0-next.17", - "resolved": "https://registry.npmjs.org/@layerstack/tailwind/-/tailwind-2.0.0-next.17.tgz", - "integrity": "sha512-ZSn6ouqpnzB6DKzSKLVwrUBOQsrzpDA/By2/ba9ApxgTGnaD1nyqNwrvmZ+kswdAwB4YnrGEAE4VZkKrB2+DaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@layerstack/utils": "^2.0.0-next.14", - "clsx": "^2.1.1", - "d3-array": "^3.2.4", - "lodash-es": "^4.17.21", - "tailwind-merge": "^3.2.0" - } - }, - "node_modules/positron-components/node_modules/@layerstack/utils": { - "version": "2.0.0-next.14", - "resolved": "https://registry.npmjs.org/@layerstack/utils/-/utils-2.0.0-next.14.tgz", - "integrity": "sha512-1I2CS0Cwgs53W35qVg1eBdYhB/CiPvL3s0XE61b8jWkTHxgjBF65yYNgXjW74kv7WI7GsJcWMNBufPd0rnu9kA==", - "dev": true, - "license": "MIT", - "dependencies": { - "d3-array": "^3.2.4", - "d3-time": "^3.1.0", - "d3-time-format": "^4.1.0", - "lodash-es": "^4.17.21" - } - }, - "node_modules/positron-components/node_modules/@lucide/svelte": { - "version": "0.544.0", - "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-0.544.0.tgz", - "integrity": "sha512-9f9O6uxng2pLB01sxNySHduJN3HTl5p0HDu4H26VR51vhZfiMzyOMe9Mhof3XAk4l813eTtl+/DYRvGyoRR+yw==", - "dev": true, - "license": "ISC", - "peerDependencies": { - "svelte": "^5" - } - }, - "node_modules/positron-components/node_modules/@sveltejs/kit": { - "version": "2.43.4", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.43.4.tgz", - "integrity": "sha512-GfvOq3A/qMRhj2L9eKjxaI8FLqZDh5SY74YzhRKT//u2AvQw96ksEfjuHviC4jg9U08mBVB0Y47EwEJHO4BB4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@standard-schema/spec": "^1.0.0", - "@sveltejs/acorn-typescript": "^1.0.5", - "@types/cookie": "^0.6.0", - "acorn": "^8.14.1", - "cookie": "^0.6.0", - "devalue": "^5.3.2", - "esm-env": "^1.2.2", - "kleur": "^4.1.5", - "magic-string": "^0.30.5", - "mrmime": "^2.0.0", - "sade": "^1.8.1", - "set-cookie-parser": "^2.6.0", - "sirv": "^3.0.0" - }, - "bin": { - "svelte-kit": "svelte-kit.js" - }, - "engines": { - "node": ">=18.13" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.0.0", - "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - } - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/node": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.13.tgz", - "integrity": "sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "enhanced-resolve": "^5.18.3", - "jiti": "^2.5.1", - "lightningcss": "1.30.1", - "magic-string": "^0.30.18", - "source-map-js": "^1.2.1", - "tailwindcss": "4.1.13" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.13.tgz", - "integrity": "sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.4", - "tar": "^7.4.3" - }, - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.13", - "@tailwindcss/oxide-darwin-arm64": "4.1.13", - "@tailwindcss/oxide-darwin-x64": "4.1.13", - "@tailwindcss/oxide-freebsd-x64": "4.1.13", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.13", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.13", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.13", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.13", - "@tailwindcss/oxide-linux-x64-musl": "4.1.13", - "@tailwindcss/oxide-wasm32-wasi": "4.1.13", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.13", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.13" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.13.tgz", - "integrity": "sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.13.tgz", - "integrity": "sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.13.tgz", - "integrity": "sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.13.tgz", - "integrity": "sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.13.tgz", - "integrity": "sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.13.tgz", - "integrity": "sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.13.tgz", - "integrity": "sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.13.tgz", - "integrity": "sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.13.tgz", - "integrity": "sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.13.tgz", - "integrity": "sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.5", - "@emnapi/runtime": "^1.4.5", - "@emnapi/wasi-threads": "^1.0.4", - "@napi-rs/wasm-runtime": "^0.2.12", - "@tybys/wasm-util": "^0.10.0", - "tslib": "^2.8.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.13.tgz", - "integrity": "sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.13.tgz", - "integrity": "sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/positron-components/node_modules/@tailwindcss/vite": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.13.tgz", - "integrity": "sha512-0PmqLQ010N58SbMTJ7BVJ4I2xopiQn/5i6nlb4JmxzQf8zcS5+m2Cv6tqh+sfDwtIdjoEnOvwsGQ1hkUi8QEHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tailwindcss/node": "4.1.13", - "@tailwindcss/oxide": "4.1.13", - "tailwindcss": "4.1.13" - }, - "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" - } - }, - "node_modules/positron-components/node_modules/is-reference": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", - "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.6" - } - }, - "node_modules/positron-components/node_modules/layerchart": { - "version": "2.0.0-next.42", - "resolved": "https://registry.npmjs.org/layerchart/-/layerchart-2.0.0-next.42.tgz", - "integrity": "sha512-vLMHaLaU5Glf7OG56cZiD/1Dt6qvYHxc9gbNTq2ypjs+3iGLekx//wvkvCAmx8mH/t6kx1fbmxwKpf+RrFkyew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@dagrejs/dagre": "^1.1.5", - "@layerstack/svelte-actions": "1.0.1-next.14", - "@layerstack/svelte-state": "0.1.0-next.19", - "@layerstack/tailwind": "2.0.0-next.17", - "@layerstack/utils": "2.0.0-next.14", - "d3-array": "^3.2.4", - "d3-color": "^3.1.0", - "d3-delaunay": "^6.0.4", - "d3-dsv": "^3.0.1", - "d3-force": "^3.0.0", - "d3-geo": "^3.1.1", - "d3-geo-voronoi": "^2.1.0", - "d3-hierarchy": "^3.1.2", - "d3-interpolate": "^3.0.1", - "d3-interpolate-path": "^2.3.0", - "d3-path": "^3.1.0", - "d3-quadtree": "^3.0.1", - "d3-random": "^3.0.1", - "d3-sankey": "^0.12.3", - "d3-scale": "^4.0.2", - "d3-scale-chromatic": "^3.1.0", - "d3-shape": "^3.2.0", - "d3-tile": "^1.0.0", - "d3-time": "^3.1.0", - "lodash-es": "^4.17.21", - "memoize": "^10.1.0", - "runed": "^0.31.1" - }, - "peerDependencies": { - "svelte": "^5.0.0" - } - }, - "node_modules/positron-components/node_modules/layerchart/node_modules/runed": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.31.1.tgz", - "integrity": "sha512-v3czcTnO+EJjiPvD4dwIqfTdHLZ8oH0zJheKqAHh9QMViY7Qb29UlAMRpX7ZtHh7AFqV60KmfxaJ9QMy+L1igQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "license": "MIT", - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, - "node_modules/positron-components/node_modules/lightningcss": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.30.1", - "lightningcss-darwin-x64": "1.30.1", - "lightningcss-freebsd-x64": "1.30.1", - "lightningcss-linux-arm-gnueabihf": "1.30.1", - "lightningcss-linux-arm64-gnu": "1.30.1", - "lightningcss-linux-arm64-musl": "1.30.1", - "lightningcss-linux-x64-gnu": "1.30.1", - "lightningcss-linux-x64-musl": "1.30.1", - "lightningcss-win32-arm64-msvc": "1.30.1", - "lightningcss-win32-x64-msvc": "1.30.1" - } - }, - "node_modules/positron-components/node_modules/lightningcss-darwin-arm64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/positron-components/node_modules/lightningcss-darwin-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/positron-components/node_modules/lightningcss-freebsd-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/positron-components/node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/positron-components/node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/positron-components/node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/positron-components/node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/positron-components/node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/positron-components/node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/positron-components/node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/positron-components/node_modules/runed": { - "version": "0.34.0", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.34.0.tgz", - "integrity": "sha512-hdDCoxWCuOCa7HnuU2ihu2tXuAOacNXtvTDDZ02km+rguHZBtglzAoo3dVYtssZjFsooY9xawvYX9HmDJqaPTA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "license": "MIT", - "dependencies": { - "dequal": "^2.0.3", - "esm-env": "^1.0.0", - "lz-string": "^1.5.0" - }, - "peerDependencies": { - "@sveltejs/kit": "^2.21.0", - "svelte": "^5.7.0" - }, - "peerDependenciesMeta": { - "@sveltejs/kit": { - "optional": true - } - } - }, - "node_modules/positron-components/node_modules/svelte": { - "version": "5.39.6", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.39.6.tgz", - "integrity": "sha512-bOJXmuwLNaoqPCTWO8mPu/fwxI5peGE5Efe7oo6Cakpz/G60vsnVF6mxbGODaxMUFUKEnjm6XOwHEqOht6cbvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "@jridgewell/sourcemap-codec": "^1.5.0", - "@sveltejs/acorn-typescript": "^1.0.5", - "@types/estree": "^1.0.5", - "acorn": "^8.12.1", - "aria-query": "^5.3.1", - "axobject-query": "^4.1.0", - "clsx": "^2.1.1", - "esm-env": "^1.2.1", - "esrap": "^2.1.0", - "is-reference": "^3.0.3", - "locate-character": "^3.0.0", - "magic-string": "^0.30.11", - "zimmerframe": "^1.1.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/positron-components/node_modules/svelte-check": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.2.tgz", - "integrity": "sha512-71udP5w2kaSTcX8iV0hn3o2FWlabQHhJTJLIQrCqMsrcOeDUO2VhCQKKCA8AMVHSPwdxLEWkUWh9OKxns5PD9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "chokidar": "^4.0.1", - "fdir": "^6.2.0", - "picocolors": "^1.0.0", - "sade": "^1.7.4" - }, - "bin": { - "svelte-check": "bin/svelte-check" - }, - "engines": { - "node": ">= 18.0.0" - }, - "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "typescript": ">=5.0.0" - } - }, - "node_modules/positron-components/node_modules/tailwindcss": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.13.tgz", - "integrity": "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/positron-components/node_modules/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/positron-components/node_modules/vite": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.7.tgz", - "integrity": "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/positron-components/node_modules/zod": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.11.tgz", - "integrity": "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-plugin-svelte": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.4.0.tgz", - "integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "prettier": "^3.0.0", - "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" - } - }, - "node_modules/prettier-plugin-tailwindcss": { - "version": "0.6.14", - "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.14.tgz", - "integrity": "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.21.3" - }, - "peerDependencies": { - "@ianvs/prettier-plugin-sort-imports": "*", - "@prettier/plugin-hermes": "*", - "@prettier/plugin-oxc": "*", - "@prettier/plugin-pug": "*", - "@shopify/prettier-plugin-liquid": "*", - "@trivago/prettier-plugin-sort-imports": "*", - "@zackad/prettier-plugin-twig": "*", - "prettier": "^3.0", - "prettier-plugin-astro": "*", - "prettier-plugin-css-order": "*", - "prettier-plugin-import-sort": "*", - "prettier-plugin-jsdoc": "*", - "prettier-plugin-marko": "*", - "prettier-plugin-multiline-arrays": "*", - "prettier-plugin-organize-attributes": "*", - "prettier-plugin-organize-imports": "*", - "prettier-plugin-sort-imports": "*", - "prettier-plugin-style-order": "*", - "prettier-plugin-svelte": "*" - }, - "peerDependenciesMeta": { - "@ianvs/prettier-plugin-sort-imports": { - "optional": true - }, - "@prettier/plugin-hermes": { - "optional": true - }, - "@prettier/plugin-oxc": { - "optional": true - }, - "@prettier/plugin-pug": { - "optional": true - }, - "@shopify/prettier-plugin-liquid": { - "optional": true - }, - "@trivago/prettier-plugin-sort-imports": { - "optional": true - }, - "@zackad/prettier-plugin-twig": { - "optional": true - }, - "prettier-plugin-astro": { - "optional": true - }, - "prettier-plugin-css-order": { - "optional": true - }, - "prettier-plugin-import-sort": { - "optional": true - }, - "prettier-plugin-jsdoc": { - "optional": true - }, - "prettier-plugin-marko": { - "optional": true - }, - "prettier-plugin-multiline-arrays": { - "optional": true - }, - "prettier-plugin-organize-attributes": { - "optional": true - }, - "prettier-plugin-organize-imports": { - "optional": true - }, - "prettier-plugin-sort-imports": { - "optional": true - }, - "prettier-plugin-style-order": { - "optional": true - }, - "prettier-plugin-svelte": { - "optional": true - } - } - }, - "node_modules/property-expr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", - "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/publint": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/publint/-/publint-0.3.13.tgz", - "integrity": "sha512-NC+lph09+BRO9LJgKlIy3WQXyu6/6WDQ0dCA60KALUwdKVf3PfGuC6fY8I+oKB/5kEPh50aOSUz+6yWy1n4EfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@publint/pack": "^0.1.2", - "package-manager-detector": "^1.3.0", - "picocolors": "^1.1.1", - "sade": "^1.8.1" - }, - "bin": { - "publint": "src/cli.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://bjornlu.com/sponsor" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT", - "optional": true - }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", - "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-recursion": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", - "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-utilities": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", - "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", - "dev": true, - "license": "MIT" - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/robust-predicates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", - "dev": true, - "license": "Unlicense" - }, - "node_modules/rollup": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", - "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.52.5", - "@rollup/rollup-android-arm64": "4.52.5", - "@rollup/rollup-darwin-arm64": "4.52.5", - "@rollup/rollup-darwin-x64": "4.52.5", - "@rollup/rollup-freebsd-arm64": "4.52.5", - "@rollup/rollup-freebsd-x64": "4.52.5", - "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", - "@rollup/rollup-linux-arm-musleabihf": "4.52.5", - "@rollup/rollup-linux-arm64-gnu": "4.52.5", - "@rollup/rollup-linux-arm64-musl": "4.52.5", - "@rollup/rollup-linux-loong64-gnu": "4.52.5", - "@rollup/rollup-linux-ppc64-gnu": "4.52.5", - "@rollup/rollup-linux-riscv64-gnu": "4.52.5", - "@rollup/rollup-linux-riscv64-musl": "4.52.5", - "@rollup/rollup-linux-s390x-gnu": "4.52.5", - "@rollup/rollup-linux-x64-gnu": "4.52.5", - "@rollup/rollup-linux-x64-musl": "4.52.5", - "@rollup/rollup-openharmony-arm64": "4.52.5", - "@rollup/rollup-win32-arm64-msvc": "4.52.5", - "@rollup/rollup-win32-ia32-msvc": "4.52.5", - "@rollup/rollup-win32-x64-gnu": "4.52.5", - "@rollup/rollup-win32-x64-msvc": "4.52.5", - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup/node_modules/@rollup/rollup-darwin-x64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", - "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", - "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", - "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", - "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/rollup/node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", - "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/rrweb-cssom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/runed": { - "version": "0.35.1", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.35.1.tgz", - "integrity": "sha512-2F4Q/FZzbeJTFdIS/PuOoPRSm92sA2LhzTnv6FXhCoENb3huf5+fDuNOg1LNvGOouy3u/225qxmuJvcV3IZK5Q==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "license": "MIT", - "dependencies": { - "dequal": "^2.0.3", - "esm-env": "^1.0.0", - "lz-string": "^1.5.0" - }, - "peerDependencies": { - "@sveltejs/kit": "^2.21.0", - "svelte": "^5.7.0" - }, - "peerDependenciesMeta": { - "@sveltejs/kit": { - "optional": true - } - } - }, - "node_modules/rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "license": "MIT", - "dependencies": { - "mri": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=v12.22.7" - } - }, - "node_modules/scule": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz", - "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", - "dev": true, - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", - "license": "MIT" - }, - "node_modules/shiki": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.13.0.tgz", - "integrity": "sha512-aZW4l8Og16CokuCLf8CF8kq+KK2yOygapU5m3+hoGw0Mdosc6fPitjM+ujYarppj5ZIKGyPDPP1vqmQhr+5/0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/core": "3.13.0", - "@shikijs/engine-javascript": "3.13.0", - "@shikijs/engine-oniguruma": "3.13.0", - "@shikijs/langs": "3.13.0", - "@shikijs/themes": "3.13.0", - "@shikijs/types": "3.13.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/shiki/node_modules/@shikijs/langs": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.13.0.tgz", - "integrity": "sha512-672c3WAETDYHwrRP0yLy3W1QYB89Hbpj+pO4KhxK6FzIrDI2FoEXNiNCut6BQmEApYLfuYfpgOZaqbY+E9b8wQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.13.0" - } - }, - "node_modules/shiki/node_modules/@shikijs/themes": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.13.0.tgz", - "integrity": "sha512-Vxw1Nm1/Od8jyA7QuAenaV78BG2nSr3/gCGdBkLpfLscddCkzkL36Q5b67SrLLfvAJTOUzW39x4FHVCFriPVgg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.13.0" - } - }, - "node_modules/shiki/node_modules/@shikijs/types": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.13.0.tgz", - "integrity": "sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/sirv": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", - "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "dev": true, - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/style-to-object": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.12.tgz", - "integrity": "sha512-ddJqYnoT4t97QvN2C95bCgt+m7AAgXjVnkk/jxAfmp7EAB8nnqqZYEbMd3em7/vEomDb2LAQKAy1RFfv41mdNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.2.6" - } - }, - "node_modules/superstruct": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-2.0.2.tgz", - "integrity": "sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svelte": { - "version": "5.41.0", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.41.0.tgz", - "integrity": "sha512-mP3vFFv5OUM5JN189+nJVW74kQ1dGqUrXTEzvCEVZqessY0GxZDls1nWVvt4Sxyv2USfQvAZO68VRaeIZvpzKg==", - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "@jridgewell/sourcemap-codec": "^1.5.0", - "@sveltejs/acorn-typescript": "^1.0.5", - "@types/estree": "^1.0.5", - "acorn": "^8.12.1", - "aria-query": "^5.3.1", - "axobject-query": "^4.1.0", - "clsx": "^2.1.1", - "esm-env": "^1.2.1", - "esrap": "^2.1.0", - "is-reference": "^3.0.3", - "locate-character": "^3.0.0", - "magic-string": "^0.30.11", - "zimmerframe": "^1.1.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/svelte-check": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.3.tgz", - "integrity": "sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "chokidar": "^4.0.1", - "fdir": "^6.2.0", - "picocolors": "^1.0.0", - "sade": "^1.7.4" - }, - "bin": { - "svelte-check": "bin/svelte-check" - }, - "engines": { - "node": ">= 18.0.0" - }, - "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "typescript": ">=5.0.0" - } - }, - "node_modules/svelte-easy-crop": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/svelte-easy-crop/-/svelte-easy-crop-5.0.0.tgz", - "integrity": "sha512-niWtner+qYVas6ypIOQ277NKNACVz9qz6wfpEW7t+x5Lhv6nOjpv3S1WhEPO+SnDaW3VZv+0bmm6jVDHK2GMAg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "svelte": "^5.0.0" - } - }, - "node_modules/svelte-sonner": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/svelte-sonner/-/svelte-sonner-1.0.5.tgz", - "integrity": "sha512-9dpGPFqKb/QWudYqGnEz93vuY+NgCEvyNvxoCLMVGw6sDN/3oVeKV1xiEirW2E1N3vJEyj5imSBNOGltQHA7mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "runed": "^0.28.0" - }, - "peerDependencies": { - "svelte": "^5.0.0" - } - }, - "node_modules/svelte-sonner/node_modules/runed": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.28.0.tgz", - "integrity": "sha512-k2xx7RuO9hWcdd9f+8JoBeqWtYrm5CALfgpkg2YDB80ds/QE4w0qqu34A7fqiAwiBBSBQOid7TLxwxVC27ymWQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "license": "MIT", - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, - "node_modules/svelte-tel-input": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/svelte-tel-input/-/svelte-tel-input-3.6.0.tgz", - "integrity": "sha512-bzgtYVWpO3cke8tqRM2JvcHO94wIp8X0C5E4SItobrmGWT8Do07jzkHN8Z+KU6RaY6Q1aBomH8neJ2LEAZAfqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "libphonenumber-js": "1.10.43" - }, - "engines": { - "node": ">= 18", - "npm": ">= 8", - "pnpm": ">= 8", - "yarn": ">= 1" - }, - "peerDependencies": { - "svelte": "^3.58.0 || ^4.0.0 || ^5.0.0" - } - }, - "node_modules/svelte-toolbelt": { - "version": "0.10.6", - "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.10.6.tgz", - "integrity": "sha512-YWuX+RE+CnWYx09yseAe4ZVMM7e7GRFZM6OYWpBKOb++s+SQ8RBIMMe+Bs/CznBMc0QPLjr+vDBxTAkozXsFXQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte" - ], - "dependencies": { - "clsx": "^2.1.1", - "runed": "^0.35.1", - "style-to-object": "^1.0.8" - }, - "engines": { - "node": ">=18", - "pnpm": ">=8.7.0" - }, - "peerDependencies": { - "svelte": "^5.30.2" - } - }, - "node_modules/svelte/node_modules/is-reference": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", - "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.6" - } - }, - "node_modules/svelte2tsx": { - "version": "0.7.45", - "resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.7.45.tgz", - "integrity": "sha512-cSci+mYGygYBHIZLHlm/jYlEc1acjAHqaQaDFHdEBpUueM9kSTnPpvPtSl5VkJOU1qSJ7h1K+6F/LIUYiqC8VA==", - "dev": true, - "license": "MIT", - "dependencies": { - "dedent-js": "^1.0.1", - "scule": "^1.3.0" - }, - "peerDependencies": { - "svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0", - "typescript": "^4.9.4 || ^5.0.0" - } - }, - "node_modules/sveltekit-superforms": { - "version": "2.27.1", - "resolved": "https://registry.npmjs.org/sveltekit-superforms/-/sveltekit-superforms-2.27.1.tgz", - "integrity": "sha512-cvq2AevkZ0Zrk0w0gNM3kjcnJMtJ0jzu+2zqDoM9a+lZa+8bGpNl4YqxVkemiJNkGnFgNC8xr5xF5BlMzjookQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ciscoheat" - }, - { - "type": "ko-fi", - "url": "https://ko-fi.com/ciscoheat" - }, - { - "type": "paypal", - "url": "https://www.paypal.com/donate/?hosted_button_id=NY7F5ALHHSVQS" - } - ], - "license": "MIT", - "dependencies": { - "devalue": "^5.1.1", - "memoize-weak": "^1.0.2", - "ts-deepmerge": "^7.0.3" - }, - "optionalDependencies": { - "@exodus/schemasafe": "^1.3.0", - "@gcornut/valibot-json-schema": "^0.42.0", - "@sinclair/typebox": "^0.34.35", - "@typeschema/class-validator": "^0.3.0", - "@vinejs/vine": "^3.0.1", - "arktype": "^2.1.20", - "class-validator": "^0.14.2", - "effect": "^3.16.7", - "joi": "^17.13.3", - "json-schema-to-ts": "^3.1.1", - "superstruct": "^2.0.2", - "valibot": "^1.1.0", - "yup": "^1.6.1", - "zod": "^3.25.64", - "zod-to-json-schema": "^3.24.5" - }, - "peerDependencies": { - "@exodus/schemasafe": "^1.3.0", - "@sinclair/typebox": "^0.34.28", - "@sveltejs/kit": "1.x || 2.x", - "@typeschema/class-validator": "^0.3.0", - "@vinejs/vine": "^1.8.0 || ^2.0.0 || ^3.0.0", - "arktype": ">=2.0.0-rc.23", - "class-validator": "^0.14.1", - "effect": "^3.13.7", - "joi": "^17.13.1", - "superstruct": "^2.0.2", - "svelte": "3.x || 4.x || >=5.0.0-next.51", - "valibot": "^1.0.0", - "yup": "^1.4.0", - "zod": "^3.25.0" - }, - "peerDependenciesMeta": { - "@exodus/schemasafe": { - "optional": true - }, - "@sinclair/typebox": { - "optional": true - }, - "@typeschema/class-validator": { - "optional": true - }, - "@vinejs/vine": { - "optional": true - }, - "arktype": { - "optional": true - }, - "class-validator": { - "optional": true - }, - "effect": { - "optional": true - }, - "joi": { - "optional": true - }, - "superstruct": { - "optional": true - }, - "valibot": { - "optional": true - }, - "yup": { - "optional": true - }, - "zod": { - "optional": true - } - } - }, - "node_modules/sveltekit-superforms/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "dev": true, - "license": "MIT", - "optional": true, - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/sveltekit-superforms/node_modules/zod-to-json-schema": { - "version": "3.24.6", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", - "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", - "dev": true, - "license": "ISC", - "optional": true, - "peerDependencies": { - "zod": "^3.24.1" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/tabbable": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.3.0.tgz", - "integrity": "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/tailwind-merge": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz", - "integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/dcastil" - } - }, - "node_modules/tailwind-variants": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-3.2.2.tgz", - "integrity": "sha512-Mi4kHeMTLvKlM98XPnK+7HoBPmf4gygdFmqQPaDivc3DpYS6aIY6KiG/PgThrGvii5YZJqRsPz0aPyhoFzmZgg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16.x", - "pnpm": ">=7.x" - }, - "peerDependencies": { - "tailwind-merge": ">=3.0.0", - "tailwindcss": "*" - }, - "peerDependenciesMeta": { - "tailwind-merge": { - "optional": true - } - } - }, - "node_modules/tailwindcss": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.16.tgz", - "integrity": "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==", - "license": "MIT" - }, - "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/tar": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", - "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/tiny-case": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", - "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tldts": { - "version": "7.0.17", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.17.tgz", - "integrity": "sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tldts-core": "^7.0.17" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tldts-core": { - "version": "7.0.17", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.17.tgz", - "integrity": "sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/toposort": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", - "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", - "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tldts": "^7.0.5" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/tr46": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", - "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/ts-algebra": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", - "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/ts-deepmerge": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-7.0.3.tgz", - "integrity": "sha512-Du/ZW2RfwV/D4cmA5rXafYjBQVuvu4qGiEEla4EmEHVHgRdx68Gftx7i66jn2bzHPwSVZY36Ae6OuDn9el4ZKA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14.13.1" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "devOptional": true, - "license": "0BSD" - }, - "node_modules/tw-animate-css": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", - "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/Wombosvideo" - } - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "optional": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/valibot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.1.0.tgz", - "integrity": "sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw==", - "dev": true, - "license": "MIT", - "optional": true, - "peerDependencies": { - "typescript": ">=5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/validator": { - "version": "13.15.20", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.20.tgz", - "integrity": "sha512-KxPOq3V2LmfQPP4eqf3Mq/zrT0Dqp2Vmx2Bn285LwVahLc+CsxOM0crBHczm8ijlcjZ0Q5Xd6LW3z3odTPnlrw==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vaul-svelte": { - "version": "1.0.0-next.7", - "resolved": "https://registry.npmjs.org/vaul-svelte/-/vaul-svelte-1.0.0-next.7.tgz", - "integrity": "sha512-7zN7Bi3dFQixvvbUJY9uGDe7Ws/dGZeBQR2pXdXmzQiakjrxBvWo0QrmsX3HK+VH+SZOltz378cmgmCS9f9rSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "runed": "^0.23.2", - "svelte-toolbelt": "^0.7.1" - }, - "engines": { - "node": ">=18", - "pnpm": ">=8.7.0" - }, - "peerDependencies": { - "svelte": "^5.0.0" - } - }, - "node_modules/vaul-svelte/node_modules/runed": { - "version": "0.23.4", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.23.4.tgz", - "integrity": "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, - "node_modules/vaul-svelte/node_modules/svelte-toolbelt": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.7.1.tgz", - "integrity": "sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ==", - "dev": true, - "funding": [ - "https://github.com/sponsors/huntabyte" - ], - "dependencies": { - "clsx": "^2.1.1", - "runed": "^0.23.2", - "style-to-object": "^1.0.8" - }, - "engines": { - "node": ">=18", - "pnpm": ">=8.7.0" - }, - "peerDependencies": { - "svelte": "^5.0.0" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz", - "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==", - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vitefu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", - "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", - "license": "MIT", - "workspaces": [ - "tests/deps/*", - "tests/projects/*", - "tests/projects/workspace/packages/*" - ], - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } - } - }, - "node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/webidl-conversions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.0.tgz", - "integrity": "sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=20" - } - }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-url": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", - "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "^6.0.0", - "webidl-conversions": "^8.0.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, - "license": "MIT" - }, - "node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/yeezy-dates": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/yeezy-dates/-/yeezy-dates-1.0.1.tgz", - "integrity": "sha512-AIHSzAm3QdX15U4qd1tvLQKBeW51UAkhmKtbemzilCFKDdxQV9eNIvc8/tAJKNUdIh/Xhhpu0GDsV+zBGsDhng==", - "dev": true, - "license": "MIT", - "dependencies": { - "chrono-node": "^2.7.7" - } - }, - "node_modules/yup": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz", - "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "property-expr": "^2.0.5", - "tiny-case": "^1.0.3", - "toposort": "^2.0.2", - "type-fest": "^2.19.0" - } - }, - "node_modules/zimmerframe": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", - "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", - "license": "MIT" - }, - "node_modules/zod": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", - "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/frontend/package.json b/frontend/package.json deleted file mode 100644 index a5633a0..0000000 --- a/frontend/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "frontend", - "private": true, - "version": "0.5.1", - "type": "module", - "scripts": { - "dev": "vite dev", - "build": "vite build", - "preview": "vite preview", - "prepare": "svelte-kit sync || echo ''", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "format": "prettier --write .", - "format:check": "prettier --check ." - }, - "devDependencies": { - "@iconify/svelte": "^5.1.0", - "@internationalized/date": "^3.10.0", - "@lucide/svelte": "^0.561.0", - "@sveltejs/adapter-node": "^5.3.2", - "@sveltejs/kit": "2.47.2", - "@sveltejs/vite-plugin-svelte": "6.2.1", - "prettier": "^3.4.2", - "prettier-plugin-svelte": "^3.3.2", - "@tanstack/table-core": "^8.21.3", - "@types/d3-scale": "^4.0.9", - "@types/d3-shape": "^3.1.7", - "@types/jsonwebtoken": "^9.0.10", - "bits-ui": "^2.14.4", - "layerchart": "^2.0.0-next.27", - "positron-components": "1.7.0", - "svelte": "5.41.0", - "svelte-check": "4.3.3", - "tailwind-merge": "^3.3.1", - "tailwind-variants": "^3.2.2", - "tslib": "2.8.1", - "typescript": "5.9.3", - "vite": "7.1.11", - "zod": "4.1.12" - }, - "dependencies": { - "@icons-pack/svelte-simple-icons": "^6.5.0", - "@tailwindcss/typography": "0.5.19", - "@tailwindcss/vite": "^4.1.13", - "jsonwebtoken": "^9.0.2", - "node-forge": "^1.3.1", - "tailwindcss": "^4.1.13", - "tw-animate-css": "^1.3.8" - }, - "optionalDependencies": { - "@esbuild/linux-arm64": "^0.25.10", - "@rollup/rollup-darwin-arm64": "^4.50.2", - "@rollup/rollup-darwin-x64": "^4.50.2", - "@rollup/rollup-linux-arm64-gnu": "^4.50.2", - "@rollup/rollup-linux-arm64-musl": "^4.50.2", - "@rollup/rollup-linux-x64-gnu": "^4.50.2", - "@rollup/rollup-win32-x64-msvc": "^4.50.2", - "lightningcss-darwin-arm64": "^1.30.1", - "lightningcss-darwin-x64": "^1.30.1", - "lightningcss-linux-arm64-gnu": "^1.30.1", - "lightningcss-linux-arm64-musl": "^1.30.1", - "lightningcss-linux-x64-gnu": "^1.30.1", - "lightningcss-win32-x64-msvc": "^1.30.1" - } -} diff --git a/frontend/src/app.css b/frontend/src/app.css deleted file mode 100644 index 85a1304..0000000 --- a/frontend/src/app.css +++ /dev/null @@ -1,132 +0,0 @@ -@import 'tailwindcss'; - -@import 'tw-animate-css'; - -@custom-variant dark (&:is(.dark *)); - -:root { - --radius: 0.65rem; - --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); - --radius: 0.625rem; - --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); -} - -.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(46.76% 0.00005 271.152); - --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); -} - -@theme inline { - --radius-sm: calc(var(--radius) - 4px); - --radius-md: calc(var(--radius) - 2px); - --radius-lg: var(--radius); - --radius-xl: calc(var(--radius) + 4px); - --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); -} - -@layer base { - * { - @apply border-border outline-ring/50; - } - body { - @apply bg-background text-foreground; - } -} - -@layer utilities { - .scrollbar-hide { - -ms-overflow-style: none; - scrollbar-width: none; - } - .scrollbar-hide::-webkit-scrollbar { - display: none; - } -} diff --git a/frontend/src/app.d.ts b/frontend/src/app.d.ts deleted file mode 100644 index 520c421..0000000 --- a/frontend/src/app.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -// See https://svelte.dev/docs/kit/types#app.d.ts -// for information about these interfaces -declare global { - namespace App { - // interface Error {} - // interface Locals {} - // interface PageData {} - // interface PageState {} - // interface Platform {} - } -} - -export {}; diff --git a/frontend/src/app.html b/frontend/src/app.html deleted file mode 100644 index 37e69c5..0000000 --- a/frontend/src/app.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - %sveltekit.head% - - -

    %sveltekit.body%
    - - diff --git a/frontend/src/lib/components/DeployDockerContainerDialog.svelte b/frontend/src/lib/components/DeployDockerContainerDialog.svelte deleted file mode 100644 index 700bdfe..0000000 --- a/frontend/src/lib/components/DeployDockerContainerDialog.svelte +++ /dev/null @@ -1,341 +0,0 @@ - - - - - - - - Docker Container bereitstellen - - - Konfiguriere und starte einen Docker Container auf der Host-Maschine - - - - {#if error} -
    - {error} -
    - {/if} - -
    - -
    - - -
    - - -
    - - -

    - Das Image wird automatisch gepullt, falls nicht vorhanden -

    -
    - - -
    - - -
    - - -
    - - - {:else} -

    - {organization.description || 'No description set'} -

    - {/if} -
    - - {#if !editMode} -
    -
    - -

    - {new Date(organization.created_at).toLocaleString()} -

    -
    -
    - -

    - {new Date(organization.updated_at).toLocaleString()} -

    -
    -
    - {/if} - - {#if editMode} -
    - - -
    - {/if} -
    - {/if} - diff --git a/frontend/src/lib/components/settings/UpdateSettings.svelte b/frontend/src/lib/components/settings/UpdateSettings.svelte deleted file mode 100644 index d0cc25e..0000000 --- a/frontend/src/lib/components/settings/UpdateSettings.svelte +++ /dev/null @@ -1,311 +0,0 @@ - - -
    - - - Software-Updates - Überprüfen und installieren Sie CSFX-Core Updates - - - -
    -
    -

    Aktuelle Version

    -
    - {#if $updateStore.versionInfo} - v{$updateStore.versionInfo.current_version} - {:else} - - {/if} -
    -
    - -
    - - - {#if message} - - {message} - - {/if} - - - {#if $updateStore.loading} -
    - - -
    - {:else if $updateStore.error} - - {$updateStore.error} - - {:else if $updateStore.versionInfo} - {#if $updateStore.versionInfo.update_available} - - - -
    -
    -

    Neue Version verfügbar!

    -

    - Version v{$updateStore.versionInfo.latest_version} ist jetzt verfügbar. -

    -
    - -
    -
    -
    - - - {#if $updateStore.versionInfo.changelog} - - - Was ist neu? - - -
    - {@html parseChangelog($updateStore.versionInfo.changelog)} -
    -
    - - - -
    - {/if} - {:else} - - - -

    Sie verwenden die neueste Version!

    -

    - CSF-Core ist auf dem neuesten Stand (v{$updateStore.versionInfo.current_version}). -

    -
    -
    - {/if} - - - {#if $updateStore.lastChecked} -

    - Zuletzt geprüft: {new Intl.DateTimeFormat('de-DE', { - dateStyle: 'short', - timeStyle: 'short', - }).format($updateStore.lastChecked)} -

    - {/if} - {/if} - - -
    -
    -
    - -

    - Erhalte Zugang zu experimentellen Beta-Versionen -

    -
    - -
    - - {#if showBetaWarning} - - - -
    -
    -

    ⚠️ Warnung: Beta-Versionen sind experimentell!

    -
      -
    • Beta-Versionen können instabil sein und Fehler enthalten
    • -
    • Funktionen können sich ohne Vorankündigung ändern
    • -
    • Nicht für Produktionsumgebungen empfohlen
    • -
    • Datenverlust kann nicht ausgeschlossen werden
    • -
    -
    -
    - - -
    -
    -
    -
    - {/if} - - {#if enableBetaUpdates && $updateStore.versionInfo?.latest_beta_version} - - - -
    -
    -

    🧪 Beta-Version verfügbar!

    -

    - Version - v{$updateStore.versionInfo.latest_beta_version} - ist zum Testen verfügbar. -

    -
    - -
    -
    -
    - {/if} -
    - - -
    -

    Automatische Update-Prüfung

    -

    - CSFX-Core prüft automatisch stündlich auf neue Updates. Updates werden nur angezeigt, wenn - sie verfügbar sind. -

    - - - - Hinweis: Bei der Installation eines Updates wird die Anwendung neu gestartet. - Stellen Sie sicher, dass alle Änderungen gespeichert sind. - - -
    -
    -
    -
    diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte deleted file mode 100644 index 708280d..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte deleted file mode 100644 index c4d823b..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte deleted file mode 100644 index aa74dae..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte deleted file mode 100644 index 349cc6e..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte deleted file mode 100644 index caea1b5..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte deleted file mode 100644 index 0eef21f..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte deleted file mode 100644 index 87192c8..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte deleted file mode 100644 index fad8f9e..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-portal.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte deleted file mode 100644 index 75f823c..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte deleted file mode 100644 index 5566a69..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog-trigger.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/alert-dialog/alert-dialog.svelte b/frontend/src/lib/components/ui/alert-dialog/alert-dialog.svelte deleted file mode 100644 index 94f27e4..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/alert-dialog.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/alert-dialog/index.ts b/frontend/src/lib/components/ui/alert-dialog/index.ts deleted file mode 100644 index 3587826..0000000 --- a/frontend/src/lib/components/ui/alert-dialog/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import Root from './alert-dialog.svelte'; -import Portal from './alert-dialog-portal.svelte'; -import Trigger from './alert-dialog-trigger.svelte'; -import Title from './alert-dialog-title.svelte'; -import Action from './alert-dialog-action.svelte'; -import Cancel from './alert-dialog-cancel.svelte'; -import Footer from './alert-dialog-footer.svelte'; -import Header from './alert-dialog-header.svelte'; -import Overlay from './alert-dialog-overlay.svelte'; -import Content from './alert-dialog-content.svelte'; -import Description from './alert-dialog-description.svelte'; - -export { - Root, - Title, - Action, - Cancel, - Portal, - Footer, - Header, - Trigger, - Overlay, - Content, - Description, - // - Root as AlertDialog, - Title as AlertDialogTitle, - Action as AlertDialogAction, - Cancel as AlertDialogCancel, - Portal as AlertDialogPortal, - Footer as AlertDialogFooter, - Header as AlertDialogHeader, - Trigger as AlertDialogTrigger, - Overlay as AlertDialogOverlay, - Content as AlertDialogContent, - Description as AlertDialogDescription, -}; diff --git a/frontend/src/lib/components/ui/alert/alert-description.svelte b/frontend/src/lib/components/ui/alert/alert-description.svelte deleted file mode 100644 index 1f9894a..0000000 --- a/frontend/src/lib/components/ui/alert/alert-description.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/alert/alert-title.svelte b/frontend/src/lib/components/ui/alert/alert-title.svelte deleted file mode 100644 index 471b789..0000000 --- a/frontend/src/lib/components/ui/alert/alert-title.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/alert/alert.svelte b/frontend/src/lib/components/ui/alert/alert.svelte deleted file mode 100644 index 8b8db64..0000000 --- a/frontend/src/lib/components/ui/alert/alert.svelte +++ /dev/null @@ -1,44 +0,0 @@ - - - - - diff --git a/frontend/src/lib/components/ui/alert/index.ts b/frontend/src/lib/components/ui/alert/index.ts deleted file mode 100644 index 75dd808..0000000 --- a/frontend/src/lib/components/ui/alert/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Root from './alert.svelte'; -import Description from './alert-description.svelte'; -import Title from './alert-title.svelte'; -export { alertVariants, type AlertVariant } from './alert.svelte'; - -export { - Root, - Description, - Title, - // - Root as Alert, - Description as AlertDescription, - Title as AlertTitle, -}; diff --git a/frontend/src/lib/components/ui/avatar/avatar-fallback.svelte b/frontend/src/lib/components/ui/avatar/avatar-fallback.svelte deleted file mode 100644 index 7b9da62..0000000 --- a/frontend/src/lib/components/ui/avatar/avatar-fallback.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/avatar/avatar-image.svelte b/frontend/src/lib/components/ui/avatar/avatar-image.svelte deleted file mode 100644 index 904284a..0000000 --- a/frontend/src/lib/components/ui/avatar/avatar-image.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/avatar/avatar.svelte b/frontend/src/lib/components/ui/avatar/avatar.svelte deleted file mode 100644 index b514f1a..0000000 --- a/frontend/src/lib/components/ui/avatar/avatar.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/avatar/index.ts b/frontend/src/lib/components/ui/avatar/index.ts deleted file mode 100644 index 591ea32..0000000 --- a/frontend/src/lib/components/ui/avatar/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Root from './avatar.svelte'; -import Image from './avatar-image.svelte'; -import Fallback from './avatar-fallback.svelte'; - -export { - Root, - Image, - Fallback, - // - Root as Avatar, - Image as AvatarImage, - Fallback as AvatarFallback, -}; diff --git a/frontend/src/lib/components/ui/badge/badge.svelte b/frontend/src/lib/components/ui/badge/badge.svelte deleted file mode 100644 index cca951a..0000000 --- a/frontend/src/lib/components/ui/badge/badge.svelte +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/badge/index.ts b/frontend/src/lib/components/ui/badge/index.ts deleted file mode 100644 index f05fb87..0000000 --- a/frontend/src/lib/components/ui/badge/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as Badge } from './badge.svelte'; -export { badgeVariants, type BadgeVariant } from './badge.svelte'; diff --git a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte b/frontend/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte deleted file mode 100644 index 3068a2e..0000000 --- a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte b/frontend/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte deleted file mode 100644 index 40ab5b2..0000000 --- a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
  • - {@render children?.()} -
  • diff --git a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte b/frontend/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte deleted file mode 100644 index 68cc789..0000000 --- a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte +++ /dev/null @@ -1,31 +0,0 @@ - - -{#if child} - {@render child({ props: attrs })} -{:else} - - {@render children?.()} - -{/if} diff --git a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte b/frontend/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte deleted file mode 100644 index e066e3f..0000000 --- a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -
      - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte b/frontend/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte deleted file mode 100644 index a36d2a0..0000000 --- a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte b/frontend/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte deleted file mode 100644 index ca26dc2..0000000 --- a/frontend/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte +++ /dev/null @@ -1,27 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/breadcrumb/breadcrumb.svelte b/frontend/src/lib/components/ui/breadcrumb/breadcrumb.svelte deleted file mode 100644 index 0bb301a..0000000 --- a/frontend/src/lib/components/ui/breadcrumb/breadcrumb.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/breadcrumb/index.ts b/frontend/src/lib/components/ui/breadcrumb/index.ts deleted file mode 100644 index e88527b..0000000 --- a/frontend/src/lib/components/ui/breadcrumb/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import Root from './breadcrumb.svelte'; -import Ellipsis from './breadcrumb-ellipsis.svelte'; -import Item from './breadcrumb-item.svelte'; -import Separator from './breadcrumb-separator.svelte'; -import Link from './breadcrumb-link.svelte'; -import List from './breadcrumb-list.svelte'; -import Page from './breadcrumb-page.svelte'; - -export { - Root, - Ellipsis, - Item, - Separator, - Link, - List, - Page, - // - Root as Breadcrumb, - Ellipsis as BreadcrumbEllipsis, - Item as BreadcrumbItem, - Separator as BreadcrumbSeparator, - Link as BreadcrumbLink, - List as BreadcrumbList, - Page as BreadcrumbPage, -}; diff --git a/frontend/src/lib/components/ui/button/button.svelte b/frontend/src/lib/components/ui/button/button.svelte deleted file mode 100644 index 2f49ae9..0000000 --- a/frontend/src/lib/components/ui/button/button.svelte +++ /dev/null @@ -1,82 +0,0 @@ - - - - -{#if href} - - {@render children?.()} - -{:else} - -{/if} diff --git a/frontend/src/lib/components/ui/button/index.ts b/frontend/src/lib/components/ui/button/index.ts deleted file mode 100644 index 66c1087..0000000 --- a/frontend/src/lib/components/ui/button/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import Root, { - type ButtonProps, - type ButtonSize, - type ButtonVariant, - buttonVariants, -} from './button.svelte'; - -export { - Root, - type ButtonProps as Props, - // - Root as Button, - buttonVariants, - type ButtonProps, - type ButtonSize, - type ButtonVariant, -}; diff --git a/frontend/src/lib/components/ui/calendar/calendar-caption.svelte b/frontend/src/lib/components/ui/calendar/calendar-caption.svelte deleted file mode 100644 index fc83485..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-caption.svelte +++ /dev/null @@ -1,76 +0,0 @@ - - -{#snippet MonthSelect()} - { - if (!placeholder) return; - const v = Number.parseInt(e.currentTarget.value); - const newPlaceholder = placeholder.set({ month: v }); - placeholder = newPlaceholder.subtract({ months: monthIndex }); - }} - /> -{/snippet} - -{#snippet YearSelect()} - -{/snippet} - -{#if captionLayout === 'dropdown'} - {@render MonthSelect()} - {@render YearSelect()} -{:else if captionLayout === 'dropdown-months'} - {@render MonthSelect()} - {#if placeholder} - {formatYear(placeholder)} - {/if} -{:else if captionLayout === 'dropdown-years'} - {#if placeholder} - {formatMonth(placeholder)} - {/if} - {@render YearSelect()} -{:else} - {formatMonth(month)} {formatYear(month)} -{/if} diff --git a/frontend/src/lib/components/ui/calendar/calendar-cell.svelte b/frontend/src/lib/components/ui/calendar/calendar-cell.svelte deleted file mode 100644 index 2389c4e..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-cell.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-day.svelte b/frontend/src/lib/components/ui/calendar/calendar-day.svelte deleted file mode 100644 index edba819..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-day.svelte +++ /dev/null @@ -1,35 +0,0 @@ - - -span]:text-xs [&>span]:opacity-70', - className - )} - {...restProps} -/> diff --git a/frontend/src/lib/components/ui/calendar/calendar-grid-body.svelte b/frontend/src/lib/components/ui/calendar/calendar-grid-body.svelte deleted file mode 100644 index 49a7fe8..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-grid-body.svelte +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-grid-head.svelte b/frontend/src/lib/components/ui/calendar/calendar-grid-head.svelte deleted file mode 100644 index 6188310..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-grid-head.svelte +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-grid-row.svelte b/frontend/src/lib/components/ui/calendar/calendar-grid-row.svelte deleted file mode 100644 index da1225f..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-grid-row.svelte +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-grid.svelte b/frontend/src/lib/components/ui/calendar/calendar-grid.svelte deleted file mode 100644 index de89342..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-grid.svelte +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-head-cell.svelte b/frontend/src/lib/components/ui/calendar/calendar-head-cell.svelte deleted file mode 100644 index 49a0927..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-head-cell.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-header.svelte b/frontend/src/lib/components/ui/calendar/calendar-header.svelte deleted file mode 100644 index 7444b23..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-header.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-heading.svelte b/frontend/src/lib/components/ui/calendar/calendar-heading.svelte deleted file mode 100644 index 7634470..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-heading.svelte +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-month-select.svelte b/frontend/src/lib/components/ui/calendar/calendar-month-select.svelte deleted file mode 100644 index 8d49a4d..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-month-select.svelte +++ /dev/null @@ -1,44 +0,0 @@ - - - - - {#snippet child({ props, monthItems, selectedMonthItem })} - - - {/snippet} - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-month.svelte b/frontend/src/lib/components/ui/calendar/calendar-month.svelte deleted file mode 100644 index 4ab4c5a..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-month.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/calendar/calendar-months.svelte b/frontend/src/lib/components/ui/calendar/calendar-months.svelte deleted file mode 100644 index 1f52472..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-months.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/calendar/calendar-nav.svelte b/frontend/src/lib/components/ui/calendar/calendar-nav.svelte deleted file mode 100644 index 7e7ffc5..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-nav.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-next-button.svelte b/frontend/src/lib/components/ui/calendar/calendar-next-button.svelte deleted file mode 100644 index 5224d4c..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-next-button.svelte +++ /dev/null @@ -1,31 +0,0 @@ - - -{#snippet Fallback()} - -{/snippet} - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-prev-button.svelte b/frontend/src/lib/components/ui/calendar/calendar-prev-button.svelte deleted file mode 100644 index a976c66..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-prev-button.svelte +++ /dev/null @@ -1,31 +0,0 @@ - - -{#snippet Fallback()} - -{/snippet} - - diff --git a/frontend/src/lib/components/ui/calendar/calendar-year-select.svelte b/frontend/src/lib/components/ui/calendar/calendar-year-select.svelte deleted file mode 100644 index 51bf990..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar-year-select.svelte +++ /dev/null @@ -1,43 +0,0 @@ - - - - - {#snippet child({ props, yearItems, selectedYearItem })} - - - {/snippet} - - diff --git a/frontend/src/lib/components/ui/calendar/calendar.svelte b/frontend/src/lib/components/ui/calendar/calendar.svelte deleted file mode 100644 index 5803335..0000000 --- a/frontend/src/lib/components/ui/calendar/calendar.svelte +++ /dev/null @@ -1,115 +0,0 @@ - - - - - {#snippet children({ months, weekdays })} - - - - - - {#each months as month, monthIndex (month)} - - - - - - - - {#each weekdays as weekday (weekday)} - - {weekday.slice(0, 2)} - - {/each} - - - - {#each month.weeks as weekDates (weekDates)} - - {#each weekDates as date (date)} - - {#if day} - {@render day({ - day: date, - outsideMonth: !isEqualMonth(date, month.value), - })} - {:else} - - {/if} - - {/each} - - {/each} - - - - {/each} - - {/snippet} - diff --git a/frontend/src/lib/components/ui/calendar/index.ts b/frontend/src/lib/components/ui/calendar/index.ts deleted file mode 100644 index 8ca76e6..0000000 --- a/frontend/src/lib/components/ui/calendar/index.ts +++ /dev/null @@ -1,40 +0,0 @@ -import Root from './calendar.svelte'; -import Cell from './calendar-cell.svelte'; -import Day from './calendar-day.svelte'; -import Grid from './calendar-grid.svelte'; -import Header from './calendar-header.svelte'; -import Months from './calendar-months.svelte'; -import GridRow from './calendar-grid-row.svelte'; -import Heading from './calendar-heading.svelte'; -import GridBody from './calendar-grid-body.svelte'; -import GridHead from './calendar-grid-head.svelte'; -import HeadCell from './calendar-head-cell.svelte'; -import NextButton from './calendar-next-button.svelte'; -import PrevButton from './calendar-prev-button.svelte'; -import MonthSelect from './calendar-month-select.svelte'; -import YearSelect from './calendar-year-select.svelte'; -import Month from './calendar-month.svelte'; -import Nav from './calendar-nav.svelte'; -import Caption from './calendar-caption.svelte'; - -export { - Day, - Cell, - Grid, - Header, - Months, - GridRow, - Heading, - GridBody, - GridHead, - HeadCell, - NextButton, - PrevButton, - Nav, - Month, - YearSelect, - MonthSelect, - Caption, - // - Root as Calendar, -}; diff --git a/frontend/src/lib/components/ui/card/card-action.svelte b/frontend/src/lib/components/ui/card/card-action.svelte deleted file mode 100644 index bdfb182..0000000 --- a/frontend/src/lib/components/ui/card/card-action.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/card/card-content.svelte b/frontend/src/lib/components/ui/card/card-content.svelte deleted file mode 100644 index 6ccd561..0000000 --- a/frontend/src/lib/components/ui/card/card-content.svelte +++ /dev/null @@ -1,15 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/card/card-description.svelte b/frontend/src/lib/components/ui/card/card-description.svelte deleted file mode 100644 index 7d99522..0000000 --- a/frontend/src/lib/components/ui/card/card-description.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -

    - {@render children?.()} -

    diff --git a/frontend/src/lib/components/ui/card/card-footer.svelte b/frontend/src/lib/components/ui/card/card-footer.svelte deleted file mode 100644 index d4310e5..0000000 --- a/frontend/src/lib/components/ui/card/card-footer.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/card/card-header.svelte b/frontend/src/lib/components/ui/card/card-header.svelte deleted file mode 100644 index 6dcf5ad..0000000 --- a/frontend/src/lib/components/ui/card/card-header.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/card/card-title.svelte b/frontend/src/lib/components/ui/card/card-title.svelte deleted file mode 100644 index 566f77c..0000000 --- a/frontend/src/lib/components/ui/card/card-title.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/card/card.svelte b/frontend/src/lib/components/ui/card/card.svelte deleted file mode 100644 index 484d576..0000000 --- a/frontend/src/lib/components/ui/card/card.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/card/index.ts b/frontend/src/lib/components/ui/card/index.ts deleted file mode 100644 index 162628a..0000000 --- a/frontend/src/lib/components/ui/card/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import Root from './card.svelte'; -import Content from './card-content.svelte'; -import Description from './card-description.svelte'; -import Footer from './card-footer.svelte'; -import Header from './card-header.svelte'; -import Title from './card-title.svelte'; -import Action from './card-action.svelte'; - -export { - Root, - Content, - Description, - Footer, - Header, - Title, - Action, - // - Root as Card, - Content as CardContent, - Description as CardDescription, - Footer as CardFooter, - Header as CardHeader, - Title as CardTitle, - Action as CardAction, -}; diff --git a/frontend/src/lib/components/ui/chart/chart-container.svelte b/frontend/src/lib/components/ui/chart/chart-container.svelte deleted file mode 100644 index e581160..0000000 --- a/frontend/src/lib/components/ui/chart/chart-container.svelte +++ /dev/null @@ -1,80 +0,0 @@ - - -
    - - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/chart/chart-style.svelte b/frontend/src/lib/components/ui/chart/chart-style.svelte deleted file mode 100644 index 41e6ecb..0000000 --- a/frontend/src/lib/components/ui/chart/chart-style.svelte +++ /dev/null @@ -1,37 +0,0 @@ - - -{#if themeContents} - {#key id} - - {themeContents} - - {/key} -{/if} diff --git a/frontend/src/lib/components/ui/chart/chart-tooltip.svelte b/frontend/src/lib/components/ui/chart/chart-tooltip.svelte deleted file mode 100644 index f62c73e..0000000 --- a/frontend/src/lib/components/ui/chart/chart-tooltip.svelte +++ /dev/null @@ -1,155 +0,0 @@ - - -{#snippet TooltipLabel()} - {#if formattedLabel} -
    - {#if typeof formattedLabel === 'function'} - {@render formattedLabel()} - {:else} - {formattedLabel} - {/if} -
    - {/if} -{/snippet} - - -
    - {#if !nestLabel} - {@render TooltipLabel()} - {/if} -
    - {#each tooltipCtx.payload as item, i (item.key + i)} - {@const key = `${nameKey || item.key || item.name || 'value'}`} - {@const itemConfig = getPayloadConfigFromPayload(chart.config, item, key)} - {@const indicatorColor = color || item.payload?.color || item.color} -
    svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:size-2.5', - indicator === 'dot' && 'items-center' - )} - > - {#if formatter && item.value !== undefined && item.name} - {@render formatter({ - value: item.value, - name: item.name, - item, - index: i, - payload: tooltipCtx.payload, - })} - {:else} - {#if itemConfig?.icon} - - {:else if !hideIndicator} -
    - {/if} -
    -
    - {#if nestLabel} - {@render TooltipLabel()} - {/if} - - {itemConfig?.label || item.name} - -
    - {#if item.value !== undefined} - - {item.value.toLocaleString()} - - {/if} -
    - {/if} -
    - {/each} -
    -
    -
    diff --git a/frontend/src/lib/components/ui/chart/chart-utils.ts b/frontend/src/lib/components/ui/chart/chart-utils.ts deleted file mode 100644 index bfeede6..0000000 --- a/frontend/src/lib/components/ui/chart/chart-utils.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type { Tooltip } from 'layerchart'; -import { getContext, setContext, type Component, type ComponentProps, type Snippet } from 'svelte'; - -export const THEMES = { light: '', dark: '.dark' } as const; - -export type ChartConfig = { - [k in string]: { - label?: string; - icon?: Component; - } & ( - | { color?: string; theme?: never } - | { color?: never; theme: Record } - ); -}; - -export type ExtractSnippetParams = T extends Snippet<[infer P]> ? P : never; - -export type TooltipPayload = ExtractSnippetParams< - ComponentProps['children'] ->['payload'][number]; - -// Helper to extract item config from a payload. -export function getPayloadConfigFromPayload( - config: ChartConfig, - payload: TooltipPayload, - key: string -) { - if (typeof payload !== 'object' || payload === null) return undefined; - - const payloadPayload = - 'payload' in payload && typeof payload.payload === 'object' && payload.payload !== null - ? payload.payload - : undefined; - - let configLabelKey: string = key; - - if (payload.key === key) { - configLabelKey = payload.key; - } else if (payload.name === key) { - configLabelKey = payload.name; - } else if (key in payload && typeof payload[key as keyof typeof payload] === 'string') { - configLabelKey = payload[key as keyof typeof payload] as string; - } else if ( - payloadPayload !== undefined && - key in payloadPayload && - typeof payloadPayload[key as keyof typeof payloadPayload] === 'string' - ) { - configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string; - } - - return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config]; -} - -type ChartContextValue = { - config: ChartConfig; -}; - -const chartContextKey = Symbol('chart-context'); - -export function setChartContext(value: ChartContextValue) { - return setContext(chartContextKey, value); -} - -export function useChart() { - return getContext(chartContextKey); -} diff --git a/frontend/src/lib/components/ui/chart/index.ts b/frontend/src/lib/components/ui/chart/index.ts deleted file mode 100644 index 25cfcd4..0000000 --- a/frontend/src/lib/components/ui/chart/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import ChartContainer from './chart-container.svelte'; -import ChartTooltip from './chart-tooltip.svelte'; - -export { getPayloadConfigFromPayload, type ChartConfig } from './chart-utils.js'; - -export { ChartContainer, ChartTooltip, ChartContainer as Container, ChartTooltip as Tooltip }; diff --git a/frontend/src/lib/components/ui/checkbox/checkbox.svelte b/frontend/src/lib/components/ui/checkbox/checkbox.svelte deleted file mode 100644 index 68c4e62..0000000 --- a/frontend/src/lib/components/ui/checkbox/checkbox.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - - - {#snippet children({ checked, indeterminate })} -
    - {#if checked} - - {:else if indeterminate} - - {/if} -
    - {/snippet} -
    diff --git a/frontend/src/lib/components/ui/checkbox/index.ts b/frontend/src/lib/components/ui/checkbox/index.ts deleted file mode 100644 index ba3b7d7..0000000 --- a/frontend/src/lib/components/ui/checkbox/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import Root from './checkbox.svelte'; -export { - Root, - // - Root as Checkbox, -}; diff --git a/frontend/src/lib/components/ui/collapsible/collapsible-content.svelte b/frontend/src/lib/components/ui/collapsible/collapsible-content.svelte deleted file mode 100644 index 6588d5c..0000000 --- a/frontend/src/lib/components/ui/collapsible/collapsible-content.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/collapsible/collapsible-trigger.svelte b/frontend/src/lib/components/ui/collapsible/collapsible-trigger.svelte deleted file mode 100644 index a24a44e..0000000 --- a/frontend/src/lib/components/ui/collapsible/collapsible-trigger.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/collapsible/collapsible.svelte b/frontend/src/lib/components/ui/collapsible/collapsible.svelte deleted file mode 100644 index 81bf979..0000000 --- a/frontend/src/lib/components/ui/collapsible/collapsible.svelte +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/collapsible/index.ts b/frontend/src/lib/components/ui/collapsible/index.ts deleted file mode 100644 index 7733493..0000000 --- a/frontend/src/lib/components/ui/collapsible/index.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Root from './collapsible.svelte'; -import Trigger from './collapsible-trigger.svelte'; -import Content from './collapsible-content.svelte'; - -export { - Root, - Content, - Trigger, - // - Root as Collapsible, - Content as CollapsibleContent, - Trigger as CollapsibleTrigger, -}; diff --git a/frontend/src/lib/components/ui/data-table/data-table.svelte.ts b/frontend/src/lib/components/ui/data-table/data-table.svelte.ts deleted file mode 100644 index fb29895..0000000 --- a/frontend/src/lib/components/ui/data-table/data-table.svelte.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { - type RowData, - type TableOptions, - type TableOptionsResolved, - type TableState, - createTable, -} from '@tanstack/table-core'; - -/** - * Creates a reactive TanStack table object for Svelte. - * @param options Table options to create the table with. - * @returns A reactive table object. - * @example - * ```svelte - * - * - * - * - * {#each table.getHeaderGroups() as headerGroup} - * - * {#each headerGroup.headers as header} - * - * {/each} - * - * {/each} - * - * - *
    - * - *
    - * ``` - */ -export function createSvelteTable(options: TableOptions) { - const resolvedOptions: TableOptionsResolved = mergeObjects( - { - state: {}, - onStateChange() {}, - renderFallbackValue: null, - mergeOptions: ( - defaultOptions: TableOptions, - options: Partial> - ) => { - return mergeObjects(defaultOptions, options); - }, - }, - options - ); - - const table = createTable(resolvedOptions); - let state = $state>(table.initialState); - - function updateOptions() { - table.setOptions((prev) => { - return mergeObjects(prev, options, { - state: mergeObjects(state, options.state || {}), - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - onStateChange: (updater: any) => { - if (updater instanceof Function) state = updater(state); - else state = mergeObjects(state, updater); - - options.onStateChange?.(updater); - }, - }); - }); - } - - updateOptions(); - - $effect.pre(() => { - updateOptions(); - }); - - return table; -} - -type MaybeThunk = T | (() => T | null | undefined); -type Intersection = (T extends [infer H, ...infer R] - ? H & Intersection - : unknown) & {}; - -/** - * Lazily merges several objects (or thunks) while preserving - * getter semantics from every source. - * - * Proxy-based to avoid known WebKit recursion issue. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function mergeObjects[]>( - ...sources: Sources -): Intersection<{ [K in keyof Sources]: Sources[K] }> { - const resolve = (src: MaybeThunk): T | undefined => - typeof src === 'function' ? (src() ?? undefined) : src; - - const findSourceWithKey = (key: PropertyKey) => { - for (let i = sources.length - 1; i >= 0; i--) { - const obj = resolve(sources[i]); - if (obj && key in obj) return obj; - } - return undefined; - }; - - return new Proxy(Object.create(null), { - get(_, key) { - const src = findSourceWithKey(key); - - return src?.[key as never]; - }, - - has(_, key) { - return !!findSourceWithKey(key); - }, - - ownKeys(): (string | symbol)[] { - // eslint-disable-next-line svelte/prefer-svelte-reactivity - const all = new Set(); - for (const s of sources) { - const obj = resolve(s); - if (obj) { - for (const k of Reflect.ownKeys(obj) as (string | symbol)[]) { - all.add(k); - } - } - } - return [...all]; - }, - - getOwnPropertyDescriptor(_, key) { - const src = findSourceWithKey(key); - if (!src) return undefined; - return { - configurable: true, - enumerable: true, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - value: (src as any)[key], - writable: true, - }; - }, - }) as Intersection<{ [K in keyof Sources]: Sources[K] }>; -} diff --git a/frontend/src/lib/components/ui/data-table/flex-render.svelte b/frontend/src/lib/components/ui/data-table/flex-render.svelte deleted file mode 100644 index 37e5bd0..0000000 --- a/frontend/src/lib/components/ui/data-table/flex-render.svelte +++ /dev/null @@ -1,40 +0,0 @@ - - -{#if typeof content === 'string'} - {content} -{:else if content instanceof Function} - - - {@const result = content(context as any)} - {#if result instanceof RenderComponentConfig} - {@const { component: Component, props } = result} - - {:else if result instanceof RenderSnippetConfig} - {@const { snippet, params } = result} - {@render snippet({ ...params, attach })} - {:else} - {result} - {/if} -{/if} diff --git a/frontend/src/lib/components/ui/data-table/index.ts b/frontend/src/lib/components/ui/data-table/index.ts deleted file mode 100644 index 05fb821..0000000 --- a/frontend/src/lib/components/ui/data-table/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as FlexRender } from './flex-render.svelte'; -export { renderComponent, renderSnippet } from './render-helpers.js'; -export { createSvelteTable } from './data-table.svelte.js'; diff --git a/frontend/src/lib/components/ui/data-table/render-helpers.ts b/frontend/src/lib/components/ui/data-table/render-helpers.ts deleted file mode 100644 index 0efdc01..0000000 --- a/frontend/src/lib/components/ui/data-table/render-helpers.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { Component, ComponentProps, Snippet } from 'svelte'; - -/** - * A helper class to make it easy to identify Svelte components in - * `columnDef.cell` and `columnDef.header` properties. - * - * > NOTE: This class should only be used internally by the adapter. If you're - * reading this and you don't know what this is for, you probably don't need it. - * - * @example - * ```svelte - * {@const result = content(context as any)} - * {#if result instanceof RenderComponentConfig} - * {@const { component: Component, props } = result} - * - * {/if} - * ``` - */ -export class RenderComponentConfig { - component: TComponent; - props: ComponentProps | Record; - constructor( - component: TComponent, - props: ComponentProps | Record = {} - ) { - this.component = component; - this.props = props; - } -} - -/** - * A helper class to make it easy to identify Svelte Snippets in `columnDef.cell` and `columnDef.header` properties. - * - * > NOTE: This class should only be used internally by the adapter. If you're - * reading this and you don't know what this is for, you probably don't need it. - * - * @example - * ```svelte - * {@const result = content(context as any)} - * {#if result instanceof RenderSnippetConfig} - * {@const { snippet, params } = result} - * {@render snippet(params)} - * {/if} - * ``` - */ -export class RenderSnippetConfig { - snippet: Snippet<[TProps]>; - params: TProps; - constructor(snippet: Snippet<[TProps]>, params: TProps) { - this.snippet = snippet; - this.params = params; - } -} - -/** - * A helper function to help create cells from Svelte components through ColumnDef's `cell` and `header` properties. - * - * This is only to be used with Svelte Components - use `renderSnippet` for Svelte Snippets. - * - * @param component A Svelte component - * @param props The props to pass to `component` - * @returns A `RenderComponentConfig` object that helps svelte-table know how to render the header/cell component. - * @example - * ```ts - * // +page.svelte - * const defaultColumns = [ - * columnHelper.accessor('name', { - * header: header => renderComponent(SortHeader, { label: 'Name', header }), - * }), - * columnHelper.accessor('state', { - * header: header => renderComponent(SortHeader, { label: 'State', header }), - * }), - * ] - * ``` - * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} - */ -export function renderComponent< - // eslint-disable-next-line @typescript-eslint/no-explicit-any - T extends Component, - Props extends ComponentProps, ->(component: T, props: Props = {} as Props) { - return new RenderComponentConfig(component, props); -} - -/** - * A helper function to help create cells from Svelte Snippets through ColumnDef's `cell` and `header` properties. - * - * The snippet must only take one parameter. - * - * This is only to be used with Snippets - use `renderComponent` for Svelte Components. - * - * @param snippet - * @param params - * @returns - A `RenderSnippetConfig` object that helps svelte-table know how to render the header/cell snippet. - * @example - * ```ts - * // +page.svelte - * const defaultColumns = [ - * columnHelper.accessor('name', { - * cell: cell => renderSnippet(nameSnippet, { name: cell.row.name }), - * }), - * columnHelper.accessor('state', { - * cell: cell => renderSnippet(stateSnippet, { state: cell.row.state }), - * }), - * ] - * ``` - * @see {@link https://tanstack.com/table/latest/docs/guide/column-defs} - */ -export function renderSnippet(snippet: Snippet<[TProps]>, params: TProps = {} as TProps) { - return new RenderSnippetConfig(snippet, params); -} diff --git a/frontend/src/lib/components/ui/dialog/dialog-close.svelte b/frontend/src/lib/components/ui/dialog/dialog-close.svelte deleted file mode 100644 index c471854..0000000 --- a/frontend/src/lib/components/ui/dialog/dialog-close.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dialog/dialog-content.svelte b/frontend/src/lib/components/ui/dialog/dialog-content.svelte deleted file mode 100644 index 5b0d2b5..0000000 --- a/frontend/src/lib/components/ui/dialog/dialog-content.svelte +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - {@render children?.()} - {#if showCloseButton} - - - Close - - {/if} - - diff --git a/frontend/src/lib/components/ui/dialog/dialog-description.svelte b/frontend/src/lib/components/ui/dialog/dialog-description.svelte deleted file mode 100644 index f963a7a..0000000 --- a/frontend/src/lib/components/ui/dialog/dialog-description.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dialog/dialog-footer.svelte b/frontend/src/lib/components/ui/dialog/dialog-footer.svelte deleted file mode 100644 index 0feb74b..0000000 --- a/frontend/src/lib/components/ui/dialog/dialog-footer.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/dialog/dialog-header.svelte b/frontend/src/lib/components/ui/dialog/dialog-header.svelte deleted file mode 100644 index d52f14a..0000000 --- a/frontend/src/lib/components/ui/dialog/dialog-header.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte b/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte deleted file mode 100644 index 08b6636..0000000 --- a/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dialog/dialog-title.svelte b/frontend/src/lib/components/ui/dialog/dialog-title.svelte deleted file mode 100644 index 8d7bf80..0000000 --- a/frontend/src/lib/components/ui/dialog/dialog-title.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dialog/dialog-trigger.svelte b/frontend/src/lib/components/ui/dialog/dialog-trigger.svelte deleted file mode 100644 index a2e7178..0000000 --- a/frontend/src/lib/components/ui/dialog/dialog-trigger.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dialog/index.ts b/frontend/src/lib/components/ui/dialog/index.ts deleted file mode 100644 index b1e6a32..0000000 --- a/frontend/src/lib/components/ui/dialog/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Dialog as DialogPrimitive } from 'bits-ui'; - -import Title from './dialog-title.svelte'; -import Footer from './dialog-footer.svelte'; -import Header from './dialog-header.svelte'; -import Overlay from './dialog-overlay.svelte'; -import Content from './dialog-content.svelte'; -import Description from './dialog-description.svelte'; -import Trigger from './dialog-trigger.svelte'; -import Close from './dialog-close.svelte'; - -const Root = DialogPrimitive.Root; -const Portal = DialogPrimitive.Portal; - -export { - Root, - Title, - Portal, - Footer, - Header, - Trigger, - Overlay, - Content, - Description, - Close, - // - Root as Dialog, - Title as DialogTitle, - Portal as DialogPortal, - Footer as DialogFooter, - Header as DialogHeader, - Trigger as DialogTrigger, - Overlay as DialogOverlay, - Content as DialogContent, - Description as DialogDescription, - Close as DialogClose, -}; diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte deleted file mode 100644 index d9693e6..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +++ /dev/null @@ -1,41 +0,0 @@ - - - - {#snippet children({ checked, indeterminate })} - - {#if indeterminate} - - {:else} - - {/if} - - {@render childrenProp?.()} - {/snippet} - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte deleted file mode 100644 index 4910f58..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte +++ /dev/null @@ -1,27 +0,0 @@ - - - - - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte deleted file mode 100644 index f81ba8d..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +++ /dev/null @@ -1,22 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte deleted file mode 100644 index bf972af..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte deleted file mode 100644 index d33830b..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte +++ /dev/null @@ -1,27 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte deleted file mode 100644 index e5b0ba7..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte +++ /dev/null @@ -1,24 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte deleted file mode 100644 index 7452366..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte deleted file mode 100644 index a15df89..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +++ /dev/null @@ -1,31 +0,0 @@ - - - - {#snippet children({ checked })} - - {#if checked} - - {/if} - - {@render childrenProp?.({ checked })} - {/snippet} - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte deleted file mode 100644 index e391c96..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte deleted file mode 100644 index d156399..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte deleted file mode 100644 index 300c2f3..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte deleted file mode 100644 index 1fdd021..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +++ /dev/null @@ -1,29 +0,0 @@ - - - - {@render children?.()} - - diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte deleted file mode 100644 index 7409c77..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/dropdown-menu/index.ts b/frontend/src/lib/components/ui/dropdown-menu/index.ts deleted file mode 100644 index 199a830..0000000 --- a/frontend/src/lib/components/ui/dropdown-menu/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; -import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; -import Content from './dropdown-menu-content.svelte'; -import Group from './dropdown-menu-group.svelte'; -import Item from './dropdown-menu-item.svelte'; -import Label from './dropdown-menu-label.svelte'; -import RadioGroup from './dropdown-menu-radio-group.svelte'; -import RadioItem from './dropdown-menu-radio-item.svelte'; -import Separator from './dropdown-menu-separator.svelte'; -import Shortcut from './dropdown-menu-shortcut.svelte'; -import Trigger from './dropdown-menu-trigger.svelte'; -import SubContent from './dropdown-menu-sub-content.svelte'; -import SubTrigger from './dropdown-menu-sub-trigger.svelte'; -import GroupHeading from './dropdown-menu-group-heading.svelte'; -const Sub = DropdownMenuPrimitive.Sub; -const Root = DropdownMenuPrimitive.Root; - -export { - CheckboxItem, - Content, - Root as DropdownMenu, - CheckboxItem as DropdownMenuCheckboxItem, - Content as DropdownMenuContent, - Group as DropdownMenuGroup, - Item as DropdownMenuItem, - Label as DropdownMenuLabel, - RadioGroup as DropdownMenuRadioGroup, - RadioItem as DropdownMenuRadioItem, - Separator as DropdownMenuSeparator, - Shortcut as DropdownMenuShortcut, - Sub as DropdownMenuSub, - SubContent as DropdownMenuSubContent, - SubTrigger as DropdownMenuSubTrigger, - Trigger as DropdownMenuTrigger, - GroupHeading as DropdownMenuGroupHeading, - Group, - GroupHeading, - Item, - Label, - RadioGroup, - RadioItem, - Root, - Separator, - Shortcut, - Sub, - SubContent, - SubTrigger, - Trigger, -}; diff --git a/frontend/src/lib/components/ui/field/field-content.svelte b/frontend/src/lib/components/ui/field/field-content.svelte deleted file mode 100644 index d859d51..0000000 --- a/frontend/src/lib/components/ui/field/field-content.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/field/field-description.svelte b/frontend/src/lib/components/ui/field/field-description.svelte deleted file mode 100644 index 907590d..0000000 --- a/frontend/src/lib/components/ui/field/field-description.svelte +++ /dev/null @@ -1,25 +0,0 @@ - - -

    a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4', - className - )} - {...restProps} -> - {@render children?.()} -

    diff --git a/frontend/src/lib/components/ui/field/field-error.svelte b/frontend/src/lib/components/ui/field/field-error.svelte deleted file mode 100644 index 162fdf7..0000000 --- a/frontend/src/lib/components/ui/field/field-error.svelte +++ /dev/null @@ -1,58 +0,0 @@ - - -{#if hasContent} - -{/if} diff --git a/frontend/src/lib/components/ui/field/field-group.svelte b/frontend/src/lib/components/ui/field/field-group.svelte deleted file mode 100644 index 8bf5da0..0000000 --- a/frontend/src/lib/components/ui/field/field-group.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -
    [data-slot=field-group]]:gap-4', - className - )} - {...restProps} -> - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/field/field-label.svelte b/frontend/src/lib/components/ui/field/field-label.svelte deleted file mode 100644 index a9640d7..0000000 --- a/frontend/src/lib/components/ui/field/field-label.svelte +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/field/field-legend.svelte b/frontend/src/lib/components/ui/field/field-legend.svelte deleted file mode 100644 index 45c5caf..0000000 --- a/frontend/src/lib/components/ui/field/field-legend.svelte +++ /dev/null @@ -1,29 +0,0 @@ - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/field/field-separator.svelte b/frontend/src/lib/components/ui/field/field-separator.svelte deleted file mode 100644 index 6832080..0000000 --- a/frontend/src/lib/components/ui/field/field-separator.svelte +++ /dev/null @@ -1,35 +0,0 @@ - - -
    - - {#if children} - - {@render children()} - - {/if} -
    diff --git a/frontend/src/lib/components/ui/field/field-set.svelte b/frontend/src/lib/components/ui/field/field-set.svelte deleted file mode 100644 index 49fbdfd..0000000 --- a/frontend/src/lib/components/ui/field/field-set.svelte +++ /dev/null @@ -1,24 +0,0 @@ - - -
    [data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3', - className - )} - {...restProps} -> - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/field/field-title.svelte b/frontend/src/lib/components/ui/field/field-title.svelte deleted file mode 100644 index 3632d75..0000000 --- a/frontend/src/lib/components/ui/field/field-title.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/field/field.svelte b/frontend/src/lib/components/ui/field/field.svelte deleted file mode 100644 index 8bc6139..0000000 --- a/frontend/src/lib/components/ui/field/field.svelte +++ /dev/null @@ -1,53 +0,0 @@ - - - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/field/index.ts b/frontend/src/lib/components/ui/field/index.ts deleted file mode 100644 index 4bc6c5e..0000000 --- a/frontend/src/lib/components/ui/field/index.ts +++ /dev/null @@ -1,33 +0,0 @@ -import Field from './field.svelte'; -import Set from './field-set.svelte'; -import Legend from './field-legend.svelte'; -import Group from './field-group.svelte'; -import Content from './field-content.svelte'; -import Label from './field-label.svelte'; -import Title from './field-title.svelte'; -import Description from './field-description.svelte'; -import Separator from './field-separator.svelte'; -import Error from './field-error.svelte'; - -export { - Field, - Set, - Legend, - Group, - Content, - Label, - Title, - Description, - Separator, - Error, - // - Set as FieldSet, - Legend as FieldLegend, - Group as FieldGroup, - Content as FieldContent, - Label as FieldLabel, - Title as FieldTitle, - Description as FieldDescription, - Separator as FieldSeparator, - Error as FieldError, -}; diff --git a/frontend/src/lib/components/ui/input-otp/index.ts b/frontend/src/lib/components/ui/input-otp/index.ts deleted file mode 100644 index 834e66e..0000000 --- a/frontend/src/lib/components/ui/input-otp/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import Root from './input-otp.svelte'; -import Group from './input-otp-group.svelte'; -import Slot from './input-otp-slot.svelte'; -import Separator from './input-otp-separator.svelte'; - -export { - Root, - Group, - Slot, - Separator, - Root as InputOTP, - Group as InputOTPGroup, - Slot as InputOTPSlot, - Separator as InputOTPSeparator, -}; diff --git a/frontend/src/lib/components/ui/input-otp/input-otp-group.svelte b/frontend/src/lib/components/ui/input-otp/input-otp-group.svelte deleted file mode 100644 index 30f11db..0000000 --- a/frontend/src/lib/components/ui/input-otp/input-otp-group.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/input-otp/input-otp-separator.svelte b/frontend/src/lib/components/ui/input-otp/input-otp-separator.svelte deleted file mode 100644 index 8330ae9..0000000 --- a/frontend/src/lib/components/ui/input-otp/input-otp-separator.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - -
    - {#if children} - {@render children?.()} - {:else} - - {/if} -
    diff --git a/frontend/src/lib/components/ui/input-otp/input-otp-slot.svelte b/frontend/src/lib/components/ui/input-otp/input-otp-slot.svelte deleted file mode 100644 index f283f2d..0000000 --- a/frontend/src/lib/components/ui/input-otp/input-otp-slot.svelte +++ /dev/null @@ -1,31 +0,0 @@ - - - - {cell.char} - {#if cell.hasFakeCaret} -
    - -
    - {/if} -
    diff --git a/frontend/src/lib/components/ui/input-otp/input-otp.svelte b/frontend/src/lib/components/ui/input-otp/input-otp.svelte deleted file mode 100644 index fd561f9..0000000 --- a/frontend/src/lib/components/ui/input-otp/input-otp.svelte +++ /dev/null @@ -1,22 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/input/index.ts b/frontend/src/lib/components/ui/input/index.ts deleted file mode 100644 index 0888f0e..0000000 --- a/frontend/src/lib/components/ui/input/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Root from './input.svelte'; - -export { - Root, - // - Root as Input, -}; diff --git a/frontend/src/lib/components/ui/input/input.svelte b/frontend/src/lib/components/ui/input/input.svelte deleted file mode 100644 index 898b5bc..0000000 --- a/frontend/src/lib/components/ui/input/input.svelte +++ /dev/null @@ -1,52 +0,0 @@ - - -{#if type === 'file'} - -{:else} - -{/if} diff --git a/frontend/src/lib/components/ui/label/index.ts b/frontend/src/lib/components/ui/label/index.ts deleted file mode 100644 index 36fb393..0000000 --- a/frontend/src/lib/components/ui/label/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Root from './label.svelte'; - -export { - Root, - // - Root as Label, -}; diff --git a/frontend/src/lib/components/ui/label/label.svelte b/frontend/src/lib/components/ui/label/label.svelte deleted file mode 100644 index d4b38dc..0000000 --- a/frontend/src/lib/components/ui/label/label.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/native-select/index.ts b/frontend/src/lib/components/ui/native-select/index.ts deleted file mode 100644 index c5f6af0..0000000 --- a/frontend/src/lib/components/ui/native-select/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Root from './native-select.svelte'; -import Option from './native-select-option.svelte'; -import OptGroup from './native-select-opt-group.svelte'; - -export { - Root, - Option, - OptGroup, - Root as NativeSelect, - Option as NativeSelectOption, - OptGroup as NativeSelectOptGroup, -}; diff --git a/frontend/src/lib/components/ui/native-select/native-select-opt-group.svelte b/frontend/src/lib/components/ui/native-select/native-select-opt-group.svelte deleted file mode 100644 index 343e920..0000000 --- a/frontend/src/lib/components/ui/native-select/native-select-opt-group.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/native-select/native-select-option.svelte b/frontend/src/lib/components/ui/native-select/native-select-option.svelte deleted file mode 100644 index 0f95535..0000000 --- a/frontend/src/lib/components/ui/native-select/native-select-option.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/native-select/native-select.svelte b/frontend/src/lib/components/ui/native-select/native-select.svelte deleted file mode 100644 index a915615..0000000 --- a/frontend/src/lib/components/ui/native-select/native-select.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - -
    - -
    diff --git a/frontend/src/lib/components/ui/progress/index.ts b/frontend/src/lib/components/ui/progress/index.ts deleted file mode 100644 index c965294..0000000 --- a/frontend/src/lib/components/ui/progress/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Root from './progress.svelte'; - -export { - Root, - // - Root as Progress, -}; diff --git a/frontend/src/lib/components/ui/progress/progress.svelte b/frontend/src/lib/components/ui/progress/progress.svelte deleted file mode 100644 index 3d516d2..0000000 --- a/frontend/src/lib/components/ui/progress/progress.svelte +++ /dev/null @@ -1,27 +0,0 @@ - - - -
    -
    diff --git a/frontend/src/lib/components/ui/select/index.ts b/frontend/src/lib/components/ui/select/index.ts deleted file mode 100644 index 198ca7f..0000000 --- a/frontend/src/lib/components/ui/select/index.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Select as SelectPrimitive } from 'bits-ui'; - -import Group from './select-group.svelte'; -import Label from './select-label.svelte'; -import Item from './select-item.svelte'; -import Content from './select-content.svelte'; -import Trigger from './select-trigger.svelte'; -import Separator from './select-separator.svelte'; -import ScrollDownButton from './select-scroll-down-button.svelte'; -import ScrollUpButton from './select-scroll-up-button.svelte'; -import GroupHeading from './select-group-heading.svelte'; - -const Root = SelectPrimitive.Root; - -export { - Root, - Group, - Label, - Item, - Content, - Trigger, - Separator, - ScrollDownButton, - ScrollUpButton, - GroupHeading, - // - Root as Select, - Group as SelectGroup, - Label as SelectLabel, - Item as SelectItem, - Content as SelectContent, - Trigger as SelectTrigger, - Separator as SelectSeparator, - ScrollDownButton as SelectScrollDownButton, - ScrollUpButton as SelectScrollUpButton, - GroupHeading as SelectGroupHeading, -}; diff --git a/frontend/src/lib/components/ui/select/select-content.svelte b/frontend/src/lib/components/ui/select/select-content.svelte deleted file mode 100644 index 82bce4e..0000000 --- a/frontend/src/lib/components/ui/select/select-content.svelte +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - {@render children?.()} - - - - diff --git a/frontend/src/lib/components/ui/select/select-group-heading.svelte b/frontend/src/lib/components/ui/select/select-group-heading.svelte deleted file mode 100644 index 7354e57..0000000 --- a/frontend/src/lib/components/ui/select/select-group-heading.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/select/select-group.svelte b/frontend/src/lib/components/ui/select/select-group.svelte deleted file mode 100644 index acdaa0a..0000000 --- a/frontend/src/lib/components/ui/select/select-group.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/select/select-item.svelte b/frontend/src/lib/components/ui/select/select-item.svelte deleted file mode 100644 index 420efe1..0000000 --- a/frontend/src/lib/components/ui/select/select-item.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - - - {#snippet children({ selected, highlighted })} - - {#if selected} - - {/if} - - {#if childrenProp} - {@render childrenProp({ selected, highlighted })} - {:else} - {label || value} - {/if} - {/snippet} - diff --git a/frontend/src/lib/components/ui/select/select-label.svelte b/frontend/src/lib/components/ui/select/select-label.svelte deleted file mode 100644 index 4f26941..0000000 --- a/frontend/src/lib/components/ui/select/select-label.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/select/select-scroll-down-button.svelte b/frontend/src/lib/components/ui/select/select-scroll-down-button.svelte deleted file mode 100644 index dc1d26d..0000000 --- a/frontend/src/lib/components/ui/select/select-scroll-down-button.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - - - diff --git a/frontend/src/lib/components/ui/select/select-scroll-up-button.svelte b/frontend/src/lib/components/ui/select/select-scroll-up-button.svelte deleted file mode 100644 index 99c6a02..0000000 --- a/frontend/src/lib/components/ui/select/select-scroll-up-button.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - - - diff --git a/frontend/src/lib/components/ui/select/select-separator.svelte b/frontend/src/lib/components/ui/select/select-separator.svelte deleted file mode 100644 index 4699bfe..0000000 --- a/frontend/src/lib/components/ui/select/select-separator.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/select/select-trigger.svelte b/frontend/src/lib/components/ui/select/select-trigger.svelte deleted file mode 100644 index f02bd8c..0000000 --- a/frontend/src/lib/components/ui/select/select-trigger.svelte +++ /dev/null @@ -1,29 +0,0 @@ - - - - {@render children?.()} - - diff --git a/frontend/src/lib/components/ui/separator/index.ts b/frontend/src/lib/components/ui/separator/index.ts deleted file mode 100644 index 56b2767..0000000 --- a/frontend/src/lib/components/ui/separator/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Root from './separator.svelte'; - -export { - Root, - // - Root as Separator, -}; diff --git a/frontend/src/lib/components/ui/separator/separator.svelte b/frontend/src/lib/components/ui/separator/separator.svelte deleted file mode 100644 index ac5b406..0000000 --- a/frontend/src/lib/components/ui/separator/separator.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/service-icon.svelte b/frontend/src/lib/components/ui/service-icon.svelte deleted file mode 100644 index 47b30ef..0000000 --- a/frontend/src/lib/components/ui/service-icon.svelte +++ /dev/null @@ -1,95 +0,0 @@ - - -{#if IconComponent} - -{:else} - -
    - {serviceName.charAt(0).toUpperCase()} -
    -{/if} diff --git a/frontend/src/lib/components/ui/sheet/index.ts b/frontend/src/lib/components/ui/sheet/index.ts deleted file mode 100644 index 527a280..0000000 --- a/frontend/src/lib/components/ui/sheet/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Dialog as SheetPrimitive } from 'bits-ui'; -import Trigger from './sheet-trigger.svelte'; -import Close from './sheet-close.svelte'; -import Overlay from './sheet-overlay.svelte'; -import Content from './sheet-content.svelte'; -import Header from './sheet-header.svelte'; -import Footer from './sheet-footer.svelte'; -import Title from './sheet-title.svelte'; -import Description from './sheet-description.svelte'; - -const Root = SheetPrimitive.Root; -const Portal = SheetPrimitive.Portal; - -export { - Root, - Close, - Trigger, - Portal, - Overlay, - Content, - Header, - Footer, - Title, - Description, - // - Root as Sheet, - Close as SheetClose, - Trigger as SheetTrigger, - Portal as SheetPortal, - Overlay as SheetOverlay, - Content as SheetContent, - Header as SheetHeader, - Footer as SheetFooter, - Title as SheetTitle, - Description as SheetDescription, -}; diff --git a/frontend/src/lib/components/ui/sheet/sheet-close.svelte b/frontend/src/lib/components/ui/sheet/sheet-close.svelte deleted file mode 100644 index e7b07bf..0000000 --- a/frontend/src/lib/components/ui/sheet/sheet-close.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/sheet/sheet-content.svelte b/frontend/src/lib/components/ui/sheet/sheet-content.svelte deleted file mode 100644 index beb82fe..0000000 --- a/frontend/src/lib/components/ui/sheet/sheet-content.svelte +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - {@render children?.()} - - - Close - - - diff --git a/frontend/src/lib/components/ui/sheet/sheet-description.svelte b/frontend/src/lib/components/ui/sheet/sheet-description.svelte deleted file mode 100644 index c06792e..0000000 --- a/frontend/src/lib/components/ui/sheet/sheet-description.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/sheet/sheet-footer.svelte b/frontend/src/lib/components/ui/sheet/sheet-footer.svelte deleted file mode 100644 index a5c8454..0000000 --- a/frontend/src/lib/components/ui/sheet/sheet-footer.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sheet/sheet-header.svelte b/frontend/src/lib/components/ui/sheet/sheet-header.svelte deleted file mode 100644 index ffd09c4..0000000 --- a/frontend/src/lib/components/ui/sheet/sheet-header.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sheet/sheet-overlay.svelte b/frontend/src/lib/components/ui/sheet/sheet-overlay.svelte deleted file mode 100644 index d86a498..0000000 --- a/frontend/src/lib/components/ui/sheet/sheet-overlay.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/sheet/sheet-title.svelte b/frontend/src/lib/components/ui/sheet/sheet-title.svelte deleted file mode 100644 index 6873227..0000000 --- a/frontend/src/lib/components/ui/sheet/sheet-title.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/sheet/sheet-trigger.svelte b/frontend/src/lib/components/ui/sheet/sheet-trigger.svelte deleted file mode 100644 index 860f048..0000000 --- a/frontend/src/lib/components/ui/sheet/sheet-trigger.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/sidebar/constants.ts b/frontend/src/lib/components/ui/sidebar/constants.ts deleted file mode 100644 index 2d3bbfb..0000000 --- a/frontend/src/lib/components/ui/sidebar/constants.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const SIDEBAR_COOKIE_NAME = 'sidebar:state'; -export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; -export const SIDEBAR_WIDTH = '16rem'; -export const SIDEBAR_WIDTH_MOBILE = '18rem'; -export const SIDEBAR_WIDTH_ICON = '3rem'; -export const SIDEBAR_KEYBOARD_SHORTCUT = 'b'; diff --git a/frontend/src/lib/components/ui/sidebar/context.svelte.ts b/frontend/src/lib/components/ui/sidebar/context.svelte.ts deleted file mode 100644 index 6788b5b..0000000 --- a/frontend/src/lib/components/ui/sidebar/context.svelte.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { IsMobile } from '$lib/hooks/is-mobile.svelte.js'; -import { getContext, setContext } from 'svelte'; -import { SIDEBAR_KEYBOARD_SHORTCUT } from './constants.js'; - -type Getter = () => T; - -export type SidebarStateProps = { - /** - * A getter function that returns the current open state of the sidebar. - * We use a getter function here to support `bind:open` on the `Sidebar.Provider` - * component. - */ - open: Getter; - - /** - * A function that sets the open state of the sidebar. To support `bind:open`, we need - * a source of truth for changing the open state to ensure it will be synced throughout - * the sub-components and any `bind:` references. - */ - setOpen: (open: boolean) => void; -}; - -class SidebarState { - readonly props: SidebarStateProps; - open = $derived.by(() => this.props.open()); - openMobile = $state(false); - setOpen: SidebarStateProps['setOpen']; - #isMobile: IsMobile; - state = $derived.by(() => (this.open ? 'expanded' : 'collapsed')); - - constructor(props: SidebarStateProps) { - this.setOpen = props.setOpen; - this.#isMobile = new IsMobile(); - this.props = props; - } - - // Convenience getter for checking if the sidebar is mobile - // without this, we would need to use `sidebar.isMobile.current` everywhere - get isMobile() { - return this.#isMobile.current; - } - - // Event handler to apply to the `` - handleShortcutKeydown = (e: KeyboardEvent) => { - if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) { - e.preventDefault(); - this.toggle(); - } - }; - - setOpenMobile = (value: boolean) => { - this.openMobile = value; - }; - - toggle = () => { - return this.#isMobile.current ? (this.openMobile = !this.openMobile) : this.setOpen(!this.open); - }; -} - -const SYMBOL_KEY = 'scn-sidebar'; - -/** - * Instantiates a new `SidebarState` instance and sets it in the context. - * - * @param props The constructor props for the `SidebarState` class. - * @returns The `SidebarState` instance. - */ -export function setSidebar(props: SidebarStateProps): SidebarState { - return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props)); -} - -/** - * Retrieves the `SidebarState` instance from the context. This is a class instance, - * so you cannot destructure it. - * @returns The `SidebarState` instance. - */ -export function useSidebar(): SidebarState { - return getContext(Symbol.for(SYMBOL_KEY)); -} diff --git a/frontend/src/lib/components/ui/sidebar/index.ts b/frontend/src/lib/components/ui/sidebar/index.ts deleted file mode 100644 index 3b5795f..0000000 --- a/frontend/src/lib/components/ui/sidebar/index.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { useSidebar } from './context.svelte.js'; -import Content from './sidebar-content.svelte'; -import Footer from './sidebar-footer.svelte'; -import GroupAction from './sidebar-group-action.svelte'; -import GroupContent from './sidebar-group-content.svelte'; -import GroupLabel from './sidebar-group-label.svelte'; -import Group from './sidebar-group.svelte'; -import Header from './sidebar-header.svelte'; -import Input from './sidebar-input.svelte'; -import Inset from './sidebar-inset.svelte'; -import MenuAction from './sidebar-menu-action.svelte'; -import MenuBadge from './sidebar-menu-badge.svelte'; -import MenuButton from './sidebar-menu-button.svelte'; -import MenuItem from './sidebar-menu-item.svelte'; -import MenuSkeleton from './sidebar-menu-skeleton.svelte'; -import MenuSubButton from './sidebar-menu-sub-button.svelte'; -import MenuSubItem from './sidebar-menu-sub-item.svelte'; -import MenuSub from './sidebar-menu-sub.svelte'; -import Menu from './sidebar-menu.svelte'; -import Provider from './sidebar-provider.svelte'; -import Rail from './sidebar-rail.svelte'; -import Separator from './sidebar-separator.svelte'; -import Trigger from './sidebar-trigger.svelte'; -import Root from './sidebar.svelte'; - -export { - Content, - Footer, - Group, - GroupAction, - GroupContent, - GroupLabel, - Header, - Input, - Inset, - Menu, - MenuAction, - MenuBadge, - MenuButton, - MenuItem, - MenuSkeleton, - MenuSub, - MenuSubButton, - MenuSubItem, - Provider, - Rail, - Root, - Separator, - // - Root as Sidebar, - Content as SidebarContent, - Footer as SidebarFooter, - Group as SidebarGroup, - GroupAction as SidebarGroupAction, - GroupContent as SidebarGroupContent, - GroupLabel as SidebarGroupLabel, - Header as SidebarHeader, - Input as SidebarInput, - Inset as SidebarInset, - Menu as SidebarMenu, - MenuAction as SidebarMenuAction, - MenuBadge as SidebarMenuBadge, - MenuButton as SidebarMenuButton, - MenuItem as SidebarMenuItem, - MenuSkeleton as SidebarMenuSkeleton, - MenuSub as SidebarMenuSub, - MenuSubButton as SidebarMenuSubButton, - MenuSubItem as SidebarMenuSubItem, - Provider as SidebarProvider, - Rail as SidebarRail, - Separator as SidebarSeparator, - Trigger as SidebarTrigger, - Trigger, - useSidebar, -}; diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-content.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-content.svelte deleted file mode 100644 index 2d7deb5..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-content.svelte +++ /dev/null @@ -1,24 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-footer.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-footer.svelte deleted file mode 100644 index 7b43e9d..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-footer.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-group-action.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-group-action.svelte deleted file mode 100644 index 1637d75..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-group-action.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - -{#if child} - {@render child({ props: mergedProps })} -{:else} - -{/if} diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-group-content.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-group-content.svelte deleted file mode 100644 index 5e27abd..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-group-content.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-group-label.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-group-label.svelte deleted file mode 100644 index 601b1f6..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-group-label.svelte +++ /dev/null @@ -1,34 +0,0 @@ - - -{#if child} - {@render child({ props: mergedProps })} -{:else} -
    - {@render children?.()} -
    -{/if} diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-group.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-group.svelte deleted file mode 100644 index 2e55566..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-group.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-header.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-header.svelte deleted file mode 100644 index 08a97f1..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-header.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-input.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-input.svelte deleted file mode 100644 index 1d3973f..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-input.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-inset.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-inset.svelte deleted file mode 100644 index 572ff13..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-inset.svelte +++ /dev/null @@ -1,24 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-menu-action.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-menu-action.svelte deleted file mode 100644 index e9fb00e..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-menu-action.svelte +++ /dev/null @@ -1,43 +0,0 @@ - - -{#if child} - {@render child({ props: mergedProps })} -{:else} - -{/if} diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte deleted file mode 100644 index 9265776..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte +++ /dev/null @@ -1,29 +0,0 @@ - - -
    - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-menu-button.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-menu-button.svelte deleted file mode 100644 index 5eed9b6..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-menu-button.svelte +++ /dev/null @@ -1,101 +0,0 @@ - - - - -{#snippet Button({ props }: { props?: Record })} - {@const mergedProps = mergeProps(buttonProps, props)} - {#if child} - {@render child({ props: mergedProps })} - {:else} - - {/if} -{/snippet} - -{#if !tooltipContent} - {@render Button({})} -{:else} - - - {#snippet child({ props })} - {@render Button({ props })} - {/snippet} - - - -{/if} diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-menu-item.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-menu-item.svelte deleted file mode 100644 index 634a08a..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-menu-item.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - -
  • - {@render children?.()} -
  • diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte deleted file mode 100644 index df960e5..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - -
    - {#if showIcon} - - {/if} - - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte deleted file mode 100644 index 91f10de..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte +++ /dev/null @@ -1,43 +0,0 @@ - - -{#if child} - {@render child({ props: mergedProps })} -{:else} - - {@render children?.()} - -{/if} diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte deleted file mode 100644 index 0516c06..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - -
  • - {@render children?.()} -
  • diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte deleted file mode 100644 index 42da2b5..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte +++ /dev/null @@ -1,25 +0,0 @@ - - -
      - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-menu.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-menu.svelte deleted file mode 100644 index 077e720..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-menu.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - -
      - {@render children?.()} -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-provider.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-provider.svelte deleted file mode 100644 index 9bba4eb..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-provider.svelte +++ /dev/null @@ -1,53 +0,0 @@ - - - - - -
    - {@render children?.()} -
    -
    diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-rail.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-rail.svelte deleted file mode 100644 index 4f7af83..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-rail.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-separator.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-separator.svelte deleted file mode 100644 index ba1caba..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-separator.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/sidebar/sidebar-trigger.svelte b/frontend/src/lib/components/ui/sidebar/sidebar-trigger.svelte deleted file mode 100644 index 4696381..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar-trigger.svelte +++ /dev/null @@ -1,35 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/sidebar/sidebar.svelte b/frontend/src/lib/components/ui/sidebar/sidebar.svelte deleted file mode 100644 index a28232f..0000000 --- a/frontend/src/lib/components/ui/sidebar/sidebar.svelte +++ /dev/null @@ -1,101 +0,0 @@ - - -{#if collapsible === 'none'} -
    - {@render children?.()} -
    -{:else if sidebar.isMobile} - sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} {...restProps}> - - - Sidebar - Displays the mobile sidebar. - -
    - {@render children?.()} -
    -
    -
    -{:else} - -{/if} diff --git a/frontend/src/lib/components/ui/skeleton/index.ts b/frontend/src/lib/components/ui/skeleton/index.ts deleted file mode 100644 index 2d93ff2..0000000 --- a/frontend/src/lib/components/ui/skeleton/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Root from './skeleton.svelte'; - -export { - Root, - // - Root as Skeleton, -}; diff --git a/frontend/src/lib/components/ui/skeleton/skeleton.svelte b/frontend/src/lib/components/ui/skeleton/skeleton.svelte deleted file mode 100644 index fdb2ccc..0000000 --- a/frontend/src/lib/components/ui/skeleton/skeleton.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - -
    diff --git a/frontend/src/lib/components/ui/switch/index.ts b/frontend/src/lib/components/ui/switch/index.ts deleted file mode 100644 index 19be952..0000000 --- a/frontend/src/lib/components/ui/switch/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Root from './switch.svelte'; - -export { - Root, - // - Root as Switch, -}; diff --git a/frontend/src/lib/components/ui/switch/switch.svelte b/frontend/src/lib/components/ui/switch/switch.svelte deleted file mode 100644 index 32031d1..0000000 --- a/frontend/src/lib/components/ui/switch/switch.svelte +++ /dev/null @@ -1,29 +0,0 @@ - - - - - diff --git a/frontend/src/lib/components/ui/table/index.ts b/frontend/src/lib/components/ui/table/index.ts deleted file mode 100644 index 7e48545..0000000 --- a/frontend/src/lib/components/ui/table/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -import Root from './table.svelte'; -import Body from './table-body.svelte'; -import Caption from './table-caption.svelte'; -import Cell from './table-cell.svelte'; -import Footer from './table-footer.svelte'; -import Head from './table-head.svelte'; -import Header from './table-header.svelte'; -import Row from './table-row.svelte'; - -export { - Root, - Body, - Caption, - Cell, - Footer, - Head, - Header, - Row, - // - Root as Table, - Body as TableBody, - Caption as TableCaption, - Cell as TableCell, - Footer as TableFooter, - Head as TableHead, - Header as TableHeader, - Row as TableRow, -}; diff --git a/frontend/src/lib/components/ui/table/table-body.svelte b/frontend/src/lib/components/ui/table/table-body.svelte deleted file mode 100644 index 26315a8..0000000 --- a/frontend/src/lib/components/ui/table/table-body.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/table/table-caption.svelte b/frontend/src/lib/components/ui/table/table-caption.svelte deleted file mode 100644 index dbde6ca..0000000 --- a/frontend/src/lib/components/ui/table/table-caption.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/table/table-cell.svelte b/frontend/src/lib/components/ui/table/table-cell.svelte deleted file mode 100644 index ce86e89..0000000 --- a/frontend/src/lib/components/ui/table/table-cell.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/table/table-footer.svelte b/frontend/src/lib/components/ui/table/table-footer.svelte deleted file mode 100644 index e8293a9..0000000 --- a/frontend/src/lib/components/ui/table/table-footer.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -tr]:last:border-b-0', className)} - {...restProps} -> - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/table/table-head.svelte b/frontend/src/lib/components/ui/table/table-head.svelte deleted file mode 100644 index d3f5003..0000000 --- a/frontend/src/lib/components/ui/table/table-head.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/table/table-header.svelte b/frontend/src/lib/components/ui/table/table-header.svelte deleted file mode 100644 index c5fde07..0000000 --- a/frontend/src/lib/components/ui/table/table-header.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/table/table-row.svelte b/frontend/src/lib/components/ui/table/table-row.svelte deleted file mode 100644 index 1864ba3..0000000 --- a/frontend/src/lib/components/ui/table/table-row.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -svelte-css-wrapper]:[&>th,td]:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors', - className - )} - {...restProps} -> - {@render children?.()} - diff --git a/frontend/src/lib/components/ui/table/table.svelte b/frontend/src/lib/components/ui/table/table.svelte deleted file mode 100644 index 5fcf2c0..0000000 --- a/frontend/src/lib/components/ui/table/table.svelte +++ /dev/null @@ -1,22 +0,0 @@ - - -
    - - {@render children?.()} -
    -
    diff --git a/frontend/src/lib/components/ui/tabs/index.ts b/frontend/src/lib/components/ui/tabs/index.ts deleted file mode 100644 index 48bce4c..0000000 --- a/frontend/src/lib/components/ui/tabs/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Root from './tabs.svelte'; -import Content from './tabs-content.svelte'; -import List from './tabs-list.svelte'; -import Trigger from './tabs-trigger.svelte'; - -export { - Root, - Content, - List, - Trigger, - // - Root as Tabs, - Content as TabsContent, - List as TabsList, - Trigger as TabsTrigger, -}; diff --git a/frontend/src/lib/components/ui/tabs/tabs-content.svelte b/frontend/src/lib/components/ui/tabs/tabs-content.svelte deleted file mode 100644 index a92e210..0000000 --- a/frontend/src/lib/components/ui/tabs/tabs-content.svelte +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/tabs/tabs-list.svelte b/frontend/src/lib/components/ui/tabs/tabs-list.svelte deleted file mode 100644 index d05319b..0000000 --- a/frontend/src/lib/components/ui/tabs/tabs-list.svelte +++ /dev/null @@ -1,16 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/tabs/tabs-trigger.svelte b/frontend/src/lib/components/ui/tabs/tabs-trigger.svelte deleted file mode 100644 index 74c642f..0000000 --- a/frontend/src/lib/components/ui/tabs/tabs-trigger.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/tabs/tabs.svelte b/frontend/src/lib/components/ui/tabs/tabs.svelte deleted file mode 100644 index 9c8538a..0000000 --- a/frontend/src/lib/components/ui/tabs/tabs.svelte +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/textarea/index.ts b/frontend/src/lib/components/ui/textarea/index.ts deleted file mode 100644 index a1bd626..0000000 --- a/frontend/src/lib/components/ui/textarea/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import Root from './textarea.svelte'; - -export { - Root, - // - Root as Textarea, -}; diff --git a/frontend/src/lib/components/ui/textarea/textarea.svelte b/frontend/src/lib/components/ui/textarea/textarea.svelte deleted file mode 100644 index 4936a0a..0000000 --- a/frontend/src/lib/components/ui/textarea/textarea.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - - diff --git a/frontend/src/lib/components/ui/tooltip/index.ts b/frontend/src/lib/components/ui/tooltip/index.ts deleted file mode 100644 index 8ecad95..0000000 --- a/frontend/src/lib/components/ui/tooltip/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Tooltip as TooltipPrimitive } from 'bits-ui'; -import Trigger from './tooltip-trigger.svelte'; -import Content from './tooltip-content.svelte'; - -const Root = TooltipPrimitive.Root; -const Provider = TooltipPrimitive.Provider; -const Portal = TooltipPrimitive.Portal; - -export { - Root, - Trigger, - Content, - Provider, - Portal, - // - Root as Tooltip, - Content as TooltipContent, - Trigger as TooltipTrigger, - Provider as TooltipProvider, - Portal as TooltipPortal, -}; diff --git a/frontend/src/lib/components/ui/tooltip/tooltip-content.svelte b/frontend/src/lib/components/ui/tooltip/tooltip-content.svelte deleted file mode 100644 index b1dcd0b..0000000 --- a/frontend/src/lib/components/ui/tooltip/tooltip-content.svelte +++ /dev/null @@ -1,47 +0,0 @@ - - - - - {@render children?.()} - - {#snippet child({ props })} -
    - {/snippet} -
    -
    -
    diff --git a/frontend/src/lib/components/ui/tooltip/tooltip-trigger.svelte b/frontend/src/lib/components/ui/tooltip/tooltip-trigger.svelte deleted file mode 100644 index b7640e4..0000000 --- a/frontend/src/lib/components/ui/tooltip/tooltip-trigger.svelte +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/frontend/src/lib/hooks/is-mobile.svelte.ts b/frontend/src/lib/hooks/is-mobile.svelte.ts deleted file mode 100644 index e3802d3..0000000 --- a/frontend/src/lib/hooks/is-mobile.svelte.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { MediaQuery } from 'svelte/reactivity'; - -const DEFAULT_MOBILE_BREAKPOINT = 768; - -export class IsMobile extends MediaQuery { - constructor(breakpoint: number = DEFAULT_MOBILE_BREAKPOINT) { - super(`max-width: ${breakpoint - 1}px`); - } -} diff --git a/frontend/src/lib/services/agents.ts b/frontend/src/lib/services/agents.ts deleted file mode 100644 index 04aae1b..0000000 --- a/frontend/src/lib/services/agents.ts +++ /dev/null @@ -1,69 +0,0 @@ -import type { Agent, AgentMetrics } from '$lib/types/agent'; -import { ApiClient } from './api-client'; - -export async function listAgents(): Promise { - const response = await ApiClient.get('/agents'); - - if (!response.ok) { - throw new Error(`Failed to fetch agents: ${response.statusText}`); - } - - return response.json(); -} - -export async function getAgentDetails(agentId: string): Promise { - const response = await ApiClient.get(`/agents/${agentId}`); - - if (!response.ok) { - throw new Error(`Failed to fetch agent details: ${response.statusText}`); - } - - return response.json(); -} - -export async function getAgentMetrics( - agentId: string, - limit: number = 100 -): Promise { - const response = await ApiClient.get(`/agents/${agentId}/metrics?limit=${limit}`); - - if (!response.ok) { - throw new Error(`Failed to fetch agent metrics: ${response.statusText}`); - } - - return response.json(); -} - -export function formatBytes(bytes: number): string { - if (bytes === 0) return '0 B'; - const k = 1024; - const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`; -} - -export function getStatusColor(status: string): string { - switch (status) { - case 'online': - return 'text-green-500'; - case 'offline': - return 'text-gray-500'; - case 'error': - return 'text-red-500'; - default: - return 'text-gray-500'; - } -} - -export function getStatusBadgeClass(status: string): string { - switch (status) { - case 'online': - return 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'; - case 'offline': - return 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200'; - case 'error': - return 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200'; - default: - return 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200'; - } -} diff --git a/frontend/src/lib/services/api-client.ts b/frontend/src/lib/services/api-client.ts deleted file mode 100644 index ee135cc..0000000 --- a/frontend/src/lib/services/api-client.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { PUBLIC_API_BASE_URL } from '$env/static/public'; -import { browser } from '$app/environment'; -import { goto } from '$app/navigation'; -import { authStore } from '$lib/stores/auth'; -import { logger } from '$lib/utils/logger'; -import { get } from 'svelte/store'; - -const API_BASE_URL = PUBLIC_API_BASE_URL; - -export interface ApiError extends Error { - status: number; - statusText: string; -} - -export class ApiClient { - /** - * Makes an authenticated API request with automatic error handling - * and logout on 401 errors - */ - static async fetch(url: string, options: RequestInit = {}, token?: string): Promise { - logger.debug(`Making request to: ${url}`, { method: options.method || 'GET' }); - - // Get token from store if not provided - if (!token && browser) { - const authState = get(authStore); - token = authState.token ?? undefined; - console.log('[ApiClient] Token from store:', { - hasToken: !!token, - isAuthenticated: authState.isAuthenticated, - }); - } - - // Add authorization header if token exists - const headers: Record = {}; - - if (options.headers) { - if (options.headers instanceof Headers) { - options.headers.forEach((value, key) => { - headers[key] = value; - }); - } else if (Array.isArray(options.headers)) { - options.headers.forEach(([key, value]) => { - headers[key] = value; - }); - } else { - Object.assign(headers, options.headers); - } - } - - if (token) { - logger.debug('Attaching token to request headers'); - headers['Authorization'] = `Bearer ${token}`; - } else { - logger.warn('No token found to attach to request'); - } - - try { - logger.debug('Sending fetch request...'); - const response = await fetch(`${API_BASE_URL}${url}`, { - ...options, - headers, - credentials: 'include', // Important for cookies - }); - - logger.info(`Received response from: ${url}`, { - status: response.status, - statusText: response.statusText, - }); - - // Handle 401 Unauthorized - session expired or invalid - if (response.status === 401) { - logger.warn('Received 401 Unauthorized, logging out user'); - await this.handleUnauthorized(); - - const error = new Error('Unauthorized') as ApiError; - error.status = 401; - error.statusText = 'Unauthorized'; - throw error; - } - - return response; - } catch (error) { - // Re-throw API errors - if ((error as ApiError).status === 401) { - throw error; - } - - // Network or other errors - logger.error(`API request to ${url} failed`, error); - throw error; - } - } - - /** - * Helper for GET requests - */ - static async get(url: string, token?: string): Promise { - return this.fetch(url, { method: 'GET' }, token); - } - - /** - * Helper for POST requests - */ - static async post(url: string, body?: unknown, token?: string): Promise { - const headers: Record = { - 'Content-Type': 'application/json', - }; - - return this.fetch( - url, - { - method: 'POST', - headers, - body: body ? JSON.stringify(body) : undefined, - }, - token - ); - } - - /** - * Helper for PUT requests - */ - static async put(url: string, body?: unknown, token?: string): Promise { - const headers: Record = { - 'Content-Type': 'application/json', - }; - - return this.fetch( - url, - { - method: 'PUT', - headers, - body: body ? JSON.stringify(body) : undefined, - }, - token - ); - } - - /** - * Helper for DELETE requests - */ - static async delete(url: string, token?: string): Promise { - return this.fetch(url, { method: 'DELETE' }, token); - } - - /** - * Handles unauthorized access - logs out user and redirects to signin - */ - private static async handleUnauthorized() { - logger.info('Handling unauthorized access - logging out user'); - - // Clear auth cookie - try { - await fetch('/api/set-auth-cookie', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ token: null }), - }); - logger.debug('Auth cookie cleared'); - } catch (error) { - logger.error('Failed to clear auth cookie', error); - } - - // Update auth store - authStore.logout(); - logger.debug('Auth store updated - user logged out'); - - // Redirect to signin page - if (browser && window.location.pathname !== '/signin') { - logger.info('Redirecting to signin page'); - goto('/signin'); - } - } -} diff --git a/frontend/src/lib/services/auth.ts b/frontend/src/lib/services/auth.ts deleted file mode 100644 index 71cf338..0000000 --- a/frontend/src/lib/services/auth.ts +++ /dev/null @@ -1,132 +0,0 @@ -// @ts-ignore -import * as forge from 'node-forge'; - -import { PUBLIC_API_BASE_URL } from '$env/static/public'; - -const API_BASE_URL = PUBLIC_API_BASE_URL; - -interface RegisterRequest { - username: string; - encrypted_password: string; -} - -interface LoginRequest { - username: string; - encrypted_password: string; - two_factor_code?: string; -} - -interface AuthResponse { - token: string; - user_id: string; - username: string; - two_factor_enabled: boolean; - force_password_change: boolean; -} - -interface PublicKeyResponse { - public_key: string; -} - -export class AuthService { - private static publicKey: string | null = null; - - static async getPublicKey(): Promise { - if (this.publicKey) { - return this.publicKey; - } - - const response = await fetch(`${API_BASE_URL}/public-key`); - if (!response.ok) { - throw new Error('Failed to get public key'); - } - - const data: PublicKeyResponse = await response.json(); - this.publicKey = data.public_key; - return this.publicKey; - } - - static encryptPassword(password: string, publicKey: string): string { - const publicKeyObj = forge.pki.publicKeyFromPem(publicKey); - // Use RSA-OAEP with SHA-256 for encryption - const encrypted = publicKeyObj.encrypt(password, 'RSA-OAEP', { - md: forge.md.sha256.create() - }); - return forge.util.encode64(encrypted); - } - - static async register(username: string, password: string): Promise { - const publicKey = await this.getPublicKey(); - const encryptedPassword = this.encryptPassword(password, publicKey); - - const request: RegisterRequest = { - username, - encrypted_password: encryptedPassword, - }; - - const response = await fetch(`${API_BASE_URL}/register`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(request), - }); - - if (!response.ok) { - if (response.status === 409) { - throw new Error('User already exists'); - } - throw new Error('Registration failed'); - } - - return await response.json(); - } - - static async login( - username: string, - password: string, - twoFactorCode?: string - ): Promise { - const publicKey = await this.getPublicKey(); - const encryptedPassword = this.encryptPassword(password, publicKey); - - const request: LoginRequest = { - username, - encrypted_password: encryptedPassword, - two_factor_code: twoFactorCode, - }; - - const response = await fetch(`${API_BASE_URL}/login`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(request), - }); - - if (!response.ok) { - if (response.status === 401) { - throw new Error('Invalid credentials'); - } - if (response.status === 403) { - throw new Error('2FA_REQUIRED'); - } - throw new Error('Login failed'); - } - - return await response.json(); - } - - static async logout(token: string): Promise { - const response = await fetch(`${API_BASE_URL}/logout`, { - method: 'POST', - headers: { - Authorization: `Bearer ${token}`, - }, - }); - - if (!response.ok && response.status !== 401) { - throw new Error('Logout failed'); - } - } -} diff --git a/frontend/src/lib/services/budget.ts b/frontend/src/lib/services/budget.ts deleted file mode 100644 index 8ea3f1f..0000000 --- a/frontend/src/lib/services/budget.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { ApiClient } from './api-client'; -import type { Budget, CreateBudgetRequest, UpdateBudgetRequest, BudgetOverview } from '$lib/types'; - -export class BudgetService { - static async getBudgets(token: string): Promise { - const response = await ApiClient.get('/budgets', token); - - if (!response.ok) { - throw new Error('Failed to fetch budgets'); - } - - return await response.json(); - } - - static async getBudgetByMonth(month: string, token: string): Promise { - const response = await ApiClient.get(`/budgets/${month}`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Budget not found for this month'); - } - throw new Error('Failed to fetch budget'); - } - - return await response.json(); - } - - static async getBudgetOverview(month: string, token: string): Promise { - const response = await ApiClient.get(`/budgets/${month}/overview`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Budget not found for this month'); - } - throw new Error('Failed to fetch budget overview'); - } - - return await response.json(); - } - - static async createBudget(budget: CreateBudgetRequest, token: string): Promise { - const response = await ApiClient.post('/budgets', budget, token); - - if (!response.ok) { - throw new Error('Failed to create budget'); - } - - return await response.json(); - } - - static async updateBudget( - month: string, - budget: UpdateBudgetRequest, - token: string - ): Promise { - const response = await ApiClient.put(`/budgets/${month}`, budget, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Budget not found'); - } - throw new Error('Failed to update budget'); - } - - return await response.json(); - } - - static async deleteBudget(month: string, token: string): Promise { - const response = await ApiClient.delete(`/budgets/${month}`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Budget not found'); - } - throw new Error('Failed to delete budget'); - } - } -} diff --git a/frontend/src/lib/services/expenses.ts b/frontend/src/lib/services/expenses.ts deleted file mode 100644 index 010993b..0000000 --- a/frontend/src/lib/services/expenses.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { ApiClient } from './api-client'; - -export interface Expense { - id: string; - user_id: string; - description: string; - amount: number; - date: string; - category: string; -} - -export interface CreateExpenseRequest { - description: string; - amount: number; - date: string; - category: string; -} - -export interface UpdateExpenseRequest { - description?: string; - amount?: number; - date?: string; - category?: string; -} - -export class ExpenseService { - static async getExpenses(token: string): Promise { - const response = await ApiClient.get('/expenses', token); - - if (!response.ok) { - throw new Error('Failed to fetch expenses'); - } - - return await response.json(); - } - - static async getExpense(id: string, token: string): Promise { - const response = await ApiClient.get(`/expenses/${id}`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Expense not found'); - } - throw new Error('Failed to fetch expense'); - } - - return await response.json(); - } - - static async createExpense(expense: CreateExpenseRequest, token: string): Promise { - const response = await ApiClient.post('/expenses', expense, token); - - if (!response.ok) { - throw new Error('Failed to create expense'); - } - - return await response.json(); - } - - static async updateExpense( - id: string, - expense: UpdateExpenseRequest, - token: string - ): Promise { - const response = await ApiClient.put(`/expenses/${id}`, expense, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Expense not found'); - } - throw new Error('Failed to update expense'); - } - - return await response.json(); - } - - static async deleteExpense(id: string, token: string): Promise { - const response = await ApiClient.delete(`/expenses/${id}`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Expense not found'); - } - throw new Error('Failed to delete expense'); - } - } -} diff --git a/frontend/src/lib/services/invoice.ts b/frontend/src/lib/services/invoice.ts deleted file mode 100644 index b35e617..0000000 --- a/frontend/src/lib/services/invoice.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { ApiClient } from './api-client'; -import type { - Invoice, - ManualEntry, - CreateInvoiceRequest, - CreateManualEntryRequest, - InvoiceOverview, -} from '$lib/types'; - -export class InvoiceService { - static async getInvoices(month: string, token: string): Promise { - const response = await ApiClient.get(`/invoices?month=${month}`, token); - - if (!response.ok) { - throw new Error('Failed to fetch invoices'); - } - - return await response.json(); - } - - static async getInvoice(id: string, token: string): Promise { - const response = await ApiClient.get(`/invoices/${id}`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Invoice not found'); - } - throw new Error('Failed to fetch invoice'); - } - - return await response.json(); - } - - static async createInvoice(invoice: CreateInvoiceRequest, token: string): Promise { - const formData = new FormData(); - formData.append('month', invoice.month); - formData.append('description', invoice.description); - formData.append('amount', invoice.amount.toString()); - formData.append('date', invoice.date); - formData.append('category', invoice.category); - - if (invoice.file) { - formData.append('file', invoice.file); - } - - const response = await ApiClient.fetch( - '/invoices', - { - method: 'POST', - body: formData, - }, - token - ); - - if (!response.ok) { - throw new Error('Failed to create invoice'); - } - - return await response.json(); - } - - static async deleteInvoice(id: string, token: string): Promise { - const response = await ApiClient.delete(`/invoices/${id}`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Invoice not found'); - } - throw new Error('Failed to delete invoice'); - } - } - - static async getManualEntries(month: string, token: string): Promise { - const response = await ApiClient.get(`/manual-entries?month=${month}`, token); - - if (!response.ok) { - throw new Error('Failed to fetch manual entries'); - } - - return await response.json(); - } - - static async createManualEntry( - entry: CreateManualEntryRequest, - token: string - ): Promise { - const response = await ApiClient.post('/manual-entries', entry, token); - - if (!response.ok) { - throw new Error('Failed to create manual entry'); - } - - return await response.json(); - } - - static async deleteManualEntry(id: string, token: string): Promise { - const response = await ApiClient.delete(`/manual-entries/${id}`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Manual entry not found'); - } - throw new Error('Failed to delete manual entry'); - } - } - - static async getInvoiceOverview(month: string, token: string): Promise { - const response = await ApiClient.get(`/invoices/${month}/overview`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('No data found for this month'); - } - throw new Error('Failed to fetch invoice overview'); - } - - return await response.json(); - } - - static async matchInvoices(month: string, token: string): Promise { - const response = await ApiClient.post(`/invoices/${month}/match`, {}, token); - - if (!response.ok) { - throw new Error('Failed to match invoices'); - } - - return await response.json(); - } -} diff --git a/frontend/src/lib/services/marketplace.ts b/frontend/src/lib/services/marketplace.ts deleted file mode 100644 index 82da59d..0000000 --- a/frontend/src/lib/services/marketplace.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { ApiClient } from './api-client'; - -export interface MarketplaceTemplate { - id: string; - template_id: string; - name: string; - description: string; - icon: string; - category: string; - resource_type: string; - configuration: any; - popular: boolean; - install_count: number; -} - -export interface InstallTemplateRequest { - template_id: string; - name: string; - resource_group_id: string; -} - -async function handleResponse(response: Response): Promise { - if (!response.ok) { - let errorMessage = 'Request failed'; - try { - const errorData = await response.json(); - errorMessage = errorData.error || errorData.message || errorMessage; - } catch { - errorMessage = response.statusText || errorMessage; - } - throw new Error(errorMessage); - } - - return response.json(); -} - -export async function listTemplates(): Promise { - const response = await ApiClient.get('/marketplace/templates'); - return handleResponse(response); -} - -export async function listPopularTemplates(): Promise { - const response = await ApiClient.get('/marketplace/templates/popular'); - return handleResponse(response); -} - -export async function getTemplate(templateId: string): Promise { - const response = await ApiClient.get(`/marketplace/templates/${templateId}`); - return handleResponse(response); -} - -export async function installTemplate(data: InstallTemplateRequest): Promise { - const response = await ApiClient.post('/marketplace/install', data); - return handleResponse(response); -} - -export async function seedMarketplace(): Promise { - const response = await ApiClient.post('/marketplace/seed', {}); - return handleResponse(response); -} diff --git a/frontend/src/lib/services/organization.ts b/frontend/src/lib/services/organization.ts deleted file mode 100644 index c11736a..0000000 --- a/frontend/src/lib/services/organization.ts +++ /dev/null @@ -1,103 +0,0 @@ -import type { - Organization, - Role, - User, - CreateUserRequest, - UpdateUserRequest, - UpdateUserRoleRequest, - UpdateOrganizationRequest, -} from '$lib/types/organization'; -import { ApiClient } from './api-client'; - -export const organizationService = { - // Organization endpoints - async getOrganization(): Promise { - const response = await ApiClient.get('/organization'); - if (!response.ok) { - throw new Error('Failed to fetch organization'); - } - return response.json(); - }, - - async updateOrganization(data: UpdateOrganizationRequest): Promise { - const response = await ApiClient.fetch('/organization', { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(data), - }); - if (!response.ok) { - throw new Error('Failed to update organization'); - } - return response.json(); - }, - - // Roles - async getRoles(): Promise { - const response = await ApiClient.get('/organization/roles'); - if (!response.ok) { - throw new Error('Failed to fetch roles'); - } - return response.json(); - }, - - // User management - async listUsers(): Promise { - const response = await ApiClient.get('/organization/users'); - if (!response.ok) { - throw new Error('Failed to fetch users'); - } - return response.json(); - }, - - async getUser(userId: string): Promise { - const response = await ApiClient.get(`/organization/users/${userId}`); - if (!response.ok) { - throw new Error('Failed to fetch user'); - } - return response.json(); - }, - - async createUser(data: CreateUserRequest): Promise { - const response = await ApiClient.fetch('/organization/users', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(data), - }); - if (!response.ok) { - throw new Error('Failed to create user'); - } - return response.json(); - }, - - async updateUser(userId: string, data: UpdateUserRequest): Promise { - const response = await ApiClient.fetch(`/organization/users/${userId}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(data), - }); - if (!response.ok) { - throw new Error('Failed to update user'); - } - return response.json(); - }, - - async deleteUser(userId: string): Promise { - const response = await ApiClient.fetch(`/organization/users/${userId}`, { - method: 'DELETE', - }); - if (!response.ok) { - throw new Error('Failed to delete user'); - } - }, - - async updateUserRole(userId: string, data: UpdateUserRoleRequest): Promise { - const response = await ApiClient.fetch(`/organization/users/${userId}/role`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(data), - }); - if (!response.ok) { - throw new Error('Failed to update user role'); - } - }, -}; diff --git a/frontend/src/lib/services/resource-groups.ts b/frontend/src/lib/services/resource-groups.ts deleted file mode 100644 index 02be6c3..0000000 --- a/frontend/src/lib/services/resource-groups.ts +++ /dev/null @@ -1,67 +0,0 @@ -import type { - ResourceGroup, - CreateResourceGroupRequest, - UpdateResourceGroupRequest, -} from '$lib/types/resource-group'; -import { ApiClient } from './api-client'; - -async function handleResponse(response: Response): Promise { - const contentType = response.headers.get('content-type'); - - if (!response.ok) { - // Check if response is JSON - if (contentType && contentType.includes('application/json')) { - const error = await response.json(); - throw new Error(error.error || error.message || `HTTP ${response.status}`); - } else { - // If not JSON, it might be HTML (error page or redirect) - const text = await response.text(); - console.error('Non-JSON response:', response.status, text.substring(0, 200)); - - if (response.status === 401) { - throw new Error('Not authenticated. Please log in again.'); - } - throw new Error(`Request failed with status ${response.status}`); - } - } - - // Successful response - if (contentType && contentType.includes('application/json')) { - return response.json(); - } else { - throw new Error('Expected JSON response but got: ' + contentType); - } -} - -export async function listResourceGroups(): Promise { - const response = await ApiClient.get('/resource-groups'); - return handleResponse(response); -} - -export async function getResourceGroup(id: string): Promise { - const response = await ApiClient.get(`/resource-groups/${id}`); - return handleResponse(response); -} - -export async function createResourceGroup( - data: CreateResourceGroupRequest -): Promise { - const response = await ApiClient.post('/resource-groups', data); - return handleResponse(response); -} - -export async function updateResourceGroup( - id: string, - data: UpdateResourceGroupRequest -): Promise { - const response = await ApiClient.put(`/resource-groups/${id}`, data); - return handleResponse(response); -} - -export async function deleteResourceGroup(id: string): Promise { - const response = await ApiClient.delete(`/resource-groups/${id}`); - - if (!response.ok) { - await handleResponse(response); - } -} diff --git a/frontend/src/lib/services/resources.ts b/frontend/src/lib/services/resources.ts deleted file mode 100644 index a415486..0000000 --- a/frontend/src/lib/services/resources.ts +++ /dev/null @@ -1,100 +0,0 @@ -import type { Resource, CreateResourceRequest, UpdateResourceRequest } from '$lib/types/resource'; -import { ApiClient } from './api-client'; - -async function handleResponse(response: Response): Promise { - if (!response.ok) { - let errorMessage = 'Request failed'; - try { - const errorData = await response.json(); - errorMessage = errorData.error || errorData.message || errorMessage; - } catch { - errorMessage = response.statusText || errorMessage; - } - throw new Error(errorMessage); - } - - // Handle 204 No Content - if (response.status === 204) { - return undefined as T; - } - - return response.json(); -} - -export async function listResources(): Promise { - const response = await ApiClient.get('/resources'); - return handleResponse(response); -} - -export async function listResourcesByGroup(resourceGroupId: string): Promise { - const response = await ApiClient.get(`/resource-groups/${resourceGroupId}/resources`); - return handleResponse(response); -} - -export async function getResource(id: string): Promise { - const response = await ApiClient.get(`/resources/${id}`); - return handleResponse(response); -} - -export async function createResource(data: CreateResourceRequest): Promise { - const response = await ApiClient.post('/resources', data); - return handleResponse(response); -} - -export async function updateResource(id: string, data: UpdateResourceRequest): Promise { - const response = await ApiClient.put(`/resources/${id}`, data); - return handleResponse(response); -} - -export async function deleteResource(id: string): Promise { - const response = await ApiClient.delete(`/resources/${id}`); - - if (!response.ok) { - await handleResponse(response); - } -} - -export async function performResourceAction( - id: string, - action: 'start' | 'stop' | 'restart' -): Promise { - const response = await ApiClient.post(`/resources/${id}/action`, { action }); - return handleResponse(response); -} - -export interface DeployContainerRequest { - name: string; - image: string; - resource_group_id: string; - description?: string; - ports?: Array<{ container: number; host: number }>; - environment?: Record; - volumes?: Array<{ host: string; container: string }>; -} - -export async function deployContainer(data: DeployContainerRequest): Promise { - const response = await ApiClient.post('/resources/deploy', data); - return handleResponse(response); -} - -export interface ResourceLogsResponse { - logs: string; -} - -export async function getResourceLogs(id: string): Promise { - const response = await ApiClient.get(`/resources/${id}/logs`); - return handleResponse(response); -} - -export interface ExecCommandRequest { - command: string; -} - -export interface ExecCommandResponse { - output: string; -} - -export async function execCommand(id: string, command: string): Promise { - const response = await ApiClient.post(`/resources/${id}/exec`, { command }); - return handleResponse(response); -} diff --git a/frontend/src/lib/services/settings.ts b/frontend/src/lib/services/settings.ts deleted file mode 100644 index 924680d..0000000 --- a/frontend/src/lib/services/settings.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { ApiClient } from './api-client'; -import { logger } from '$lib/utils/logger'; - -export interface Setup2FAResponse { - secret: string; - qr_code: string; -} - -export class SettingsService { - /** - * Setup 2FA - Generate secret and QR code - */ - static async setup2FA(): Promise { - logger.info('Setting up 2FA'); - - const response = await ApiClient.post('/2fa/setup'); - - if (!response.ok) { - throw new Error(`Failed to setup 2FA: ${response.statusText}`); - } - - return response.json(); - } - - /** - * Enable 2FA with verification code - */ - static async enable2FA(code: string): Promise { - logger.info('Enabling 2FA'); - - const response = await ApiClient.post('/2fa/enable', { code }); - - if (!response.ok) { - const error = await response.text(); - throw new Error(error || 'Failed to enable 2FA'); - } - } - - /** - * Disable 2FA with verification code - */ - static async disable2FA(code: string): Promise { - logger.info('Disabling 2FA'); - - const response = await ApiClient.post('/2fa/disable', { code }); - - if (!response.ok) { - const error = await response.text(); - throw new Error(error || 'Failed to disable 2FA'); - } - } - - /** - * Change user password - */ - static async changePassword(oldPassword: string, newPassword: string): Promise { - logger.info('Changing password'); - - const response = await ApiClient.post('/change-password', { - old_password: oldPassword, - new_password: newPassword, - }); - - if (!response.ok) { - const error = await response.text(); - throw new Error(error || 'Failed to change password'); - } - } - - /** - * Change user email - */ - static async changeEmail(newEmail: string): Promise { - logger.info('Changing email'); - - const response = await ApiClient.post('/change-email', { - new_email: newEmail, - }); - - if (!response.ok) { - const error = await response.text(); - throw new Error(error || 'Failed to change email'); - } - } - - /** - * Get user profile with 2FA status - */ - static async getProfile(): Promise<{ - id: string; - username: string; - email?: string; - two_factor_enabled: boolean; - force_password_change: boolean; - }> { - logger.info('Fetching user profile'); - - const response = await ApiClient.get('/profile'); - - if (!response.ok) { - throw new Error(`Failed to get profile: ${response.statusText}`); - } - - return response.json(); - } -} diff --git a/frontend/src/lib/services/subscriptions.ts b/frontend/src/lib/services/subscriptions.ts deleted file mode 100644 index 02eb66c..0000000 --- a/frontend/src/lib/services/subscriptions.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { ApiClient } from './api-client'; - -export interface Subscription { - id: string; - user_id: string; - name: string; - amount: number; - billing_cycle: string; - next_billing_date: string; - category: string; - is_active: boolean; -} - -export interface CreateSubscriptionRequest { - name: string; - amount: number; - billing_cycle: string; - next_billing_date: string; - category: string; -} - -export interface UpdateSubscriptionRequest { - name?: string; - amount?: number; - billing_cycle?: string; - next_billing_date?: string; - category?: string; - is_active?: boolean; -} - -export class SubscriptionService { - static async getSubscriptions(token: string): Promise { - const response = await ApiClient.get('/subscriptions', token); - - if (!response.ok) { - throw new Error('Failed to fetch subscriptions'); - } - - return await response.json(); - } - - static async getSubscription(id: string, token: string): Promise { - const response = await ApiClient.get(`/subscriptions/${id}`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Subscription not found'); - } - throw new Error('Failed to fetch subscription'); - } - - return await response.json(); - } - - static async createSubscription( - subscription: CreateSubscriptionRequest, - token: string - ): Promise { - const response = await ApiClient.post('/subscriptions', subscription, token); - - if (!response.ok) { - throw new Error('Failed to create subscription'); - } - - return await response.json(); - } - - static async updateSubscription( - id: string, - subscription: UpdateSubscriptionRequest, - token: string - ): Promise { - const response = await ApiClient.put(`/subscriptions/${id}`, subscription, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Subscription not found'); - } - throw new Error('Failed to update subscription'); - } - - return await response.json(); - } - - static async deleteSubscription(id: string, token: string): Promise { - const response = await ApiClient.delete(`/subscriptions/${id}`, token); - - if (!response.ok) { - if (response.status === 404) { - throw new Error('Subscription not found'); - } - throw new Error('Failed to delete subscription'); - } - } -} diff --git a/frontend/src/lib/services/system.ts b/frontend/src/lib/services/system.ts deleted file mode 100644 index 9aa4290..0000000 --- a/frontend/src/lib/services/system.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { ApiClient } from './api-client'; - -export interface LocalSystemInfo { - hostname: string; - os_name: string; - os_version: string; - kernel_version: string; - uptime_seconds: number; - cpu_model: string; - cpu_cores: number; - cpu_threads: number; -} - -export interface LocalSystemMetrics { - timestamp: string; - cpu_model: string; - cpu_cores: number; - cpu_threads: number; - cpu_usage_percent: number; - memory_total_bytes: number; - memory_used_bytes: number; - memory_usage_percent: number; - disk_total_bytes: number; - disk_used_bytes: number; - disk_usage_percent: number; - network_rx_bytes: number; - network_tx_bytes: number; - os_name: string; - os_version: string; - kernel_version: string; - hostname: string; - uptime_seconds: number; -} - -export async function getLocalSystemInfo(): Promise { - const response = await ApiClient.get('/system/info'); - - if (!response.ok) { - throw new Error(`Failed to fetch system info: ${response.statusText}`); - } - - return response.json(); -} - -export async function getLocalSystemMetrics(): Promise { - const response = await ApiClient.get('/system/metrics'); - - if (!response.ok) { - throw new Error(`Failed to fetch system metrics: ${response.statusText}`); - } - - const data = await response.json(); - return data.metrics; -} - -export function formatUptime(seconds: number): string { - const days = Math.floor(seconds / 86400); - const hours = Math.floor((seconds % 86400) / 3600); - const minutes = Math.floor((seconds % 3600) / 60); - - const parts = []; - if (days > 0) parts.push(`${days}d`); - if (hours > 0) parts.push(`${hours}h`); - if (minutes > 0) parts.push(`${minutes}m`); - - return parts.join(' ') || '0m'; -} diff --git a/frontend/src/lib/services/updates.ts b/frontend/src/lib/services/updates.ts deleted file mode 100644 index f4e5fc7..0000000 --- a/frontend/src/lib/services/updates.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { ApiClient } from './api-client'; - -export interface VersionInfo { - current_version: string; - latest_version: string; - update_available: boolean; - changelog: string | null; - release_url: string; - is_prerelease: boolean; - latest_beta_version: string | null; - beta_release_url: string | null; -} - -export interface UpdateResponse { - success: boolean; - message: string; -} - -export class UpdateService { - /** - * Check for available updates - */ - async checkForUpdates(): Promise { - const response = await ApiClient.get('/updates/check'); - - if (!response.ok) { - throw new Error(`Failed to check for updates: ${response.statusText}`); - } - - return await response.json(); - } - - /** - * Install a specific version - */ - async installUpdate(version: string): Promise { - const response = await ApiClient.post('/updates/install', { version }); - - if (!response.ok) { - throw new Error(`Failed to install update: ${response.statusText}`); - } - - return await response.json(); - } - - /** - * Get changelog for a specific version - */ - async getChangelog(version: string): Promise { - const response = await ApiClient.get(`/updates/changelog/${version}`); - - if (!response.ok) { - throw new Error(`Failed to get changelog: ${response.statusText}`); - } - - return await response.json(); - } -} - -export const updateService = new UpdateService(); diff --git a/frontend/src/lib/stores/auth.ts b/frontend/src/lib/stores/auth.ts deleted file mode 100644 index aeffadd..0000000 --- a/frontend/src/lib/stores/auth.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { writable } from 'svelte/store'; -import { browser } from '$app/environment'; -import { ApiClient } from '$lib/services/api-client'; -import { logger } from '$lib/utils/logger'; - -interface User { - id: string; - username: string; - force_password_change?: boolean; - two_factor_enabled?: boolean; -} - -interface AuthState { - user: User | null; - token: string | null; - isAuthenticated: boolean; - isLoading: boolean; -} - -const initialState: AuthState = { - user: null, - token: null, - isAuthenticated: false, - isLoading: false, -}; - -function createAuthStore() { - const { subscribe, set, update } = writable(initialState); - - return { - subscribe, - init: (user: User | null, token: string | null) => { - logger.info('Initializing auth store', { hasUser: !!user, hasToken: !!token }); - if (browser) { - if (user && token) { - logger.info('User and token found, setting authenticated state'); - set({ - user, - token, - isAuthenticated: true, - isLoading: false, - }); - } else { - logger.debug('No user or token, setting initial state'); - set(initialState); - } - } - }, - login: (user: User, token: string) => { - logger.info('Logging in user', { username: user.username, userId: user.id }); - set({ - user, - token, - isAuthenticated: true, - isLoading: false, - }); - }, - logout: () => { - logger.info('Logging out user'); - - // Cookie is deleted by the /api/set-auth-cookie endpoint - set(initialState); - }, - setLoading: (loading: boolean) => { - update((state) => ({ ...state, isLoading: loading })); - }, - }; -} - -export const authStore = createAuthStore(); diff --git a/frontend/src/lib/stores/theme.ts b/frontend/src/lib/stores/theme.ts deleted file mode 100644 index 2e0a9c3..0000000 --- a/frontend/src/lib/stores/theme.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { writable, derived, type Unsubscriber } from 'svelte/store'; - -export type Theme = 'light' | 'dark' | 'system'; - -// runtime store that holds user's preference: 'light' | 'dark' | 'system' -export const theme = writable('system'); - -// derived store that yields the effective theme (based on system preference when 'system') -export const effectiveTheme = derived(theme, ($theme, set) => { - let mq: MediaQueryList | null = null; - - const update = () => { - let prefersDark = false; - try { - prefersDark = - typeof window !== 'undefined' && window.matchMedia('(prefers-color-scheme: dark)').matches; - } catch (e) { - prefersDark = false; - } - set($theme === 'system' ? (prefersDark ? 'dark' : 'light') : $theme); - }; - - update(); - - if (typeof window !== 'undefined') { - try { - // matchMedia returns a MediaQueryList which in older browsers used addListener/removeListener - mq = window.matchMedia('(prefers-color-scheme: dark)'); - const listener = () => update(); - // modern - if ((mq as any).addEventListener) (mq as any).addEventListener('change', listener); - // fallback - else if ((mq as any).addListener) (mq as any).addListener(listener); - - return () => { - if (!mq) return; - if ((mq as any).removeEventListener) (mq as any).removeEventListener('change', listener); - else if ((mq as any).removeListener) (mq as any).removeListener(listener); - }; - } catch (e) { - // ignore - } - } - - return undefined as unknown as Unsubscriber; -}); - -export function setTheme(t: Theme) { - theme.set(t); - try { - localStorage.setItem('theme', t); - } catch (e) { - /* ignore */ - } -} - -export function initThemeFromStorage() { - if (typeof window === 'undefined') return; - try { - const stored = localStorage.getItem('theme') as Theme | null; - if (stored === 'light' || stored === 'dark' || stored === 'system') theme.set(stored); - } catch (e) { - // ignore - } -} - -export function clearStoredTheme() { - try { - localStorage.removeItem('theme'); - } catch (e) { - /* ignore */ - } - theme.set('system'); -} diff --git a/frontend/src/lib/stores/updates.ts b/frontend/src/lib/stores/updates.ts deleted file mode 100644 index dd3b554..0000000 --- a/frontend/src/lib/stores/updates.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { writable, derived } from 'svelte/store'; -import { updateService, type VersionInfo } from '$lib/services/updates'; - -interface UpdateState { - versionInfo: VersionInfo | null; - loading: boolean; - error: string | null; - lastChecked: Date | null; - isInstalling: boolean; -} - -const initialState: UpdateState = { - versionInfo: null, - loading: false, - error: null, - lastChecked: null, - isInstalling: false -}; - -function createUpdateStore() { - const { subscribe, set, update } = writable(initialState); - - // Check for updates every hour - let intervalId: number | null = null; - - return { - subscribe, - - async checkForUpdates() { - update((state) => ({ ...state, loading: true, error: null })); - - try { - const versionInfo = await updateService.checkForUpdates(); - update((state) => ({ - ...state, - versionInfo, - loading: false, - lastChecked: new Date() - })); - } catch (error) { - update((state) => ({ - ...state, - loading: false, - error: error instanceof Error ? error.message : 'Failed to check for updates' - })); - } - }, - - async installUpdate(version: string) { - update((state) => ({ ...state, isInstalling: true, error: null })); - - try { - const response = await updateService.installUpdate(version); - if (response.success) { - update((state) => ({ ...state, isInstalling: false })); - return response; - } else { - throw new Error(response.message); - } - } catch (error) { - update((state) => ({ - ...state, - isInstalling: false, - error: error instanceof Error ? error.message : 'Failed to install update' - })); - throw error; - } - }, - - startAutoCheck() { - // Check immediately - this.checkForUpdates(); - - // Then check every hour - if (intervalId === null) { - intervalId = window.setInterval( - () => { - this.checkForUpdates(); - }, - 60 * 60 * 1000 - ); // 1 hour - } - }, - - stopAutoCheck() { - if (intervalId !== null) { - clearInterval(intervalId); - intervalId = null; - } - }, - - reset() { - set(initialState); - } - }; -} - -export const updateStore = createUpdateStore(); - -// Derived store for easy access to update availability -export const updateAvailable = derived(updateStore, ($updateStore) => { - return $updateStore.versionInfo?.update_available ?? false; -}); diff --git a/frontend/src/lib/types/agent.ts b/frontend/src/lib/types/agent.ts deleted file mode 100644 index 6ad7c5e..0000000 --- a/frontend/src/lib/types/agent.ts +++ /dev/null @@ -1,35 +0,0 @@ -export interface Agent { - id: string; - name: string; - hostname: string; - agent_version: string; - os_type: string; - os_version: string; - status: 'online' | 'offline' | 'error'; - last_heartbeat: string; - tags?: Record; - capabilities?: string[]; - organization_id?: string; - created_at: string; - updated_at: string; -} - -export interface AgentMetrics { - id: string; - agent_id: string; - timestamp: string; - cpu_usage_percent: number; - memory_usage_percent: number; - memory_total_bytes: number; - memory_used_bytes: number; - disk_usage_percent: number; - disk_total_bytes: number; - disk_used_bytes: number; - network_rx_bytes?: number; - network_tx_bytes?: number; - custom_metrics?: Record; -} - -export interface AgentWithLatestMetrics extends Agent { - latest_metrics?: AgentMetrics; -} diff --git a/frontend/src/lib/types/index.ts b/frontend/src/lib/types/index.ts deleted file mode 100644 index 5d8a540..0000000 --- a/frontend/src/lib/types/index.ts +++ /dev/null @@ -1,120 +0,0 @@ -// Re-export types from services -export type { Expense, CreateExpenseRequest, UpdateExpenseRequest } from '../services/expenses'; -export type { - Subscription, - CreateSubscriptionRequest, - UpdateSubscriptionRequest, -} from '../services/subscriptions'; - -// Budget types -export interface Budget { - id: string; - user_id: string; - month: string; // YYYY-MM format - total_budget: number; - categories: BudgetCategory[]; - created_at: string; - updated_at: string; -} - -export interface BudgetCategory { - category: string; - allocated_amount: number; - spent_amount: number; -} - -export interface CreateBudgetRequest { - month: string; - total_budget: number; - categories: { - category: string; - allocated_amount: number; - }[]; -} - -export interface UpdateBudgetRequest { - total_budget?: number; - categories?: { - category: string; - allocated_amount: number; - }[]; -} - -export interface BudgetOverview { - budget: Budget; - total_spent: number; - remaining: number; - percentage_used: number; - categories: { - category: string; - allocated: number; - spent: number; - remaining: number; - percentage_used: number; - }[]; -} - -// Invoice types -export interface Invoice { - id: string; - user_id: string; - month: string; // YYYY-MM format - description: string; - amount: number; - date: string; - category: string; - file_url?: string; - verified: boolean; - created_at: string; - updated_at: string; -} - -export interface ManualEntry { - id: string; - user_id: string; - month: string; - description: string; - amount: number; - date: string; - category: string; - matched: boolean; - matched_invoice_id?: string; - created_at: string; - updated_at: string; -} - -export interface CreateInvoiceRequest { - month: string; - description: string; - amount: number; - date: string; - category: string; - file?: File; -} - -export interface CreateManualEntryRequest { - month: string; - description: string; - amount: number; - date: string; - category: string; -} - -export interface InvoiceMatch { - invoice_id: string; - manual_entry_id: string; - match_confidence: number; - matched_at: string; -} - -export interface InvoiceOverview { - month: string; - invoices: Invoice[]; - manual_entries: ManualEntry[]; - matches: InvoiceMatch[]; - total_invoices: number; - total_manual: number; - matched_count: number; - unmatched_invoices: number; - unmatched_manual: number; -} diff --git a/frontend/src/lib/types/organization.ts b/frontend/src/lib/types/organization.ts deleted file mode 100644 index f675671..0000000 --- a/frontend/src/lib/types/organization.ts +++ /dev/null @@ -1,47 +0,0 @@ -export interface Organization { - id: string; - name: string; - description: string | null; - created_at: string; - updated_at: string; -} - -export interface Role { - id: string; - name: string; - description: string | null; - is_system_role: boolean; -} - -export interface User { - id: string; - username: string; - email: string | null; - role_id: string; - role_name: string; - force_password_change: boolean; - two_factor_enabled: boolean; - joined_at: string; -} - -export interface CreateUserRequest { - username: string; - email: string | null; - password: string; - role_id: string; - force_password_change: boolean; -} - -export interface UpdateUserRequest { - email?: string | null; - force_password_change?: boolean; -} - -export interface UpdateUserRoleRequest { - role_id: string; -} - -export interface UpdateOrganizationRequest { - name: string; - description: string | null; -} diff --git a/frontend/src/lib/types/resource-group.ts b/frontend/src/lib/types/resource-group.ts deleted file mode 100644 index d009fb5..0000000 --- a/frontend/src/lib/types/resource-group.ts +++ /dev/null @@ -1,25 +0,0 @@ -export interface ResourceGroup { - id: string; - name: string; - description?: string; - organization_id: string; - created_by?: string; - created_at: string; - updated_at: string; - tags?: Record; - location?: string; -} - -export interface CreateResourceGroupRequest { - name: string; - description?: string; - location?: string; - tags?: Record; -} - -export interface UpdateResourceGroupRequest { - name?: string; - description?: string; - location?: string; - tags?: Record; -} diff --git a/frontend/src/lib/types/resource.ts b/frontend/src/lib/types/resource.ts deleted file mode 100644 index b2aab93..0000000 --- a/frontend/src/lib/types/resource.ts +++ /dev/null @@ -1,204 +0,0 @@ -export interface Resource { - id: string; - name: string; - resource_type: string; - description?: string; - resource_group_id: string; - resource_group_name: string; - configuration?: Record; - status: 'pending' | 'running' | 'stopped' | 'error'; - created_by?: string; - created_at: string; - updated_at: string; - tags?: Record; - container_id?: string; - stack_name?: string; -} - -export interface CreateResourceRequest { - name: string; - resource_type: string; - description?: string; - resource_group_id: string; - configuration?: Record; - tags?: Record; -} - -export interface UpdateResourceRequest { - name?: string; - description?: string; - configuration?: Record; - status?: 'pending' | 'running' | 'stopped' | 'error'; - tags?: Record; -} - -export interface DockerConfiguration { - image: string; - ports?: { container: number; host?: number }[]; - environment?: Record; - volumes?: { host: string; container: string }[]; - command?: string; - restart_policy?: 'no' | 'on-failure' | 'always' | 'unless-stopped'; -} - -export interface DockerStackConfiguration { - services: { - name: string; - image: string; - ports?: { container: number; host?: number }[]; - environment?: Record; - volumes?: { host: string; container: string }[]; - depends_on?: string[]; - restart_policy?: 'no' | 'on-failure' | 'always' | 'unless-stopped'; - }[]; - networks?: { - name: string; - driver?: 'bridge' | 'host' | 'overlay'; - }[]; -} - -export interface ResourceTypeTemplate { - type: string; - name: string; - description: string; - icon: string; - category: 'compute' | 'storage' | 'network' | 'database' | 'stack'; - configurationSchema?: Record; - template?: any; - popular?: boolean; -} - -export const RESOURCE_TYPES: ResourceTypeTemplate[] = [ - { - type: 'docker-stack', - name: 'Docker Stack', - description: - 'Mehrere zusammenhängende Docker Container. Perfekt für vollständige Anwendungen mit mehreren Services (z.B. Web + Datenbank + Cache).', - icon: '📦', - category: 'stack', - popular: true, - template: { - services: [ - { - name: 'web', - image: 'nginx:alpine', - ports: [{ container: 80, host: 8080 }], - environment: {}, - }, - ], - }, - }, -]; - -// Vorgefertigte Stack Templates für den Marketplace -export const MARKETPLACE_TEMPLATES = [ - { - id: 'wordpress', - name: 'WordPress + MySQL', - description: 'Vollständiger WordPress Stack mit MySQL Datenbank', - icon: '📝', - category: 'stack' as const, - type: 'docker-stack', - popular: true, - configuration: { - services: [ - { - name: 'wordpress', - image: 'wordpress:latest', - ports: [{ container: 80, host: 8080 }], - environment: { - WORDPRESS_DB_HOST: 'db:3306', - WORDPRESS_DB_USER: 'wordpress', - WORDPRESS_DB_PASSWORD: 'wordpress', - WORDPRESS_DB_NAME: 'wordpress', - }, - depends_on: ['db'], - restart_policy: 'always', - }, - { - name: 'db', - image: 'mysql:8.0', - environment: { - MYSQL_DATABASE: 'wordpress', - MYSQL_USER: 'wordpress', - MYSQL_PASSWORD: 'wordpress', - MYSQL_RANDOM_ROOT_PASSWORD: '1', - }, - volumes: [{ host: './db_data', container: '/var/lib/mysql' }], - restart_policy: 'always', - }, - ], - }, - }, - { - id: 'mern-stack', - name: 'MERN Stack', - description: 'MongoDB + Express + React + Node.js Entwicklungsumgebung', - icon: '🚀', - category: 'stack' as const, - type: 'docker-stack', - popular: true, - configuration: { - services: [ - { - name: 'mongodb', - image: 'mongo:7', - ports: [{ container: 27017, host: 27017 }], - volumes: [{ host: './mongodb_data', container: '/data/db' }], - restart_policy: 'always', - }, - { - name: 'backend', - image: 'node:20-alpine', - ports: [{ container: 5000, host: 5000 }], - environment: { - MONGODB_URI: 'mongodb://mongodb:27017/app', - NODE_ENV: 'development', - }, - depends_on: ['mongodb'], - restart_policy: 'always', - }, - { - name: 'frontend', - image: 'node:20-alpine', - ports: [{ container: 3000, host: 3000 }], - environment: { - REACT_APP_API_URL: 'http://localhost:5000', - }, - restart_policy: 'always', - }, - ], - }, - }, - { - id: 'nginx-postgres', - name: 'NGINX + PostgreSQL', - description: 'Web Server mit PostgreSQL Datenbank', - icon: '🌐', - category: 'stack' as const, - type: 'docker-stack', - configuration: { - services: [ - { - name: 'nginx', - image: 'nginx:alpine', - ports: [{ container: 80, host: 8080 }], - volumes: [{ host: './html', container: '/usr/share/nginx/html' }], - depends_on: ['postgres'], - restart_policy: 'always', - }, - { - name: 'postgres', - image: 'postgres:16', - environment: { - POSTGRES_USER: 'admin', - POSTGRES_PASSWORD: 'admin', - POSTGRES_DB: 'appdb', - }, - volumes: [{ host: './postgres_data', container: '/var/lib/postgresql/data' }], - restart_policy: 'always', - }, - ], - }, - }, -]; diff --git a/frontend/src/lib/utils/logger.ts b/frontend/src/lib/utils/logger.ts deleted file mode 100644 index 2d54b07..0000000 --- a/frontend/src/lib/utils/logger.ts +++ /dev/null @@ -1,66 +0,0 @@ -export interface LogEntry { - level: 'debug' | 'info' | 'warn' | 'error'; - message: string; - data?: any; - timestamp: string; - context?: string; -} - -class Logger { - private context: string; - - constructor(context: string = 'App') { - this.context = context; - } - - private log(level: LogEntry['level'], message: string, data?: any) { - const entry: LogEntry = { - level, - message, - data, - timestamp: new Date().toISOString(), - context: this.context, - }; - - const logMessage = `[${entry.timestamp}] [${level.toUpperCase()}] [${entry.context}] ${message}`; - - switch (level) { - case 'debug': - console.debug(logMessage, data || ''); - break; - case 'info': - console.info(logMessage, data || ''); - break; - case 'warn': - console.warn(logMessage, data || ''); - break; - case 'error': - console.error(logMessage, data || ''); - break; - } - } - - debug(message: string, data?: any) { - this.log('debug', message, data); - } - - info(message: string, data?: any) { - this.log('info', message, data); - } - - warn(message: string, data?: any) { - this.log('warn', message, data); - } - - error(message: string, data?: any) { - this.log('error', message, data); - } -} - -// Create a default logger instance -export const logger = new Logger('FinanceVault'); - -// Factory function to create context-specific loggers -export function createLogger(context: string): Logger { - return new Logger(context); -} diff --git a/frontend/src/routes/+layout.server.ts b/frontend/src/routes/+layout.server.ts deleted file mode 100644 index 55ff8cf..0000000 --- a/frontend/src/routes/+layout.server.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { LayoutServerLoad } from './$types'; -import jwt from 'jsonwebtoken'; -import { env } from '$env/dynamic/private'; - -interface User { - id: string; - username: string; -} - -export const load: LayoutServerLoad = async ({ cookies }) => { - console.log('[+layout.server.ts] Executing load function...'); - const token = cookies.get('auth_token'); - - if (token) { - console.log('[+layout.server.ts] Auth token found:', token.substring(0, 15) + '...'); - try { - const JWT_SECRET = env.JWT_SECRET; - if (!JWT_SECRET) { - console.error('[+layout.server.ts] JWT_SECRET is not defined!'); - cookies.delete('auth_token', { path: '/' }); - return { user: null, token: null }; - } - console.log('[+layout.server.ts] Verifying token...'); - const decoded = jwt.verify(token, JWT_SECRET) as jwt.JwtPayload; - console.log('[+layout.server.ts] Token verified successfully. Decoded payload:', decoded); - - if (decoded && typeof decoded === 'object') { - const user: User = { - id: decoded.user_id, - username: decoded.username, - }; - console.log('[+layout.server.ts] Returning user and token:', { user, token }); - return { user, token }; - } - } catch (error) { - console.error('[+layout.server.ts] Failed to verify token:', error); - cookies.delete('auth_token', { path: '/' }); - return { user: null, token: null }; - } - } else { - console.log('[+layout.server.ts] No auth token found in cookies.'); - } - - return { user: null, token: null }; -}; diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte deleted file mode 100644 index 2cd76ec..0000000 --- a/frontend/src/routes/+layout.svelte +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - -{#if showSidebar} - - - -
    - {@render children?.()} -
    -
    -
    -{:else} - - {@render children?.()} -{/if} diff --git a/frontend/src/routes/+page.server.ts b/frontend/src/routes/+page.server.ts deleted file mode 100644 index 5dff359..0000000 --- a/frontend/src/routes/+page.server.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { redirect } from '@sveltejs/kit'; -import type { Actions } from './$types'; - -export const actions = { - logout: async ({ cookies }) => { - // Remove auth cookie - cookies.delete('auth_token', { path: '/' }); - - // Redirect to signin - throw redirect(303, '/signin'); - }, -} satisfies Actions; diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte deleted file mode 100644 index 30b340a..0000000 --- a/frontend/src/routes/+page.svelte +++ /dev/null @@ -1,12 +0,0 @@ - - -
    -
    -

    FinanceVault

    -

    -
    -
    diff --git a/frontend/src/routes/admin/+layout.server.ts b/frontend/src/routes/admin/+layout.server.ts deleted file mode 100644 index 2df7bf4..0000000 --- a/frontend/src/routes/admin/+layout.server.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { PageServerLoad } from './$types'; -import { redirect } from '@sveltejs/kit'; - -export const load: PageServerLoad = async ({ parent }) => { - const { user } = await parent(); - - if (!user) { - throw redirect(302, '/signin'); - } - - // In a real implementation, you would check user's role/permissions here - // For now, we allow access if user is authenticated - // You can add RBAC check by calling the backend API to verify permissions - - return { - user, - }; -}; diff --git a/frontend/src/routes/admin/+layout.svelte b/frontend/src/routes/admin/+layout.svelte deleted file mode 100644 index 57a9519..0000000 --- a/frontend/src/routes/admin/+layout.svelte +++ /dev/null @@ -1,64 +0,0 @@ - - -
    -
    -
    -
    -
    -

    Administration

    -

    Manage your organization and users

    -
    -
    -
    -
    - -
    -
    - - - - -
    - -
    -
    -
    -
    diff --git a/frontend/src/routes/admin/+page.svelte b/frontend/src/routes/admin/+page.svelte deleted file mode 100644 index 6aa047f..0000000 --- a/frontend/src/routes/admin/+page.svelte +++ /dev/null @@ -1,58 +0,0 @@ - - -
    -
    -

    Welcome to Administration

    -

    Manage your organization and users from here

    -
    - - - -
    -

    Quick Tips

    -
      -
    • • All users must be assigned a role when created
    • -
    • • You can force users to change their password on first login
    • -
    • • Admin role has full access to all features
    • -
    • • Permission checks happen automatically on all API calls
    • -
    -
    -
    diff --git a/frontend/src/routes/admin/organization/+page.server.ts b/frontend/src/routes/admin/organization/+page.server.ts deleted file mode 100644 index f04e9ce..0000000 --- a/frontend/src/routes/admin/organization/+page.server.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { PageServerLoad } from './$types'; -import { redirect } from '@sveltejs/kit'; - -export const load: PageServerLoad = async ({ parent }) => { - const { user } = await parent(); - - if (!user) { - throw redirect(302, '/signin'); - } - - // Permission checks are done by the backend API endpoints - // If user doesn't have access, API will return 403 - return { - user, - }; -}; diff --git a/frontend/src/routes/admin/organization/+page.svelte b/frontend/src/routes/admin/organization/+page.svelte deleted file mode 100644 index 1c6bf13..0000000 --- a/frontend/src/routes/admin/organization/+page.svelte +++ /dev/null @@ -1,190 +0,0 @@ - - -
    -
    - -
    -
    -
    - -
    -
    -

    Organization Management

    -

    Manage your organization settings and members

    -
    -
    -
    -
    - - {#if error} -
    - {error} -
    - {/if} - - {#if success} -
    - {success} -
    - {/if} - -
    - -
    -
    -
    -

    Organization Details

    -

    Basic information about your organization

    -
    - {#if !editMode && organization} - - {/if} -
    - - {#if loading && !organization} -
    Loading...
    - {:else if organization} -
    -
    - - {#if editMode} - - {:else} -

    {organization.name}

    - {/if} -
    - -
    - - {#if editMode} - - {:else} -

    - {organization.description || 'No description set'} -

    - {/if} -
    - - {#if !editMode} -
    -
    - -

    - {new Date(organization.created_at).toLocaleString()} -

    -
    -
    - -

    - {new Date(organization.updated_at).toLocaleString()} -

    -
    -
    - {/if} - - {#if editMode} -
    - - -
    - {/if} -
    - {/if} -
    - - - -
    -
    diff --git a/frontend/src/routes/admin/users/+page.server.ts b/frontend/src/routes/admin/users/+page.server.ts deleted file mode 100644 index f04e9ce..0000000 --- a/frontend/src/routes/admin/users/+page.server.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { PageServerLoad } from './$types'; -import { redirect } from '@sveltejs/kit'; - -export const load: PageServerLoad = async ({ parent }) => { - const { user } = await parent(); - - if (!user) { - throw redirect(302, '/signin'); - } - - // Permission checks are done by the backend API endpoints - // If user doesn't have access, API will return 403 - return { - user, - }; -}; diff --git a/frontend/src/routes/admin/users/+page.svelte b/frontend/src/routes/admin/users/+page.svelte deleted file mode 100644 index cf279a5..0000000 --- a/frontend/src/routes/admin/users/+page.svelte +++ /dev/null @@ -1,389 +0,0 @@ - - -
    -
    -

    User Management

    -

    Manage users and their roles

    -
    - -
    - -{#if error} -
    - {error} -
    -{/if} - -{#if loading} -
    Loading...
    -{:else} -
    - - - - Username - Email - Role - 2FA - Force Password Change - Joined - Actions - - - - {#each users as user (user.id)} - - {user.username} - {user.email || '-'} - -
    - - {user.role_name} -
    -
    - - {#if user.two_factor_enabled} - Enabled - {:else} - Disabled - {/if} - - - {#if user.force_password_change} - Yes - {:else} - No - {/if} - - {new Date(user.joined_at).toLocaleDateString()} - -
    - - - -
    -
    -
    - {/each} -
    -
    -
    -{/if} - - - - - - Create New User - Add a new user to the organization - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - - - -
    -
    - - - - - - Edit User - Update user information - -
    -
    - - -
    -
    - - -
    -
    - - - - -
    -
    - - - - - - Change User Role - Assign a new role to this user - -
    -
    - - -
    -
    - - - - -
    -
    - - - - - - Delete User - - Are you sure you want to delete {deletingUser?.username}? This action cannot be undone. - - - - - - - - diff --git a/frontend/src/routes/api/set-auth-cookie/+server.ts b/frontend/src/routes/api/set-auth-cookie/+server.ts deleted file mode 100644 index 9828de7..0000000 --- a/frontend/src/routes/api/set-auth-cookie/+server.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { json } from '@sveltejs/kit'; -import type { RequestHandler } from './$types'; - -export const POST: RequestHandler = async ({ request, cookies }) => { - const { token } = await request.json(); - - // If token is null or empty, delete the cookie - if (!token) { - cookies.delete('auth_token', { path: '/' }); - return json({ success: true }); - } - - // Set HTTP-only cookie - cookies.set('auth_token', token, { - path: '/', - httpOnly: true, - sameSite: 'strict', - secure: false, // Set to true in production with HTTPS - maxAge: 60 * 60 * 24 * 7, // 7 days - }); - - return json({ success: true }); -}; diff --git a/frontend/src/routes/change-password/+page.server.ts b/frontend/src/routes/change-password/+page.server.ts deleted file mode 100644 index f263e59..0000000 --- a/frontend/src/routes/change-password/+page.server.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { PageServerLoad } from './$types'; -import { redirect } from '@sveltejs/kit'; - -export const load: PageServerLoad = async ({ parent }) => { - const { user } = await parent(); - - if (!user) { - throw redirect(303, '/signin'); - } - - return { - user, - }; -}; diff --git a/frontend/src/routes/change-password/+page.svelte b/frontend/src/routes/change-password/+page.svelte deleted file mode 100644 index 9b36f16..0000000 --- a/frontend/src/routes/change-password/+page.svelte +++ /dev/null @@ -1,107 +0,0 @@ - - -
    - - -
    - -
    - Passwort ändern erforderlich - - Bitte ändern Sie Ihr Passwort, bevor Sie fortfahren. Dies ist erforderlich für Ihre - Sicherheit. - -
    - -
    - {#if errorMessage} - - {errorMessage} - - {/if} - - - Neues Passwort - - - - - Passwort bestätigen - - - - -
    -
    -
    -
    diff --git a/frontend/src/routes/local-system/+page.svelte b/frontend/src/routes/local-system/+page.svelte deleted file mode 100644 index 26249f2..0000000 --- a/frontend/src/routes/local-system/+page.svelte +++ /dev/null @@ -1,320 +0,0 @@ - - - - Local System - CSFX Core - - -
    -
    -
    -

    Local System

    -

    Monitor the system running the CSFX Core backend daemon

    -
    - -
    - - {#if loading && !systemInfo} -
    - -
    - {:else if error} -
    - {error} -
    - {:else if systemInfo && currentMetrics} - - - -
    -
    - -
    - {systemInfo.hostname} - - {systemInfo.os_name} - {systemInfo.os_version} - -

    - Kernel: {systemInfo.kernel_version} -

    -
    -
    - - - Running - -
    -
    - -
    -
    -

    CPU Model

    -

    {systemInfo.cpu_model}

    -
    -
    -

    CPU Cores

    -

    - {systemInfo.cpu_cores} cores / {systemInfo.cpu_threads} threads -

    -
    -
    -

    Uptime

    -

    - {formatUptime(systemInfo.uptime_seconds)} -

    -
    -
    -

    Last Update

    -

    - {new Date(currentMetrics.timestamp).toLocaleTimeString('de-DE')} -

    -
    -
    -
    -
    - - -
    - - - - CPU Usage - - {currentMetrics.cpu_usage_percent.toFixed(1)}% used - - - - - d.value} - innerRadius={(radius) => radius * 0.67} - > - `${d.toFixed(1)}%`} - class="text-3xl font-bold tabular-nums" - y={-4} - /> - - - - - - - - - - Memory Usage - - {formatBytes(currentMetrics.memory_used_bytes)} / {formatBytes( - currentMetrics.memory_total_bytes - )} - - - - - d.value} - innerRadius={(radius) => radius * 0.67} - > - `${d.toFixed(1)}%`} - class="text-3xl font-bold tabular-nums" - y={-4} - /> - - - - - - - - - - Disk Usage - - {formatBytes(currentMetrics.disk_used_bytes)} / {formatBytes( - currentMetrics.disk_total_bytes - )} - - - - - d.value} - innerRadius={(radius) => radius * 0.67} - > - `${d.toFixed(1)}%`} - class="text-3xl font-bold tabular-nums" - y={-4} - /> - - - - - -
    - - -
    - - - Network Statistics - - -
    -
    - Total Received: - {formatBytes(currentMetrics.network_rx_bytes)} -
    -
    - Total Transmitted: - {formatBytes(currentMetrics.network_tx_bytes)} -
    -
    -
    -
    - - - - System Information - - -
    -
    - Architecture: - x86_64 -
    -
    - Status: - Healthy -
    -
    -
    -
    -
    - {/if} -
    diff --git a/frontend/src/routes/marketplace/+page.svelte b/frontend/src/routes/marketplace/+page.svelte deleted file mode 100644 index 82491e1..0000000 --- a/frontend/src/routes/marketplace/+page.svelte +++ /dev/null @@ -1,424 +0,0 @@ - - -
    -
    -

    Marketplace

    -

    Wählen Sie aus vorgefertigten Docker Stack Vorlagen

    -
    - - {#if error} -
    - {error} -
    - {/if} - - -
    -
    - - -
    -
    - - - {#if !searchQuery && popularTemplates.length > 0} -
    -

    - - Beliebt -

    -
    - {#each popularTemplates as template} - - -
    -
    - {template.icon} -
    - {template.name} - Docker Stack -
    -
    - -
    -
    - -

    {template.description}

    -
    - - {template.configuration.services.length} Services -
    -
    - - - -
    - {/each} -
    -
    - {/if} - - - {#if containerTemplates.length > 0} -
    -

    - - Docker Container -

    -
    - {#each containerTemplates as template} - - -
    - {template.icon} -
    - {template.name} - Container -
    -
    -
    - -

    {template.description}

    -
    - - - -
    - {/each} -
    -
    - {/if} - - - {#if stackTemplates.length > 0} -
    -

    - - Docker Stacks -

    -
    - {#each stackTemplates as template} - - -
    - {template.icon} -
    - {template.name} - Stack -
    -
    -
    - -

    {template.description}

    - -
    -

    Enthaltene Services:

    -
    - {#each template.configuration.services as service} - - {service.name} - - {/each} -
    -
    -
    - - - -
    - {/each} -
    -
    - {/if} - - {#if containerTemplates.length === 0 && stackTemplates.length === 0} - - -

    Keine Vorlagen gefunden

    -
    -
    - {/if} -
    - - - - - - Docker Stack bereitstellen: {selectedStackTemplate?.name} - - Konfigurieren Sie die Bereitstellung dieses Docker Stacks - - - -
    -
    -
    - {selectedStackTemplate?.icon} -
    -

    {selectedStackTemplate?.name}

    -

    - {selectedStackTemplate?.description} -

    -
    -
    -
    - -
    -

    Stack Konfiguration:

    -
    - {#each selectedStackTemplate?.configuration.services || [] as service} -
    -
    - {service.name} - {service.image} -
    - {#if service.ports && service.ports.length > 0} - - {service.ports - .map((p: any) => `${p.container}${p.host ? ':' + p.host : ''}`) - .join(', ')} - - {/if} -
    - {/each} -
    -
    - -
    - - -
    - -
    - - -
    -
    - - - - - -
    -
    - - - diff --git a/frontend/src/routes/otp/+page.svelte b/frontend/src/routes/otp/+page.svelte deleted file mode 100644 index 1e7d29e..0000000 --- a/frontend/src/routes/otp/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/frontend/src/routes/physical-servers/+page.svelte b/frontend/src/routes/physical-servers/+page.svelte deleted file mode 100644 index 8126eda..0000000 --- a/frontend/src/routes/physical-servers/+page.svelte +++ /dev/null @@ -1,223 +0,0 @@ - - - - Physical Servers - CSFX Core - - -
    -
    -

    Physical Servers

    -

    Monitor and manage your physical server infrastructure

    -
    -
    -
    - {agents.length} - {agents.length === 1 ? 'Server' : 'Servers'} registered -
    - -
    -
    - -{#if error} -
    - {error} -
    -{/if} - -{#if loading && agents.length === 0} -
    -
    - - Loading servers... -
    -
    -{:else if agents.length === 0} -
    - -

    No Agents Found

    -

    - No physical servers are currently registered. Install and start an agent to begin monitoring. -

    -
    -{:else} -
    - - - - Server - Status - Operating System - Agent Version - Last Seen - Tags - - - - {#each agents as agent (agent.id)} - handleAgentClick(agent.id)} - > - -
    - -
    -
    {agent.name}
    -
    - {agent.hostname} -
    -
    -
    -
    - - - - {agent.status} - - - -
    -
    {agent.os_type}
    -
    {agent.os_version}
    -
    -
    - - - {agent.agent_version} - - - -
    - {formatLastSeen(agent.last_heartbeat)} -
    -
    - {new Date(agent.last_heartbeat).toLocaleString()} -
    -
    - - {#if agent.tags && Object.keys(agent.tags).length > 0} -
    - {#each Object.entries(agent.tags).slice(0, 2) as [key, value]} - - {key}: {value} - - {/each} - {#if Object.keys(agent.tags).length > 2} - - +{Object.keys(agent.tags).length - 2} - - {/if} -
    - {:else} - - - {/if} -
    -
    - {/each} -
    -
    -
    -{/if} diff --git a/frontend/src/routes/physical-servers/[id]/+page.svelte b/frontend/src/routes/physical-servers/[id]/+page.svelte deleted file mode 100644 index af887c3..0000000 --- a/frontend/src/routes/physical-servers/[id]/+page.svelte +++ /dev/null @@ -1,600 +0,0 @@ - - - - {agent?.name || 'Agent Details'} - CSFX Core - - -
    - - - - {#if loading && !agent} -
    - -
    - {:else if error} -
    - {error} -
    - {:else if agent} - - - -
    -
    - -
    - {agent.name} - - {agent.hostname} - -

    - {agent.os_type} - {agent.os_version} • Agent v{agent.agent_version} -

    -
    -
    -
    - - - - {agent.status} - -
    -
    -
    - -
    -
    -

    Agent ID

    -

    {agent.id}

    -
    -
    -

    Last Heartbeat

    -

    - {formatTimestamp(agent.last_heartbeat)} -

    -
    -
    -

    Registered

    -

    - {formatTimestamp(agent.created_at)} -

    -
    -
    -

    Updated

    -

    - {formatTimestamp(agent.updated_at)} -

    -
    -
    -
    -
    - - {#if latest} - -
    - - - - CPU Usage - - {latest.cpu_usage_percent.toFixed(1)}% used - - - - - - {#snippet aboveMarks()} - - - {/snippet} - {#snippet tooltip()} - - {/snippet} - - - - - - - - - Memory Usage - - {formatBytes(latest.memory_used_bytes)} / {formatBytes(latest.memory_total_bytes)} - - - - - - {#snippet aboveMarks()} - - - {/snippet} - {#snippet tooltip()} - - {/snippet} - - - - - - - - - Disk Usage - - {formatBytes(latest.disk_used_bytes)} / {formatBytes(latest.disk_total_bytes)} - - - - - - {#snippet aboveMarks()} - - - {/snippet} - {#snippet tooltip()} - - {/snippet} - - - - -
    - - -
    - - - - Metrics History - Last 50 measurements - - - - - v.toLocaleTimeString('de-DE', { - hour: '2-digit', - minute: '2-digit', - }), - }, - yAxis: { - format: (v) => `${v}%`, - ticks: [25, 50, 75, 100], - }, - }} - > - {#snippet marks({ series, getAreaProps })} - - - - - - - - - - - - - - - - {#each series as s, i (s.key)} - - {/each} - - {/snippet} - {#snippet tooltip()} - { - return v.toLocaleString('de-DE'); - }} - indicator="line" - /> - {/snippet} - - - - - - - - - Metrics Data - Detailed measurements history - - -
    - - - - Timestamp - CPU - Memory - Disk - Network - - - - {#each metrics.slice(0, 100) as metric} - - - {formatTimestamp(metric.timestamp)} - - - {metric.cpu_usage_percent.toFixed(1)}% - - -
    {metric.memory_usage_percent.toFixed(1)}%
    -
    - {formatBytes(metric.memory_used_bytes)} -
    -
    - -
    {metric.disk_usage_percent.toFixed(1)}%
    -
    - {formatBytes(metric.disk_used_bytes)} -
    -
    - - {#if metric.network_rx_bytes !== undefined && metric.network_tx_bytes !== undefined} -
    ↓ {formatBytes(metric.network_rx_bytes)}
    -
    ↑ {formatBytes(metric.network_tx_bytes)}
    - {:else} - - - {/if} -
    -
    - {/each} -
    -
    -
    -
    -
    -
    - {:else} - - - - No Metrics Available - Waiting for the agent to send metrics data... - - - {/if} - {/if} -
    diff --git a/frontend/src/routes/resource-groups/+page.svelte b/frontend/src/routes/resource-groups/+page.svelte deleted file mode 100644 index e074989..0000000 --- a/frontend/src/routes/resource-groups/+page.svelte +++ /dev/null @@ -1,256 +0,0 @@ - - -
    -
    -
    -

    - - Resource Groups -

    -

    - Verwalte deine Azure-ähnlichen Resource Groups für Docker, KVM und andere Ressourcen -

    -
    -
    - - -
    -
    - - {#if error} - - -

    {error}

    -
    -
    - {/if} - - {#if loading} - - -
    - -
    -
    -
    - {:else if resourceGroups.length === 0} - - -
    - -

    Keine Resource Groups

    -

    - Erstelle deine erste Resource Group, um Ressourcen zu organisieren -

    - -
    -
    -
    - {:else} - - - Resource Groups ({resourceGroups.length}) - - Klicke auf eine Resource Group, um Details zu sehen und Ressourcen zu verwalten - - - - - - - Name - Beschreibung - Location - Erstellt am - Tags - Aktionen - - - - {#each resourceGroups as group (group.id)} - handleViewGroup(group.id)} - > - {group.name} - - {group.description || '—'} - - - {#if group.location} - {group.location} - {:else} - - {/if} - - - {formatDate(group.created_at)} - - - {#if group.tags && Object.keys(group.tags).length > 0} -
    - {#each Object.entries(group.tags).slice(0, 2) as [key, value]} - - {key}: {value} - - {/each} - {#if Object.keys(group.tags).length > 2} - - +{Object.keys(group.tags).length - 2} - - {/if} -
    - {:else} - - {/if} -
    - -
    - - -
    -
    -
    - {/each} -
    -
    -
    -
    - {/if} -
    - - - - - Resource Group löschen? - - Möchtest du die Resource Group "{groupToDelete?.name}" wirklich löschen? Diese Aktion kann - nicht rückgängig gemacht werden. - - - - Abbrechen - Löschen - - - diff --git a/frontend/src/routes/resource-groups/[id]/+page.svelte b/frontend/src/routes/resource-groups/[id]/+page.svelte deleted file mode 100644 index ac2f907..0000000 --- a/frontend/src/routes/resource-groups/[id]/+page.svelte +++ /dev/null @@ -1,594 +0,0 @@ - - -
    - {#if loading} - - -
    - -
    -
    -
    - {:else if error || !resourceGroup} - - -

    - {error || 'Resource Group nicht gefunden'} -

    - -
    -
    - {:else} -
    - -
    -
    -

    - - {resourceGroup.name} -

    - {#if resourceGroup.description} -

    - {resourceGroup.description} -

    - {/if} -
    -
    - - - -
    -
    -
    - -
    - - - - Details - Allgemeine Informationen - - -
    - -
    -

    Resource Group Name

    -

    {resourceGroup.name}

    -
    -
    - - {#if resourceGroup.location} -
    - -
    -

    Location

    - {resourceGroup.location} -
    -
    - {/if} - -
    - -
    -

    Erstellt am

    -

    {formatDate(resourceGroup.created_at)}

    -
    -
    - -
    - -
    -

    Zuletzt aktualisiert

    -

    {formatDate(resourceGroup.updated_at)}

    -
    -
    -
    -
    - - - - - Tags - Metadaten und Labels - - - {#if resourceGroup.tags && Object.keys(resourceGroup.tags).length > 0} -
    - {#each Object.entries(resourceGroup.tags) as [key, value]} - - {key}: {value} - - {/each} -
    - {:else} -

    Keine Tags vorhanden

    - {/if} -
    -
    - - - - -
    -
    - - - Ressourcen - - - Docker Container und Stacks in dieser Resource Group - -
    - -
    -
    - - {#if resources.length === 0} -
    - -

    Keine Ressourcen vorhanden

    -

    - Erstelle deine erste Ressource oder wähle aus dem Marketplace -

    -
    - - -
    -
    - {:else} -
    - {#each resources as resource} -
    goto(`/resources/${resource.id}`)} - > -
    - {#if resource.resource_type === 'docker-stack'} - - {:else} - - {/if} -
    -

    {resource.name}

    -

    - {resource.resource_type} - {#if resource.description} - · {resource.description} - {/if} -

    -
    -
    -
    - - {resource.status} - -
    -
    - {/each} -
    - {/if} -
    -
    -
    - {/if} -
    - - - - - Resource Group löschen? - - Möchtest du die Resource Group "{resourceGroup?.name}" wirklich löschen? Diese Aktion kann - nicht rückgängig gemacht werden. Alle Ressourcen in dieser Group werden ebenfalls entfernt. - - - - Abbrechen - Löschen - - - - - - - - - Ressource aus Marketplace auswählen - - Wähle ein Template aus oder starte mit einem leeren Container/Stack - - - -
    - {#if error} -
    - {error} -
    - {/if} - - -
    - - -
    - - -
    - {#each filteredTemplates as template} - - {/each} -
    -
    - - - - -
    -
    - - - - - - - - - - Docker Stack bereitstellen: {selectedStackTemplate?.name} - - - Konfigurieren Sie die Bereitstellung dieses Docker Stacks - - - -
    -
    -
    - {selectedStackTemplate?.icon} -
    -

    {selectedStackTemplate?.name}

    -

    - {selectedStackTemplate?.description} -

    -
    -
    -
    - -
    -

    Stack Konfiguration:

    -
    - {#each selectedStackTemplate?.configuration.services || [] as service} -
    -
    - {service.name} - {service.image} -
    - {#if service.ports && service.ports.length > 0} - - {service.ports - .map((p: any) => `${p.container}${p.host ? ':' + p.host : ''}`) - .join(', ')} - - {/if} -
    - {/each} -
    -
    - -
    - - -
    -
    - - - - - -
    -
    diff --git a/frontend/src/routes/resource-groups/[id]/edit/+page.svelte b/frontend/src/routes/resource-groups/[id]/edit/+page.svelte deleted file mode 100644 index f8a38bd..0000000 --- a/frontend/src/routes/resource-groups/[id]/edit/+page.svelte +++ /dev/null @@ -1,196 +0,0 @@ - - -
    - {#if initialLoading} - - -
    - -
    -
    -
    - {:else if !resourceGroup} - - -

    Resource Group nicht gefunden

    - -
    -
    - {:else} -
    - -

    Resource Group bearbeiten

    -

    - Aktualisiere die Details der Resource Group "{resourceGroup.name}" -

    -
    - - {#if generalError} - - -

    {generalError}

    -
    -
    - {/if} - -
    - - - Resource Group Details - Aktualisiere die Informationen für die Resource Group - - -
    - - - {#if errors.name} -

    {errors.name}

    - {/if} -

    - Der Name muss innerhalb deiner Organisation eindeutig sein -

    -
    - -
    - - -
    - - {#if resource?.resource_type === 'docker-container'} -
    - - -
    - -
    - - -

    - Format: [{'{'}container: 80, host: 8080{'}'}] -

    -
    - -
    - - -

    - Format: {'{'}KEY: "value"{'}'} -

    -
    - {/if} -
    - - - - - -
    -
    diff --git a/frontend/src/routes/settings/+page.server.ts b/frontend/src/routes/settings/+page.server.ts deleted file mode 100644 index f263e59..0000000 --- a/frontend/src/routes/settings/+page.server.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { PageServerLoad } from './$types'; -import { redirect } from '@sveltejs/kit'; - -export const load: PageServerLoad = async ({ parent }) => { - const { user } = await parent(); - - if (!user) { - throw redirect(303, '/signin'); - } - - return { - user, - }; -}; diff --git a/frontend/src/routes/settings/+page.svelte b/frontend/src/routes/settings/+page.svelte deleted file mode 100644 index 2b72396..0000000 --- a/frontend/src/routes/settings/+page.svelte +++ /dev/null @@ -1,499 +0,0 @@ - - -
    -
    -

    Einstellungen

    -

    Verwalten Sie Ihr Profil und Ihre Sicherheitseinstellungen

    -
    - - - - - - Profil - - - - Sicherheit - - - - - - Updates - - - - Organisation - - - - Benutzer - - - - - - - E-Mail ändern - Aktualisieren Sie Ihre E-Mail-Adresse - - - - {#if profileMessage && !profileMessage.includes('Passwort')} - - {profileMessage} - - {/if} - - - E-Mail - - - - - - - - - - - Passwort ändern - Ändern Sie Ihr Passwort für mehr Sicherheit - - -
    - {#if profileMessage && profileMessage.includes('Passwort')} - - {profileMessage} - - {/if} - - - Aktuelles Passwort - - - - - Neues Passwort - - - - - Passwort bestätigen - - - - -
    -
    -
    -
    - - - - - - - Zwei-Faktor-Authentifizierung (2FA) - - - Erhöhen Sie die Sicherheit Ihres Kontos mit TOTP (Time-based One-Time Password) - - - - {#if twoFactorMessage} - - {twoFactorMessage} - - {/if} - -
    -
    -
    - -
    -
    -
    -

    Authenticator App (TOTP)

    - {#if twoFactorEnabled} - - - Aktiv - - {:else} - - - Inaktiv - - {/if} -
    -

    - Verwenden Sie eine Authenticator App wie Google Authenticator oder Authy -

    -
    -
    - - {#if !twoFactorEnabled && !totpQrCode} - - {/if} - - {#if totpQrCode && !twoFactorEnabled} -
    -
    -
    -
    - TOTP QR Code -
    -
    -

    Secret Key

    - {totpSecret} -
    -
    -
    - -
    - - Verifizierungscode - - Geben Sie den 6-stelligen Code aus Ihrer Authenticator App ein - - - -
    -
    - {/if} - - {#if twoFactorEnabled} -
    - - - - 2FA ist aktiviert. Sie benötigen bei der Anmeldung einen Code aus Ihrer - Authenticator App. - - - -
    - - Verifizierungscode zum Deaktivieren - - - - -
    -
    - {/if} -
    -
    -
    -
    - - - - - - - - - Organisation - Verwalten Sie Ihre Organisationseinstellungen - - -

    - Besuchen Sie die Organisationsverwaltungsseite, um Ihre Organisation zu verwalten. -

    - -
    -
    -
    - - - - - Benutzerverwaltung - Verwalten Sie Benutzer und deren Rollen - - -

    - Besuchen Sie die Benutzerverwaltungsseite, um Benutzer zu erstellen, bearbeiten und löschen. -

    - -
    -
    -
    -
    -
    diff --git a/frontend/src/routes/signin/+page.server.ts b/frontend/src/routes/signin/+page.server.ts deleted file mode 100644 index 739a004..0000000 --- a/frontend/src/routes/signin/+page.server.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { fail, redirect } from '@sveltejs/kit'; -import type { Actions, PageServerLoad } from './$types'; - -// Redirect to home if already logged in -export const load: PageServerLoad = async ({ cookies }) => { - const token = cookies.get('auth_token'); - if (token) { - throw redirect(303, '/'); - } - return {}; -}; - -export const actions = { - default: async ({ request, cookies, fetch }) => { - const data = await request.formData(); - const username = data.get('username'); - const password = data.get('password'); - - if (!username || !password) { - return fail(400, { error: 'Username and password are required' }); - } - - try { - // Get public key - const keyResponse = await fetch('http://localhost:8000/api/public-key'); - if (!keyResponse.ok) { - return fail(500, { error: 'Failed to get encryption key' }); - } - const { public_key } = await keyResponse.json(); - - // Import node-forge for server-side encryption - const forge = await import('node-forge'); - const publicKeyObj = forge.default.pki.publicKeyFromPem(public_key); - // Use RSA-OAEP with SHA-256 for encryption - const encrypted = publicKeyObj.encrypt(password as string, 'RSA-OAEP', { - md: forge.default.md.sha256.create() - }); - const encryptedPassword = forge.default.util.encode64(encrypted); - - // Login request - const loginResponse = await fetch('http://localhost:8000/api/login', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - username, - encrypted_password: encryptedPassword, - }), - }); - - if (!loginResponse.ok) { - if (loginResponse.status === 401) { - return fail(401, { error: 'Invalid username or password' }); - } - return fail(500, { error: 'Login failed' }); - } - - const authData = await loginResponse.json(); - - // Set HTTP-only cookie - cookies.set('auth_token', authData.token, { - path: '/', - httpOnly: true, - sameSite: 'strict', - secure: false, // Set to true in production with HTTPS - maxAge: 60 * 60 * 24 * 7, // 7 days - }); - - // Redirect to home - throw redirect(303, '/'); - } catch (error) { - if (error instanceof Response) throw error; - console.error('Login error:', error); - return fail(500, { error: 'An unexpected error occurred' }); - } - }, -} satisfies Actions; diff --git a/frontend/src/routes/signin/+page.svelte b/frontend/src/routes/signin/+page.svelte deleted file mode 100644 index de6a4db..0000000 --- a/frontend/src/routes/signin/+page.svelte +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/frontend/static/logos/CSF_Logo.png b/frontend/static/logos/CSF_Logo.png deleted file mode 100644 index 4c304e0c9a7066c524b0466f64da6a57513fc25f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93686 zcmXtAdpy(M|6fu~HygR zi7}UuY2=a!A-U(e- z1`x=uYtY@`Z+;#)?g)P4yJ}3h4uR|wO4D8uhe<2#MaM4dE?J$2aLxr@|rS^yiuu)deyNDak_Og^!dIoXMZ@_))5FjJp&zr zofcN9iZ6VgPgP!-o&E-Rn0=Rrl!{em-^sob#MBbe_}Oq8+k4-6RkBBVM;YFnit} zGZKzZ4Hyg>?-~1rgA5}dMgQXt<=y>yKK+IAQ#-dJHVz8^ zS`~E*=f`g@*J{^c%u7jL$yT`K-L5W3_26sJ|UYW{{?gv=tMH3-B{s5gUUUE-;+(H89PlDcQ4n*6DrT*=G3?w?sphUwu?XJc+uwBTob*B_>5PwvW z=WT``u?n`@Gf2HJchCLPPqEj{hXp%4e7-aOS&lckF^%EpRdo4yw8t3MmWQ-noFrHf z&m0X}U0a%}ASdqnr3Sh3$Pjw^<}8%(iX4A*pfA3~-rt9`E#nyvwHB1Ch~a%(mq=6Q z`N-zINco#U=gIU-nj z{HM+R=$79|GmHhF#SMcY;X++zLToDoA7D9C=I=f8VEyZK&02ZrgQ29GMKp#WTY1t% zQA>~+VA+vI;a4fX|0_2L%iswRg`6~2AzLE#rS5mTVz5yGb1TXaip;i{>Pr7Kl@|YL zf4G3e+65o^`QcneS5blLZ1qAsknHO79amkA5jeqPN|#ZnM>sd7D$}+60lQJbd(;wp z_Utzs#q_xf_aUQ%C2V4KFY8*HT7lKMKYv8~ju_rg z>B!Kz9+|kS0Tv-KqD0@Sp5BRs$>f~WfGAQ`ePmZ()HIILS7~;%dK(x!-OX|DYv)6Yc@I1#qp+G>d*{L)u&Ed z593#O{k)(gep(HYJ(Q8kGA|B#;3SL{h8aL!J~D=O(%0SO+De+Q7zOn~#I`SR3vauJIfSkyx#{esmvV-&Ydk(yPrK_Uo5dyBXSI3(FneQAxe)CGiiet^4Jt0`0d( z-P8qYwB5YgT@*AnvLO9K#4_L-hDr|_5AjIe?2k&GedfzYt#To57?h#5^ESxuyeTc;{!=vUYYU))2R zF`fRS9oZxOKCTZ_=Hxo!@*UC~GIb>i_2MZ~7PTpka4q2?3RMhvwF|UfXikqa&e<>@ zmwp}oiTA)UQ%?=MS`Sor^`dv0|K(T8rrS4L!QsD(HJ47KIt^Yj)!LL5uh?qbb)Nqj z0CJT#f_S@Xe}v+8Xjsc3C$3J&n*(`_TiIzZ{cp*t}AxetW|5+>AKlhhbEJ{TS#Zs z#T!byd1F)WP%3JaI>tC_Dx7(haQ`$&fC$7ULXM0B$Ei)GBzNdKlvdpG#Esnb??heT z+a% z@dV?ZtX)tWp4rQym09RFd{CIuF`Vl{>cNd*-bFF_%cJ=}Z4`ZUPK(XybR|a;n!b8B zF?8LTu^ELHr)R6;eX~Pjr(aB_4cr-bjd2xUZ7$>H`QnGqI8$39@t-*B{2k!w_{DE(Y{7vmBz7-w%XFvj!t=fpFZ)PpaNH$rOn?@&7ZX-4~f$p*+0%zv3@n> z#($7|${FuJ+C9m+{*>bspZ(+m#2&txL2REiK0G&n;{Dy^BTO%o593YYb0Xn$lU_SP z@Hl8}4Q+->+MV{RatfYIj!Vg7+q(4)SD*9$RB#~QzNV|)JHdY;yQlcT7q=&U^z!LY z!V=-%fBc+u6m~ZHN+wC@6>qXx9|O#M2t@e z$bPXZTC>_aowaoiq!Ig@pFkq93PrIan)@gRfE*=Z|6S5OjL=Jw^yn*)0$b)g_&geYZSY1V?X3-VIU8|N_&o% zKQ%*0v*=nz{pB&{7)IUQgzF&(B6cDoVaLuBcfm|}n}67Qv2UJbDPIhG7o4>V(yw2) z^NrI4C*1kR>sMJu!Wau}YqePVpo&|lm|ls4-8wDZ->0rfyE4<-z6|4&_TTM#+)q`FbbsEFpF?K)JrMtDD$5}8p*ZTd752D;2Bch^vit}p2 zzzRBt)J48_je}l*8{xZAFs!o)J?zf)hikOwVJD_)7hm({V}WXS`rbad%%Z#587c)` zMFuKqrOq0DCr(%2Vs72iTdd$L4{h~>-QNxH)<*`R$Qv8gYqt-b%Fqc}UcYHRoez~t zj>uw%OxXoRyGtA1U`YGmwzJ_WWYXME>-Wy;du97x<`h%5KF#Z{mg=pSjz5?Dro40b zjxCl_{%g!_ri|29Yo6k7_trhL^0=+SDHm?ofn3s>*LNP%L0avQL&bW|ZX~W|{Jxw^ zgB!JH4gfz3I1jlBFTomTCdVBlAkS%Q9kVrF*EKKgCJUwdMWbtI$yfMJS+SBcZ_A64 z*z}@Vs)ldp@;yD1$A!uL_l%Vu6Qar;PvcX5q3rcJnI7`YPn_?;AdikQHl=?F`j~z# z_Q~AkQ$5|28&`l%Hw~ecoqOB+!-Nm9Z_zSh-~ZyE1vy@;tgiKc;=9V0bZIv4#{75h z7T^kg)y(tzz;pTaj|DzIskNvOzco{L@7C`6m6(11fKNbdUF;4;ST!peX_xV1>L|#xRq~K8k9Cnm_7%M}RQMB#=);a_ zbP{`!dDJ1#kOwadkd?=df41X$Ja+k=3r_HW)MG}iX%MrvqZq30lU+@eG!noH|2ZiZ z5jTm#26w&-*1EB1ew_7oh3daax6YJ%8i>7@S;Wu z{m>0EBxZQY<(IXT6R#;ysNKtm-XknHkl{mj)R~E!NoTwrbP$!ks)rZ|UDVbWLlXfbLFtFlD86%w=(s`sXsqV?G|( z#_y@!uXYF_aQB4MD2R#^Q+AGZWz)HFDZkj>#Fp)N_f^DajpN?p=LE8Ysc=|y@ll`(7~q=yNzDx<&)`c78EOlY@$93wP( zEFFt2&sZuf4<9}DoOQ5x%d~3UKWI#+j85#LX_osF)+bgcrhbLGw-0Q$+8BbqSOt_vGHXAZOJqb$ILV$~oEe5r14ry(Lrm-|=PcojA^S)wi)S_+2Epj_F zLJDUsJ9?-Xk97lpKP&xsAr}}axyp;o<;e=8UiBf1G}GQ&1fWZI!Q7zO{qfw26GCqg zM0xya&uOmCe@y?C>t*7V$yguVqxa|CLialahSymDgCt(g`|}!qs57~1u%uv=u$mFd zVukcYI`eQh@CiJJ-{ozgFIES4tVyMy(R+yxO&=y%|48Fje^QVmPtD>^--C@rONt?g z$xxRulsk7>J#E;`a4zpAp|))4T&-zu*6Gn}G6Fd?r#M*286vd)94N3-YKldC9^KEq-tWOOf=fhtXrZmn9sY;iGIy}faP-0)AXoKlT_->k8TcPn#l$&vNlRnI z0B-p59H?pz@;dLTTW#~Jo%<-_v@w4lOSu#rG*|-9^$D_GOUqACciR!)&ZsmChrBs3 z!Kv6W)I5`A#>|+k((}t=97GTFFC%r=7JZ4v4|`cDbsaSt2;w(3ALMQzihOHE60x~v z_b!{`sd23!sn@rB*?p#LU$|3B&-nu+y;8T*qPb_1QAMyrxkfkfP1P+@JLwZugDoq4 zn9_t|mbCVI(d<@nB|05-eEm(w^ar1oE>6?bQ%?UfVQ7(~X}`kpEW&aU7FcVJ_KoYm z%ED$swZl_2%Y(BQO)JAH6NN4*JZ5e!ih}_EeIuCX68s5l{=-((kFF{9OjrRskdEnS z>9q}^MtpzwKs91La*O|J-B%M%Mc#AEmV_@>L;P8Ww=Izdm|1A&w3M`T_}b=dI48S1 z>AleYrwl19@b0PwZ{KueDNU1xK)zBSVty%4&}rxDt7*?b6f6fqPl8klloSq*?!ICPcE{T zgR@+gt1_2DSD3WQAKFF%;JidV?oSwX|2prk1jCi`6izW~GfMtEvod1}CZWCAZQki;4PkO7fPS`35 z!_Sn>MEY0LWlrqEGo2*FT+E&{&&7j~e zVZ4dVw~Dn!eX1vTJZ8ExEjTI2;JxKHLsRDe!Eq0-dB&06v!=J{G?gH}DOzgBu?t}u z$?@bkC1jl$#fb5BvBKB3)@Q?SyhU7@P2qP&rol=+ZH-)sg9)(lVMS`p1b5e5Lcb#+ zp=H;s@E#)9aj#xdLY&Zw%R|Q6-nr}ko$qKeWMqu68eN?(h!q~x*%5J8maK-yQ5jK} z?CwO5%al4^_bw!dsyM1>=3HqjtlQ4o;bDvs5E)~}Cq zF852t@l5vCP~zYSS=6gVTO>t3-V&D>TYnq69dmk(C7QfP-cuOQlA0;vD2>$MLzhQO z?S-(yfwvVR-XqD{0QHv@d3=nHg>|`_l{bIRC54QsrN=s0Lpy!lGCWR56xX(dozr6l zJX?)l?(xo+OZH;=rfX-~)mYoVaHF|8oaVzCzf3=o5lI3&a#l2 z9^jw)f^OQ=+5U{`Far8{`PqfdGaOD@rZ1s5+`aj*bX)k1E&QrQNY(;F(?3m5MWuv! zt3sF^mU8+>Mjb<=|6uAk^>m)&fR$d)#)|=QJyes5PpR7~Jk$PjYC&BOxOC2hpxfAm?oFeKsToC^>U9@>Dya+ z#h|Kky-wO35|?fzCT!IWm)A+p+BV5+?q=7f9IMOYgsczuq%I95@RtXVhP5`{d&NjT zi}%c*G&iqYiPF{?8x-oIfy(mMpKnpc=TGjp*%1*h49|)dJ;AD(31c@1r1qwCwlurR zp&!VTvdR?f4|sDeX}F|S^n2T3`F3HvyIDYVUZt&tRGOLfhV7}Lo#j0pwSPup(nY|N zdO+(Xa$sGhNq;(v?XeWO^SJlMa%TOkiKLZtrGzJ_t`u3I z?cQyFoi?-Eb|2tT_*eFAhF1@;-UME5{D(r0I%jFjQkHn)f}?y*0*uE#%WuEDW}&ai zuqngmR2Wjvy0)lkA(c&k)evj^_0=sKT&(GOHRf84llv`VLR@n4=_`(v@bo=KU%P(( z+OwnQdr{}Q-IV$I!4s>je`b4W-yfY$Fq&!^wWm9V)XZBvL5c=l~V&qcI?%{hN6*`E* z^+tndQ3?;1yhtl1ZH*-hU5Z{(CuT}T^5o~;C6eU+QUo{MxxZ(;r_veiEK?>Sj!S zaEZ%BPWLQ{``ch`i*aRbtW|BU&#Luc_XCb2%qyF1ALKVEcr68>-!&&_gyL9l-PTgL z4o7q&#ZlXH%FfQe2ALPzN9f<|vQL;thQv%8T34O139Z*?71zEpBMA9nz}fT0=}INX z=Z)~G*n_6i_B^P1}&=0`rpWIh(*5$1ka^FN8==D(~I~TM*X$(4#g%o+*;!!8~`zo{PgrdZJ-2 z|BCVi=u5-ropF(i{j6YFsTXvJ2sG9KvawSn1UQ!f7m1O!aro5^70_PJJ)3ZBm@+YxX z7+YNimzXjV=iYdjV#)h}P^*+Fh8Vk*uwbo;Wt_r+^Pic;bvDG7XGIE?Qwg&KLAXn_ zj9o_3kJpX0cEa3+&Ijft5n}5v%+!$$Eip)JPMnCv9TX&!maAfYL2S{n<8kU(%B|=ZMcprY@BLsv zk64dJdZe&fjA|6Q;5c`KtGp#VMt*wtZOVJH^wyT(h)7D}X`n7MXG8KLlkONj`iYLp zbPR5^{?S}!{FL&@?PAR^cOk_0_MwB-sy`VYstIre2Cb#uD4>TEBPSv$h^tG17hS~% z{rv~*tUo5zR`+OtrkYo6R<&_;K1BkJ;nnBm?x1X_vbSt*vUOst=&9<6(L&M_anw8v zyZg-k+l5CKRw_4}T2@-rl@PLuiHjPY{`kc&SU^BZKxMd#uk!Z2QA6D!l4D}y4xw5@i?KZotON+k*x@o7ILXq4(>RGL@ zGdZM?Gopr(wv$2#Ss#^!G}!#wk`FmiA7(JDFgFPAVwJ)rI^W9U14p9VirK+DF=I>@ zML6;E$?Y9{72s_>fIWp>5HeJgP$|hFY0+`yB3@PAm+|*tU7YmTWWQ+X5>vV_(PMS# zXXzt3{Nl4ni~h6&*uVVCov>C-MFryB2zc%Z^&f#(jdt36BtTcwuQzeZ1lnG&yuIX( zJcCR>mr+h*dmLISlKd-pEc7rTU7dP3Dd0}oQW31{`IDy6;;@yfp-m`)sDry(-}4HJ z7?+MPKY=yQR&Xyfz8^Lqc&hAZbP;TXPeNQs6^XhU=%3ct9)jg=I4r>U$1}uMgza$) z@5b7TNRIRHSal>PE@;3J54i8)EQ`#MSG>2l%<2-*3PyYsG}czqqLEnsca6VHER1cO zQT zB4#AdvKdQ9J4zNNp4WN0mCS4-ye~0SFO_T!)H0|T`4AFm?LCH z!O=9z>m$gVCIMhrIPhPnaW-}3l2r6i6e8H4dkKiqWnysagci1B_RnuJOmQzxS$eP< z#fuu78ulDq;^u*!(7<(eR8qamG zR1Kh~RidG6(FWM5!>rGb?jHG{WdpxT2}+S{OX~JjmnaNV87N))6gGjDz;W3R$Q#+s zFY4kSUOs6QU^5nv^59CF_aZ=KkS8a$eQV!y@Z;btwBV&r&@}?wNGjHIzsW2FoucyDlG;e@V&7xmRQw$b~jOYw=V^33U0vnO1dw||$%#*Z zEyZ;6A%^nri6+x39MKXadmf`BWi>!{6z{woSmKtMNIU&7c;AT0x_;a5*Fm z7!1vBn)A3^so8ceI!Ec9p(2lqC~|0=SY#pb|qr**p<<%}v0O z!G8xc1}Djh`)-T!h&)4*7xltIYEJcd|0^HsY1yq^(ff_S#+@!WXu*XzUN4x? zw#BDBm5y@9!ALsxc#{N2fAQS7^Kpd1eO=EN;uBr#CE?SJo;XHECn5=SAx%+w-EVskyB85+7_xX> z75@J*ChA(o(F<@ahMroWifI$TD5bZ4espD1keuiW^qk%W0uKMsp6vIAuKO$+3Qg?Y z7s^QHmIcR6j&G~#ON?>7ZR1NJs=-SijqI!__Y}52OKY%ht6!)e%CwQ@+t$=o-Zf*G$+ReVV^sk-a)D(UX94of!M!d}Ur_rgal|hQ zVblI}c9o7P0Hv7I_4|BCWi4mj_agR{s>pD41}XjB5FJUSzyPnY&_@-*=17}CJCmV^ zrroN%d8Ht*ytcv_%f@?}5Y98F=H_Jyhz7->hueWA0tJsg%#I2cL&&<$MoZb*x%a== zgBbk-LYrkUA}6;^K-nFN2u;VBR4RkofYwTJh9^xL9E9V!2M>2?pT6jl7zTpqbhOQ+x5X&S(E8KF4D3IrCPpS2tAX&DT#sPV zLX8+$j=3rn(Yud|I3C$qph~JT&pbw6WCWwrV?zz0ofLB777umlHf&pMA*d#r*gx5E z0i{^uLkC>O+_G^m-c!nP&`M>PfwQ_9^mK99r!Ix}A5G^z#4P`wU(3Ce;$?*(;&K@G zWN`m-g|E*|yyz0#`P6*&byx0?x7O%#@r;vOJFnMF0G6}CRb zV;))CcZSgO;>^@b0Kh9|r`Y{c+> zphh2SI0c3;*3&j)kHQKMIM%wM7RqJ_Sc(SWp1$P&sHtWFuD45Lk|wR%$WHeoRg8{tH-%_0hi`^T1cuSOc4b z>G@b%j3)<@&f;QZ$X}sfz4Y&)9h2?g|0`Sa&ZwAXT6VeBmXp{aR4FKed-7GBHatgq z+&UCTJ&aLNjE^;qQw6?qh2kL}0XePie%TUA9W#nde8E6YtW=99=SDIwp71b-ukXr3QA&a8HF8 zAx_BUjWr)r6U*%Lw=9-(B(@k{^eBVEf#M<=u;YM_4O@r zeceDchR#jvNOZId25#@9tS@`5^>9Tz6p{An+iF){qb(Q>37e=xkiQu;Av^|_=YK49O0uQH|Jva&i-C{y6@uSS-7CoU3GxH% zSIunbY~ADGBLHd_U*frKg*6HQ>G3p@1I^_8d39CqRPj&Vy!8Wm$tbwAv zNIIzdz{=z)h=B7dU~WJRj?fY6&yTfGzAx6K~Xmd!tfp;vk*L))}^( z>596|nI`!+_CUDA?X;dyeH26md+227img9JrQ5nK%Ep?R(1oY`+%E3E{Hv?kAfQ~* ziArJ!&`j}+PhBOmJ5{@M*GFPh!ZyA|N!Mz=8@MBS&7+Kx*a;v6=+hoqD9^P?DW6HI z_*v1i?1_vuvi^K#gR88F?5BJO?sv}l9Dsjq>lbkkFlf;*1k_62@Qu_zB&Xn{+5yQ7dugNn& z`B@LARgeg}ie#LZbtrX$3YRFk(_rdkWxstm!BV=#ZP$ZymBzm(x>3(iJ{_M$DQEUq z?gY$nk&%UvkVTGW4_;aN-utMpVgC#JjJ8+wQ*&|6*``J6GZ;t5G`5zeQR#!lmnwd? z=OwI#o~uTU0+ph%(CS?-jJR&|xS&AF^UB5k&R`Z@Re`L{3rARo+6_1c`1_7=F7Me+4AU7j0>a^4~w^cO@67Chk%lz1z8^p7&fKj7Sfuixbu#Sxva*IYS2x z`-e`5g^X?gh%o6k3M5KR#8D30rGm0IbyCG*FuFi>I70MVHg^z}K}n1>j`*GTVbN`L z`CkE5Bq`h97>~l@$%)3dnjMWx{+1Z_GSY)Vz^Uy_OM6(QtJIFLs^3yDm07uquJt=r zM|T4dwZLD0-Q-U`p6oe>wm^Mn3KEqv?d*wZZmwhY8UiZfvfkV6|N0CykeUm0E^|@g zkC2OYWgDK}v19h5b+BVN690h)IqFDLY<^g|KA*M0=?BV9f9O^2a(1w z5NrGa43xgKAIm10fBrO&PH$PW%Q`BU_kru?^>9zuuA;!s#uDn2iYFfhFxnC%hh!t@ zZ8Qj>0?QO=0hnj1ZGB*3UN*;4uS0nyZS4A+c~0%^{8E;1xL_|LgY+X*Dp}eGSn*B- z?=r9I=w1pLW?~Dt9E`tXZCU3$3VAvAg8%1jhaQF+!*PO|YsQH!Wht>{8o{!H@N2ct zRW}32;8^E(kAI>lVHgEV;`1i% zy&;Ehw;H^qdL|k}U(c6hMalcyE~%>T<_iDRHaxS?On-7goBAQGHY=(5&*xi)Gevt5 z;;0ehBX#^L+ZOZYPz^*N&fFv3A@jb9MtN7xFqPmv z!NmhoEKZ@h)*wgVbk^7&xLk4j`f@LjXAcFj=NqWz3jh-emr<~g(ILR)`VW$h&6H^b zYFKO?rO0vjxQdRg{obx1!Y7kz3^)6lUyB+wTX%etq8A3ZBwbKbLtGd;61n#HgHg0X zl}*+I!=)AUnp`*e?(%BWT8~+_r3#X}6U2Vl%xcb8aZ91wRXdYiaNO>6;eIUi5>G?o zzHB~(HPOhhOcbuEG?y(efF-{55F8_fA=Bn1sY`pft6#~5=;asU!iZh{!2t3D7lwn( zB||{u&{miX>r&=kVMj^3RrovPMR#1$?_2P{<)#r*OZSPF2cJYn%}U807DNJZ}>PCZ@u^pCmBuJg;~F$OjCHc1{Gm) zF>cY*4WpZlL1B$8!*Ec-8R+foddZRajWy7LF&~fT@TWrKL65=Bfw_=u9Yh*X@B=hK zw#Hv_^{UsJ=a})KRIvjiq=cNfy@>I#!UY}#@4+2Zgx1{ZcqZrf*HzA-pqzNJ4Ansz zUFAMWvtJe_biOZ{Qc+0yj~uCw`TWQs>QZq|+db$cOK%I*`Y|w`D2OU?&ma_`7rs2r zKKbGfzR~(+#mv1LrHceRuRb~`J%1lsj664i;67iyRO=&QSGJ+6D;h1J>&}OW>n(N) z-vIq<&NS~;7|cM!9S8NA66%K!l}LF#A7kF&Z!^zr&6l*0;V!>=$X)Mgp=knO;jAm+ zh=$+gP{1ld4)VG%?t;z)XYEnF%UZBc78S28=4G4Da&g{+fRu*so0en`jmF~IX94oI`zSM8~xMDk_=OeeM z4n2MvHDjRUrzH7-M#%7l%w5wXY2w{`z{T%hV>4S9A5DWyaHey9tpKnFS8u=!j$8;Lcnj)rF~s#6C-0?@)#RGH)_I$c z>@}zf(EoT$HMVg=QT=5;5wXlv&v?3Hs)8Wp2q02l0=GMB>6F}e>gQ+C$}3474-5LX zL)ayW`FBo4t-|)OV+(gC4yd;=6L3^P;HPj3LNIV{2J-f)UMQ+n?r1PTo~ts5u;z{ zQo`d_opD94cqxRbn%S_)Tn`ksdJ$ioXoGu5$*GEVua0_Nli*n;M2|8--FGVA zPR3vEEjwQ+%!e_n0H3Dhl0C>R}nY)KTtT2WX;}XCuZFw0(L(#=^jD`{G z%tHG9S6jgu_`8;oiARyLQ_o4oPsG1}0l}l^U(pNBAoHz?L>-YaL9+I|qhdj&kWY$-=Q&&dgOkC7|)h?r#*%%aE=I$iw! z*~QhgGg@qiYqAr_`AMv$oD4Sa!+!P&D!kXt)r-KaXLN{oBm!EBR9Cb`pYY zJG-1{Vh%k$w2;qT#SarhesS?`6_+MCC}%?x!IuiLo(b^31(wOD7?}&FeouS!5hGz} z8bE8I-3~^uM-$Ma#)t(=i#%Pi7lH=Kvv6uX9^; z{;mZgr$!{_vf*`4-J%;Nq70}sAS?wm@$;J`_51r$)a z-{bH@ThG9hhdb`7Wy3=@mLe;FRmz!d{irYKLe%9htcNFNooTGS?`QT;0aTXinYC&O zCW`nGyua>O)tqo3C#ux`afybmUN+nST}70xLJ+Cn-rJ2xsC-GX_p(ZldUs5XyAQ;k z3fIT@Cxf}@wpb|D1Z~FD3J(hw#_DSB_=*TvZBHx*BX5#@CYI>i@9aCE;$5u1<)8O! zt2gp*^;~HNQ&Rt7@~&0^{Sr5|9R^oAgt2!h08PE|`E`E37f2#EPl1H20=m|XQ9n%9 zVy6`W|NQfV&xieK5X?2iw#_~=ym?8}^`|M(2~<3%&5yqJ1>4q+yp-zfcq}eR@|j8w zEi0Q>@JfzLn$2~acmJ}j^Hz6y{Wm^gs+kqE86Rp(2kc(>@D-#1mvE-Ru`kAmcIJ3! zCji$<;ne?O&Rrb*Pgrr$IPqw5B6ygxTVz;-b^zk8F@k9MiISy(4`ozO``1kak~#*| zG3d~3YdRbWsGDS6j5=N!Y|;28NEMeZUi!ai9_sQY=DPv-`lR_<>I@?#S$RQ6qBu6m zTxrqk=;feG?PKqET z|7(tD2^8V6w3vOwMG18N%ozE5kA^-Gt9k*;>VdPpN%ufU++twc&O-hd?fDWP84Fc1 zf48nzb}jAr{HSS_1vybVe0x9&^7Ptu7Y0Z+DpeJ*uJ49qW6-9Ey!SWGTs>BTWaJM} zo?gy1vOp$>jz}WFTk~Bxx1XD5vbP$)rj3-i-Jqnf1Pvo%ab(+AJQ=qNqNd>?u6ae6 z2*kOTYTWn6G4i=Hw{~LS(N(YD_ftX0pa6!GMW?^)LC=)*C#%Fnodw(S>(d58cXmnoVV|}n}e)`53pvY%RP2=Wxqkvg$1dgp~BDG9jb>0f} zVpr?x2r55%R{X&8FKKy*UC_r?E!2?vSTdDjT|3q*aJp!|%NkGKSgxou1p8gb2Z&2pdGBIr}Q%rlFxF5`Or7cWtzmNl=f!|E)xB@|h`fSzi@rngePNI;q53E7= z`JyW@uW}bgarovG=Y?4ufq}bj`yPkqW+bt128GO$&gm1azq6yI|D(?N-1#Jg(k-N| z5Dn=HA3lpl1YH^%m3($3d?I^ilyz3Rk9h%H` zYPsg1# zjw0u8nXN6Jab{$7VZ*+EuuI`N+ZfM#FZLB;rB3`l6mk<|o{tX=sx>l*PkQCh)2=Ap zqxx^>^M9?RL#~YujS|MEg~!Iad)ZsPXE+JW_%ocLl+?{a!|>K${q}qa+5rn3gV6fN zPVZVnLYO21%!k_uigh8eYOk@%rBh=6$O@cLz*5GU=L)ZQ7*b;$s{Yu{@I?GmB=0y= zG1APpKC_ zBWT%9jQRYB&BEoG2jJ^Rz^`6!EnD_H389*MDbB@LDoK|UG9GjWjY>)vIt&IqEr0H} zZvhDyW@oQIU?6O7SuX4Kes=8aRRJIAMyefEu zMpEopP+{7v-yOStH`CYQfS+{lpbTl|!Iqxm$<3jTs8qcz~j4}24A-wBimxJhEOW8CCIqANiR0A3^4k7<07*L0WZ| zKB#!t^P;OTptW0qM{V+gbZIkECXCnlPo&#Mr%!&<~*VIMW5uXF^tLe77G&R~| zdWT(&Sa>LbkU(E-@m{qSOQ3>&kUpO@j7R=1Zp5!7L{mI$hwX}eEul@n9BQ+lWwd+M{O0GK@ z<})COeSwW>_37UPKN2CQ4Tc>x%k}_mjg-8EAFtY*rdPGk&DtEiw7yIrE$qJTlVz!} z6gU>&kmd?$8u1(&gLk087ssDCeo?4fDTIGIn8nbWeQWv0v&O*0>U7hym+@4XK(vGy z_(s`&1&qR!52zS*yVZJpPnzqhcw5Ok@w&Yfz2`z&J)*at+ekc|(ps*m7!kPK;|co1 zF%SzbnDQSv9#Cfw`u5l{zW@{%<_SIR=fyUh#E@uE7dGN9n4+VKYzDo#=>T@P>RU8n z+M)aXgo3N#mBoGl3Dd;Ck8-79ARM2H8Dr@a-1AUcJ zJ-Ms&4fhp8#qN}zb_5|H&)ltDaIJ18eM`E6)3+Ax&IwMZOC>R-PPVZW3d>R6HY!9< z|Go=-G1?$U?z`HlHB1|VkI+o0A4`h2Yq-*G-=b@SPa73%+IHIhd-#;sq>$5~^Ua2F zab+tN08DjWF9)Z?wae60^aM!UIYi*wZ zV_EnEv?sz}Ti^Ni89Lk(o*&7a>z>$y?dqMrZo5F!X-*{+V_<8WZ{0m4nXM2r`--lz z;H+hW2HRCLINozCd)ci$H-EF_*R=C#*Y7lYX>?uRujv3`?vU{EDcsQWa_Q9T3Yzp1 zwB0(Uwn#HqW%iH#`Xlyp-~Q^gqO$2N9CM$;le zc+IT-LXV%(ddBL@qVI%N$LiT57X!-b9JPw*9<>$I%O%=F>x{Pm6)H0f-}8cT1z`mh z1BWUpw2uBqlTu%WRdK3q$;R-qNrXD%wt+cGoP@NO~O6%Mog5nz`f0f7##F{;H z6vD@D>%4T`VNULOBav0E?KcU24ug^G9a{}MG4tUwklQrT%E^>*mjzXOoamDJMJ0f4 zBL2bj4#Oq@XrtA{ku|ZqO8m_X8}B2 z3|B#?i-Zn^W+c5FbL+c0v+1N|u5Le7-OMUjjf*ENg~V+rGu_f!Q*8jkXmYN&dfRF9 zr%m|v+Mu-?gksZxPRAQ>Qvjaq?_d5uroKELs_*}QluD&+l_Z3sNNR*+D|?nCI~mm2 zjZw0%m4vJbArv9Zgc-(8N(^HO8D^}NooTW!!_4=f_viP!kN5kJ+&lN4bM85>`#P`J z^YwfZx*m5Dg*>>N6$1~Lsd~9f7Y?$5;s7gjXCyR!ItipZKPy7Tn(TUnm_EHa5g~!} z@uY9AfkY>5jv2!3kX%pXJFdbXg^wetXql|V4S)}GE7nypN#Mte7i4*riiW4sYLoYj zybwc{{U(99ErI;6Vps*i?oge=jyg%xeJ9W;oc@A;M-sYJbAw18<=YDi4;O=0OCPwA z@B#Xt3*HKMt$vX3A0c`R4RllUye|O+x4BDw+3%6$&i%|KeRY@axPF{~dRSU6`76Z)2<)%Mwhn7_E3w!&6n6X(}uazIv zVqTAz)$lusFQOi$qP=XF0`{N;PmS3VIvu}Sq?voFj|)6aI}fJTNny@wP+xP757xy0 z_>tv|!4gYI*oi~crlb_F7kr{i4o>k{uI^s>D!-Z< zJ)yiR90}rs}S?I(flT?R)gHeLaUY!J^wM6=<{#O8u6X;d5ny?Fv?n zL!!u9V`{{Xw4A8L zE~&_Mq#Fb?A)i9>sbGJirOG7$AI=GlLrn?JH-fCgs|GIFtMedvRAAJZ63^?))9NxF zyB3wP1m84jd?$_A4mt5rE#wyd!q0LxYR6{Xd<_K)%k)cW_2e!}Qs7BuraVKo?y;-d z(>BiQ09^AZ|KQ=I{?Q2b_>-?{ncDjWLvB1T`Ur2NorPN8#<{nz@1#c&F z-aC{|eP32`*Tk}X4k{F$lwqDh^$!XKGn`M?*8%Lxx{EBGbbOt-)}3b`O^+|@I7#-D zK1NtA3NK2RUcXrF^%D|q=J5%|_r_>}xHgnc=Ls6~eu&ueQ9Cw^ybYx}lUkUHHu-)K z%dgcf1d=V0`rEb#GmJs7@I z1(_*f*}y3wWLb2N;s1c7?Vr=uJVF~@rH^ny?(HiqI-0@0@b_=raFSC-5gwPi9d+9& zzO8{KDnJfX?Hk3hm!aWZbK;&cudNJ=OqvFe$nV>cYL7QpGX4fAoD)(jE&X#YA9+xa zTF;>8i9#w)nbb;w1ayb;{!i@Pe?wV8*IS8+EsLPs!A^kWXA~MEk@5I5rCa$zAx0w{ zpHvP^ajWqH)Kg+FAGHE;E(kB0#z}R`KUU+XOs*=8&T!Sxw^AI*cBGlKB&-uxCn)tM zumNwhQoHH$8#7wUdJNW1n%Bvp3{6$#$;_}OSbx)0%YC~#WJ1uK?(*(aWfYCK1b|{% zFls2A`qs$xFpl0wDYK93)7veH2>=WMF~$GAngU~S+M_CY)Nz*lIwk0oZYKBo3}r(= z$Ehc;tO^dZmPxQD!OImD2Bd?2*0mf}vL~DFSMcx6A(_k;tqngbljW6~$+XK3lznu$ zW`f2mXOh9_@-P^P#Rqj#E6Umn`xo`UzRN>}S2wD;A{IRq%G)sd%l_nQLdnQ5HebQ*4NByB6tdQfm5~UFX<$ z=0g(Jiw4Kl;fgMy?4+Xzc}^9D%%obo2NdoQ4c==;9f=%IKA*a$mZh<@q%IC{!gZ)8 zIx8&(W5Tp)g4^@u(t^86i%SG?7*X*^y9W+XSdslx*{b}UU0{2DmQzckTwEnww{tLDgKjarko}Tn zk9m#g1xt**O)t_k6JqRISXZz#zN$pG;1%;VALwGDrfza*1k0j5Fcx)wFt?k_6`j|- zOL-HuNn*WF;wo@SN5~k-E{4ZAaqT@r8SzV2EN#fN2tlqA`S2Ko)(0We)@vf6Z%y01 zL*Z)C=;!Q}D1cF8OZf!qi%wu&As4f5YRT7YAWfj-7`sb?AyLCx(e4oqm%*1?y8Bbg zLW7Fu;Ln3TWHTXce=doI`PF*H7D#QlFMpuxP5guIZV22?2TO*T)#-sjOQv9`+EY!L z+E*frwE`Z@>>n?4?z?+IYDPIhWYM1GjD^4Ew+w?clH(WSfoA%uid#{>1EP}dABRXB zF(|u@u9=vt2HFnD5Ie+TRY@N`^3{yv`J_`I?*pTP6g@?F4{zVJrsI zJ3BiI1=O(1i56J;ZSggChnfEdW()#cn$Lc%?9Lhp4R_k8S&$MUu`m7gQlE z?mri(=&}{vZ?Y<(!pr_?*+a*uLlGe_X3cZeVSaxHX~B}7WIAwH;`h4KYzpt?*=rp$ zNCeHXuRVUNx_4H2D_E)T2g9zCXW3=I1hyiJ=e#-W8vN*l3jGf=ME03@*yciV{pRT4 zda`$DK(VXlo)>L>-GxCll%`X*YU0^BnkwOmN%?usdyBunJRWFaWUo<6T9V$|GWXf3 z{f3-jF86swc_)FyZ4b2QdzQV}?;{eOT(_YHXSOze|NafCO_iBG>)GxM!8W1Yb}}dl zL21E?+B?dSag&-G-2nOERG8RF)}Y|WEWMzCvv~*Iw@RNpm9?4T@qPMQBCV`bAtz#U ziT0L{-Pb7ziEd*x&>&m>idd<&4^5d{FE(C}EK2cgU#Ry?v+qqSTb;udc!=Bg)-MNH zt{i{=nqD8cg>7vMp)-zCtRI}PkCETNxr}F(sm3!RW}TE&w%zzKUEE1ROXi)@3CCRiYh) zgF<)$k`&!f|aIiBA437lv{6nH=YdhtBs>4@`Iv_AE(I1|)*@-Q@tG$oogp>C(h5 z*P7+U1HeQz`Oc;b0%WqMqz;(DslQcBXBQFUvxE?xukb{NrxMA!@>jofes(2J*VL@9I-(x8j0DESn=FK}bH z>kLW3#d0>*UoE2T80y5D6%!=Hva!muG zfvWvE#V*wWT&wT0#Xx*`JV4#Jp8NE9ODOLid`@$=Wej;d{z_`HgnW1IMbZP)h`IS~ zbm8EsY=Z)@gc@$kKA%ibUQbZ=4cZe@{Zr@4*!=u_effn8NA$mk3*CS!3Gs?cK1e<; zqhR|D8~fMILR_{Ca@Ym=PU1t6mzy6hn}aW7B(H&mQ=D2OP}D)_>>w~E-!75L>z2{h zZ^4tmaea70HbqzM#n}g$$JJ|~CZXZI8IhyE)=O|$PXb6*;JY=s9A{Gl)r%9xHL@h3 zIQ)Oicl~> z<`(Z12VStc%E6GPxkU}GGa4WvIs-~P)S|UFghJk$20w(+%eV7U_1AWiG?26FwI_e6 zBYl2_-%GB8cAZXD);H>EwWE}uiM-V1HpQ-fM&)+wdB8kqPNtnq3Pd>ILRby$Pc`!SPk-4}6XtNyT>MpudZE{5D?HV62`fDJ)vIqJWb;|h z+!2f-4|rY{D!@71)KqL3Gb8?=hCtKg1hfr1hAG z;~ZSRY$5&zC&_q9Jx&R5d>pn{3x&_V;W%=aU6=jl?nAl0aDTLCJ|ZcZmb<<{{;lro zI9|5QAx8Q1dhb-r?ZVV^p*|evrE&q{e7BMW5`y;aBShtXgfl0+ID=^vTa0_t{i~Ns z(f5)UD;i&wEnzuRypM#BDa#5=o{Zon``u;s^@Ig2ppk*I)Z04`h43zv1t+vPyO_L0*ZVq9=4fS%}H-9G*>rQlqRaUlg=SK?bJ%+!$6RUM~69oV}_!Ut*kJh9mGJ&pSZgTkS~Wo&3f?j2-iyh27b%X6;=yKU5e@# z)2W-kb`V^UVy;edB=KdQf0zO1?%n}_tL{T+dC)O1~)mKTmw%W84_fOlf^%Hh}xf%-K!^n|188v2tLLa+zTD2;>w+;Z%F) zqYHv#?Hh!}pv~p&b=3K9(71nr5No?7;iYfEMULCj_nq!6MFv@L!k%=2<)aoA)|4dFxLFxDbtbh5|Qo)Mge$@M{qJ> z>12Oom&XX##ShV|D!q|^ZP$%+I|3HcsR5JgJ4h7BXh_X*9-(YyjL=PMjR_}1c-Hjg zL_a%T3}SY%HVx1!Z6hkVB3z}ID_k2R&V_2d|H`TV=G0Eo7Si`rUN4uM>8gS1S1vx( zV@a`dytV*ss76z{%HsO`czf4E7N$!sGkWG@{|bR_4gcToLdC<(R6@_aTJlQ7#{^Z2 zIm2g*IMs_Fu7KaFWDX=)OeUsV=$2O0ZOp^&w09Xr2Pg3OT5Cz80b`?aV}!Jd#!9*{ z#Gh0Bu}{`>yf~m^Lw+!F^b5f1>Zjf~Sz82( z^R+?0Lh*QKKeV^a>zX?WUbU$PCkr*Q1(h-WfbJTUe`SAhSQMN9#_3!x)bBoYdP+m zA^eY1g*D3=>`Xlmb{aT3bC98@ksVBJaBS4nsQEr~y1j2^es}~@yblJ~YEqJ~&D|)k zG`Gy%g|mK^xO_IuD7V3AD~hbq6CgGX!B#dJT@;^raFc6)Ha=b|6RNlazlFFx5xnx@ z>9Nxro|K6;Y;q9x^6~wb+Cfg{)Yeag1O2+`huQ$(VTkU2YD0KOcTJ9;C%!N1q8OEP z-fd%ycC^OZ-$w~mDjhs5_@T<>BM6e7c+p-bS&<&q|1eCg<+Vxz7^wWlm6@24SuU1K%gkMC5DP zul%Fre2wR4H?REH`pA)&f?Yq7qwW|8N?A4Cr_fZ`wQTeit_Up-$EHvZ#Skk~##c<-<6E9k9nqEJxv6@2qAi<$avj8h*wY@AMq^|*%r*H-vqaDo%wTNF;W z1*`vy=3_(IyZdd}penGHdweOUxYVD&9avpR_a0scoKV}xXp@;l7|K@`Ph^({6|wR| z=P)gs&!XOJyh4mf)@}1pUElRE22ZAGghhpOz<8)z0w&BX24~zaXmr*)3&c&Q1ixvi zksSkfwT;{X5JCpe_B6(|DdXEdW;+MB;E#noZ#6^q!`{~Z5j9b;rJ!g&j$a?4?HVLPJyzl-1WzyZT3ZpjT*!&^W1BM}|SDWqW|sURp6 zdBS|rja`2;eE9f6*nj?=+nXhM)s3_qtvURMTbY(2f0_CsSC7UWN_?buOfLA1(5{V? zZMUSd&cmLPCnaQcvAHcq&l4l5+Ex(%5|J6LPyDot3qj={rq< z{DGLVMz}R9Jh7cnZctgd4+q-#5{clNRI+fN$T$)??U_=wq#RW8=u?B`z@BM z0|GS|9HxNE0ae-3k3KAX60lW;?^>S0eShRtiFZ;&z9-M)u;WmM+TP-Gk509c^DmnZ z%*ksWt2PC=Z2tTIU9C!GZMiI@0MGoOdHLM_n5HPY4Pg4HIsb~wKyY`oG+jl)<^;9y z^?Tgl^l$q|r{Gx%#I?CT>-wNA#(&)iRaFmz<2Uyq|1zH*6+$UWN*TgI0*WPG){q>| zy88*M{y8J0s-b>@Zo$2BpAZ}!?+aVfD!KSyQ;vW&5FeaHN{HvK+7oqo;Zy7!;aNH7 z(l)o|%)d7$TH~ME*!6rrz+~A$B@LEyyS7>T#{aF&+h)gkptK8~z1GWthjkO4DB|mQ zKX6YG=|?;>iJ7yc`d@*Jt=0eBp+BL<_wjSUr>M8jJT4c0^oin|D|)#Wbr!c@+x@pL zkM{_v+HXEP9M9{nuXaCU&e~j_&@`PL{%>eZbzib}WrPV_-~IdqZUthcAZZ>ODnHV!R$_z%Lc3|^N%ez-bgsRKVZ?!ORIW?!Q#XLaQ2^n z_a~xVNEKCDz;y>sjf_-h^~{KdDZ(ds2d@YjleAhkmhR0xc*1Mx?&V?Bvqo4+-vgyQrNB5os{>8a$(HotI#BbAO|M{if zjh0~ig3I1K%ucplvUY^v?8ojc3CU>;pL@lA3ozquAETe%EOY>Lq)tnnOXzmrDW_*U zu~X+hcU4xuPF_j8AoF$?KM1jQh&*}!`5&aB-MhOnjvW1|UL6k1M+<9`a2nt7HSo0> z`hSx^({-b-%3m+x=2VEwm+RJrTi;UoPaK4H|Cu}R{{~YpfdmCxAD7a6v()nj5v&p2 z96Nw{pyc2xqc`Dr<_)N%`W9gxFUXT=%)8Up5Puu;)sz%j3sRbj+n>=>`5IwuA$7Y$ z^7nvDpacFqiC4DhHbqi{Ddxt?hz;(VLyE<&nFB8;K5Ee24z}^8{ecDRy{E0d+$6V$ zM|(gbdHaw#rfNU(*q8psWN-NwSB{6Vy97Xxz9#$ocorUmXS}l4#9ZjwRp?cvtbCY7 zijq|tXZ9{x1;iccDi-GY5SugP{>bov=FNp>)0E+HewZ@%MdXKQd%34}Js=1#K#rb>Kj}h$7{+_EKXT4`)SfZ!h#2XD*|e>*?fm@janM}d z#I_@646Q~TeS#g*rVnf$*#&`quG8gEwb!&V+85iET(D;@S~k5&Ueh7t_tK6Xg;aRw zh6@tfjqR`B_$KgKI$m)k%_=yiycDnbLvmvwqX<^>p=hU5pA|8r`W7=Msh=80V?xd; z7}39hzzeqwZg(o^;EX~i4Q<2}Ts z&e@MCp6%sEckh1cM)@nlPjU{8aeQOy3zg1MPrIHQpS}P{*i!1Aj_$sOzcSn$suydV zpe_ur$4v42a4Km@c6uHqt=j&D0Rqym(5idm{~4RacDi2ff?H@4iu;qZY!>EHh=jTS zC*K~pJ{{H;6ajE@1NPZ3pg*MXU`@e#fan{bu=^V9FtcSYWU5`82)F^;W95- zdDg4D=IW7<(-EkTmlqXf66>4!d{=kp-e(Eyw7hD8enu@jqt&0MU>f3LCM*{9HlgOm z@tr5w@TKV`@Km-ew)#juIh)1&IgGyB{=YJYjqFt94F}c72Tn%|XC@?0@6Hg&>X&0z z#w^@06+EGeq*;Na-Rs{qmEzeCe%U)HPpog){nKYV(nTn|-OxSb-B;=O<8qe*VLe5= zr|Rxwxj%lIFX`o48n=(jTfCg+4FADD`R+vG{a)JIn$JJ)K{Pi)&{EkG=D(LjZti*5 z|Ex_}m||XUI*D~iqkr9o{D9rk&o?U_aXk9fn#eO!p8onxOm2MCK~dk`=(3QWgNR~P1?;6>A!v5yDjVcW-ociN?5@NNyhZRA-FUC zpG-R&CcKH2E@hx}bLS#pPgeHyN>iuaa5OwwV@l3l;53Z(I@%fOh}mEUKiWPl+UA7*v^U%Mb+1n_Y>b(vqQe8ERNskG?pmynD_RbwX84^2*TR*;|S|a2tJM2GWIYQGQqU ze_b{UeOC}M5SmYkX zV5tm@N6#V4kng*@Eq5!|6Fit@|DzfK;Lm-HbBl?KJJt7)QSo6;)q*`uk38%Wc`E10 z&_~ZcvRBAlbNKHe5?A1ApWpC2{JEb0!ffVw zedkoj1E@M{NoZKgudn3%Jvx>Za?cfS{_ET|k?ot=7J2i*2@gFES>91Z%CYUX@)Duc z32Je+2?p5f_gqfMRzD9SQ~&cp^sL`iC7*debPsxN|H}Qs#ejA>R9VZy>Ky4kjBj@q z6w9Rz?Ta2f6EkcCV3PYP97?q$3WGWRH?@r!Wp34#1l=xDwjw0Dpjg(wz%=J#yx>lw z-I1ropzzt%n7{lS{V#bW*A}Z|^-f<(yuRjQRUyN^_ut6c_N=YV zv~%CzcTd>lhx)nh{Dm()96Lxi@I(6N-1~Ugul=%q?zd`^6IOh-ZW3IS9NvzwME|?( z=$&}MZ1?N~$&Hb$DV}s>V9+A+zr_UFqc*JICYZ~vz6aZ)5vHbuYnqAOO#8RD zfS)=d`0K#ESFZ5zX8xxKvJUOsch@ZI3k;4moCEERiuAJ7Px$$7rjHI+q;h}c++td7 zWi3HYD{q!v`uC$6e{wj0*0_z;@ZxkdG9Ya>a*RvoW+XhhnD)2_(3=@+0?Nvg^dh?< z|AQVA)QW7EjL8RMr}(>q_WEZMaj1F*B`QeAF37qFXB`N*FVX9N0?n3NuG0d`TK$*( zXo(ki->*l-SQ~+25RxAqg;N9B|8oSpPM*%p()i^iPvd$dV9V}k{;2OWE)i@%8?UpV z-Dbr0TMDixY}sxRBSX5$f^nnV*zYBwxHS((10$s}5F4SZk;E#mTY)-g7RBnk4K z%U_7x?1yK6J=faf&Kk5%u%?dpP9s`7xOM6g9#7L|nU>$pOIkyl0%6hz3rg^95phU;5?lx&8z zDWiPj(Q#i_|12dDP$K=|%pceN*Y>MgpRgsx}fEGo-zq%;$Wt@rK^czUhN zS_aQL)aw^@7-rQSN=%E>2HEr8#RhEtYr@8<_ZwD4a-y0m^}nS2b?y7R7+cr%BR0g^ zrmV9)?S$l@%Ua5*aj#pb1MrA5-6Ce1EOKW+$m3q?$XpeZ#^0cR$%c6H9!T&zfC~1r zk2`(jsixa8F%-{|h5iT`C-ZlSDEbq+=CWF-s4kCkuo`n6s@liCxs&bMDJg5xMttNM#B>4$mz5w2WA=erq2 zcanEv$lPBI&a7yidQD*zr9Xi(|UfKz@lg z;TD8kI|}5o7;6b0*1>fs<&*jYsK=nrX?_l4XMfMKkamAOnl&T)K@vhUCj%AxQL%S{ zC)grmT-1L~vrb1++0b;kx^+%xe9ewLlcVXIWHnyBuo?Biw6$}_dx=3FX?ANWEOM6(8{;^bzAj*k6W^2==Y`RlXts0tk-Y8Hiw0*0 zZbSNCh=jtCOIc55ru6PCYoG*<0XRds^H@2>vHk^?oPA^%8KJo1q{ny90bpM;e@{Bn zrqpxI9BFaU`&-q1`DBIHbeMC9vV|4*lx>aIuW>VeH7jp)#lkX1<4~NcsNw=8WTSPj zlBGSNfp<`n%ogy0-(mC0yFC?FR|U`dT~9u)2cXM*q@ww$ zLA~@!@8b|@g?`(IwiZp+xO>dM4t>6278;k}V?GlO;Y3@qLF}!Hu=-QL5mA~_-{W%8 z_2)qmKvz;ys1~|3(5-f#e&Dpy}uL!#vQ#LN`WFmxTJFMSU%H?&1TyXFq)Z32h`2xSX~ z-aCkl5Oh&vHuoxYf|}QN4PFY#mh!IxrRbmSrU9UadAbkFafVapPM52g9eKo^(C{DlzR?ZlwU8N|!e z(=pRY?Zjp!0(zAZPxaZKgn#$*AdduEvgn{-ZF-8O2tYY0?W8gG!Du zWSUGkTB&!5Jf?Un3Gr(0&o)DQ%B_;|`tk$>Fvt&nBzLXoxL~~>yrb0jUMft7>J^qZ z`)gn7k*JcRZ|t-HLP%ft&Lv1}&Fy>1(D#k_=|P1K?aG4T5OWN4B; zV+6;r-cyJ;VNoq!FKUs2DlZaVv~u(srcQwIt^xdND!|JpMogt|x@<7^7Pi;XC6bar!-O^4{6?Rew z=h~!cFMu6M92d8oB+^oslNI+1j~M3GIV-o*>wKnrsfyLHB$;SXw37)t8(!SVdEtiI zufgy&!GTjbPUFLWbAZ&F0H78fJ4Ct){XiCUh!E9W6AYmV(wMWw)aG)Q0Lfzp#75~Q z`y)=qsUFDzzsFo>5J2O`VcenB7ggER%9PW#m=Wd>9qM8>gG{t;I3O(dn** z6Pg3EXbD(#4aTBsNu5!z%UF#;oG=g0WjHFq*AHmED{j@SXM-s(wMJ4*ClR4>;uCjz z;2PK4RF+>Hv=Qn0R_QGJOk0tX6Arl?D+1~l^p^hOEG_E)Y1fJNWHmS(C&Uicx7C@> zM#j8w$RxpL0d!%juJ1!EPBYgoR^L8TVJ2gJ3;ZwjW}q2Gh36qGA?X;MVl=&<_?RT@*VJcAG!T1@^tWog_zHs^E1N>%stmB zKR61TdLAcper~!4^DKy<(Y152ivTF-{z{X@Z^WS+>hw)A}^T5 zWWnTD?Zp6%5mjp?vOp2rcZR+*Ertw=TZX?59H3MQu9mEFk(RttMkLVDU6sAv5@~LL zflQ;~;1xAh`a5$ch}6e>$0VQ2n(Ymd3!tx0D$B9OWe{%Kl)BCm-*sUZU2|%^kCZMD z@5yHSiBounV)p;)DkVz+r`HBigf0_vX&_S=AE5m zTK@u%Y)W30&m-9_OfjTKQmUX^f+`!!O(_{R?-R?Jlal^Kn5Nd7;8q0*tG*}LthWL$ zsoQEcoc}#1U=uO=qt&vsR15 zL02Dl#eI+pB$PwLBIDwuI=8t@>c{udX%Z!>Nz0+fDg$9bQS6W8EADHl%Y9P24?kcK zxZe7iP>_sguMj~AOq2fZF%DSJK%od z=RlGTlmA<`W25NeM($4Q` z+OIe&Yrcm2WuIp{ueNNL=M>Zx?+#!u>+RoJov;A%%g98>I0KGGE{#$kkD~DyJ!WwT z;!bm{UnZ1Y@(am}w#=Rl14MWSPo-)JFV-%kP=;ky@D!*XYs!^<-xdw#J0G9CCPe;b zEB@rm-9H>^kcqBPcKz?gYVq+1@pdeNFjLwa@AC2D*Rqq4(Q9h;EyJon!c1}m7!?hz z`7h4NGU?;(OUJN5Iw8{(=_lE%$5}412+FpJU4bv9^PkApFM#g7guKjB9QNYHhBd|5 z)gI6XGTZP2-Ws*D^GQiVQ+_L_EZQgi4ny2eV^*~dEMm{W9F?v%WS6hHrsD5MoWj7U zfr5$ie@XP;!K+j{kcp}=2RrK283%;J$0Vl}5|p*gM*P#wfZ|IK5bt>xwkz${Cn@3I zNfhgQaO6%c2Fvg6qw?@-m?Lfrx0J@WsV#s}Je9;o&HsQyS`3J-1J5uMRXpET^64~o zsv7@8fMm>n4NuL|Ukxy)lx$i|K567VtR|ajk=~o8;H!WR{2o*5d0MI&7zXHo*EGO- z^Tobsn0?~KN?Y-j$%t)RolP(A^6j0Ux8D3_z5OC5c0RJ5#ouleSmeD}`Fim3v#BqS zjxmx1z$}T&<5nRrf3R+4vKGX3e?EmoS$$7*{sx zi5)D|lj?K}x!E;~Wv6wEszi}a`J$~r`F$*c-d{ji-|;|-dQ-CJJSIr3fX-Baf4Opk z?y!+m2U0nBK$Jg8UvtVNvZ=_K~iyII|6Mli6lXzTjEM z_C3Y3hr9ux?q}5+^%8yK-QwF51u&YoD2OWq&ileKCdlW9`9Kt=?|?asOB}U93qUI_ z1odbqAm*9bC6KrL!QvEk5FDf4c9+$q$@1v2kba4XOHEcSty$vT9+u?-13O0 ztSiDDxR{fo72?2Q;PizS*`bR_6s9S2aSKP~Kfw4UPwr??R!Rn~zs7UQXVoO-l8loK zQtz#{I<6a#Pv9H!PoMRlJ(cy|Q05Rkq?;DqAzKFN+f!CeOZY~NAOqKOHV@)(R zI!ar_XL}1lSyFl_CD4g}ZWvG%T_BkITGaLNQ_TR8+9X=KsW&EnQfi>yuVzuZPzoEo z#He5t30B!VQX)4J$Ll2p_+neB+L`=0PBPkQ%In*@dZ6+0_pY4X=;A5kn=i>hhDf_U zd~Y!uJS)RAxEC23mzi0_H}V&h4NAHslW?vZIi=AHSy!V|`V4$k-w*x8ZiZpnA+anYdDy z(N@w!M%5Z&Yy+E9s3Qv(Rt*MZsrxbAn&?H738xjbQfHI1OKxnLCp9O>By(o#JHulu zSiA;j9w-C~$^Dxf;8!7rMOzG`1mO)DyNRLJtXvNPHK&b zRwGFPMNy`vb==EV;BS?Mr zM42tmvkyiVa?S`Xe#jIR7CR>xv>CKDKhGgJ)$s1!ZGqV<@XZY|trDEB=&z)_#Wj)d=Ytkdo6H>X7ZbvtpD(VJIdlAbhD zch3`WFGoqbjGzPCgRFsWcC4}W4Odt1%!s^zSFY{&B%In;X8OpI$;oem>-K=Xkf zBYEcC$ z=1*=2E}L7$@8%g{ccTSy9dj7rCD9-5H&J!X5Ai4XK-ryzeZJTpqFwqHCWinWE`#y< zxX3zTtWqz3C@U0H9hZ`QwN>TG3J-);*YawjZx^D;(TMtBvghqIlWaZY_n1Iyf8>eR#hOL&8SxAx}QpKe&1qnac+wokuLu6wZ;ouSc)GY`wyR(DxG1jP+<@L@oYk&12B) z#OtKCl%I*JC_GkCssB`VtB^L`5?gE`9IneO$Q;yZ4^oxV))W5EP|gkl>r8u2-lT`i zvTK4$xNV`qKL`A!z)C6Pm$1fmEtJ(b-jNj0HgekoHS6<54BlC$Dta!>VfBsCqWz>Q zba-eht~W`7utWpZdNVWSST+=9B`G}#wjNYgLqA!%jF)-Y+u^7TZSHZ79Tcs6Z70@z zqp(kYa*9!jD3Zwb>D!NPCs$tBa%$GZ#*d>P7q-XiJ$CI_XA%5+0_>iJmDP?Q*iDwD z3*89z?R2KL`xJFn$b^uv%2ivN_Kl~~;~L_565~}9qL}jTn$>4&cG&TaCm2t~KZ{~@ zWy|>CYM$?Nc08n@%0ENbEJjki@1ZubO7tGn)$D`>6d%omdPmik&dJU3X%^L(Xyp2i zAmIafmIK{+($QL2^jkwfc`IpV7zL&Mz)dr7op@w!9S1b)nTZCjS8Vd2dd8WovTx3X z6Uz5}&Bat$v}6LGI2#A_TcG;8Wd|jVA7=ZNWPZz;*>?>J6rK;HZRO>(*xA=MV|q3T zj|ok@XEg^-bwy`7BrH!S)`z)xj*B>ljkw6cEX(Yufv6wJTOGLT4mkU!N==6Kq&IHu z=laXW7xu#C(gWIOwX8)jg@;6uH&~bw%NygI9bPuREPIwia+Sb+4t%x7M1N%mza^_{^>AA^imeGC`qmJwFa z5>zGIHMgW9%{vx;uUqFfZ7Vi)>O&3{3aM_~>^FQ=_v-{)?I@rJj6{EnY*lZ(e*w9E zZG<%g@+TVjjtenyYzjM*wih ziDt_QDa4;*&n4h4x3(1R`4D9cJHPt+b9eAljJmP*8(4h#b zv+8~P+b!h;1+|q)kA^T^3p)%mk_QMbMfIBg?pF#G`_^uRz0hig$5O}djwo&^uXH7K zRa~kPF;aVpb4yI{k{aQ9#aG|z_(~R(aj|2xS>q*p;(aar!sdD|7Fl6fxgYl@xNr(! zB=wmq_HC2r+-k_G0y4A~CdcLhSMHK{kCYS4uWT-AcCPDFFP7{P{eZnm@Be$=m4!5y z2#)yZ(w9Q&LO0dEis$tjgxk}{^ud1_nUFo8hdk}&Z{EMNNIz|JxJJMaa&3P~c${=r zI1bh_J0JzBcTfQmwF09Zbtc*)kG}IA!PN$!(Y=A+=cL#ki!I0U_v!Kx6D%ne=7y=* z6@zLqN(_GRvw9FZtsHQ;RZb*!_N!AqW#}BI#V`K2UJg%9y3OcJ=e9gk#0?vHHQgP% z?4LdE|FngLgqieHTJK|QSSu?to$X&5ffqP(J5dkhJSsWK6AFQoX7o6%?MxfE9 zSy|N|``d{+MH~4^d?mbcbQoWD;B`#;&rG^9F)2LivU4w2gdD&sjd|@uza1ysVq8#R zG3wW4HJ7@B!S#KxGlGS1e7eapPsU&6sqn-AIi!0i^Ue<~j}hAxg5(twU-B~UNO*b8 zgd0VGi0$ildFdhed+}6fgXMJcDw$E{co<>j78_+OVJpmOsnHdByfEWjkz$+W!bkw{ z1GBkqJWUne;J~rf1!5@XdZ}*_wQ)OH*#-NG5$0 zXk|_@-x<3T8(J%Xb8TMk-p(7F`@iQ`w3b_Cs{4gk(X#9d<>*WvHzgCG7UqSD7Q^Qa z{7b9!Z~7}Lo0t~`u@Ul2V~Mb$BNlu_?}A>3KpFoyyX|3kUD2UoUwAri%7eVb zPJU}bCXVtmP;xlPbZc1&)BMdMwyqDK**ok%$H4yGcy4d$WVjrF3AniQyUWp)ETqH< zYKle}bWPC^rd+i!S5oCFYOl@f@y*xD{as!%McUHPQ17tM5|7RbHlBLz^2|ZP>XZMo zZf!bw)|qA%v8jewoI^v|Ox;zDO7es9NFH`@dH*P}W?M?7NFY4Mqtt5aQ^D4wrpk%l zYT^jlqg9)*@v=32|4c2Bo@skk`)dJ~LBVadE_H3xdfj?>R?6fL1<*7D^3bpg_wfmf zBGWwFpUqF_OSsD)8+J?gQ}qTaN^J3h?)s;}yx2e9%bWk=mtF~w=_b5JlS@ak>>t#g ztzB^2PdzsSgXv(&r_0)%3t3ljD_>jv{VB9N$Lj)+~kKpqM63;+)P(D3?1x__zw)#p3IlYt2cGg0zDiP2F(Jp)dY zgRDaHs$?-I(B4##X79T0u#!bOxh@#7pfLx*z4M!QT#>qTo#2a94*@ZRigWgiK(`U) z0=u%D-V^P^+B=j88CH+8lP@?>RGUmE`r)xTlgbNLTl`ryb64^MG7~+%>JZinN(IT~ zZR?kR^6v{6!pdh2_yJ}~k~y0@D*n-Nf1rkjE>>3yFT3{}C@{IA0>t$PGUAh4 z4nRWI@gp#a1$D9$hidnvNxT3@prXcDGc{R=kr%w#9K6|e&}L7XBIj_SFcYA}ZEtAP zie;fZb-D>>8QcR%pSugPzIAh#E(KZAe3WPlCe^5gq}a${C#hGm2?Y$7V=xV}LRIGR zpU%+`nQUER5JARab_mnPKd!lfS+2g!wZZW6^sT1=9jE-wBsl53&;~b);N=9TctNPE zSEsaf@!r>IDGCdg77g@!`>R>X{Lnv-I8RAcxj64?IYJ2DgH@Zkm|_csXy+r zIi$lt)=4OvZzx@9)vD!yR;fm;tfki8QVv`qhq1v4Py{OKu>GKo zeVuht8w>H_(ET>gTQ~I<4dwFe1M2-fet3aEZ7cy_%9Eu<4W7`slZJG#&}n^Xl;i1a(p}N-Sq|4g(Y~sdUa|Nn#<-0R!C7}5%MPmJ9qYd$ z?1T4!zBK7LRoyCs<{8j_cvgk$E*TWUxwgCqiF$h*8L?D|5gvB&gvP#TKoXmShG;hX zX=>GH04X>Qq2Jl5d1YXS3=}*12nE+LVdziweUGi`iC6FvQRx_3+_Yu#sMbh>Zv113 zzO&uFeNS-XGh&_Hd%?4s1K7s-HBaY{)iVzU@%df3QrBM`M7<5^O!gMW#Wzg>9h!EW;w z2H3j!Nz1xGWEq#EjC9HYu3^o2#n!^_oA58$Wg}X0XQ&6(1Lca`3KhG{Wu`g?|Ef{q zX~!uEONqYkKTKE;2l!0B8`s(BSurFImG`+M+qocIn%_wx1Iq)g9$69kX8v?_q|cO0 zAucMz7UYk~ zKgqe(Z-n3UVY>H}hr3*{BFSry7LF588lLUGeW@(1CjM&57x}%L1KjVNh%0c+Um{O%g0x(T?<&prUrq2upQbpjN;)UN4!pU;|dZ*dp`R7lKR`YPME`f(wjd zkePod9y$CHREv$^6SHP9Yb_t7F@`2WAeSqz*c1-b+n&5EaZYV>oNV6!1jhHIh@TA~ zO|!%;?wewEzp5ap#_OXgD@Y7coCRzD=MY?NI^`yE+|OxfEap3dc&k1>xDc>tPhB(j zbZWkZGySx>Y)KXT-fBSuViv=a@758su(YzRz7^B|W9i((ng0L(ze+_1jF3~>oC-@u z&WB*~7R zSAVS6;rV(#ABX$nexsviHrG6Q{6e=7E6ONVfbNX0H;Mi>jFr)aIs%Uj15%F7H`@~} zEAZ)2W;s2|4;9&|nXThO9%6eX&v^dJ)%f#?gAbvP3UGX%V5tb~bf2CDHFKxeMmsi& zX(Gz^Aeh|$T)#YAQxt(1zuR*dw3RSoz2E3JTE9hJ!i%jn5p96@C-hb5@?zGuxz|L}*G$J~tT$5UQqG zwaTs)am%yr;yks$|7%fIvN(8}v-q<0xyPGnrs;9OgZulnrKPa}-<{XzuRYZHuFaA2 z0UrD8u!#h4JFBJ~3v`YG)*q}h=2p<_3YGg4f?L3Jvv`D#%II8rx>)XQdW2r_^1C}Z zx~v&676GiO&zt4Slqew$I~!{MHTWCTInF;0c71&UW&AFE4~L<#X(`b^d{V&B=-|^c zh=#A_#y*nN(h4(~+qaFhfIhFh?Ma_V(v7a1+}}!tIaB7T-9LZ>|C1g$r4D`}qu3PM zE@Vv~{f&6Er!VOnXLgN5``$dngZM^Wc-ddmTpQs07e4}N&|{W z#np~PS!clG6cS0=oq9tGNL@KN$8n2`csEwXGx4Ob1n}5M({--#>Uctlk6-0&f9NL- zXt z52~|?l$;R(^Z;*0Pu0`WZQ?sG>l!ka0le;y=T6ReDg(>-<%Z&Tv&aRKv7v8yCj~UZTb7l#*LO~Q0|!>xLDOrgsAQAA6^ z5|_9sNWG1QalDrX>oUkCtR|7CS9U89*+0&w9u9n6M=}MBkUMe&VOBm`1AA)Ih6i|e zoPHwZkC~JP@Vmm~^>9qd69lZI${1>f2BzALN*;O1orMq2*=OHSdwB8lgGP&+>){Xl z#@@Acw~x0Za)$jebfpj}Hm2l5#f2_@xvR`lA6CkUXQF(AgcXpkTG)gpELX1D^Tg;} z`ap;{0^+;K;Qw(izs-TPnHDtk5yEpWag8GcCV$&WlMox7c^{Do*p`nan+v=BLZ=LE zIJ^HX`)hlmd+7^2RAWdC_EqwoAYsDSZg!V#=>5Lw(W* z;-@?n@L*1s8OC|1DE@@r_xqWX4#RexSvKzA?9&$&Y52y)l^g8mxQX_OAG3}O-yeUY zXiYDCqp;|4O3UCzKsMGTUMv!~#eD7m1l@qQ< zt0lzE)6@kgq82X*=iHZx^)5yMbZ2Z9>6FD6N`hE=3W;Z2*MoH-JgSO!3p{6O(a3D< zmIuc%;DM;3(0m1z;07Gig+7*jz;MqfGa%YoPtH0C&JOK+k;&ocW{zt@%Ec-~Glx#H zEXK<>hH-ej&G@E7H9>gT{b#F*H7Ag}+Z8p$|FWRCo^yC>YqMETa*Q~8uiC&pj|B*( z?WOg!^SRgWH5j@>NzZ5Fk9@OQlrbF}FS&=Hmwa3<oa-c3IQLH?Pj1tNwybc4Ei;XzzQ9lPi#RrLzUq@@boSCQLn!Vy zI`G&~19z2XkW!3;3H=G~Z~K9q&_~oi3&}zr4T@`5dgT<|bprLoSy7 zJ}!Qo#99C3V<|q7;JCU_=Yuh6R90)a{;Cx}ixu&IXH$>~ZOb~t`&QX6vUiW`Kd^6U- zm5WElYyHuHHX;a+c@Cm%eA=0j!Ni z@8NU>OI!v-Ov9px7*m<5DT&9G>L1PvQ_^Tgl4_M8-Qr;I%( zK|B&+#P|>WDGrBD-2Ek>U)@Aq{hv;+{e}`Yr%&l%y8qV%)w+ZBOD{G{G*`?YY`^e# z%{hkJ-k#NCOW2@HjFKyABHl(kN)t5itM{*3Ylw3Hhu;rTKjz1N&Ih&XU++lpJ_QU{ z8Mv7T-suvOV5?u!SM*kS8Ex7UIXXwuEQd67PpHMW?2_i5zgt}bM7Q0IT@iM#$vwMl zmP=vh7+Q zi{>FU$wCeVlE;ZqnDlf>Q{aT-r5L~1El4GRm3;mBH3G*w9H0pAG=rh4jOG1i8h?*? z8GWuBL587oE576v`P@1HX&0kcqzOk=V{?BR{zvrDc@Ko5-m80WzJW%?gvY)7s~dxH z7I-9d^QoEo3}?eV$EX}-4iMsZ@Sg~O#A|-jeo@AI42Q>JvY}c?_+_JScA_OXtY79T zSoZFij-!f^9Wo#}@|hsrxJrk|Lj1RVz8;Z$TrCr2Em{R>P2Rp0UR_Xfs=m~1@EPoM zHvnqe?f+Q4T5$?HNyPTM5DQ$%tsCO9+JaFDvH^Q$%NL(yCZ|$Q$*6FDw@%m7 z6hKl}$MreE$E_~|#~AXTCJE{jH65z4fo-L&C$1}aex`J)yMYjoWasuyp*s7`a8Q&A zykq&r81NBZgkJ{}nfYzzgQ$?c$GaER?+3jT)f^otQJywtEPr?g;{`ir0QvV(X5)1M z)t1YajjQ9T4Nuo5nn(rx`TO>6GrolHcY0$I>WP`7;uSx#vVnWDH}FPW)iURox_ z6J>_H-y(Hi{!2Zx9|V&+`;9*iFv+1a4ZwLtg3_C*3w$;1l=TZ28$M9@tFlPsOgA~B zVf~3K=7$(c)#8{G@<%v`s&=M!s-L^gL@=2lf%a7`W>j1rkDp`7X8!k`0pj}UHe>LX z8g%_yRj;L51TwBJ08tUw#MZrLPWLfh4e z$s|`E<^6`u#AQj~AgJP!0nq94;nq8UIc0TbK$JGvR{^l`6`uhOMkOM*=%ngH-u>Tz z7lL=-udDm~TtY<;JJz9Xb>175eL2>)+*SXGlEy4C=CmI!Rwg`%mvIU$HoEbvj@0nm zzAe2qE4s2R7Z5;DrLApQb{X}6Ae6iI%*=puA4Lf-WPO}}j+e?d*h zRqO-vbphh!Py88|hQS2+aWLK1uG$xVmM#gtqm~5TDn+SBJbSj@&pSPrmUIGpTMw1s zekRI_ppx1Jt!qA9@$&ZU>R$N>e*3g2lyAp=#)#UwGfZk+_H$_dG@_G^VvxS69fW)% z=8VY>b;JXsyDBFc{g?K8T!2M=#R_^|l7199>ZnZ^W1Roh{__uHfmv)7KvSG6`dOvq zilQ`qt&wox99}aRk&g}CmBXy1Oo~BbKGc&|TS+(}S0x9sjYTS;VvD0E2w%vvyGQn} z^(cSEn#v)Ds5Ndu;53Qv953qIwZ4BZ@J70;`WTAG^#X+(Ngbc{Iemtgt4oQ2qY9G_ zO?_mNPDC#WocQ?%Aay$QFJ`$E?!j!^fh5j)6c3`m;VeK2{Lq@*7;w~roKgC6G;gB} zf2Fa(q~rwm$38#2?X{;2CpNWfukz|``%IzHnaq(O%*1^jImc*f4DP@CG+<+OUJf&N z5E7$-GBB%rTj>K#opWVYvd^F`I5z;LVCN?{q~}@_x1-9>x2ylaiaHfSLbx$r!^9}!bx1%9_T@0MmgPTrI;yN*rH_*fZLH+7& z(hkVc&u91R;g~+S=+taAqm~9^>!X}b%6*1Y6 zxm9B+psx+}EEV6gqM3ap;95)z`weW8tEi$PlGuDe<%zijW`pWSw13sT({M}VY1K8- zvUUiA8`Q*G!Z6HW#Gs?^j7OBr*PdFsu_|+?D^M8H9zs-n;)!}>J=cedrD*qGIrnY4U~`YAhee@;fZmzp)$#HyFV;gqtCoCkw1%c^d)jS*n`WF>7LnpR+tM;O zlw{T*orM|f!A-qr5~{SnCIV{f`&e%Kflg}QO^0zMkET)L7fCs7*qJI@7} zIm<>*@&cw6Nm@%m#(h*0XU9aJNc2>L$Ii2B+jjRtJn+8Dl%(P)=P$7O88DFq71Z~f zYU<>xgyZEz#X22HC`_19xH?YuoJ9a5)o^M21Mi$=aCLRCynkY}!Ae`lKr;SLZ@_u@ z53jb(vDzr&ftXjv`h}-j4-!Y794s&Zr{2Gzh~sNtjGY#!@6K|k4A0eb9K(X+zc{@< z$zMeY4BGxIY4uK-kCBC>$t%xxQ!uX_kHWAzW2_LL(nidvm)`n@_&yN+;2dy0v(}mQp;(z;rvaF1M;mdl$C21;bqPF z>R-TU^$Qg`i4U=7NeBTUB>py|tp6n(V@FbP+e>TQawp`k_HF(bx8h}lG9l_*=S&33 zxeh)PQtae$upeC)P$z`!A(E67^a`DCaBhH?0ZRP;`>o!T=HLpQ<5ucwo?Lvn#j_{~;P8bv~5d~^u zq>^&H_0lVB@14O3epQ8NoQ{DzGynU@e3Q;qcw;z&%z`Lu#8)KQ2ReMK14PL2ReP7T^xjHdcsHO%X$+RdSD+z~9D_!z zRede$miO=BYeH}OIA!UZfBaxSQm7!aS`mkcJYD*!VY)9!)14mjV5 zV1+PUs!Zhp-2`~htzRyCGG^P%0f}LO^iTLc96lQI*dJ-&tgTmgt@z*OJ+>nVmu^X^ z<}1JSvKsR}Ky=@J)wa(;2q(r| z3AGWGWtPajHd)fAha0&5APMdPlW#ed^$8bWI2my&pf&K2a*9WcL69#Mw*E0}k>*vT z^F{4R6kQ%7o#COAy|@J4m{AO!in;ml4(s0k(r76XmC1sN$^A<%Zu4r}KCr-)@DnUZhtz zEEsyrWEeD1d*stkd7|^9@7^^=akeKaA&{6u4I(Au51)3P6U%f*M>}nmC&|PrJj*x( zCrjga`AR(^y+(?|iz5$#T2xwQsl(s|6!y|h8334iG?*abk)?Qo#QXjsIj8;1)Tr98 zc~?>0Gq)c@Vf5vnGN+D=29SFN%{gDCiLY5L^)4I-M^N=3#x!PeM7zimuzX*tIitc` zZi21pR@5=$xKN%K6IY*=cIqH7ZF`4+a;bRM#w9scDKIKc;3aU1=W_DC!T0}fjWmIu^`})-tH$no@=?&u zS@i1TlcDx~$(;58S*&nLl1~8%oQFqA(l@qp!NC6c_*|@zX-*w5X`@8C>869j=ipE9 z#3RAVmD-9Ma8KesU2sMHL|4nMvB5Q0Ed>zD!M#C6#Ma$G&wiibX3r5AowOEBQAsiR zSAhe)`q7&pmbfsYD*B%vm*n`+NkkD?3@e_%424Ugq@dPc(sq10tK|DJU2k`59}mfZ~`MroEO&29siV%UlE(gV3pHEZ6CVZv_#*XkwRr6hY~+dD8Lz%=zh zf{#mPx|n|G;?NWXmqU<)|DM?oN;3s=Lm zm~TY6WYBNHnB%%F_lf0Im&#=_)5Hm8@%-Gz z^09XN{rxme&I(WbVkMQG-U zBis4pNt_L_n~LYP0y?J@V4&%!$Jp0StEWAKRq3~Q7(7*rf@rjmRqx)ttCeFR5Atp| zeH+enT{%)=!57)8YSIGQKDGKea!LpsFOs9&62iy@E>T*G|5Hk0b= z3i8Ixe>Cv6^^kHq`24+hx&NBuZ6@7C^61S|AQuzLop2)SD3!nih_k*VUcM}BwoRUA ziF20@HAH4VaAe?qC}23ul;=A?erGVA2)NL+oltHtD0%Qa*gK5eRZ7kmSsmuT3FD8_ z7!6b`JiUL#?opb}%^{A5Ae4!;j-#SNSR-;(G!zDvhSuXN<^WH(JOzm@dK2&Mhyjsu zu@2HLvG4l-u!6DuaovAUi#Dj-`Yv`66O&cM-kx0u4T{BliQD!r4!XePvi*Ak{iF^y z?Mx2|9*f!bdc+F{znc$J>hQbgkn#`R(iu<&(>8dv@8tJuP^ocI(W(HMYvNu|{k5+3 zL>V{l{l?8$yw|}Kmpcbm6eB6b`AyETh)1)UAi<*u71^Xo&!X#;bP%f328g8(4y5@w%GJCj{aD+6F`yY zmsjKfsh1MsJh+)U()vb^{`U+X9&2KWVMinMDJ~0;Z&Nvf!pKbD18P<04>-x+5t(f` z0%O%Xqtb0YC3J9GyiD^@xNp#qI+rx}cSH(jLYTQAyDkm_V3=HU#P*AW> z3;qhQwv3%Mcx(&#Kui+G0Ym8{-?`yJQ+v{KIW`DB`fupsKSrSqr+v{`)@*<+5^Os$ zt{XnN0ALrktdSr2)3azAIKinSvFU}`84kI4Nqu6ekofXEtwEx7jqbO=f_!t!Rkd&L zGm-;(wM4Nw5#k>S&5WR-SYE7#0jGUEM_KPE_aH{?VA|jnDZI51ZxZ?NMHF2 zrf9}VHswEi3B3W1nAkK`j41ekUySSy(0fQ0Di$V2f9rbIQLzfuE@O_PU_I2t_v=ay zOU7Dfx%Uo4_;H=j{}tbwjW5B!mhiPRaDRCbR3WBllo=a+6BOzGv&QcZ2O*!iHH;Hv zFQU?gM#lM0D~MLrsNxH#1}gh&VjJfj63#?wJaC&bRCH--VEZR=hFHdM6 zJR40vB?EjukgEI!+%OZnlpn+7Jcs~^PsDSJmD17_f;4bPGLVXV*M6*3@VX&dgRzby z;HH2pX}hXjn}J{}EAE%HxgqDPV~^57Na@PfVhe#h|Lz3X6>t1!1%&Yq=^rZ%_}vl& z@8ffz!pQ46Lu=)cz1(4NSjXd^lp`nQ({BQgY=!g>{6^I(x#gAu<^)xFR4ka+iSuWi zW=wPgSl~wbFKDT~sU#of>+TYobE8)r;w0`RBs{_lii{bpi=$Oj#}bCl8(d4@;&3;C zNy*z;a~uQK)9xEfJ;rN=ASS;I5F}Q0)Aq;rRu(JG05EaeztargCp1o0@h-D~BXBo2 zq$b0MzrrD~*aBcOU(386?*eo0JId3EvS+;ECQsY0zMe~zplLRiDwJ#_)U8=;_G~(` z2r2$G&frW>L_PKw9xPLXOHEVdtB%Ll17Q&4CRqKi)NcCR{9t1z-fACc|E&%)%V}S6 z?~zZT&^QeSG1pK0J%)6pIe!=K6GgWez?IxV@R;&8ud1P2i13Zj1A$zWoSw44Wg zxgjUP>;IZwwORFfa&ppQ(gl**=g6ZOQ*LO;+5N+B7>2-xH(t%%BXHvb{2Uts6FIn9 z?8o1PkApbN>Lx{dh5Y1XI{cAs4Lp{3rf3S(0AgxS0^5|m-}ICCluNjy?Ru0T{u+D) zG_jI_pwjg!CHbt|xp(l~K0>9AZi!Na?tf{2Q4bfB4}noDjW+u->@}=`^&@@@$Zr9C zBH=xt6+@zW(@u`4hBU?n+PwVLcv$@)kt|ydzZkj|du{o+9(!Yu-8ByO?sWKdFYAd) z1A4fJS9^mP#k=l$m1 z>IYl6FRZ_(?#bw*-|7iQ=R(!wf?`A6IyT8yEAp16xnSv^31zE8*Uw!)RKJ(7S{L@0 z=qFHr)*OLN@PUgoQh#N^Tr18Wa$%UjOnrvCer$Brnze z?LH}5XJ-QY7+u%fgRyn9DpL0_=iGk8N3;*plS+H26sJ5cm$g4BCSqAT|A_j6Ez6a#T5}K^@=oHiav4sD+6b0`nPUb zAt2y(W{u4@e(@N1Ex5VBx6($aD9L;@@X1#DF;WQ({UMdWmINOBni?-PT37b&I8}d; z@y{<>%O#PsJAto(YWwmVw6s^7sqN+el9h1$0|5jOrZ(Tw)@a++?HRNpfDJ6ZsKD?9 z;7N!+s1duX+-}sI`7p+mg7kS-`N>b)8a=d*`{X3q3dpAC;Z*s|;_%>}&AnSK^$Ek_ z`>N1Fg?jymUWh<$YPC>~4U*ivxI}Olr;a}a-3jjvG!am_A=aUnj=fT~j?i?qkCs#w zQF-qw|MIlb=)(JiKva8R=2`ewt2o8h1YJqZ$>pZA#--!G_CraUz>*zX^;yHdoymBMMC*unkgOSrQm zX-j6bRpm0!3uHu2+;-j%@i*PluF($i0!HxjtuM}vlRPB$AcYrsuFG6&z1zuS^GiSh zIpdx4!3I+sjQwn?dPFMoXQ_+)|N01_ZJ}!XGs6M3me{>YQY+14%PT8&1W!Ds9k>s2 z^~)jZ=)~UY(JHvk2KA)Z3yHxn0Q(XHUYyH9|MnFSEm~jeT zkK+EYAMD8268my2ZGW&Qa;HCB$(&I(@YvhiWk8P%F_E15$=>qKJ|p#yS8x6${Th+f z$FT!b{@SS@v_$nL;RFDeRlnHJjRWl7F&~r-AWLv1ZAUC)MSkVapFdXmN5HE0?{Aemv^7q6S+$OJkOwj`iLu-yrTDzHG>8 zUz>DH8~BrPr^-Gcw(*y|HSwy*LZB-C_`+1+MWUzsuh_dt~V$v&@*o=TWL@ zQielpnk_nPW@l&4K=HwQemT3A%GC z`SYsaO2r<4GVUo))ld7bX4yl<<0}`QhHd`+J-x$T2TR3ON*6UO6wjw`^WAV9k7(Q> zt~pEgkmuzWwGV->lQzkwbnzEW>&qSteIb^%WW^7bEyc; zR2t=#DIdQcNOz4vu&?*^0u)xYm_|eIlC~e1$qYJP(c1ffte|F<4?yYuQ(f$RiY}8X z&uCC2Y*a~c146_oTh=NbwoeNRv{LcDEZn6^!C8m`zlzYH6AHr6|g zrHfg&UGdpSq&OX*c}ecy%TscM`(GKl18_j00+sG5d8yLCeeaq0sqW#BO42m8qDFs_eyG9*IPibTvp|85Bkr>4M_s+xBc`}!&%Xgu&faYub@5I0PhQUuS zl;n|9#UR%3tR`cY;lpsrv_5sO;R|Cmpi&GGdy+i#A16#oWW)^sBNGJ8LHG<{tMf9~ z@VfuxXCPM}ow@y-TI8fB1Ty1Z#kTD$oUam2BS0=v2>LicVH%cud;CpRf>5sC+zH7o z2&Crz>KoBU#|Xv;oVn58p>2ov@zNo7!JwPnu9Tx{=6RzY&$3Vc_tKTe@fz0+))H2! zWB|VwA%o`~Df24`H%z}Gi~kIArgas1F8G`kw;aj7hGQ< z!Uw2gAYGn&3J#G`N3Jsv5Wt>6d0cgVu6_b+Rr56E;3vEm9QIT^t1#F;dxi?SFNo%2 zxaU@9OWrjA2Zm6)_lBg_7hHlk^QRJ6uaDe{f$VjSy|3Y+k6Qw@z36hFWaQ4i7x#G_ z(|n#|M8)uWy@A$6Efb|!$K7`i&5e75K{BLk>Vs9B|N;>m8jol(h~ z5xIt^9y0I%>4Yppl?7y!qNaD2iuH&p7V|?rCa@oW{_JgpPu}n8WFmWMeg|%u$XSXJ zN@!&s_q;?53S&k#`&6r+ypxNax0Nt-yDtPoI&v<}w?uwgt|p#olLKU%mpW5Qpejk3 z^h^RJZaysnNmx&~EuD9n?pGW676_E~D<;4QON_U<<02oI`&X*tg2pV${#M`l=%PO(*$SnxH8QLJwN{DNEtnR@aTh z5rz5>z2GlnuEPW*0xvu+d6Kt!E7`wtPNluRJ4CEe?PAtIZSYR-02x2>1Gi^P*OVhE%1`X^AE zhR9y>%}Ev#F78)5&1yAjrrxB&Er=9>7&JFw5f)ZZb-9oPu)8o^8*>prJy)wIZ-x39;TG?)w^YlYhzcVc z{_{`dCzSl8*^U5Z?=>Rz7RnGp(^t?ibbxhi5zJFL-LQUPg}+{u-iU>=*mWdj4|sUt zS8X6*B1wl2tnHQ=>l*`(xx4H~K7%W=F64^C&&!u? zAA?T+{5iwrl!~YTebT6SDA> z+I--0g1OCU(2#g{D~Gf_3-DHZFFSLZ?3N%KS{>+zKl21P5%*e$y$f1cnJ}@#t9@vd)G_+I>j@`Km*97`nE9qzO>vlEp+e}=x}uP332Bs zDkAt$bQa}qE${oGlMr=}K3AllyL||e0E@yomqJg`j0z5#-`w~4L3R60F1|vnbvD^T zdE5WK5R{J#U-+xO#`t{#sfHFP9g7+)MLbHYM(pL5h1pUi=@Q7+uTMsh`jizcIG@#h z(0m3M_cutCCn6ha_9Nf7S7y3P|L2X^lQGbitq*>GO)eQW+ZG#TdhjPo#=9xTYJXWs z(o*r1=Hm~Kg_?4{xonh#^1!n%F?2yw2fX0n-QB_6R+fN1VHdf-M=sRc1M~o5f~KXF zq(l#9gstd^%8!&-2|eKKGioj?j_|7TK91kc6XZg~--PO)(hgnRtq~R(&Cqya!_jHZ zdmNsv6NYxCN7)u#07Q6DJlC;OslfdP^sw<;*(SddaCs8tSNCq@D7s(7C>@SPk9l3N z7>{q?*HuL@m z3IFWHrl?a2r*I<~(71OtR5MHWx6{%D4XO{_Wk55FJ|>I&M!JO1TL$!h^j;}(hm`A= zLGQSu!ZE#mQQU|J3f20Qw|}~{>RkkdzqcpxCUzV%|D3?_82m$gnqbYR-r9RU*CNkS zC2`4|qG%Oknf+j=yV~y#WOL87e3Ux$-{zk3$?@tndY?=Rw6u>w%S}D-Y6daCfR(~< zY?|=8AI^|7Y<0}G?J+o@C6|zVq6AYs+CnAWBlT=7raR%o-i^>cpj(hY=7q1eouDc1 zJsYjKkGu$YM}v6cpT%Y6DU+w%Ll3ESuQ;XAKa7k}-DMJdrkv^fQ~E|1;cCcY@DX)X zbyZ5rkJxQJ{TLxgQXO9frkg8^QDoyt2L|#h;KOtGmIG8~u# zOT20#?ZENvnwV8GMYZ##vrS($ffLrYqSfYZ6l(`BBl=`pHkl=%GAhr5nu?t@%NRJk zwmX5RV-fKjl=Nm)v@HJF)x~w16m7BDM?o_qCTNE2W+MGq|Lt%;DhLx-h4D9{y_a=T z)3FpSA&sDM{iy7|dzsSqkJ3byj7<(%v=G5L{+>?>sjE$7#Ixy&3(@_bdzz4d)(G)8K9L1u zAqO$$&prz5JyLyr_ z3n5|Ib(y}7Y-(%mQX=I4C#J*hDz<8)y8b~#2Uw#X2LILxY$ersF-ut?7hoL>A(~+7 za^tFpci&$8a4zAjOQwAVw{iOK<&==8XgsjhgR~Nd9lEkF*qqMo58Ct}H7+EytQCelR#l8A%Z&XO`c4N8&erqH_ za~8*|o z&XuCCvaF`nZ3mz6T?eYsnnU7R7bAXNiSn#AxpiI7vz8}y;^p(N53s=28<0jXMw0ir$|zY-gV`zhYM7n;3Hfd-l#p8YJ3L~rvJAz zV<*KY)jYoj-+S9Z_7dHmLA%NgdB!syIGbm?nsqiivIbM=H&!|uq!_#H4gU0VL%!_~ ztE;g~c~=HtU}>2GP)EbuGPj!K3_n+#XS>hEZ3#9<&+5e8b0E+L6VOj zJ79}D*-Dh%i5uu+-t5uVB^fYI7wp(|zFBd-GbzJ6x;1inzGeGLvl}i@@$1|*zZp3& z3(rGa9nUtLDI^TM2`+G;nwHg=eN8XWenS6`MH8w;FT7ps=?=#G59$by&4^clHWBD@ zK+feXQ!(RlkSu4L%B)#Cw++umkCVrX;7pyzD@%Ux7sJ zGqWU3tKpDFvk<+iuC6Q0#1oazYAZ6qxGHr@;2=bhPXwVfWS*lAu(ju2-T|L(hj*m|-)n^7Hwlri(*sK&Eu~ zY*7U42P=|Bu4V_X>JbL%O`e$o`Yjb1g*zi8ue7iUlF#hsvyqyDUz_va(NI=t9hwDs z@AE+;S!2dsC1R4a>k`4i+h1mE0zh~DS9__;<3LRZc`frEeeLhH#vV*`f&$}LS9`;- zzx+_egCk?!4-V3V`~KDZ={4J(aoL?=?M!vgH~pyNF>guxEdWCS@;AW;my%tSa-@EK ze6~b}P;kJq#F_5DF`tzJTHvW`8}e+0h{0^4Feq;Cr2FiRXG7Z6TF&41Z6=PWXupu6 z5ByyHd;{x+d&HEAXk8ESjL_UIEIPKA&Yae%pJNI56W-sKeQJG>5092dTp#FhNi2lr znj{24byddMfjjw2ZQjQt@Ffox_d)nf#p((rg}o^$wl+m2sB6^%T$ zTgHmd`Z*>!JeS694)G_hp_(Ui?_nhz04H%v0zd7wlR8cc{-a&&Cx88Fm2w20^jjXM zSbHw_kN9Zc2H_qNlbTIluzcf7kJRU|CpX^CDs`GfY^4*#ci)U@5BFh zdZoJ4sWWv(xu^G!`=dVgzH1&vhtG|kp)M2F4Z;1VOpj$}d0`_!%k47-vOx|7oLI*85**o?{D+rS~^zdguVlw~B#^AR(Il#&8s7;PQ+* zX1D7|F1x(kY0V*Jz7>h4O}J}@YcmKs@PGyOuNkjG>D=W)UczkGUiWJEHrP7={R+$z zyluS`s(s1T*}=!=O-RIxa-|}u7Tj@gf>A3hZu9yS=76txZ<+w|$C?fGm!@%ow2kl9 zne;8ObODR;I~G#)9Z#$4M&wC-Wy{H0s>|dTBQNT=SD!Lni4E?w@byPR_TRrws~O#S zxbFDXZ3ox88IYkU*Akhr>ac~!8h6p@UW#}Gb4RZ*I?x4AO22CnIy)zMh8O7+0wMb=^PPwg?F99cdQ?q}LISbsVWE&VR z7JT>Haq+q^MSd>8VN==FxPwpNh&yG&URFCRCz*{ax~{7Sxh5Mi=~XCSX!3o`wULb9 z8JY{)W1&Mn>#+0sinhCpv}tPE(euLLQ^uVW^tBTq3-<%YvcHyJndqUb*Q!)}4_~ZF zG?`E60h4~-C`0C5s6MV1XeSiutW%a9{Few*l)i0u%S3|4NA{(VlbCQ)b@pU~B1_j} zU78`Rp+b*p4715K%fm_R=sM2Qngxw&GYkDXG_z^T%H4MYJfb|J8`#D_3wxcm=)u2O zD?5?q7n5tMdX@-tz<7kMvphqyU#|`JZ*iB24EI=X`%Tx~i^{cUAC0d9x%KNiu@eEJ z6TQn|dv0^4?g}d8pFuPSU?X~kc8B$6|06!+qV}2`Al+qDjr!huj0~IygY=slUy`H! zqUkTNB9i*XCyraaS!nz_*YtC+p`P;Cg0-Y0!;GTLDYqzS~z={As*nE{c$zY)v- zy6-^Lb;lxDjCGikkH(02W--5f{^OOuG}cEo@df&`+XgA?V+h?_82=`@sDR=y~N*@MgGAlxlpMI?? zcU-D!-%FaEo1t{=nT*&iTc5=%mFqTMB25h&+WUACqT?#_a}4g)4d^uNB>iEN z@AM8YDtNGC?&k2nR&+7*hShJ>`kfJkMDEpAuk3#6`~{f)hj4j?odS`pExl%T*6bHS zZ+HUf)PEK17q%TkI2?YP6{HD++?w)cT?un>+`#FvG+-+pU(xpR2s)a+vUk&(0jAs2 zsd`bjNBdxKE#w#sIilNKGt)iOM{dao3Jp41exG{2=VgT36{C}VPaArysihY3C*H{V z`l`sG$~@o(#drEsJ>9WhJ$;0N6zw+2;su+T%Hlqlq=Q`4%uccR7ODCR&W>GfYr%9p z*BIW~#L#95zi_r4XTRJSE!0_#ezIF@mWy_wFH!$^EC|nS)Yq6YKRfO=5(q6bz4Wyj ze&%bR5F2N#!<}uT-(kC`wyoSre_*x?1-^Ko)#=I%hoZ(cP)Pn)p36U)q%$a`^It+4 zc|3?gprxRv)){{kJQrWF#6NRG)B=ruT8Nm=TCbQ;MvS-m)512!cNWIJ>nIn`CT5q> zFsY;Ug=f*mA*HM#JAmu1^_On#qUNbJDBt+~dI0m|t(MGe(_{&1>Yd=KSn-$o`ZdQR zj><*mt!*ne{_9`_{5-rN2mjFsWV{3*rqBGO_+_-*V)6^yu7$}ZmU{;J2Az0fc$r@6 zQHwVY6G>0WipC#r@snckE-xd++p4cAnI22*3H^&^D|e**+D)CK=$cj&lu=I%?qq0t zwgihqAwY17=g6bnwJtY15Hs2t0Zl)9JuLmj%#G~5hoLcoXBzU-l7to<^y6gQFr%2= zCM<0`WcK)y-H%*Yo$p50i`S8eunMv5=2LHwFW2+ZKvRm-0`Ixi`vcBUM>q+=bD-+1UX*ZD?l)4VIWOl|HYM+86l> z>&F~+35h1?g5;y=o{aYf(6K`x9!=qDMNyl-^VQyo!Lw8Xx5!%InW>zw-mZ=n>ktB? zJv915cIq`72c-NTj{WO3O8)yf^faQmh6zU?1_`|{$zi#(-B&PL z2Ns%AdQ!$S@r<6y$}dX2dyT?Etubvy^DWlE%d^1$4+0T?3OBIXUF2aewr}n!5|U@MI5Ui{9pm=xM29@ExR2MIQfBMnErn?q7Bbj#X>N6% z^j44?_RXQ~V5`2#9fj7(vL2109?GQRLZBdhq0+00*1dyMwP(|#?1OJ?8&O+=&sDF0 zlX?UAtg6zc&#fy3=_0#6Yn{u}W3q>P?4l~S=t0N-qEja(1H2@J7XD#s)T(s*jen58 zzHM&ak_XvDjBcDmQ&Hp^Er09qQnT74le8;u$zc8Ul9F-fR`4v!1i?PKg?so-%!h_& zlgT%s7gUrz8dAn8oSvSV@nI0N<>lAe;ICSfI@I?GdJCHU zo7Ev@NFM=GOEfark7}{%fZxnkJ-STq`BbYDMBa`jP$E7yv5nXKk_gIAGRFso2kLLM zWlx_}T zqKv&E!%&p0Av-d>?%sXv92C$KfqF9=mv-N?zKsa4R;hENRy9UAcGYeVN(YOxSRP6OTxS>*aL zyto2OYok6yy~KD1MZ9qQt|O=S9+~p2F9*YF{3uB=c~7)za97%^S-yEC*nO`Ym5{g7 zT%G^5h7^l8r|&iF6c5GiHjmblwyg)_ri}kme+`fnB&MZTU%lByibgP6G#{}Vd6+C7 z#=d_`@3tHiUevf7nIVozN%voT zwvF)TeRG@^M5!+l$%e|$W1MN+B0F=yz2_@jK z*fZI_-!u z;K)5dqhN|m`wOo<3ZwIA14u7@L(#d z&Y3`!$h&o>D%X=DbpX(>Mk#hH*bUCaekX1P#8Ge8_>|vY_L- z`QLM-=lZ-I4jQ~Nwbggi{P1EZrRTP@eT{#a6V3%Ubh{M3|IA6Wyv;@yuuGZcFho=F z#HTC`M23W!IKwPOXNwiv(!LpLN$LQ`s_N7No$>p zZp3qUoD&z#d8d2E)Xh}oByc$e4G+JO+~#(z=(y#6N9%R7+iP}x+h%1MeD_)b+cVMc z8{GO^)~~&DTMKG;c(AT740u=e+EX%x$7BBzIxL$OPf!XAdpcH2V8O%@t6k7NZrlWB zt2EUfVgjvURE`>E?0WfCYfO{8BN&DQcqglUY9ko(wW(fr?)S@N`PiK8Vs3VYvZ`6N zP|2XqPrtS;(1#;qpyQJPy~n$aMVj5s*Q+^cCtEPzFk%od>wtkCLv)5zQuVsB9iUj} zHvbsjf%g+#;)G-8J9pL>_jVWeXuzln2yPxA;Mst+(d(UW43tYWrpZOSqnNPc(as$C zoxvU>g8h}6$1jKdPVz3OzK^p-78Ol&v+GOpC->MOp|g#ma^ZSNN!xzsXaOEN&lV@~ z(nrop*ov)qR%4jNpff2+PFu2lzV{5emzQZ~4O35%%UucA&fA;61SI9offl~MT%f<| zWzSUO9fsG!`dLpoA>#FzW@p!21FCWpXE9`1S=&{g1hM;m#ObO+ju)KrlJ=bUS`5nn zE_v#{i8(5(CKzln%Q<43^E>9MY1#8jTHY=i9x4(MYb+0P!6U?nU_ADue-TZiQ`G@2}p3Qss?lf^BpHI3HtNpo7J>~ zh8C9}?Bpu8ePS=@Np@V^!~e~{ICL}y7ee)(s&!VAe!;-39v!+{VPAuXvU`=!-G5Wc zIMJP+nt6X6Lwn*1Jqr8M`c?wR99%{ftLIFtL~J`%m}zvM$R+I6nr*8syWy_wqgbXs zKQT}iEv)gHTpvARJ>}v>Rh_fg_$o)Ko&7lH>8!GWOQ5;>cF$krum9QnnQ)3)+ktBt z4U`Qa{Aw^p=vYqbe*WD^cA4BX_uS`qV4m!b1D~i1vamhPfV^m~#-yUaaZL5M3qX?Z zQ%8+wj;w6?%Ar$*?HF!$-*>8GJOYjdS8^uZ=+yqlB}bXeH2Z@>(ZOgO&#)g=M8a`0 zLG{u^Mn756BUQg2X#NL^Xe6b!*8nhpFsWLP3p&cwqB18BM85 zY)2N|g2I9Br9(6yk7iz>k6bPQVwKsnd$>xHlyVPo(>7!HtOCo~s?3f^)!D1oC1R8``+$*(PrNNt<4p*bDR(m@;v62UAsrj{SFj znY%{JhswgjOy>(b5Yvh-M0bO%|rHF4Ex!pr{!=_&V(t4VXHUHnN4qzz`C#D<_Q z;9QW@PgV9cBR^GE8s17b2=fL!JDcy)v5w(Q4l2Gu9VYcPtQB{=5ANET_6RaH7_E&Y zb1Ij*gq!eznDRTz`O?D1eCT*Sh-$x84X%`Wl^7w{xMwHc-6KCp37oIWZ1nsKoJGRs z;2@*2KH~Idi0=uAiG`hN!v1Tlmz4Y9>Z{iAY+ivBc+CQP*d#4>44o#uG5Et?YVb#u z%$(I%`q#J@{D6p3l{I&f(xrar3cvNPpHr~M=H_ngpP7eYn-9l;{t6g@2SzVwUUokf z#EIAl1H=eJpfnNf6(|(?^=qsyMo&fBb}C5Gq!t&fBo#OoW38y>-PDLVd7J(z?62|O zthb*zxp{Z4In)<==f51JWt32fO3hdGXM?*`NEsJPt^(V4Q|Kut^c-|HH>oE=|a{LKA`$Q;*6a1b+RjL1S$$F=`n{Wn)zsT@KWeOqJUbI6}Jp!;`v ztuf*Yx{vDR^)@=WaKJmi)M9flc81McV{n@`SXmK791Gpk*!`&y`W9qofM%GO`%K_i z3N&Y@dTTE5*?=Z?%OvU(AauJq<-`|F8Vk}>IOBE8^%U-VbrmgcZ1_Da^*{K=$uYk= z0GDVLf^$XdBuk{crB1n&trou%^nbfYpS5EP2s*-8yaFOB5Gm;of$?a9ep%TM(V|7J zy9)I@yx5{A!kb5~C76IVw?WE>lJcgydS}_*!;3FFsw}fn@Qfdcn|r7n!%u_ii>%@M z6MH>Bwqpd2-C(n@W{Zdwe?F z1{_rj3a9n6+iCYrtWGsHfy4}exMO3q1B_=gn#yZUe2QX=W{z_O?Na<6}Io|&Ja{gB3v;XFFvgx;XJ zy`5&jAq?HRyZ_!7qmwwa&!9BXV>7@w_#gY0<; zi=V?|DmYo4c&srW<6>N80)HdDMq~%>Thej2Z>bID-8b4>V?4CR&@)&9K%T)LhmyVw z`Zfg7w7t?<&Wz=Okz=~*0q;B8uD9u`N2;uCC(vUtRWVAtM5<7m3mB>ESNi)g5qEMm z|0gR9ck70J$$XTqb56g+oSab1wREW||6Y^#xgn!;78qmsi%*g`wa<{)5mcg|ntP(P z7SfEZeb{2-jEAYF_mShDELD;kwX}QL(mba#=Cs;4uE?vD*if5OvepIqB|v{FJ(;`Q zv-fj`U997-tMskrJ@35@?}UeprI`-BB63$%JcT~Dv~sczJPe^}Vw5kWo&2bWIM|iV zJJl!GzHmlM2g%aloHHFRn!a&Vh$lmFtiI6Y>*7iPPzdhL+sWP8YdoH|1sa6G-xX0& z=}1XWVT>zpc1n@lmz4fKxq!X|q_OBRlZm%zWkT}Fd->7xFavVIjTwXuptC(%+rDxE%c+K`-bu0?ioO`mB4)EYLX>5(1=@hcID6-U3cMmoGTHI zpIf+}zqwE@ia~sMrZeeN7aX|hk5&n`thdb3-%zf9AkiD4H}k7DAvfflfXd+K?5HmR zu$#iRLk)~Mr7KUuwo=0a{`m#HyMAC7V3@C?qs8Imm;sq(Wu=sIzo289tp=-@?Naj6 zL*;iPw|Pf8nBP+U(Duvi3QMrjkaC*4UmAVXp!3VO3@+Os!pFLlnK1s^lP65Jmf__M zRV@F{iVwJmM@r5g#!5?SqHUY&>kXelrA9Lx-0V3K#hGPfk-vSwp-0|xj@a4!>~jZ# zY!V4n_up(*{hi`n(sUCRn1X)OrBTu$T+ve>`%e}J3Lk*nNdzk{kmK$?*mo#*QJ}fL|f2(%*=9u#C z1w^Toez9I-pen8W-P#vh;njxc8_8?rGTQF1{`w%ziRJyRfA<~#G4ZKUgq~kxzAoEx zD~r^(oHq4U=bH7F!iUp@n5$NSracZs!8umnB^XuhmHujQPtN^#Yl_^eO-0!^2!5xE zyYUoa%jtKb4qJf7zSnqtcLUf6925Zs!}ZpXAtb1SFTOY&Gwm@wf21q7Pd{Z6IX|Ib z@g{XnKr|8ACQ;W+^m(D?ZEbh+SQ=}JoWoqv%kk(-G-+w^&{5hknD-)MN0^wofDgup zlbZxo&kL}#!eosJ3CbE+Zx4HCO;LY!!YDo=Mli+pL8Gl8H6)#rKmSzsqFCdgS#RRo z8K1YwD+4=xJHL`o-#n{f%(lPBSMJLI)94bATbL;Eu<|HmJ(pgZDpG44k?f-4hUEqN zZEdJbr@8aahfgs>=%FcFpio)@BK||&J%+tQMAP4^1EhyyooDE$w>nb3?Wt`63FqmD zTWc2>Pm8yC0SHKjY;M@hG*?S~g6FVTZ&TEI+;R$5bdY?1+qp@z*UtE2R2ShLp=O1+ zEw;mLvG>e5sXd`=F7~qr4LNC*UgiDUYpZX6NOJJUkKl-OC#Ge^vcO7jK|dbyN}FX` zXMvp+R3v=l{1b_DynN$R{Vp-sYiIaP4Bu#o*<~Dc_5JEio=;UDYcsdDY-_`;&<4(0 z`!4DrsK>_g#X!-!_l?*3uHt+3RB7~FcN@+y@aLiinfQh)vq|+Ou_{9eW{EOS3 z6q7jR2+aA*k|z3PHHs+-1|estjoi^PR#uCzc$0E2e)y>n*ll1UJm;OYI|I}d{`p|@ zo{upCa4fX%PEby}Y?PiMAja+(&m4EP|MACkw8Ppds4Ua)6FU~!8jp2U>nxbO4zb5U-yY^*eiKD+ z$l7hu*lqz@IE)3A%e0PLerCo#)nkrsh0vClm9Ky?$0?i2HkKMZ)H`K{8wmj_luW`6jagn(q-e|m3sY>&RNf4<6MN+8;2tTfS@ z);*^Y#2(CG+OLJL?sNxirRBm)ZJ{>u`D22-1KKCF-#(Cqkpb=yv5 zc_W-`y~n@_`+L>t^FQ_<{sOK9T>odl^}iIN30%=L-!$9iQ-I99XP4gk>$Ev@tikk! ze*GuqvzH4jb5`Hg^0d^IE7W)Sz-}gd?7Ho)2J0#Ma~%L&*)6N*zHGIO(HqC;-x=92 zKcH2B!L>QH1|S6ZlvljDx%sAMNeYC9H5zBqPU=tSPRVs?xu_urYK8?fzu~Gz*ZoRC zTMw8xT=T2w_sxXvSf9&3`4ZIW4HxUm30XShgbxWDVT*zo#=16&=J0*94qg6PyoBXM zoJlcWad$BE7`p&Eat3;=^0hUO3_D+rr-Iv{H0`H-;~CX^JylQ2ms>xTmhbr}^HbI{ zqAx^G(U<1sX47qvd2as1y`Vh?!-;?28GVPRvXbpVIT-K^erDjc0xCN3>L8OZ_4-Xi(y3DgQHEkXa0GI_A6WA_10%j7oAF0a5<1 z`G5yOLG=jC_P@~lLVO9A_L)5BxGyGWy=!C=|AzwL%D2V5G9~>rQ&MOV;|64dnlNwPnf<%5YZ_OBmsT0mHNEo*Q69widv9+OeC3gU z<}Svjjmu?)aY7Jf)&bOwbm|4QJn7C)#ht6?1}+o&AF`T`1)4MCXByUD9qXZWn*MII z^tBv8+2z}OL^_g|Zp4Xo9)%@ucU()sD6n=L5PMEFMh$s&G*ojT)ER9Se7_l{@*S^v z+@yjTn;Zk}OTmutP=3A)*F)Fuo*D>%zmD{6s=@p{pjLT*xt1%D(Xe+=Qzy^hNAa($4YnOP4S;zgeKqbwSP< z#Q$$+gEf!e8wxxLDShJP+aVi{nbZdS0<$oW-Qj?@)SmThEF7o{|haz}D|t0Gl!6brN#ebtw-E9-f@H78`PJ3s|sXH=rGz7?%aoJbDumZd1=z^&FznuuTaJS}m1r|G|3!l^5YWD0pLS z{+VB+OJqH9B*kJ}C(3`Fyr#ppWe97)yx|#-&6|&f?SpIJN zd^?Y8Sm&(KujS3nTnN5@ZWXP0eD+o(G)GEJ6Vd6N+IIntv+&jZ+|DN$w5?iC>5-rK z{CmWJhHH2lqg0`gR_AOJWTuHg2BCA58@#;rjGX*?Lw98UZHe0x?!NX|eKWNKc~_IR zQeMM4Ey6LPG5&OiFQj&wA5QuG8LmSE`ok+*P1@nXEg+Q%>7J-$iQdKim_+p zLYyNoMuC2A13Ws9nbr9g_Wng**G{)49zZf<&lpQ$H+X(%cP4CG#12>QwF!)&`P1=B zl{!cIi%YtbwuUnnJ%rd#2Lz|Li~+46DjFWrKG)o{dQE+$bd24NXS zwBNZUjoJQ}yNVumAVcK@5jmK6#ZreP{nRFBj%dX}qp6`-%#D=mEw%n>_}3=w{V;!t z$;SB5>Rk!Td%|EQBbOnuC`Obv!_j+z=K%Wv!KmPGe!>T6~s$T@9A9N zva&&bXg5HzxxLA=ZW4sm3pewAx+k8w98-}PcZLGHjD#MY@Fxy7=nja$C1YRF^;DBd zmIq)tFbq1X0TC)k5zsu1sT*DD`5(|Adcc7!#DJ!EC!6G!aqF{w_=A(K69t%LpkoZ;gRS?EQ=lNp#TGNv!BYX_$P$Bu@{R zY=?~wAA@yPr2Pxgl+I!Vk^qn^0fA9Tr@4U7O1-cO&YVOh-tdYFRgJgUC}2+2&@N`DiX5<|C zR5Etmmhk7a%*~l+9X;w?!|L4|{97g4#yl#qxP-4Ld9J#dy zmxK59bao>Ah@p}{gak1_3t1S`U>*8pGwkiRz8$1Qoik&8_rfoj25ypYr79HJUaA<`#uzR3>HS(qvxCz7-!`~ z5u;Mdw=8N#@}2qfb=6_^!@HS=x@z=hYqZYuQ2{nH$kgymt)JXMB-K1}{&H+Y1P@s( z4zid2j_rgSc5bxk>v6<$1U&=drJCK!fl%L?NP4(`QB{b8cLCA#_BuGupI{hC?OSJH zAmS)>^^^V9(Th9u8QTe3m8W6D{{#09iiwgPn5Ls-xZJu*g zzOsc7*Rd88hRQ?wy@@_QTt@^wmkWQN962@mcdg$zRk~XhREGf^Dguo>|8g;OvtGj* z6l>ijw9p?pbR{+Oq~Nv2$T)PTX?x1$>63JU4K?LK7QV}};ZdT&o}9A+bI~2nf`WmR zh;W`ki{4OF?iG2>ysAua%Z?}9?9KYEv-KFmt90`mb@EMYhTdrPG*+S<`*nL~C*@9l!p}S3{uopQ&SK$3% zZgujUQ?=S;kg%Zp#_uqpJN^Ob?_MV-kLygdjEI)J`g)`@HHD->N&o@Q#xCI1{0pmZ z0hggG1jo374j4(o4G02=ldQ~5T92fKc)F=17D_086&k(O;`YC{KQK79gTQf`t*cFDo42v+#knT?g zgbt4_s^8PJrjy-o7U-9G>$L?`K2ocBeK%5r7wxcfX4jU#wmX_ZbewlIcqn<@{Tn7R zkiJo?j_iwl_Qa-?=++m0bdc;WhOD%U{zEBlaknONT)9^49?d^$?;!}9SwT629H?+o z0E6Ddfp$LKaWE_fU7kz61Csp%wCvv>+3k>CL7Tbk0VZ2xQj`w_Ld4-xBcT`z z!``N<3n9dC1NaNE$t;Eozrw~aBW`Ay2}DI?7oGx}^Q(U`H%F4p;?!%9FSY9|mvr&+ z*hq`FHeJl7Y_!Z_c%R+mNWAvAs9)Xi9r-!u^@bhn=4=W*v|lFns^5~_E5Wr z1)hri(r&Xm5cEUVFK+t~>b zyM|sFUWkRlYCy)1+QIIK_pLV9#6ECn|JH|fc`@JO0@5HTr(f+0Y%cX$TBxCg-{q^7nnKGe~uehHKn=0*hR5|W} z0XANB#F`GY4!iU>M^o+!B~usg{~7_41n>NywHz{cw)e%e9&coxQsJCs72gy5J5vET z24Ql}u5K+ixe~!)e38O@!tnc2U)*|IXR7nRFyt5b9Vn=Q{GBd^RzW`=_4pIZDbR;} zPIQvzPnQO|AmziTH%-x_;XLa>Z4M}xl~*dmQCf2sYeq%``c{aJccNc`)VC-)Kk6O( ze-cioZxpYktdwIu&{6>D|n?nYd^Jtf&hrM|0wLnamwx)B2l4HhcLJz zm7&L0xuP2M%(HFnbPhr_zR?>4mqD4f#5z8VT@9NL%DMj)h`YU@0L_~Wy^HNEFx+>6 ze)%70(|Nrzjj!cRdlX&%#_E0efepNjE(ZdI7dvIhO<9pMti8}*d@xER2K`d}Ro8?K zBJ$>$nE0ovA}coTnU2r8eC_jZG&?_>_bFrj59@_4+@g}K?b9C#%n>^*d|ksaW~1zS z5_2m)^&vi!ycoa&l4LO@5ISwQI>gEg?2}A@yF#1m-xBdS{f#oiz*;NWrvtrZ~B`J*vVR6R=6do6J3(mh<}|;&EDz{UPx#Gmc2Dm z$RISe>?gAg%noE8fx}pL`KMf^*{uAiIt4V6LtmCo8}4Oe8$P)pp!@`->yP?I*gl^t z7kYs_w{6kZQMVV^j**WlQ2TUAQ$EtBW~mi}w>NCSM6h;7P2GgU2MOzCVeb)mjfTd? zNkcitK{|>Na6vM_*c*2f!&ZFisC71hpfw;vWC0y2bQaAVYovC}&Sj1*mRjnYSk?90 z)LummroUcS_P6&%IZJFCG{|;i_f#5747o`vH(H$MKx=U)MCQf^{rfvIS))MUj>(^= zHBk->tU6{l5h)suKAdPEk8$Cj)N$j)?=4*K8s6i1}``h-Bia$re>iL|A;aV-UDH%lD zlocyzl#?Jc+Q@BPadFapzEbK`Ki^hC;0m{(wZDF5+* zH%GZFA!wAY)ar%`ysT>ij2y9had6_z@t-qs64BeFPK=LQn_R-Gd#b)izrukQiF2Sf z6-SaJu5pBB}dN>L}L zYahfI9}Z~1&%LeQj9-r9aJofvTi2be-u6-6#4Ww1Ic+<|M~NWj!*}{xS-Z1DAGxZ- zVVG)u6fZ0cf*9Q|J=%cyi7Wgx;tZZ8@#(y|v+4mMtFkpD##Is2jcA$L#=+sMIhQ(I zN<6O2T{Mqq@TvcA#H9z+NvgY9ZU`#!+!JCGwfmd2J5i_j3b}h&(R<-A78vcR{T$yM zM6!p$cbKygz+TK@W$(K-rPC?)0b#hg(jfbM=0p=}I`*VTfn%i7{l69vfwcR5ib1yi z>+2Y~WU=QrwPVzI=*40=rPhiIBoSwHpWH!=87L=xW!5sfypkhY4C)9mGuQ7I*|SnyTmtuA`K@+9tj#e`>oW^g)pQMj#?)pzMAK>hRN> zEx+c2+VGphq;0E%PgB9S9=$^#Wr9;L{Nb4?c{51>1J?&(k0E)ZQ>^SZWHTA$#hyLGJ# zU>H4nD#;v`(isCy|NjriBRG@HgjT=>%=WG3zjDUhMMq&~kA*mrb7)qRFquzq0;lzW z%(xHy@l;=$)D^SCiP&qQAAf&M)WZ1UUB={4t&zm#)>Bef3DNWNSZ%6CUDGrrbnAT~ zV5&|t4&S3=M`R|#K?%kll+T(fJpkO^g#k0vyQ7@5AnG|iM%6xP)eEzTQYWNJ#hJ#* znloW#(OAdJKULSj4L>)(<3GlL=)kn-Bt*GvX_ zM_@!j;`ju2G7NQkNJ~ixt*bCn`=mTtIXCU(ozvCVYYUuXWK$8SyRHk>EG(VWk)C;N zk@S{g?fU=9=IA}9~zfp zSIIAMj`#kZgNMQ~alTi}+VG-v@8GEr^Wl}`p5~emakNf1A5rXRrwF?ex=z%}KNS1~ z2LfM(yEs0i9t!HmM*xxwzWW7WwQxrgbUgaJ*@yu;I@y~B^c%ezstC#+g;Ue)*i1d+ zivG_%HPm}v3pKB&?UZySP2O>YsUFZC24^iC<9ov2EiGTvfk+WDLF+q(Y;O10|8r2{ zz(EOMp*Jk;qg&%+;*1DjEN>@LaCOR#BRVh`)&5|VG#cfhY4`Bb`;5RiG1;HHjnYb;^|%mkUE(l>s;n#c`EgmUEy(55aB5MO_X_S`wMk+j z#atuoPUEEwRV`{7eGMBDo8SR*harY&hOENazkv8|4>a=KZ^kI=3?5AchvM%{v6F`6 z3dC_k=xp5YqQvEXKhM%@Hxv)v%4e6lcu)&-&8)TPyl%Om?E>EXaQ$dt4=+zN5Qq}o zbThlV+iw9 z>ZYm|BYAt|b3lgKl*Gs2WOS%X1HJYY5Zb?_rOnR{8PFxI&`*5lp$~1HIt+>NZ-t+` zh8FWa=zO3rDmQv6D{36La$o;{MO4Ki&hxr?!L18#!+xxujFo(KDx4^FkHKa5Es9W z2+j3^ySGTp*#?d7c(R_i!fm+FI0yOF{g=KM@`tQZ_DiLYI1bA&+kmQI^PdusbQmC+ zD5Mey>6MEqaixUpCm=qlORYyo*1TR^k8#I@H z;fv@&2bMg58Ct+Tr58v|)}=W6DwWy@C;{pniuk&?m(Urdem?w-u%v#Zmh*2Uq&x$6N|1;T>EDkJ2`+x=% zC`;TFL^KpZ60|Yg*1o|~%@2rUh~kI&*-kfF@z#vZ&>+LRXuerC=>6L2lZhePgS0;Mz8x81PnCTT!? z`Hm}0r#@4^{HTCcgf0~Q))&Q$WzbCi2i8|WFai~$S5kg|1WH8+GO?moy(Sg>Tpxz4J= zh{GkJz)g|};h3*ktl?zY`6=Fin``}u`(VcX4sB<=uiDU`vdy4|*5K0H$oM*uirrO7iky23 zeUIuUzCq##^=_wKZ?6i8-2ScH+s?*(L+f$bo!+^r@KjP>U@X+r8 zqc}u#Nf*0xFD$INbBGMs1|QkkB{g#;l>8}7X9al$mFre#)e5k$Q}oM+0%xfTr&cW! zN<|IU*rGjTZLNFfQz4I+Z{Vg{*rfqIr?qMU6ln_8M(Miy8v`!U@2`XR=wo5h>)0ca7s^lG^x9lzepSscvwH zE#}hSL0Gx4{sKGJ4u;f(=X)&srF^93@yAb+Ac$fU0lNp7uA2FVqWCmW(04=?`W~Z9 zStU+i4w8hoxJpcmj_~l&E^%w)25I9rC(iVx zDu(kS?DVwphi&g8d#}NvIL~RwW(mGM3MY(0N1W{LO`l>tmExbh1zHcuEc~B!h3=Z^ zL{se(ZVd>&g$O@TCa>~gE7x;`fiRcrGV}3S!TPlb?vkEwJ*O{!*?GRzYpLEy?_m^d zp{!u_Ov+^hssVGdle&_hT+`uB&re=0dhilVO%NeLU$r72=gdrCzqsRno1;4~Yh1W= zt@UXhFOoCU+jtw(m!oR<9Zb0(1q=Bh=6D_>Mxu6Pg6DD*)c?-905oqOIbs7RQB)I9 zuo1B_7SE&41HIaAR6$TcGSMiCr2FVVhRL!PyREL;Zs5xICI8;klwS(woCtaB$Ikxk zZ_E&ZTo}fzM)alFmd19%-k(!V@(g%Y03&c$Ha666kX;$}xYgPqQ0Ez+W`2z}E`V@c zedU#f_j@(8%T?=Ms{Lc1Ff0GeKSs61SCJN&6`09KYvEf3e(Lod zd_~cZFwFcpqQ=m}|C);cQbSs}FD!_$P^6H|FZ}x6QDr9K`~I2y?G0(q@->7n*`rcd zud>5`mQsDRO%xvQ1WJ~fq8PHgv_uPsWR)M7fn+T7VSbNq!F()?p+Cz&HXnh==hgYK zo!<|`NZ#b8AFMDq_WF4AX&e;RpC8tZN|~FzV#q&ALio*OUo#7KU5*d3ZmRA)DwOP# zK0EVa*-~Wg(y&;{R#4}fpvx;48%v=r|?l8pu#N zEN}nC9*iatx1Fip<3$N;8@oeNNpE&%8D?{Z@j(sCq4yV$KYPQ%>qRqa)jJHA)w!cf zPZj=E)becYyo;rXV4#J%bEb3;-EG_!e%5N@i3?YL=`1!u?*VAn&!YGOgkdpO4~!>c z8axK}M7|VyAJF&AhIe)v>7ri43%-py93rp-Ld7kPpEBrt%ZKd>hD|z7KE;x9Gi4X0 z8eKXAG_KzHFOulgfiACh<&Ig)k7iHLg8XPH?i}eQGZOVj|AB>7O8}6$qs1XFDWLuA zU}eOy^4Q7T{P9i+bAgf1g>p99etE##4p){PNr7Z=vq-wiZXUgWVhmgg2=zuGVp zTMX@+a@s-C8FzLCFcX)@v25+gP=6C>iYr#Uam%-ydg{Y^^9#@CGv&zkG%#TBkn5hoiSYTk7GbP!Fflo#npV5R1W7eH+FNC`4rY z?pXmt;MY;|mV*lQDRjC&IW|S4{Q*u6ruSd3@xWlUW8*rBl)F~UU-C*cRzL8moDv^u ztwnN-Ml9Nmg+5;|jJ`-KI%POBH2w!H`EHW&xH@nQ`7&bSuK`ji8jRwZ?C&6K>r3#C z#>R2JxiYQv>6g*^(Oc=SQ^Ygk&Mdul^bhTd-|hhF5Z1;+t1!I=%&AVhkp!bJ(c6rJ z_ZdWe1jqfnDy+hLB6RfV2`V!n2xk%EyJp;&o0P4J&H(BZfxs1+mqw_*J`9A z!~ZRx1n(9^rTi6FoPd|ACSurZkl>aE#!fRaxdN9@m{=dQ-`fTaZ^4eue*=WvEwKE< zfy6JPOCC+d{#Zet+sI)p{zhKWQaKTwQ&Js*=L8%E()6d(m5c*>tsk7QhGk9(#Xq)Uc=(mG=o^}wsbTm=zUmD(5bp;hCor|cs1 zzF4levX|~^YqbS%;i9lLopy-pDegPq#`)&^K0tPu){C^aaB5uR8^h_1e>+8!2Mayo zYz2eFhgq<`FQ19tLc#-Ki?GiQ+gEbJ`ji`OYafn$;^0 z<7Cfym^dc|N1#_qi=KPt8PdZn9SkyhUI~CTUuzyaaN(%ejR64XkFY?l7P$@zf=Dn1 z%?-JP?;()7t@~}ou7hzH#$Vh+))0~C9}RX~b6XpTA-~xlI%uNeLZ4v?3ok8Xc^jQ` z4J^oH1zvaD|J$GWJ1XMt&T27hpFLF}!Z3DIiG#Y{(>ufDo)ga(j5-#mVZF;Z9_+zX z-3M7N2R3^vKSiJs3p06uS!4L0&)|@7wa)>fE$;iR6G_W3M1x*zkfUB~@^5TN zO9tfr_j9o2To=7()s21qmplEgS6|kiIc_I{dz&bJbGdZVjl!Rj5L2%AwIVoZmho(i zFI&m@vf>vIT2ap4ThG^H3v_o0(D+vJNhj24AZ5yDBK$!mVL0^eX!*05VDlWrua|4Su4~Dg?i8xl3FM?X|1&m1li* zY4jr2bE|ZPVMsaJ5-^rc2D{!LM5+VOs4k*KrkyccWsZSW)+kBnC#bc%MWLbLUuJpS zpF`dhuOEy}ti6*UKs0;$9?!zA^9uYc6A}Ec8Ib&Rn`U##UWtv>J6S*`y^)JXfs!t9 zNv5=771T!b2@$16JWTpRP}6M-x8xbN-qB~S?FFSv3Orz`&##{{nRo9u^@Iw8(q_ut z+dA{`b_wRe?Xf2ELcge3N2* z*U+Zq52jBzS?u)NlW5`)c^#X%^pL9X5=;UDi;+R-P(eqs(G;|uQL6Xys%uY0l8F{t z&&-h{T;-usr-sMpV7My%P$yKPqevb|pU7;d%R@A&23 z*V#Jf+_2m<0b3q>K5R1%j2>ZP;scKn4(jft#V5CA?V<+G{c_kMwm!!SoEzBo5Kx)c z9562LcC}m>&dFsto9voP8@xVIu6zB5G9bG>0x%xaQA%DhHSh%~Ctnv9EySU4Ye9PL zM@ahz6_VF3HB(Xf>GgchZoGiJTv^Hd^)!QkGDcW81J3h1=vi68K`^+4HjMaynKIS} zdZ>cItz<{^i4&OkHv^A74=1_~X*y}R&<^V11?*9Q^=o~ngsm>RFxo5u1@^#QkR&dK zECzvSmpODCFtVq86|&Jn27-bgT%8(%{UJP!GOKUb5s_VgTBWD?V9qv+gs2o92rPxE ze_v{!>Cq7fmMh_lVS9A%z;G}-k!EQkxVgDJ=qZG1#gH_x zBD06QaVk-+UdP0|{qz06RYpAQ&tt{Hqz|ZcoSJ=Lnq42Vq|?A-RdToiKn=XXahoKX zw#q5W=kSi*wFm4alT4_<+*DP~ib3PGTHF6^#_LA_6ly^?=q02W$m43m`uM} z*`Uo;R0pVG1vpLeYc4!WrjLJBva}ZWTsvN>xdeXvktHyL(^$aRH6R+g^}}!Y=NL?Q zBX?2}54HnG-4lka*F9Drts$5Xpo^7GdzOw;ppJ{M;^q!H=Y{ zQ0`b$&ZF!m%vZCM3BiwzCr<=;o3?vibJF)sw3e4 zp@$q;-Z7yf$ld0O1vQvw1H)2jFlVA91%rJj2DjvKe ze807%d{cR9i*biovS~AkRItDpgD&i-rQ~=;@BC`(T)muTe6wPyZO6JtfrP0`GhQ6QXt$y4RG#LS7eFANtliRy zB?p(QHpB*Z+GLXNUG0n!KSN1;;>q(U&9tm?R9b%h598^JfZMs4hGJVrV3R#3q9%0- zHGO&I9-_aBoDwXZ{}?%qGWT9k_BM$)`c6!3FyEXs`2R6=-GNko|NoJZ9ZE&^s>ohN zMzS(0JNH^;yVl1H8QC*#MMhC(#x>%SagmmyE*JOe+C|1SDl3HFd3^eQzrR2H<=p3- z=e+0Z^?pC+WT8%h-|1>HQw>LfPxnCaFI^2S^x#olrW?t zueIs;cx_eCd0rB|^`YhciAAj(CKj2E}->^lc-QHa%MXDwwin>%$j(oqzy|abLZ=EDgub|C(APXp zh346BO`Zx(AE;^?Q1e%Csu7M#ysUdNB)X{4`|cSyssd6DI#tgo)Dx~(sO8UDWWfM{CD$ld zGZz0S>AQ4>+vQt@3>IM7Mi+?xc}>ML^YlD4-V%XZcE zXf_VVK=S7cRRyce@+Wg5UCjUdh<$5BjybFl2#llPPkww7Y%s4m`13!_l z-*{EMMvh)cHy2%2c@qiT!U$;s1fHEa4%=!TKEDgC`uBZk$tZxa!a~{SMC890}&2abj{;Z=tu)gc?F2;h8vHMk;+>lCN$RNN`SswvD z%ZjPV+5LdL5SdWydRwz0y^S~Fa^GqddL$7>;J!vc)K^nAe#dD1?g>9Vr6+uuPY5j{ zoNpsP^zHr=0qmpX&Q}-WFo|z)Ms{N0baZHv4fy280+GKHB7cv=r%M1L@XM53Kz3lE zGMNv_%+j|oJNintyZ7z`oRZ$Me2q6H9~plbR(*hgpsNoxwu>}EYtn$Nrw7g_@y3?U zmPa6hUnRF+P-qKGa75!aD!OjI%ct;xUsS+z$y5s5n$bIyAo{rbmrMah#g(%Id1T@) zWhUb*HAx1H@}vU0oODzt@!ahYulCVWfDrmm2go~HotyfwD!JOQo3vp}{`HQ>rL!Jh zh7_pXM#(z>#uW6?2piM5Ydp&1)M3*KXrs>?e<2}!*=PDqrkySN47IPfz#MEv$Kho# zME-dn`DduOf)eE1%_O9s<}quiS_(c_`v*UGN+;|_zbJ%!kQBlFQ?&;sVH{wAq=MEQ zkyC;~ORrALzbZO`?w8Ov?{VLus-?}G6RBM6o()kfu-O5l55(6C#0M&5yI_vsr&XIPAem)vKtm|Cx%1_Fku@Q?-51yKQcxpuNYQWB>a(^H$CNI=HY1e2(!A z+zORqa4hkdLG=?%!o!BuSe}L3JzF{u>)YXUq?VH)$ECT4ZHY?7 z&zlybkC)V~%XXZwKXNErN9mW4{Cju{I>F&TROkKSS}Q#*`nb<|mNujB_05RG(%{zi zsB4ri%QZX0gyR}7zr*1V4j;6@RCZVsRGi-Bn#Hod?pX^WSA9FHQ8OZSgw|*3CY^jy z=`_iyVpCi9F%6g?5g5u#Ho$-9O3<*sadpxfLMNu?Xfe#5V7(jcn_k(24 z1n8brBKVH!SC6zkx18fYOT5YX*CH&tSsx^cd0_6iJZ$<}OFJHzXI#KQx&WS?3P7jt z%|DZeHGY5j^<@lH+EJz3`&O!vL#%mN4YF@u#gV9-+ehWnwQr<3*zO$R>l=h^_tCRB z$oKBW6WS5AD?E3WS#qeJNUHd76%e(naO*OUp~g2HYF8yafPlPV-!1@l=;d|rUE?fX zSX+IQCIh5ZW7zv#Sp>3mSC`R0<#Hlo)UO#F=z0Rr#x8!pVgNMMqy?(aRK}^@ zASh2V3X&r%vOUV$Fb=KxF=(dySz619-t$#=y|8?pFJAkV4Fybdpd*YoXwh!nz1X@L zS+|K|d^S_@I^_~PwwLl;rOkz?{RWJLBtc}e0%sL0f~%c#o`H)mEJgJ3Cv2RY5-qR2 zOE;={T%RMvtl2{Z-?S@EB&SOnJq347!B`x!0=?N)>_R_;a=@JuKb~+}Df}arn^OFX z%Pz{UG4G1p-?emch`_8`gVr_fcX@m6VH z?c3{8*F>gKa^OcWu`$W`FT-?rD)xm*1aW`SZ|KTts>b3?iXl=jUd9N{KmZX1PB(_P zQ`VLSEgkfO)6z-znyYcp=TLR&P_y5;pAh+O?8A%~YG`UBIq)j~ci8#EG!{4xZ>V-ZYw?7=i=%NPql^Lmbm@uE>Q_~hu*&p- zm;yz0?&KQ2Qx|`frcl0J@__z*aVRddmq+XMj{|@S>>{dCbR%-hqEZ7FLM@H}o2G^E`WF^YUF=Gz-$AhV&=p=!e z#bC{p>+2h_ny+Xofa9VlwJht3iDjvS0Z=H=U+DJLn%{N9VLq=%l8hw4{g5u57tl|H z%VzDmr~Ny?AXw|5s3<;k@e;HVM5yrTD>+kNwMxh9lF=OR8ZM;#v9gP%0t|c#qB$f` z`{u~XrzRqM@8>!hCiN1gGUyPvo(+0T4K&4fy}Ncd|E8Qt=)2QT^v|EjqI}_Cx@Mf= zc*p__fq^w-b#0CF5!Y)QxyyFMP?sR_q+@rv+)VU_YTofM#eV>!VAdImdP*)&5mKpO z7cxEeq0qR~pn<{jZjh~YG(SlIo=gZ#22q)qC#)-S8Pm+?kc#AjKU6(G9+lPm=-vww zLYHU0*;}%M`N4l>7G3ew0Vmo7u7D0VQ?DOjV0)HyH)qN&H@*9FeR}O5+5f5;M3)pl zw5E$PpJ)$zfH<^vOGo`mTX*@wby;h5vm+!GFg<9FfCZ?k+@0Dqxb(>5#a>$om)r(3 z`mULne0gnFWW`Y|Z~~nn@P=6#Zd6KUUb&{YkMmro<9%wdqE>r7$6?rTweNe6_07+0 z;DP_{jNytEQlU-SEj1#ysqAxq3)Mw&6GJs2Tl}MkFNy!ri%x$z`?Q}QLpHt$QX#e$ z_8=Z=N@!Yqb8oW4i$5}V#lh3uKs@Xm;z(l7=}sZ4f9nu(SZm`we4eK4Hs+t*zitM4 z8Cs=0l=*omHAGMM<~_FIyw zN9zA0JQQa5UH-qDHtA8P9;y18M7Ue|nd^Re$1i7AvCLTO-gag3%sI9_u&BREJ#;2{ zfu@3d!dcvePwlqPAeD>Y+jd5Ioo>lLU{GfuKpK$1^JG4p`K)@kW&&HICb%IRr@qC_ z0seg;cHi|I{wJMO!}@75B#WYxNq0vV(p00IQbK~xy&(OxeC-1UPRaqrkE%Q^|Bw3+ z__8s_vSaqq2eT<~Nsn8P&HJTV-e#XW#s_}IO%QC=t-$;WAuZ=UnnJ}%9`u8s_jO$BWka7M9d(_>p!<3yp-_$&+A|)G1(m&|T5w z)ZZU|^DNmAxMDHGw|;;0{NJW^`d3ZK;hr@2gS#gKnco~ae@s5XMu)Wi+#dWsiW#;9 zd{VoRJV$;3mz-lDN7%$|c~^SRx7}Dpm7B6)OeZt&o|7IQf<6|~vwQv0-73eYJ{5eM zo!@Lg4tM&@mL1oYC0=m5vDt97F@H1^F`Lsn^bTp_@|JPi#|O!CEA`BV`yJ4_+mjZ?VxH0`f{LZJ_(!1 zHI`sXQ(26@`QgVL{bhmaXWRa%0guuIoH@|Q=~G@`>K5kRu25;S+RuxMBe_heuV1o5 z62tuxDOXQ@bs5_E|GbAU_J&X6j7&~`k`ZPtzxjmtYtQMCu<`8I$9o?)69b*3X zy3zDUl9Pi(XhJCO0=H8(tP19^3zJDyw7;v=Hj{xC1X|Sib(my1qyAUu2RmISq*=va zQCYAyI9}}YOVinS-bFH4%g-^kA4y+;S?xJs6K%< zapTG{81S1PXs|Q!v0x^CEc6L3=POgE5v!t}KK{=|)P-dj9sFH$(6Aw%My|$3 zuao_d48ob=hvr1(2P?PV7Uw)*^gl>UVEI6oly1GLf83 z4-!dd?qZ(XAUXf}M>}9D6yyt0;0qdHzg$Vh8N78LM+LIdOhM^+sb7DqaGgy+v1DWep0qbl9k&^Sa|xR>j%%viwzfis~8e0wF^qBSv#g$ z;0-)*fYDq}&Tff5x*X8wVnk+qir(_{-yruqM0r&lJph%U-H-~1Kfcn9_ier#TTgqF zy#6d(<1Ht?JdDtJwnJ2ZO|nw}p&g&f{9(Jin3^ZKA8&-}-3vYX6-L%@&<9#JI8_8@;kI6?$r6ZjXL?^q2c(uI9Z3^ zOwm)&v1s`Wx!S*fw=bV3wUgPDVsU8bwQKXrbr=2y!}Xu$fr=k;_I9D0-OCFe1`AZB zdv_`rpFXo77M$u$V`kPPIV5fzDI(N9!_K)+|304Y4>?HOq}RL@kTN#v;N#@*5}PZ+ zTbpb5+NemC(`yWKmSm4t^cnwcb{P6C87T-IOI^O#9~N<(BKCvBGh8?9_0a(*D2nGM zeW%5>8NF+fMaXe)oUTlloyQOtX4V_^_Wmq4lzr*sAs$O__ID|0Ne_N!B$8TZ=1K`04* z388Rda47@F@I`d{MSB??pCuqjoPN1<}~}_PoD45 z*@W;#P(Pdg%|vy+ijYfN@@t>`R7%-cjMVPx;Kogr?qGdRvE_KT*kUTxWA_g&4-IEe6`CVDO9--yOZf50s z1r(`De0rQk2lW{OY-+*%iu1 zwFc(7CH8wXZ3fWXC{Cf;T>LKg%VuM*eULo-pSQ3QC-F;u!>?-)^i~82xq^!&itEmX z_BbyC)i1Y+R8f3gY*Ce?#|tUnL@~9F0ZaF|VpNBOdNb5ttKkFYH_L-|yD#8XpuWps zU5YQd-OG1-eF%CQ@AFkjzUSua6~29`u#gM!ri#KbT!t78GKId@sLf)lwN>uW}aMMJ?H$n=p!3)t6#`1Snv5Vsom3ss9Ov);gN&@mrLh0WrZTjsA)>2l%(l_r6t#n^*8^p@-2xP??T%nD5WOZ0`_T^HM*uK>~X4i^*TS zv6(rN6<}yDDu1}DPojmcdyae&g5<$VRfm%1^lK`44Vy%HmzshwAK5lILL&4?!`3xk zj(Q@{q-CsN=hRZ&Q6q2JfzhA({B$v+BP}iEYZtQ)rFE|&DPaLrH=!u*oAkc7OD+v& zUCM@HNFt_z=8Ouu;#rN0?GIl>iU0fRwFWVb<35ds$l-fNX&-*3DQ{+ly({80$6zY` zUChBX=!5i^qh9A)L==oH)GPRoB4kY&?HU{7?E3qBQ8Po9K>)M(fz{l^HqJffbkNqJ zemJMR(40Z%@^Y5gLQw|?0D}SwSjY|BgeR%%LH}7AwSt;}ssQ_#%NwR)N?}bz-u~4c z=TBf?-rLhdR{gJRmRq`8gqleuNyyyDub2t@@-uwEkjF#(rgMg9yB(& z&_fx*ph_@jA}(`B__JMTJ_haXf};sPn0B(3;B#NE=})g0CJ*J0>SEs@)JJ*DUr60+ z*D3f$Sjkqr{MVEoRkQfj_&gc7G(nUR<{)TlPX`wU_sk)8+jC&20Zf)#m(EKVIqJ=O z?0Y*}`AL*oZ?=;B&X;pzdd^@CKxx4{#_<_Gd#$3KQ%8?_({dye7~00g2}+JcxLBqj zxF=kOM!PY0y0?rPe0=(uK{mY4n8C|cR1M3R8WKHjPhbrb3xUz2+6UvDszKbgdg4HZ+P;~PW z>?Uh^hD(v9g7=B*&8u{Yy)Ue0Oja5Parg#zIk1=xHmF)R824PVszt{;*C@a>w?uOB zSy@*(c4oQitV>ByDL~T~V9}ZC=ufwBF+JBU`=A~C>pEwbk@R|q>0bkz^e~LmlhEg4 zI4eX+eONt@WAz9XzrW0$JE)%b*R-zJI$wWenKCL~%ogR#)I5 zAIZ>wXZ%K=idv@=z+gFbYZ5R*cuRMdj4xB#E76tzE+Seo<|P+(=eRl%`MWy(mE=S5 z%Pt8=u@%Rls52mT-Qv2j&ir*_n6P289mTgvKYei)(v*fHQh@R!Vqi}la%J(BX1ATo z)m1XVDs6!cdYS;jOC7SwkBpriq|bP$GG` zXtO6yMvWr<{M^k_qGf+m=y>cM05;&~8)Wh$dv^U%=)rcA^y*iAI~N?{iTC6%*x(H@ z5h^GY7$YMB6<54Ol%nohM~I-QZaK+px{YM{F;iwkLJCm+{jE9;uE(I4hhgW@e+h}Y zJLI-cX&2I6ZpF6H_zB@nR-!BFFS8*jhaffJdw47*JoWJ;Iv|LI$hzUP%z?Z?njy-#wdTB89Q%3(@XiZNzwU1^upNl!@R5cdk zV5>+y1bM*mDU(Q(Qs@6m*;H8zt zI}FKj@;nhwkd(N5@%6v5xv6tFK%OoFOJ(b1e1FbW)*=e|GFY?UKa%PBA?U)M7Q~8L zp&D}=ej$3EJ)$;Y&O9?^Zp9)X*JyfmF#E4xuWn@iOh6GS!E2VNHRg+Ye z`IEH`^r@$aJNMPJ8yj(oe{-i=6MSK*eDIXplX|RF*azApI6Qfd*n(TCf_*8R6%t-q zuV`h6QaJYVeQNw;TKlO^d)Ccd@UW0r!eOib6RboGn6fvj!)y88NY;dPrP`bssAut6 z*?n4kI=l7#Jw0q#1wa}g1%RwDwl<-pAHy8^RU_-nd~y7v25Zg0d%c_;&kuv1!k)K6 zQLR+@;f>8l)iWk7rL(Kky>@f@8cHi=AjDW-!&wCK?Ogw(_5K%y++0N2}iAR z5D7cjqFx&|;htcF^xQvX%+1c*Mg`)oe%SW!w3OazK8P*weuTbGz>+6x8}8{T2+VWc zZVdVrh5Is33*Bab)eI}HVZbSz((`k!CwM{?v8j4ni-+-**pk4U2D{Q%BG~0CDahoKz8%2XPZNkAhOT#*D>q z5tt@^Gw0#U-m`_{Sgqq>RscL7h#8T|Rn+<^b@|7Aq=Ots@8I}rX88gM)HDQb3NTaY zKcut3QaMm;B>RT_?_QzSc9~<)*kGOXYZYVIg`(^ZvMDMHcNIhLseyo-L+f}O{vY(A z`EPLrBcsu8uwe)Ql)HbPIMg{bCm^MK-tcm|P3HS7pQa+JWS`y~(e0hOnVh`3t5-k5 z4hAG84n@|~FY{4_o94D%%+2LzMT?lqv+gmhK~ZY35DZ#BtVv}cDBrTERWH%kdoqx9 ziId<~j64{x5n8C-eP!j`^6FUiS9V#XzVyr~wFrmfUH+zzAPprhx=H$SFSWX&MkP1x zYm5nD($BAu-p=PJ)xZBN-K_pMZ2^v&_iQ8U3j?O-jh^L3cXL9!(#w|IiU3q(b=`WN724w5f6V%*vLtcc`;WM0b zGrjXxdM)tG2Ea3){9@X4T&s%2T)tkO977V|?q2ugvZX{`u-x9QgRu_C>0XMnwCFay zv`r942Z9p_mMF-e4H?J&fx#?HC_Ia&C{T%1BgLdD2|}3tZ4r5i3!q8l$R+xJaiU@i z@*Q#K;dWE$A!&3V3X~`{!P18i62(|fpW>zNSrgeV;Y9U>dWp-iXa7btox?s@th(Ps zJf2aOnXb8My}s>z!z0WRZTvyfqNC=>sl*E7Go3g{; zm3{t{Q$v5U4s7^vkT5lFZuz({lCoi>ntj17?kyj_zxVnZe^zLXBOVgbrE|x;wGrg}Z}^gIDtNy&$SK#bawY##p+Ky)&?Q@i zwv>yH#MPh!T*)DfBopZpDE`7RZF95w9lXj7ewU{#ckev2Em{l0lJRYGt;)zpYF|Ok3vLg<39;fg=AT*Y! z7lH=aY@h*b<|BShie3&1Zu6plCdWfd13#JW?AF6b4G504ax-sfPD;jbBoH!P2%Gl* z?7>uIfd7Nb=Ab)xcbk%-Q}Tzc>W@1w;od>u4goWJb5SZtItkzaS=9SSHqZSi;zy{> zy-PMjFjyb8CbiA~EHA2ZPU>Vi;nsa*hZ=sVk$vmj{Ce$BuTHeEg(;@CX!c9vU*N+k zvAwi9rzvy7CDlBBEmpi}GaC8Dk(=CN4@J?#*$*a=ZG+5N)F@$GZR^dOff>ovO7EXY z(;u-bAqr2N~)8&on}6l-F>SvoVaXo)JvIg*wZBRdyyB(#UkK2aODR{S156D z_}8Z`qx4@FZrch`<`)%rX(0zVe@T;y=~O$M&`;4j5f#T3+LXR==Mc0h0z0$P+(F{@ z+!wKi;M(DO!vrd^FgHw%KfCo{)6jc9PYlyvm_B~}mJ>_*V7Iqik&%^yG*YW+oRQGps!wYH?}&9Il;kV zW)NB`G+2EXnRqoJ>0%Kw=;;;w0g^kQe~6YX{g-TuqKv0R~tQpa7r zMb@aHVPLyFmhMZ@rlQ?*ke9;KlUz2{BUwSschyqk?+8D$zdFzTm-6zxEibO=7w-8) ztbRFijXP7Yw{MmCGa~z?t|9|en+fvrn+n(G#<+vu?UJaCF42eO)TOQ3wSK(4Oa;rQ zlLkxJSIC~@{j-D(l=l25J-Lj4MMiW$QI5cPY(7;?zkH4vs|#cz%td49;zkL$n3vWA z1n_T|Nzu`Yp9^db)Hd)koHf|hZIrRCFrg7zeAe(Jpx6sVDorFS=7&H6TEHQ2GH?}= z(r6^mubl9%vS*y6o1aRy{P-bB>Z5|r0H(`Er>v-<8u?HwH3ua+cv9g-S^q5Roxk;t z+K*9c7_&rauSlI}J}Zl%wa`W_G6?N;oKMLvo?;IB5JCPrpcj;n#*{ma7 zdQ|vuRJvXU_gwj)M6lX~Aw-cdceFO~XCiZ-kQbu$&9F(lS~1?&3zsn-7vq{(ZGQ-= zg$Hul{;0DMywAkza*jKP$vLz=Tv@>BNb^F9+l(Ft-!QhV-W=9==;Q&N0>JLLp29`z z>UrKOFBW+t_DK_+;7b*8=b9&a`j={{AUF*|M#qwyh@$nSQ=R#Zv7W-HsA;>|=ybA* z7$q6#7|dJ_ElT>JCOqu5J0yL0DHo1}C0{K_ia!<Xbo9e8 z=02kbfa!aCWu;kH&ua-(%{jo-tQ*{q*RNXtNV|aiG(2;LV6~zmMA}YtKox#&%2($~IfO9QL zrV8)!?rg4yC!rT_^YPc_gNxU~l#0l&SE!-uFbQ1Qko~QS${fH7)H7nB1|~{ZlwM7! z^;JUze_@9-Ht@0mCofi0d;Ks}8wcl1<9E&RUH7rya0RE8$4Z-y=wrp@iC%^8i@ci5 zLmRptu3tM)49#2V3(5KgC2=?OR^%PS?Coj-Ma@MLDY84w6kBb8xDVKFC&b4V+a=^L zwNhd)y|Yo?vr-FA0&=Lor4-9#?ypSN3vNOL+zJ-H`}LY-Xu(2 z=n}%qIGs?3R>Go;)2JZbKl2QePYYAfx@9k`Z0THl#@n{OQQS1#`EjITO3HKQo0#Cb z0rJoOIJ2#0T$lFUm7#jiTl(a;oSp2V)A&&t(rU!%^|SJdC;{!7)MWSZ8Iv$$%*%SX*_y}WU# zeq96GSRa!?STV$}m{f|3a3^2fS^I;3e-zT}@|J_FNar{E zhtJ<=yJ~1*>J&C>nKv#_qqr_glGzzH4@=>?yP=K1G;@u3{GLX(#ZnS z%9=}OcMG1aUAV0lTH4n8Sj)^~B$v;uwK1^9KvM|ZNvE_kaJ2JPiP;U^(hmT!ZXa{$ zBamfFXStF=qu&$M6X|vKa>fs1uGZ()xA?&e*5-VK$+Va*t^pg5lKuH`-O`zc?P+IZ z{xi!s9jCCdk`Cg|T8O7DQgwXW_PIrN)n_IxD9Rn!M3R2VdxTRIc|n-e9_(?+n~FHD zewznbnl(t)zL&Xecsa+k)}(Ud%$TZ`*Nf2osSa>aXvgtb=)i+=BP@7J#+>{FySvS^ z^Rb357Fgd%H48qqA%T+QR75Lz$I?P?*+x?41C8V(f$6->m5E3dD#+*{4AL={P&s>X zcOEZ7Y5h=1qp>UL6Ox+|4Q>le*PqdU_Enqh5VQyqj#?8G;*%Rzx7v1z+`ugw?89g8 z#b{9Nb-tk3+%YtcH=h&fx;Jl>G18{8$oM=wfN$b>eoU^7ek? zX(QylA>wM{8dna-gSNdZ@WPg^U4sr|olOSJ$?vy!voIkj5^=ftI`6OFS^GY~^7B3J z&Hc3LC~;To{~**a^jDzs%VjB!&B+-EHUgtAtdE9{R2ET{fw%kXDTaX7Dk*SN>?ZCsHg3)+ z5%*VI=>*kC54G;=m*{c36>Ef*y@NGhuUHNM7pY>Eq5}N_WDJvqK)Ry~8wci`IJT14 ze*YYn6D+(24O4Xrwk`@z!`xS==_;F7FXrpdymQmh#}8&(W}x$>arT>;8>fN1?Euvb zRU=xv2OE35ECRJld#lPU*Nh&W{jmOaPe|}RFjJp1ma2A)Mt-E(d!*=$)vZ5c0|NuF zvp!r3hw?eCattHdrn`<+u#gg8e6zP3Av!N$#rC4ZbX{jU*V?O{rmVXG=y9C>ygIDL zqDMiBm&wZKis5{*j7k|*UR9$?8gue4J59rtqcu?Rx%&y61&lLlWo;gehXKbYgoIPG zlJfB4yu6hl!5{ZA1N4_ZNPZs2*S}E`gozS45u_cHF&h~PjOs@rEDZ@`!}%{9O+zdC zwJ$_dr<4qafGzf~VjYSC+d-;$Zzww5bY#65U!W1Wxv@0D5A;wvk=Fd~Yoz!YLc#nN zpSynC(XwdB|8hYC;L7xapYVVeGv{Lic+i8e<&n?pLxEp0!cU02~;#WFCShdu_ zXR>wzupkIjP6109`98mjVkSms=bBvv>2su&mx>3yi&xOA7=dC1PM6)iJL>zT;Zyk? zbb>w;?Xbk9v*5{z2>y~ybh`m3kJ{9mZmsH|2VY3N9(f3?UbU?|qoG7Vicy-oMeM(U z!3r39t%s3zI2Wq8YD_<5UNXW_P_w<>%)Xk=n~AaIS=_z!SD{!(PgOQ=r7B z&+wI2ao6&2XzamceH}hu&FzH zvyzwm3#Jc5Ti@UI^U>J)J!F>nMT7T+oPy1cxJQ|L43%r*d$l2ZfwYfwIeZ6GR6|-GrG1E`48Zoe`LVuwE4{Mf%oH5<`s`aPAUd3`E z$~rTj@|1^mQY+S-5xv=?`yJhi;1g3C;(j8XAcleY1qRs+pj

    c9?FRN~(YpGHSa4&e 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 J51o#j|365WL5KhV diff --git a/frontend/svelte.config.js b/frontend/svelte.config.js deleted file mode 100644 index 23b9567..0000000 --- a/frontend/svelte.config.js +++ /dev/null @@ -1,24 +0,0 @@ -import adapter from '@sveltejs/adapter-node'; -import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; - -/** @type {import('@sveltejs/kit').Config} */ -const config = { - // Consult https://svelte.dev/docs/kit/integrations - // for more information about preprocessors - preprocess: vitePreprocess(), - - kit: { - // Using adapter-node for Docker deployment - adapter: adapter({ - out: 'build', - }), - alias: { - $components: 'src/components', - $stores: 'src/stores', - $lib: 'src/lib', - $utils: 'src/utils', - }, - }, -}; - -export default config; diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json deleted file mode 100644 index e3898cb..0000000 --- a/frontend/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "./.svelte-kit/tsconfig.json", - "compilerOptions": { - "allowJs": true, - "checkJs": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "sourceMap": true, - "strict": true, - "moduleResolution": "bundler" - } - // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias - // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files - // - // To make changes to top-level options such as include and exclude, we recommend extending - // the generated config; see https://svelte.dev/docs/kit/configuration#typescript -} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts deleted file mode 100644 index 12c9911..0000000 --- a/frontend/vite.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import tailwindcss from '@tailwindcss/vite'; -import { sveltekit } from '@sveltejs/kit/vite'; -import { defineConfig } from 'vite'; - -export default defineConfig({ - plugins: [tailwindcss(), sveltekit()], - define: { - 'process.env.JWT_SECRET': JSON.stringify(process.env.JWT_SECRET), - }, -}); From 3ace8180c249a4f77fbf979e91e61accf26208ab Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Mon, 1 Jun 2026 19:16:54 +0200 Subject: [PATCH 02/12] feat: added all frontend auth pages --- app/package-lock.json | 8 +- app/package.json | 2 +- app/src/lib/components/ui/input-otp/index.ts | 15 ++++ .../ui/input-otp/input-otp-group.svelte | 20 +++++ .../ui/input-otp/input-otp-separator.svelte | 27 ++++++ .../ui/input-otp/input-otp-slot.svelte | 31 +++++++ .../components/ui/input-otp/input-otp.svelte | 23 +++++ app/src/routes/(auth)/+layout.svelte | 15 ++++ app/src/routes/(auth)/login/+page.svelte | 72 +++++++++++++++ app/src/routes/(auth)/otp/+page.svelte | 53 +++++++++++ app/src/routes/(auth)/pw_change/+page.svelte | 65 ++++++++++++++ app/src/routes/login/+page.svelte | 90 ------------------- 12 files changed, 326 insertions(+), 95 deletions(-) create mode 100644 app/src/lib/components/ui/input-otp/index.ts create mode 100644 app/src/lib/components/ui/input-otp/input-otp-group.svelte create mode 100644 app/src/lib/components/ui/input-otp/input-otp-separator.svelte create mode 100644 app/src/lib/components/ui/input-otp/input-otp-slot.svelte create mode 100644 app/src/lib/components/ui/input-otp/input-otp.svelte create mode 100644 app/src/routes/(auth)/+layout.svelte create mode 100644 app/src/routes/(auth)/login/+page.svelte create mode 100644 app/src/routes/(auth)/otp/+page.svelte create mode 100644 app/src/routes/(auth)/pw_change/+page.svelte delete mode 100644 app/src/routes/login/+page.svelte diff --git a/app/package-lock.json b/app/package-lock.json index 43d53af..9554015 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -14,7 +14,7 @@ "devDependencies": { "@fontsource-variable/inter": "^5.2.8", "@internationalized/date": "^3.12.1", - "@lucide/svelte": "^1.14.0", + "@lucide/svelte": "^1.17.0", "@sveltejs/adapter-auto": "^7.0.1", "@sveltejs/kit": "^2.57.0", "@sveltejs/vite-plugin-svelte": "^7.0.0", @@ -671,9 +671,9 @@ } }, "node_modules/@lucide/svelte": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-1.14.0.tgz", - "integrity": "sha512-MVuP5VRCBQa2OaIpaRbuEV4k5OV2dy9MyxA6Tf4Sz/IN0v3zzUU72ObHc9r2Zn/wSMXDg6lLrHrczqI7w7gCzQ==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-1.17.0.tgz", + "integrity": "sha512-q06YCFBN5CO8cd1ADmLCxWRVMVb7xxvHzqC0lvNoxGa+FLW6Cd1Y1AOxgbQk4Iwe68vkAMCRveNHint4WoaVKg==", "dev": true, "license": "ISC", "peerDependencies": { diff --git a/app/package.json b/app/package.json index 3066d8f..23a8cfe 100644 --- a/app/package.json +++ b/app/package.json @@ -14,7 +14,7 @@ "devDependencies": { "@fontsource-variable/inter": "^5.2.8", "@internationalized/date": "^3.12.1", - "@lucide/svelte": "^1.14.0", + "@lucide/svelte": "^1.17.0", "@sveltejs/adapter-auto": "^7.0.1", "@sveltejs/kit": "^2.57.0", "@sveltejs/vite-plugin-svelte": "^7.0.0", diff --git a/app/src/lib/components/ui/input-otp/index.ts b/app/src/lib/components/ui/input-otp/index.ts new file mode 100644 index 0000000..e9ae273 --- /dev/null +++ b/app/src/lib/components/ui/input-otp/index.ts @@ -0,0 +1,15 @@ +import Root from "./input-otp.svelte"; +import Group from "./input-otp-group.svelte"; +import Slot from "./input-otp-slot.svelte"; +import Separator from "./input-otp-separator.svelte"; + +export { + Root, + Group, + Slot, + Separator, + Root as InputOTP, + Group as InputOTPGroup, + Slot as InputOTPSlot, + Separator as InputOTPSeparator, +}; diff --git a/app/src/lib/components/ui/input-otp/input-otp-group.svelte b/app/src/lib/components/ui/input-otp/input-otp-group.svelte new file mode 100644 index 0000000..2e75884 --- /dev/null +++ b/app/src/lib/components/ui/input-otp/input-otp-group.svelte @@ -0,0 +1,20 @@ + + +

    + {@render children?.()} +
    diff --git a/app/src/lib/components/ui/input-otp/input-otp-separator.svelte b/app/src/lib/components/ui/input-otp/input-otp-separator.svelte new file mode 100644 index 0000000..99fdbb9 --- /dev/null +++ b/app/src/lib/components/ui/input-otp/input-otp-separator.svelte @@ -0,0 +1,27 @@ + + + diff --git a/app/src/lib/components/ui/input-otp/input-otp-slot.svelte b/app/src/lib/components/ui/input-otp/input-otp-slot.svelte new file mode 100644 index 0000000..4351fd4 --- /dev/null +++ b/app/src/lib/components/ui/input-otp/input-otp-slot.svelte @@ -0,0 +1,31 @@ + + + + {cell.char} + {#if cell.hasFakeCaret} +
    + +
    + {/if} +
    diff --git a/app/src/lib/components/ui/input-otp/input-otp.svelte b/app/src/lib/components/ui/input-otp/input-otp.svelte new file mode 100644 index 0000000..709bb22 --- /dev/null +++ b/app/src/lib/components/ui/input-otp/input-otp.svelte @@ -0,0 +1,23 @@ + + + diff --git a/app/src/routes/(auth)/+layout.svelte b/app/src/routes/(auth)/+layout.svelte new file mode 100644 index 0000000..2c56f27 --- /dev/null +++ b/app/src/routes/(auth)/+layout.svelte @@ -0,0 +1,15 @@ + + +
    +
    +
    + {@render children()} +
    +
    + +
    diff --git a/app/src/routes/(auth)/login/+page.svelte b/app/src/routes/(auth)/login/+page.svelte new file mode 100644 index 0000000..33f0cf6 --- /dev/null +++ b/app/src/routes/(auth)/login/+page.svelte @@ -0,0 +1,72 @@ + + +CSFX Logo +

    Sign in

    + +
    +
    + +
    + + +
    +
    + +
    + +
    + + +
    +
    + +
    + + +
    + + {#if error} +
    {error}
    + {/if} + + +
    diff --git a/app/src/routes/(auth)/otp/+page.svelte b/app/src/routes/(auth)/otp/+page.svelte new file mode 100644 index 0000000..1a8bf52 --- /dev/null +++ b/app/src/routes/(auth)/otp/+page.svelte @@ -0,0 +1,53 @@ + + +CSFX Logo +

    2FA Verification

    + +
    +
    + + + {#snippet children({ cells })} + + {#each cells.slice(0, 3) as cell (cell)} + + {/each} + + + + {#each cells.slice(3, 6) as cell (cell)} + + {/each} + + {/snippet} + +
    + + {#if error} +
    {error}
    + {/if} + + +
    diff --git a/app/src/routes/(auth)/pw_change/+page.svelte b/app/src/routes/(auth)/pw_change/+page.svelte new file mode 100644 index 0000000..29417a8 --- /dev/null +++ b/app/src/routes/(auth)/pw_change/+page.svelte @@ -0,0 +1,65 @@ + + +CSFX Logo +

    Change Password

    + +
    +
    + +
    + + +
    +
    + +
    + +
    + + +
    +
    + + {#if error} +
    {error}
    + {/if} + + +
    diff --git a/app/src/routes/login/+page.svelte b/app/src/routes/login/+page.svelte deleted file mode 100644 index 9f693d3..0000000 --- a/app/src/routes/login/+page.svelte +++ /dev/null @@ -1,90 +0,0 @@ - - -
    -
    -
    - CSFX Logo -

    Sign in

    - -
    -
    - -
    - - -
    -
    - -
    - -
    - - -
    -
    - -
    - - -
    - - {#if error} -
    {error}
    - {/if} - - -
    -
    -
    - -
    From 9f18045554f0cba824de209bd588eec83197937e Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Mon, 1 Jun 2026 19:45:04 +0200 Subject: [PATCH 03/12] feat: login flow --- app/Dockerfile.dev | 12 ++ app/src/lib/auth/api.ts | 127 +++++++++++++++++++ app/src/lib/auth/store.svelte.ts | 53 ++++++++ app/src/routes/(app)/+layout.svelte | 32 ++++- app/src/routes/(auth)/login/+page.svelte | 75 ++++++----- app/src/routes/(auth)/otp/+page.svelte | 52 ++++++-- app/src/routes/(auth)/pw_change/+page.svelte | 67 ++++++---- app/vite.config.ts | 10 +- control-plane/Dockerfile.dev.shared | 6 + control-plane/api-gateway/src/routes/mod.rs | 2 + docker-compose.dev.yml | 19 +++ 11 files changed, 376 insertions(+), 79 deletions(-) create mode 100644 app/Dockerfile.dev create mode 100644 app/src/lib/auth/api.ts create mode 100644 app/src/lib/auth/store.svelte.ts diff --git a/app/Dockerfile.dev b/app/Dockerfile.dev new file mode 100644 index 0000000..324adcf --- /dev/null +++ b/app/Dockerfile.dev @@ -0,0 +1,12 @@ +FROM node:22-alpine + +WORKDIR /app + +COPY package.json package-lock.json ./ +RUN npm ci + +COPY . . + +EXPOSE 5173 + +CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"] diff --git a/app/src/lib/auth/api.ts b/app/src/lib/auth/api.ts new file mode 100644 index 0000000..eb2eb37 --- /dev/null +++ b/app/src/lib/auth/api.ts @@ -0,0 +1,127 @@ +const API_BASE = (import.meta.env.VITE_API_URL ?? 'http://localhost:8000') + '/api'; + +export interface AuthResponse { + token: string; + user_id: string; + username: string; + two_factor_enabled: boolean; + force_password_change: boolean; +} + +export interface UserProfile { + id: string; + username: string; + email: string | null; + two_factor_enabled: boolean; + force_password_change: boolean; +} + +async function fetchPublicKeyPem(): Promise { + const res = await fetch(`${API_BASE}/public-key`); + if (!res.ok) throw new Error(`public-key fetch failed: ${res.status}`); + const data = await res.json(); + return data.public_key as string; +} + +function pemToArrayBuffer(pem: string): ArrayBuffer { + const b64 = pem + .replace('-----BEGIN RSA PUBLIC KEY-----', '') + .replace('-----END RSA PUBLIC KEY-----', '') + .replace(/\s/g, ''); + const binary = atob(b64); + const buf = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) buf[i] = binary.charCodeAt(i); + return buf.buffer; +} + +async function importRsaKey(pem: string): Promise { + const keyData = pemToArrayBuffer(pem); + return crypto.subtle.importKey( + 'spki', + keyData, + { name: 'RSA-OAEP', hash: 'SHA-256' }, + false, + ['encrypt'], + ); +} + +async function encryptPassword(password: string, publicKey: CryptoKey): Promise { + const encoded = new TextEncoder().encode(password); + const encrypted = await crypto.subtle.encrypt({ name: 'RSA-OAEP' }, publicKey, encoded); + const bytes = new Uint8Array(encrypted); + let binary = ''; + for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]); + return btoa(binary); +} + +export async function login( + username: string, + password: string, + twoFactorCode?: string, +): Promise { + const pem = await fetchPublicKeyPem(); + const publicKey = await importRsaKey(pem); + const encryptedPassword = await encryptPassword(password, publicKey); + + const res = await fetch(`${API_BASE}/login`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + username, + encrypted_password: encryptedPassword, + two_factor_code: twoFactorCode ?? null, + }), + }); + + if (res.status === 403) { + throw new TwoFactorRequiredError(username, password); + } + + if (!res.ok) { + throw new Error(`login failed: ${res.status}`); + } + + return res.json(); +} + +export async function changePassword( + token: string, + oldPassword: string, + newPassword: string, +): Promise { + const pem = await fetchPublicKeyPem(); + const publicKey = await importRsaKey(pem); + const encryptedOld = await encryptPassword(oldPassword, publicKey); + const encryptedNew = await encryptPassword(newPassword, publicKey); + + const res = await fetch(`${API_BASE}/change-password`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }, + body: JSON.stringify({ + old_password: encryptedOld, + new_password: encryptedNew, + }), + }); + + if (!res.ok) throw new Error(`change-password failed: ${res.status}`); +} + +export async function validateSession(token: string): Promise { + const res = await fetch(`${API_BASE}/validate-session`, { + headers: { Authorization: `Bearer ${token}` }, + }); + if (!res.ok) throw new Error('session invalid'); + return res.json(); +} + +export class TwoFactorRequiredError extends Error { + constructor( + public readonly username: string, + public readonly password: string, + ) { + super('2fa_required'); + } +} diff --git a/app/src/lib/auth/store.svelte.ts b/app/src/lib/auth/store.svelte.ts new file mode 100644 index 0000000..c00a2c5 --- /dev/null +++ b/app/src/lib/auth/store.svelte.ts @@ -0,0 +1,53 @@ +import type { AuthResponse, UserProfile } from './api'; + +interface AuthState { + token: string | null; + user: UserProfile | null; +} + +function createAuthStore() { + const TOKEN_KEY = 'csfx_token'; + + let state = $state({ + token: null, + user: null, + }); + + function init() { + if (typeof localStorage === 'undefined') return; + const stored = localStorage.getItem(TOKEN_KEY); + if (stored) state.token = stored; + } + + function setSession(response: AuthResponse, profile?: UserProfile) { + state.token = response.token; + if (profile) { + state.user = profile; + } else { + state.user = { + id: response.user_id, + username: response.username, + email: null, + two_factor_enabled: response.two_factor_enabled, + force_password_change: response.force_password_change, + }; + } + localStorage.setItem(TOKEN_KEY, response.token); + } + + function clearSession() { + state.token = null; + state.user = null; + localStorage.removeItem(TOKEN_KEY); + } + + return { + get token() { return state.token; }, + get user() { return state.user; }, + init, + setSession, + clearSession, + }; +} + +export const auth = createAuthStore(); diff --git a/app/src/routes/(app)/+layout.svelte b/app/src/routes/(app)/+layout.svelte index 11a66eb..0f57dcb 100644 --- a/app/src/routes/(app)/+layout.svelte +++ b/app/src/routes/(app)/+layout.svelte @@ -1,13 +1,31 @@ - - - {@render children()} - + + + {@render children()} + diff --git a/app/src/routes/(auth)/login/+page.svelte b/app/src/routes/(auth)/login/+page.svelte index 33f0cf6..80b0413 100644 --- a/app/src/routes/(auth)/login/+page.svelte +++ b/app/src/routes/(auth)/login/+page.svelte @@ -2,18 +2,36 @@ import { Button } from "$lib/components/ui/button/index.js"; import { Input } from "$lib/components/ui/input/index.js"; import { Label } from "$lib/components/ui/label/index.js"; - import Checkbox from "$lib/components/ui/checkbox/checkbox.svelte"; - import { Lock, Mail } from "@lucide/svelte"; + import { Lock, User } from "@lucide/svelte"; import { goto } from "$app/navigation"; + import { login, TwoFactorRequiredError } from "$lib/auth/api"; + import { auth } from "$lib/auth/store.svelte"; - let email = ""; - let password = ""; - let remember = false; - let loading = false; - let error: string | null = null; + let username = $state(""); + let password = $state(""); + let loading = $state(false); + let error = $state(null); - async function handleSignIn(event?: Event) { - goto("/"); + async function handleSubmit() { + error = null; + loading = true; + try { + const response = await login(username, password); + auth.setSession(response); + if (response.force_password_change) { + goto("/pw_change"); + } else { + goto("/"); + } + } catch (err) { + if (err instanceof TwoFactorRequiredError) { + goto(`/otp?username=${encodeURIComponent(err.username)}&password=${encodeURIComponent(err.password)}`); + } else { + error = "Invalid credentials"; + } + } finally { + loading = false; + } } @@ -22,51 +40,44 @@ alt="CSFX Logo" class="size-20 mb-6 rounded-md p-2 invert dark:invert-0" /> -

    Sign in

    +

    Sign in

    -
    + { e.preventDefault(); handleSubmit(); }} class="flex flex-col">
    - +
    - +
    -
    +
    - +
    -
    - - -
    - {#if error} -
    {error}
    +
    {error}
    {/if} - diff --git a/app/src/routes/(auth)/otp/+page.svelte b/app/src/routes/(auth)/otp/+page.svelte index 1a8bf52..e63240a 100644 --- a/app/src/routes/(auth)/otp/+page.svelte +++ b/app/src/routes/(auth)/otp/+page.svelte @@ -2,14 +2,41 @@ import { Button } from "$lib/components/ui/button/index.js"; import { Label } from "$lib/components/ui/label/index.js"; import { goto } from "$app/navigation"; + import { page } from "$app/stores"; import * as InputOTP from "$lib/components/ui/input-otp/index.js"; + import { login } from "$lib/auth/api"; + import { auth } from "$lib/auth/store.svelte"; - let loading = false; - let error: string | null = null; + const username = $derived($page.url.searchParams.get("username") ?? ""); + const password = $derived($page.url.searchParams.get("password") ?? ""); - async function handleVerify(event?: Event) { - goto("/"); + let otpValue = $state(""); + let loading = $state(false); + let error = $state(null); + + async function handleVerify() { + if (otpValue.length !== 6) return; + error = null; + loading = true; + try { + const response = await login(username, password, otpValue); + auth.setSession(response); + if (response.force_password_change) { + goto("/pw_change"); + } else { + goto("/"); + } + } catch { + error = "Invalid code"; + otpValue = ""; + } finally { + loading = false; + } } + + $effect(() => { + if (otpValue.length === 6) handleVerify(); + }); CSFX Logo -

    2FA Verification

    +

    2FA Verification

    +

    Enter the 6-digit code from your authenticator app

    -
    + { e.preventDefault(); handleVerify(); }} class="flex flex-col">
    - + {#snippet children({ cells })} {#each cells.slice(0, 3) as cell (cell)} @@ -40,14 +68,10 @@
    {#if error} -
    {error}
    +
    {error}
    {/if} -
    diff --git a/app/src/routes/(auth)/pw_change/+page.svelte b/app/src/routes/(auth)/pw_change/+page.svelte index 29417a8..5cba8b7 100644 --- a/app/src/routes/(auth)/pw_change/+page.svelte +++ b/app/src/routes/(auth)/pw_change/+page.svelte @@ -4,14 +4,29 @@ import { Label } from "$lib/components/ui/label/index.js"; import { Lock } from "@lucide/svelte"; import { goto } from "$app/navigation"; + import { changePassword } from "$lib/auth/api"; + import { auth } from "$lib/auth/store.svelte"; - let password = ""; - let passwordRepeat = ""; - let loading = false; - let error: string | null = null; + let newPassword = $state(""); + let confirmPassword = $state(""); + let loading = $state(false); + let error = $state(null); - async function handleChangePassword(event?: Event) { - goto("/"); + const mismatch = $derived(confirmPassword.length > 0 && newPassword !== confirmPassword); + const canSubmit = $derived(newPassword.length >= 8 && newPassword === confirmPassword && !loading); + + async function handleSubmit() { + if (!canSubmit || !auth.token) return; + error = null; + loading = true; + try { + await changePassword(auth.token, "", newPassword); + goto("/"); + } catch { + error = "Failed to change password"; + } finally { + loading = false; + } } @@ -20,46 +35,48 @@ alt="CSFX Logo" class="size-20 mb-6 rounded-md p-2 invert dark:invert-0" /> -

    Change Password

    +

    Change Password

    +

    A new password is required before continuing

    -
    + { e.preventDefault(); handleSubmit(); }} class="flex flex-col">
    - +
    - +
    -
    - +
    +
    - +
    + {#if mismatch} +

    Passwords do not match

    + {/if}
    {#if error} -
    {error}
    +
    {error}
    {/if} - diff --git a/app/vite.config.ts b/app/vite.config.ts index 56f40c7..904d0f5 100644 --- a/app/vite.config.ts +++ b/app/vite.config.ts @@ -2,4 +2,12 @@ import tailwindcss from '@tailwindcss/vite'; import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vite'; -export default defineConfig({ plugins: [tailwindcss(), sveltekit()] }); +export default defineConfig({ + plugins: [tailwindcss(), sveltekit()], + server: { + watch: { + usePolling: true, + interval: 1000, + }, + }, +}); diff --git a/control-plane/Dockerfile.dev.shared b/control-plane/Dockerfile.dev.shared index 1b65081..246cfc1 100644 --- a/control-plane/Dockerfile.dev.shared +++ b/control-plane/Dockerfile.dev.shared @@ -30,6 +30,8 @@ COPY control-plane/registry/Cargo.toml ./control-plane/registry/ COPY control-plane/shared/entity/Cargo.toml ./control-plane/shared/entity/ COPY control-plane/shared/migration/Cargo.toml ./control-plane/shared/migration/ COPY control-plane/shared/shared/Cargo.toml ./control-plane/shared/shared/ +COPY control-plane/csfx-migrate/Cargo.toml ./control-plane/csfx-migrate/ +COPY control-plane/csfx-updater/Cargo.toml ./control-plane/csfx-updater/ RUN mkdir -p agent/src \ control-plane/api-gateway/src \ @@ -41,6 +43,8 @@ RUN mkdir -p agent/src \ control-plane/shared/entity/src \ control-plane/shared/migration/src \ control-plane/shared/shared/src \ + control-plane/csfx-migrate/src \ + control-plane/csfx-updater/src \ && echo "fn main() {}" > agent/src/main.rs \ && echo "fn main() {}" > control-plane/api-gateway/src/main.rs \ && echo "fn main() {}" > control-plane/scheduler/src/main.rs \ @@ -48,6 +52,8 @@ RUN mkdir -p agent/src \ && echo "fn main() {}" > control-plane/sdn-controller/src/main.rs \ && echo "fn main() {}" > control-plane/volume-manager/src/main.rs \ && echo "fn main() {}" > control-plane/registry/src/main.rs \ + && echo "fn main() {}" > control-plane/csfx-migrate/src/main.rs \ + && echo "fn main() {}" > control-plane/csfx-updater/src/main.rs \ && echo "pub fn lib() {}" > control-plane/shared/entity/src/lib.rs \ && echo "pub fn lib() {}" > control-plane/shared/migration/src/lib.rs \ && echo "pub fn lib() {}" > control-plane/shared/shared/src/lib.rs diff --git a/control-plane/api-gateway/src/routes/mod.rs b/control-plane/api-gateway/src/routes/mod.rs index 4a2068c..b8e0cad 100644 --- a/control-plane/api-gateway/src/routes/mod.rs +++ b/control-plane/api-gateway/src/routes/mod.rs @@ -53,8 +53,10 @@ pub fn create_router() -> Router { // Allow multiple origins for development (both Docker container and localhost) let allowed_origins = vec![ "http://localhost:3000", + "http://localhost:5173", "http://localhost:8000", "http://127.0.0.1:3000", + "http://127.0.0.1:5173", "http://127.0.0.1:8000", &frontend_url, ]; diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index b37a5b0..b04f367 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -57,6 +57,7 @@ services: VOLUME_MANAGER_URL: http://volume-manager:8003 FAILOVER_CONTROLLER_URL: http://failover-controller:8004 SDN_CONTROLLER_URL: http://sdn-controller:8005 + FRONTEND_URL: http://localhost:5173 ports: - "8000:8000" depends_on: @@ -181,6 +182,24 @@ services: timeout: 10s retries: 3 + app: + build: + context: ./app + dockerfile: Dockerfile.dev + container_name: csfx-app-dev + environment: + VITE_API_URL: http://localhost:8000 + ports: + - "5173:5173" + volumes: + - ./app/src:/app/src + - ./app/static:/app/static + depends_on: + - api-gateway + networks: + - csfx-network + restart: unless-stopped + volumes: postgres_data: cargo_cache: From 81406865af1f2aa268543472304da83f764ea8ce Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Mon, 1 Jun 2026 19:52:53 +0200 Subject: [PATCH 04/12] fix: migration in docker dev enviroment and auth fix frontend --- app/src/lib/auth/api.ts | 48 +++++++++++++++++++++++++++++++++++------ docker-compose.dev.yml | 32 +++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/app/src/lib/auth/api.ts b/app/src/lib/auth/api.ts index eb2eb37..cf30447 100644 --- a/app/src/lib/auth/api.ts +++ b/app/src/lib/auth/api.ts @@ -23,22 +23,56 @@ async function fetchPublicKeyPem(): Promise { return data.public_key as string; } -function pemToArrayBuffer(pem: string): ArrayBuffer { +function pkcs1PemToSpki(pem: string): ArrayBuffer { const b64 = pem .replace('-----BEGIN RSA PUBLIC KEY-----', '') .replace('-----END RSA PUBLIC KEY-----', '') .replace(/\s/g, ''); - const binary = atob(b64); - const buf = new Uint8Array(binary.length); - for (let i = 0; i < binary.length; i++) buf[i] = binary.charCodeAt(i); - return buf.buffer; + const pkcs1 = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0)); + + // SPKI header for RSA with SHA-256: OID 1.2.840.113549.1.1.1 + const spkiHeader = new Uint8Array([ + 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, + ]); + + // BIT STRING wrapper: tag 0x03, length = pkcs1.length + 1, leading 0x00 + const bitStringBody = new Uint8Array(pkcs1.length + 1); + bitStringBody[0] = 0x00; + bitStringBody.set(pkcs1, 1); + + const bitStringLen = bitStringBody.length; + const bitStringLenBytes = encodeAsn1Length(bitStringLen); + const bitString = new Uint8Array(1 + bitStringLenBytes.length + bitStringLen); + bitString[0] = 0x03; + bitString.set(bitStringLenBytes, 1); + bitString.set(bitStringBody, 1 + bitStringLenBytes.length); + + const spkiBody = new Uint8Array(spkiHeader.length + bitString.length); + spkiBody.set(spkiHeader); + spkiBody.set(bitString, spkiHeader.length); + + const spkiBodyLen = encodeAsn1Length(spkiBody.length); + const spki = new Uint8Array(1 + spkiBodyLen.length + spkiBody.length); + spki[0] = 0x30; + spki.set(spkiBodyLen, 1); + spki.set(spkiBody, 1 + spkiBodyLen.length); + + return spki.buffer; +} + +function encodeAsn1Length(len: number): Uint8Array { + if (len < 0x80) return new Uint8Array([len]); + if (len < 0x100) return new Uint8Array([0x81, len]); + return new Uint8Array([0x82, (len >> 8) & 0xff, len & 0xff]); } async function importRsaKey(pem: string): Promise { - const keyData = pemToArrayBuffer(pem); + const spki = pkcs1PemToSpki(pem); return crypto.subtle.importKey( 'spki', - keyData, + spki, { name: 'RSA-OAEP', hash: 'SHA-256' }, false, ['encrypt'], diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index b04f367..2209c34 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -44,6 +44,27 @@ services: networks: - csfx-network + migrate: + <<: *rust-service + container_name: csfx-migrate-dev + environment: + DATABASE_URL: postgres://${POSTGRES_USER:-csfx_user}:${POSTGRES_PASSWORD:-csfx_password}@postgres:5432/${POSTGRES_DB:-csfx_core} + RUST_LOG: info + depends_on: + postgres: + condition: service_healthy + volumes: + - ./control-plane/csfx-migrate:/app/control-plane/csfx-migrate + - ./control-plane/shared:/app/control-plane/shared + - cargo_target_migrate:/app/target + command: cargo run -p csfx-migrate + restart: "no" + healthcheck: + test: ["CMD-SHELL", "[ $$(cat /tmp/migrate-done 2>/dev/null) = 'ok' ] || exit 1"] + interval: 5s + timeout: 5s + retries: 20 + api-gateway: <<: *rust-service container_name: csfx-api-gateway-dev @@ -63,6 +84,8 @@ services: depends_on: postgres: condition: service_healthy + migrate: + condition: service_completed_successfully volumes: - ./control-plane/api-gateway:/app/control-plane/api-gateway - cargo_target_api_gateway:/app/target @@ -84,6 +107,8 @@ services: condition: service_healthy etcd: condition: service_started + migrate: + condition: service_completed_successfully volumes: - ./control-plane/registry:/app/control-plane/registry - cargo_target_registry:/app/target @@ -109,6 +134,8 @@ services: condition: service_healthy etcd: condition: service_started + migrate: + condition: service_completed_successfully volumes: - ./control-plane/scheduler:/app/control-plane/scheduler - cargo_target_scheduler:/app/target @@ -129,6 +156,8 @@ services: condition: service_healthy etcd: condition: service_started + migrate: + condition: service_completed_successfully volumes: - ./control-plane/volume-manager:/app/control-plane/volume-manager - cargo_target_volume_manager:/app/target @@ -172,6 +201,8 @@ services: condition: service_healthy etcd: condition: service_started + migrate: + condition: service_completed_successfully volumes: - ./control-plane/sdn-controller:/app/control-plane/sdn-controller - cargo_target_sdn_controller:/app/target @@ -204,6 +235,7 @@ volumes: postgres_data: cargo_cache: cargo_git: + cargo_target_migrate: cargo_target_api_gateway: cargo_target_registry: cargo_target_scheduler: From 60f7e415c0273d199dfc1e62303969d82160296b Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Mon, 1 Jun 2026 19:56:08 +0200 Subject: [PATCH 05/12] feat: added user name in sidebar and added nodes page demo for testing --- app/src/lib/api/nodes.ts | 54 ++++++ .../lib/components/sidebar/app-sidebar.svelte | 11 +- .../lib/components/sidebar/nav-user.svelte | 156 +++++++++--------- app/src/routes/(app)/nodes/+page.svelte | 117 +++++++++++++ 4 files changed, 249 insertions(+), 89 deletions(-) create mode 100644 app/src/lib/api/nodes.ts create mode 100644 app/src/routes/(app)/nodes/+page.svelte diff --git a/app/src/lib/api/nodes.ts b/app/src/lib/api/nodes.ts new file mode 100644 index 0000000..6cdfb24 --- /dev/null +++ b/app/src/lib/api/nodes.ts @@ -0,0 +1,54 @@ +const API_BASE = (import.meta.env.VITE_API_URL ?? 'http://localhost:8000') + '/api'; + +export interface Node { + id: string; + name: string; + hostname: string; + ip_address: string | null; + os_type: string; + os_version: string; + architecture: string; + agent_version: string; + status: string; + last_heartbeat: string | null; + registered_at: string; +} + +export interface NodeMetrics { + agent_id: string; + hostname: string; + status: string; + cpu_usage_percent: number | null; + memory_total_bytes: number | null; + memory_used_bytes: number | null; + disk_total_bytes: number | null; + disk_used_bytes: number | null; +} + +export interface ClusterStats { + node_count: number; + online_count: number; + total_cpu_cores: number; + avg_cpu_usage_percent: number; + total_memory_bytes: number; + used_memory_bytes: number; + total_disk_bytes: number; + used_disk_bytes: number; + nodes: NodeMetrics[]; +} + +export async function listNodes(token: string): Promise { + const res = await fetch(`${API_BASE}/agents`, { + headers: { Authorization: `Bearer ${token}` }, + }); + if (!res.ok) throw new Error(`agents fetch failed: ${res.status}`); + return res.json(); +} + +export async function getClusterStats(token: string): Promise { + const res = await fetch(`${API_BASE}/system/stats`, { + headers: { Authorization: `Bearer ${token}` }, + }); + if (!res.ok) throw new Error(`system/stats fetch failed: ${res.status}`); + return res.json(); +} diff --git a/app/src/lib/components/sidebar/app-sidebar.svelte b/app/src/lib/components/sidebar/app-sidebar.svelte index 7cda9db..ea7092a 100644 --- a/app/src/lib/components/sidebar/app-sidebar.svelte +++ b/app/src/lib/components/sidebar/app-sidebar.svelte @@ -16,11 +16,6 @@ import IconBucket from "./icon-bucket.svelte"; const data = { - user: { - name: "shadcn", - email: "m@example.com", - avatar: "/avatars/shadcn.jpg", - }, navBottom: [ { title: "Monitoring", @@ -36,13 +31,13 @@ navMain: [ { title: "Dashboard", - url: "#", + url: "/", icon: LayoutDashboard, isActive: true, }, { title: "Nodes", - url: "#", + url: "/nodes", icon: Server, }, { @@ -121,7 +116,7 @@ - + diff --git a/app/src/lib/components/sidebar/nav-user.svelte b/app/src/lib/components/sidebar/nav-user.svelte index 3f8cef0..fbd9ab3 100644 --- a/app/src/lib/components/sidebar/nav-user.svelte +++ b/app/src/lib/components/sidebar/nav-user.svelte @@ -1,87 +1,81 @@ - - - - {#snippet child({ props })} - - - - CN - -
    - {user.name} - {user.email} -
    - -
    - {/snippet} -
    - - -
    - - - CN - -
    - {user.name} - {user.email} -
    -
    -
    - - - - - Upgrade to Pro - - - - - - - Account - - - - Billing - - - - Notifications - - - - - - Log out - -
    -
    -
    + + + + {#snippet child({ props })} + + + + {auth.user ? initials(auth.user.username) : "??"} + + +
    + {auth.user?.username ?? "-"} + {auth.user?.email ?? ""} +
    + +
    + {/snippet} +
    + + +
    + + + {auth.user ? initials(auth.user.username) : "??"} + + +
    + {auth.user?.username ?? "-"} + {auth.user?.email ?? ""} +
    +
    +
    + + + + + Profile + + + + + + Log out + +
    +
    +
    diff --git a/app/src/routes/(app)/nodes/+page.svelte b/app/src/routes/(app)/nodes/+page.svelte new file mode 100644 index 0000000..a16246d --- /dev/null +++ b/app/src/routes/(app)/nodes/+page.svelte @@ -0,0 +1,117 @@ + + +
    + + / + Nodes +
    + +
    + {#if stats} +
    +
    +

    Nodes

    +

    {stats.online_count} / {stats.node_count}

    +
    +
    +

    CPU Cores

    +

    {stats.total_cpu_cores}

    +
    +
    +

    Memory

    +

    {bytesToGb(stats.used_memory_bytes)} / {bytesToGb(stats.total_memory_bytes)}

    +
    +
    +

    Disk

    +

    {bytesToGb(stats.used_disk_bytes)} / {bytesToGb(stats.total_disk_bytes)}

    +
    +
    + {/if} + +
    + + + + + + + + + + + + + + + {#if loading} + + + + {:else if error} + + + + {:else if nodes.length === 0} + + + + {:else} + {#each nodes as node (node.id)} + + + + + + + + + + + {/each} + {/if} + +
    IDHostnameIPOSArchVersionStatusHeartbeat
    Loading...
    {error}
    No nodes registered
    {node.id.slice(0, 8)}{node.hostname}{node.ip_address ?? "-"}{node.os_type} {node.os_version}{node.architecture}{node.agent_version} + {node.status} + + {node.last_heartbeat ? node.last_heartbeat.slice(0, 16) : "never"} +
    +
    +
    From 8a331f432e62af605d65d0b899213c1e0282dba9 Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Tue, 2 Jun 2026 22:59:11 +0200 Subject: [PATCH 06/12] feat: add animated custom icons for all sidebar navigation items --- app/package-lock.json | 10 ++ app/package.json | 1 + app/src/lib/auth/store.svelte.ts | 5 + .../lib/components/sidebar/app-sidebar.svelte | 34 +++-- .../components/sidebar/icon-activity.svelte | 59 +++++++++ .../components/sidebar/icon-container.svelte | 84 ++++++++++++ .../components/sidebar/icon-dashboard.svelte | 51 +++++++ .../lib/components/sidebar/icon-laptop.svelte | 62 +++++++++ .../lib/components/sidebar/icon-layers.svelte | 72 ++++++++++ .../lib/components/sidebar/icon-logs.svelte | 124 ++++++++++++++++++ .../lib/components/sidebar/icon-server.svelte | 63 +++++++++ .../components/sidebar/icon-ship-wheel.svelte | 59 +++++++++ app/src/routes/(app)/+layout.svelte | 3 +- docker-compose.dev.yml | 75 +++++++++++ 14 files changed, 683 insertions(+), 19 deletions(-) create mode 100644 app/src/lib/components/sidebar/icon-activity.svelte create mode 100644 app/src/lib/components/sidebar/icon-container.svelte create mode 100644 app/src/lib/components/sidebar/icon-dashboard.svelte create mode 100644 app/src/lib/components/sidebar/icon-laptop.svelte create mode 100644 app/src/lib/components/sidebar/icon-layers.svelte create mode 100644 app/src/lib/components/sidebar/icon-logs.svelte create mode 100644 app/src/lib/components/sidebar/icon-server.svelte create mode 100644 app/src/lib/components/sidebar/icon-ship-wheel.svelte diff --git a/app/package-lock.json b/app/package-lock.json index 9554015..f8bea9d 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.1", "dependencies": { "@iconify/svelte": "^5.2.1", + "@jis3r/icons": "^2.7.0", "geist": "^1.7.0" }, "devDependencies": { @@ -625,6 +626,15 @@ "@swc/helpers": "^0.5.0" } }, + "node_modules/@jis3r/icons": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@jis3r/icons/-/icons-2.7.0.tgz", + "integrity": "sha512-RXee+W1AoWFHtFliLZ7SQxVopAezmCH0xU45HKTvvpDQ+6Y3g6tUHvKOK16J52TM8YsN4WDnsiOmcwau+bHmwg==", + "license": "MIT", + "peerDependencies": { + "svelte": "^5.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", diff --git a/app/package.json b/app/package.json index 23a8cfe..facda63 100644 --- a/app/package.json +++ b/app/package.json @@ -33,6 +33,7 @@ }, "dependencies": { "@iconify/svelte": "^5.2.1", + "@jis3r/icons": "^2.7.0", "geist": "^1.7.0" } } diff --git a/app/src/lib/auth/store.svelte.ts b/app/src/lib/auth/store.svelte.ts index c00a2c5..beecab6 100644 --- a/app/src/lib/auth/store.svelte.ts +++ b/app/src/lib/auth/store.svelte.ts @@ -19,6 +19,10 @@ function createAuthStore() { if (stored) state.token = stored; } + function setUser(profile: UserProfile) { + state.user = profile; + } + function setSession(response: AuthResponse, profile?: UserProfile) { state.token = response.token; if (profile) { @@ -46,6 +50,7 @@ function createAuthStore() { get user() { return state.user; }, init, setSession, + setUser, clearSession, }; } diff --git a/app/src/lib/components/sidebar/app-sidebar.svelte b/app/src/lib/components/sidebar/app-sidebar.svelte index ea7092a..7473538 100644 --- a/app/src/lib/components/sidebar/app-sidebar.svelte +++ b/app/src/lib/components/sidebar/app-sidebar.svelte @@ -3,47 +3,45 @@ import ChartPieIcon from "@lucide/svelte/icons/chart-pie"; import MapIcon from "@lucide/svelte/icons/map"; import BookOpenIcon from "@lucide/svelte/icons/book-open"; - import { - LayoutDashboard, - Server, - Layers, - ShipWheel, - Container, - LaptopMinimal, - Activity, - Logs, - } from "@lucide/svelte"; import IconBucket from "./icon-bucket.svelte"; + import IconActivity from "./icon-activity.svelte"; + import IconLogs from "./icon-logs.svelte"; + import IconDashboard from "./icon-dashboard.svelte"; + import IconServer from "./icon-server.svelte"; + import IconLayers from "./icon-layers.svelte"; + import IconShipWheel from "./icon-ship-wheel.svelte"; + import IconContainer from "./icon-container.svelte"; + import IconLaptop from "./icon-laptop.svelte"; const data = { navBottom: [ { title: "Monitoring", url: "#", - icon: Activity, + icon: IconActivity, }, { title: "Logs", url: "#", - icon: Logs, + icon: IconLogs, }, ], navMain: [ { title: "Dashboard", url: "/", - icon: LayoutDashboard, + icon: IconDashboard, isActive: true, }, { title: "Nodes", url: "/nodes", - icon: Server, + icon: IconServer, }, { title: "Resource groups", url: "#", - icon: Layers, + icon: IconLayers, }, ], projects: [ @@ -55,17 +53,17 @@ { name: "Kubernetes", url: "#", - icon: ShipWheel, + icon: IconShipWheel, }, { name: "Docker", url: "#", - icon: Container, + icon: IconContainer, }, { name: "Virtual Machines", url: "#", - icon: LaptopMinimal, + icon: IconLaptop, }, ], }; diff --git a/app/src/lib/components/sidebar/icon-activity.svelte b/app/src/lib/components/sidebar/icon-activity.svelte new file mode 100644 index 0000000..ed8bcc5 --- /dev/null +++ b/app/src/lib/components/sidebar/icon-activity.svelte @@ -0,0 +1,59 @@ + + + + + diff --git a/app/src/lib/components/sidebar/icon-container.svelte b/app/src/lib/components/sidebar/icon-container.svelte new file mode 100644 index 0000000..02945af --- /dev/null +++ b/app/src/lib/components/sidebar/icon-container.svelte @@ -0,0 +1,84 @@ + + + + + diff --git a/app/src/lib/components/sidebar/icon-dashboard.svelte b/app/src/lib/components/sidebar/icon-dashboard.svelte new file mode 100644 index 0000000..d7c1078 --- /dev/null +++ b/app/src/lib/components/sidebar/icon-dashboard.svelte @@ -0,0 +1,51 @@ + + + + + diff --git a/app/src/lib/components/sidebar/icon-laptop.svelte b/app/src/lib/components/sidebar/icon-laptop.svelte new file mode 100644 index 0000000..11c333d --- /dev/null +++ b/app/src/lib/components/sidebar/icon-laptop.svelte @@ -0,0 +1,62 @@ + + + + + diff --git a/app/src/lib/components/sidebar/icon-layers.svelte b/app/src/lib/components/sidebar/icon-layers.svelte new file mode 100644 index 0000000..bea14bb --- /dev/null +++ b/app/src/lib/components/sidebar/icon-layers.svelte @@ -0,0 +1,72 @@ + + + + + diff --git a/app/src/lib/components/sidebar/icon-logs.svelte b/app/src/lib/components/sidebar/icon-logs.svelte new file mode 100644 index 0000000..8028720 --- /dev/null +++ b/app/src/lib/components/sidebar/icon-logs.svelte @@ -0,0 +1,124 @@ + + + + + diff --git a/app/src/lib/components/sidebar/icon-server.svelte b/app/src/lib/components/sidebar/icon-server.svelte new file mode 100644 index 0000000..13abaa8 --- /dev/null +++ b/app/src/lib/components/sidebar/icon-server.svelte @@ -0,0 +1,63 @@ + + + + + diff --git a/app/src/lib/components/sidebar/icon-ship-wheel.svelte b/app/src/lib/components/sidebar/icon-ship-wheel.svelte new file mode 100644 index 0000000..60ceee1 --- /dev/null +++ b/app/src/lib/components/sidebar/icon-ship-wheel.svelte @@ -0,0 +1,59 @@ + + + + + diff --git a/app/src/routes/(app)/+layout.svelte b/app/src/routes/(app)/+layout.svelte index 0f57dcb..c20aa38 100644 --- a/app/src/routes/(app)/+layout.svelte +++ b/app/src/routes/(app)/+layout.svelte @@ -15,7 +15,8 @@ return; } try { - await validateSession(auth.token); + const profile = await validateSession(auth.token); + auth.setUser(profile); } catch { auth.clearSession(); goto("/login"); diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 2209c34..966759d 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -90,6 +90,12 @@ services: - ./control-plane/api-gateway:/app/control-plane/api-gateway - cargo_target_api_gateway:/app/target command: cargo watch -x "run -p api-gateway" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/api/system/health"] + interval: 10s + timeout: 5s + retries: 10 + start_period: 60s registry: <<: *rust-service @@ -98,6 +104,7 @@ services: DATABASE_URL: postgres://${POSTGRES_USER:-csfx_user}:${POSTGRES_PASSWORD:-csfx_password}@postgres:5432/${POSTGRES_DB:-csfx_core} ETCD_ENDPOINTS: http://etcd:2379 REGISTRY_PORT: "8001" + LISTEN_ADDR: "0.0.0.0" RUST_LOG: ${RUST_LOG:-debug} SCHEDULER_SERVICE_URL: http://scheduler:8002 ports: @@ -126,6 +133,7 @@ services: DATABASE_URL: postgres://${POSTGRES_USER:-csfx_user}:${POSTGRES_PASSWORD:-csfx_password}@postgres:5432/${POSTGRES_DB:-csfx_core} ETCD_ENDPOINTS: http://etcd:2379 SCHEDULER_PORT: "8002" + LISTEN_ADDR: "0.0.0.0" RUST_LOG: ${RUST_LOG:-debug} ports: - "8002:8002" @@ -148,6 +156,7 @@ services: DATABASE_URL: postgres://${POSTGRES_USER:-csfx_user}:${POSTGRES_PASSWORD:-csfx_password}@postgres:5432/${POSTGRES_DB:-csfx_core} ETCD_ENDPOINTS: http://etcd:2379 VOLUME_MANAGER_PORT: "8003" + LISTEN_ADDR: "0.0.0.0" RUST_LOG: ${RUST_LOG:-debug} ports: - "8003:8003" @@ -169,6 +178,7 @@ services: environment: DATABASE_URL: postgres://${POSTGRES_USER:-csfx_user}:${POSTGRES_PASSWORD:-csfx_password}@postgres:5432/${POSTGRES_DB:-csfx_core} FAILOVER_CONTROLLER_PORT: "8004" + LISTEN_ADDR: "0.0.0.0" SCHEDULER_SERVICE_URL: http://scheduler:8002 VOLUME_MANAGER_URL: http://volume-manager:8003 RUST_LOG: ${RUST_LOG:-debug} @@ -193,6 +203,7 @@ services: DATABASE_URL: postgres://${POSTGRES_USER:-csfx_user}:${POSTGRES_PASSWORD:-csfx_password}@postgres:5432/${POSTGRES_DB:-csfx_core} ETCD_URL: http://etcd:2379 SDN_CONTROLLER_PORT: "8005" + LISTEN_ADDR: "0.0.0.0" RUST_LOG: ${RUST_LOG:-debug} ports: - "8005:8005" @@ -213,6 +224,66 @@ services: timeout: 10s retries: 3 + agent-1: + <<: *rust-service + container_name: csfx-agent-dev-1 + hostname: dev-node-1 + environment: + CSFX_GATEWAY_URL: http://api-gateway:8000 + CSFX_HEARTBEAT_INTERVAL: "15" + RUST_LOG: ${RUST_LOG:-debug} + depends_on: + api-gateway: + condition: service_healthy + registry: + condition: service_healthy + volumes: + - ./agent:/app/agent + - ./control-plane/shared:/app/control-plane/shared + - cargo_target_agent:/app/target + - agent_state_1:/var/lib/csfx-agent + command: cargo run -p csfx-agent + + agent-2: + <<: *rust-service + container_name: csfx-agent-dev-2 + hostname: dev-node-2 + environment: + CSFX_GATEWAY_URL: http://api-gateway:8000 + CSFX_HEARTBEAT_INTERVAL: "15" + RUST_LOG: ${RUST_LOG:-debug} + depends_on: + api-gateway: + condition: service_healthy + registry: + condition: service_healthy + volumes: + - ./agent:/app/agent + - ./control-plane/shared:/app/control-plane/shared + - cargo_target_agent:/app/target + - agent_state_2:/var/lib/csfx-agent + command: cargo run -p csfx-agent + + agent-3: + <<: *rust-service + container_name: csfx-agent-dev-3 + hostname: dev-node-3 + environment: + CSFX_GATEWAY_URL: http://api-gateway:8000 + CSFX_HEARTBEAT_INTERVAL: "15" + RUST_LOG: ${RUST_LOG:-debug} + depends_on: + api-gateway: + condition: service_healthy + registry: + condition: service_healthy + volumes: + - ./agent:/app/agent + - ./control-plane/shared:/app/control-plane/shared + - cargo_target_agent:/app/target + - agent_state_3:/var/lib/csfx-agent + command: cargo run -p csfx-agent + app: build: context: ./app @@ -242,6 +313,10 @@ volumes: cargo_target_volume_manager: cargo_target_failover_controller: cargo_target_sdn_controller: + cargo_target_agent: + agent_state_1: + agent_state_2: + agent_state_3: networks: csfx-network: From 07fc8b64e678167627d8fd82dc498ee7f0ec11c3 Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Tue, 2 Jun 2026 23:08:31 +0200 Subject: [PATCH 07/12] style: added sidebar in nodes --- app/src/lib/api/nodes.ts | 39 +++ .../components/nodes/NodeDetailSheet.svelte | 275 ++++++++++++++++++ app/src/routes/(app)/nodes/+page.svelte | 20 +- 3 files changed, 333 insertions(+), 1 deletion(-) create mode 100644 app/src/lib/components/nodes/NodeDetailSheet.svelte diff --git a/app/src/lib/api/nodes.ts b/app/src/lib/api/nodes.ts index 6cdfb24..b3470aa 100644 --- a/app/src/lib/api/nodes.ts +++ b/app/src/lib/api/nodes.ts @@ -25,6 +25,29 @@ export interface NodeMetrics { disk_used_bytes: number | null; } +export interface NodeMetricsLatest { + id: string; + agent_id: string; + timestamp: string; + cpu_model: string | null; + cpu_cores: number | null; + cpu_threads: number | null; + cpu_usage_percent: number | null; + memory_total_bytes: number | null; + memory_used_bytes: number | null; + memory_usage_percent: number | null; + disk_total_bytes: number | null; + disk_used_bytes: number | null; + disk_usage_percent: number | null; + network_rx_bytes: number | null; + network_tx_bytes: number | null; + os_name: string | null; + os_version: string | null; + kernel_version: string | null; + hostname: string | null; + uptime_seconds: number | null; +} + export interface ClusterStats { node_count: number; online_count: number; @@ -52,3 +75,19 @@ export async function getClusterStats(token: string): Promise { if (!res.ok) throw new Error(`system/stats fetch failed: ${res.status}`); return res.json(); } + +export async function getNode(token: string, id: string): Promise { + const res = await fetch(`${API_BASE}/agents/${id}`, { + headers: { Authorization: `Bearer ${token}` }, + }); + if (!res.ok) throw new Error(`agent fetch failed: ${res.status}`); + return res.json(); +} + +export async function getNodeMetricsLatest(token: string, id: string): Promise { + const res = await fetch(`${API_BASE}/agents/${id}/metrics/latest`, { + headers: { Authorization: `Bearer ${token}` }, + }); + if (!res.ok) throw new Error(`metrics fetch failed: ${res.status}`); + return res.json(); +} diff --git a/app/src/lib/components/nodes/NodeDetailSheet.svelte b/app/src/lib/components/nodes/NodeDetailSheet.svelte new file mode 100644 index 0000000..3f40e4d --- /dev/null +++ b/app/src/lib/components/nodes/NodeDetailSheet.svelte @@ -0,0 +1,275 @@ + + + { if (!v) onClose(); }} +> + + {#if node} + +
    +
    + {node.hostname} + {node.ip_address ?? 'no ip'} +
    + {node.status} +
    + +
    + + +
    +
    + +
    + {#if activeTab === 'overview'} +
    +
    +

    Node Info

    +
    + ID + {node.id} + OS + {node.os_type} {node.os_version} + Arch + {node.architecture} + Agent + {node.agent_version} + Registered + {node.registered_at.slice(0, 16)} + Last heartbeat + {node.last_heartbeat ? node.last_heartbeat.slice(0, 16) : 'never'} +
    +
    + +
    + +
    +

    Live Metrics

    + + {#if metricsLoading} +

    Loading...

    + {:else if metricsError} +

    {metricsError}

    + {:else if metrics} +
    + {#if metrics.uptime_seconds != null} +
    +
    + Uptime + {formatUptime(metrics.uptime_seconds)} +
    +
    + {/if} + +
    +
    + CPU{metrics.cpu_model ? ` — ${metrics.cpu_model}` : ''} + {pct(metrics.cpu_usage_percent)} +
    + {#if metrics.cpu_usage_percent != null} +
    +
    +
    + {/if} + {#if metrics.cpu_cores != null} + {metrics.cpu_cores} cores / {metrics.cpu_threads ?? '?'} threads + {/if} +
    + +
    +
    + Memory + {bytesToGb(metrics.memory_used_bytes)} / {bytesToGb(metrics.memory_total_bytes)} +
    + {#if metrics.memory_usage_percent != null} +
    +
    +
    + {/if} +
    + +
    +
    + Disk + {bytesToGb(metrics.disk_used_bytes)} / {bytesToGb(metrics.disk_total_bytes)} +
    + {#if metrics.disk_usage_percent != null} +
    +
    +
    + {/if} +
    + + {#if metrics.network_rx_bytes != null || metrics.network_tx_bytes != null} +
    + Network +
    + RX {bytesToMb(metrics.network_rx_bytes)} + TX {bytesToMb(metrics.network_tx_bytes)} +
    +
    + {/if} + + {#if metrics.kernel_version} +
    + Kernel + {metrics.kernel_version} +
    + {/if} +
    + {/if} +
    +
    + + {:else if activeTab === 'actions'} +
    +
    +

    SSH Access

    +
    + {#if node.ip_address} +
    + ssh root@{node.ip_address} +
    +
    + + +
    + {:else} +

    No IP address available

    + {/if} +
    +
    + +
    + +
    +

    Power Management

    +
    + + + +

    Power management requires agent support

    +
    +
    +
    + {/if} +
    + {/if} +
    +
    diff --git a/app/src/routes/(app)/nodes/+page.svelte b/app/src/routes/(app)/nodes/+page.svelte index a16246d..0303358 100644 --- a/app/src/routes/(app)/nodes/+page.svelte +++ b/app/src/routes/(app)/nodes/+page.svelte @@ -3,11 +3,14 @@ import { auth } from "$lib/auth/store.svelte"; import { listNodes, getClusterStats, type Node, type ClusterStats } from "$lib/api/nodes"; import * as Sidebar from "$lib/components/ui/sidebar/index.js"; + import NodeDetailSheet from "$lib/components/nodes/NodeDetailSheet.svelte"; let nodes = $state([]); let stats = $state(null); let loading = $state(true); let error = $state(null); + let selectedNode = $state(null); + let sheetOpen = $state(false); onMount(async () => { if (!auth.token) return; @@ -23,6 +26,16 @@ } }); + function openNode(node: Node) { + selectedNode = node; + sheetOpen = true; + } + + function closeSheet() { + sheetOpen = false; + selectedNode = null; + } + function bytesToGb(bytes: number | null): string { if (bytes == null) return "-"; return (bytes / 1_073_741_824).toFixed(1) + "G"; @@ -95,7 +108,10 @@ {:else} {#each nodes as node (node.id)} - + openNode(node)} + > {node.id.slice(0, 8)} {node.hostname} {node.ip_address ?? "-"} @@ -115,3 +131,5 @@
    + + From f633d185a279d63b014027f8cdee48a5ddbf2ec1 Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Wed, 3 Jun 2026 19:46:45 +0200 Subject: [PATCH 08/12] style: revert icon changes --- .../lib/components/sidebar/app-sidebar.svelte | 18 ++-- .../components/sidebar/icon-container.svelte | 84 ------------------- .../lib/components/sidebar/icon-laptop.svelte | 62 -------------- .../lib/components/sidebar/icon-layers.svelte | 72 ---------------- .../lib/components/sidebar/icon-server.svelte | 63 -------------- .../components/sidebar/icon-ship-wheel.svelte | 59 ------------- 6 files changed, 7 insertions(+), 351 deletions(-) delete mode 100644 app/src/lib/components/sidebar/icon-container.svelte delete mode 100644 app/src/lib/components/sidebar/icon-laptop.svelte delete mode 100644 app/src/lib/components/sidebar/icon-layers.svelte delete mode 100644 app/src/lib/components/sidebar/icon-server.svelte delete mode 100644 app/src/lib/components/sidebar/icon-ship-wheel.svelte diff --git a/app/src/lib/components/sidebar/app-sidebar.svelte b/app/src/lib/components/sidebar/app-sidebar.svelte index 7473538..3844484 100644 --- a/app/src/lib/components/sidebar/app-sidebar.svelte +++ b/app/src/lib/components/sidebar/app-sidebar.svelte @@ -3,15 +3,11 @@ import ChartPieIcon from "@lucide/svelte/icons/chart-pie"; import MapIcon from "@lucide/svelte/icons/map"; import BookOpenIcon from "@lucide/svelte/icons/book-open"; + import { Server, Layers, ShipWheel, Container, LaptopMinimal } from "@lucide/svelte"; import IconBucket from "./icon-bucket.svelte"; + import IconDashboard from "./icon-dashboard.svelte"; import IconActivity from "./icon-activity.svelte"; import IconLogs from "./icon-logs.svelte"; - import IconDashboard from "./icon-dashboard.svelte"; - import IconServer from "./icon-server.svelte"; - import IconLayers from "./icon-layers.svelte"; - import IconShipWheel from "./icon-ship-wheel.svelte"; - import IconContainer from "./icon-container.svelte"; - import IconLaptop from "./icon-laptop.svelte"; const data = { navBottom: [ @@ -36,12 +32,12 @@ { title: "Nodes", url: "/nodes", - icon: IconServer, + icon: Server, }, { title: "Resource groups", url: "#", - icon: IconLayers, + icon: Layers, }, ], projects: [ @@ -53,17 +49,17 @@ { name: "Kubernetes", url: "#", - icon: IconShipWheel, + icon: ShipWheel, }, { name: "Docker", url: "#", - icon: IconContainer, + icon: Container, }, { name: "Virtual Machines", url: "#", - icon: IconLaptop, + icon: LaptopMinimal, }, ], }; diff --git a/app/src/lib/components/sidebar/icon-container.svelte b/app/src/lib/components/sidebar/icon-container.svelte deleted file mode 100644 index 02945af..0000000 --- a/app/src/lib/components/sidebar/icon-container.svelte +++ /dev/null @@ -1,84 +0,0 @@ - - - - - diff --git a/app/src/lib/components/sidebar/icon-laptop.svelte b/app/src/lib/components/sidebar/icon-laptop.svelte deleted file mode 100644 index 11c333d..0000000 --- a/app/src/lib/components/sidebar/icon-laptop.svelte +++ /dev/null @@ -1,62 +0,0 @@ - - - - - diff --git a/app/src/lib/components/sidebar/icon-layers.svelte b/app/src/lib/components/sidebar/icon-layers.svelte deleted file mode 100644 index bea14bb..0000000 --- a/app/src/lib/components/sidebar/icon-layers.svelte +++ /dev/null @@ -1,72 +0,0 @@ - - - - - diff --git a/app/src/lib/components/sidebar/icon-server.svelte b/app/src/lib/components/sidebar/icon-server.svelte deleted file mode 100644 index 13abaa8..0000000 --- a/app/src/lib/components/sidebar/icon-server.svelte +++ /dev/null @@ -1,63 +0,0 @@ - - - - - diff --git a/app/src/lib/components/sidebar/icon-ship-wheel.svelte b/app/src/lib/components/sidebar/icon-ship-wheel.svelte deleted file mode 100644 index 60ceee1..0000000 --- a/app/src/lib/components/sidebar/icon-ship-wheel.svelte +++ /dev/null @@ -1,59 +0,0 @@ - - - - - From 779bb167c8968dfaa22175f93daa94c9c76ff79b Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Wed, 3 Jun 2026 19:56:24 +0200 Subject: [PATCH 09/12] style: added refresh buttons and nodes managment overview with small graphs --- app/src/routes/(app)/nodes/+page.svelte | 211 ++++++++++++++++++++++-- 1 file changed, 196 insertions(+), 15 deletions(-) diff --git a/app/src/routes/(app)/nodes/+page.svelte b/app/src/routes/(app)/nodes/+page.svelte index 0303358..00fe0a5 100644 --- a/app/src/routes/(app)/nodes/+page.svelte +++ b/app/src/routes/(app)/nodes/+page.svelte @@ -1,8 +1,9 @@
    @@ -58,23 +130,132 @@
    +
    +
    +

    Nodes

    +

    Manage and monitor your cluster nodes

    +
    +
    + + + +
    +
    + {#if stats}
    -

    Nodes

    -

    {stats.online_count} / {stats.node_count}

    +

    Total Nodes

    +

    {stats.node_count}

    -
    -

    CPU Cores

    -

    {stats.total_cpu_cores}

    + +
    +

    Healthy

    +
    +
    + +

    {stats.online_count}

    +
    + {#if onlineHistory.length >= 2} + + + + {/if} +
    -
    -

    Memory

    -

    {bytesToGb(stats.used_memory_bytes)} / {bytesToGb(stats.total_memory_bytes)}

    + +
    +

    vCPU Capacity

    +
    +
    +

    {stats.total_cpu_cores}

    +

    {cpuPct().toFixed(1)}% used

    +
    + {#if cpuHistory.length >= 2} + + + + {/if} +
    -
    -

    Disk

    -

    {bytesToGb(stats.used_disk_bytes)} / {bytesToGb(stats.total_disk_bytes)}

    + +
    +

    Memory

    +
    +
    +

    {bytesToGb(stats.used_memory_bytes)}

    +

    / {bytesToGb(stats.total_memory_bytes)}

    +
    + {#if memHistory.length >= 2} + + + + {/if} +
    {/if} From 353f803e93d9ac069778e6263c96b312f61fb753 Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Wed, 3 Jun 2026 20:48:15 +0200 Subject: [PATCH 10/12] fix: nodes offline check --- app/src/routes/(app)/nodes/+page.svelte | 2 +- .../api-gateway/src/routes/system.rs | 5 ++++- control-plane/registry/src/db/agents.rs | 20 ++++++++++++++++++- control-plane/registry/src/main.rs | 4 ++-- .../registry/src/services/registry.rs | 7 +++++-- docker-compose.dev.yml | 2 ++ 6 files changed, 33 insertions(+), 7 deletions(-) diff --git a/app/src/routes/(app)/nodes/+page.svelte b/app/src/routes/(app)/nodes/+page.svelte index 00fe0a5..a351be7 100644 --- a/app/src/routes/(app)/nodes/+page.svelte +++ b/app/src/routes/(app)/nodes/+page.svelte @@ -69,7 +69,7 @@ } finally { loading = false; } - pollInterval = setInterval(fetchStats, 30_000); + pollInterval = setInterval(fetchStats, 10_000); }); onDestroy(() => { diff --git a/control-plane/api-gateway/src/routes/system.rs b/control-plane/api-gateway/src/routes/system.rs index 8e39fd3..1f1df3e 100644 --- a/control-plane/api-gateway/src/routes/system.rs +++ b/control-plane/api-gateway/src/routes/system.rs @@ -52,6 +52,9 @@ pub struct ClusterStats { } fn is_container_id(hostname: &str) -> bool { + if std::env::var("CSFX_INCLUDE_CONTAINERS").as_deref() == Ok("true") { + return false; + } let trimmed = hostname.trim(); trimmed.len() == 12 && trimmed.chars().all(|c| c.is_ascii_hexdigit()) @@ -128,7 +131,7 @@ async fn get_cluster_stats( let mut online_count: usize = 0; for agent in &physical_agents { - if agent.status == "online" { + if agent.status.eq_ignore_ascii_case("online") { online_count += 1; } diff --git a/control-plane/registry/src/db/agents.rs b/control-plane/registry/src/db/agents.rs index f9b8dd4..c6b16ed 100644 --- a/control-plane/registry/src/db/agents.rs +++ b/control-plane/registry/src/db/agents.rs @@ -112,6 +112,21 @@ pub async fn update_heartbeat( Ok(()) } +pub async fn mark_degraded_by_timeout( + db: &DatabaseConnection, + timeout_seconds: i64, +) -> Result { + let threshold = chrono::Utc::now().naive_utc() - chrono::Duration::seconds(timeout_seconds); + let result = agents::Entity::update_many() + .col_expr(agents::Column::Status, sea_orm::sea_query::Expr::value("Degraded")) + .col_expr(agents::Column::UpdatedAt, sea_orm::sea_query::Expr::value(chrono::Utc::now().naive_utc())) + .filter(agents::Column::LastHeartbeat.lt(threshold)) + .filter(agents::Column::Status.eq("Online")) + .exec(db) + .await?; + Ok(result.rows_affected) +} + pub async fn mark_offline_by_timeout( db: &DatabaseConnection, timeout_seconds: i64, @@ -129,7 +144,10 @@ pub async fn mark_offline_by_timeout( sea_orm::sea_query::Expr::value(chrono::Utc::now().naive_utc()), ) .filter(agents::Column::LastHeartbeat.lt(threshold)) - .filter(agents::Column::Status.eq("Online")) + .filter( + agents::Column::Status.eq("Online") + .or(agents::Column::Status.eq("Degraded")) + ) .exec(db) .await?; diff --git a/control-plane/registry/src/main.rs b/control-plane/registry/src/main.rs index 0ed4b33..bf52921 100644 --- a/control-plane/registry/src/main.rs +++ b/control-plane/registry/src/main.rs @@ -85,10 +85,10 @@ async fn main() -> anyhow::Result<()> { let health_check_handle = { let registry = agent_registry.clone(); tokio::spawn(async move { - let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(60)); + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(15)); loop { interval.tick().await; - registry.check_agent_health(300).await; + registry.check_agent_health(30, 60).await; } }) }; diff --git a/control-plane/registry/src/services/registry.rs b/control-plane/registry/src/services/registry.rs index 9b12bdc..fe2b01a 100644 --- a/control-plane/registry/src/services/registry.rs +++ b/control-plane/registry/src/services/registry.rs @@ -280,8 +280,11 @@ impl AgentRegistry { Ok(()) } - pub async fn check_agent_health(&self, timeout_seconds: i64) -> usize { - match crate::db::agents::mark_offline_by_timeout(&self.db, timeout_seconds).await { + pub async fn check_agent_health(&self, degraded_seconds: i64, offline_seconds: i64) -> usize { + if let Err(e) = crate::db::agents::mark_degraded_by_timeout(&self.db, degraded_seconds).await { + crate::log_error!("agent_registry", &format!("Failed to mark degraded: {}", e)); + } + match crate::db::agents::mark_offline_by_timeout(&self.db, offline_seconds).await { Ok(marked_offline) => { if marked_offline > 0 { crate::log_info!( diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 966759d..6117a95 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -79,6 +79,7 @@ services: FAILOVER_CONTROLLER_URL: http://failover-controller:8004 SDN_CONTROLLER_URL: http://sdn-controller:8005 FRONTEND_URL: http://localhost:5173 + CSFX_INCLUDE_CONTAINERS: "true" ports: - "8000:8000" depends_on: @@ -107,6 +108,7 @@ services: LISTEN_ADDR: "0.0.0.0" RUST_LOG: ${RUST_LOG:-debug} SCHEDULER_SERVICE_URL: http://scheduler:8002 + API_GATEWAY_URL: http://api-gateway:8000 ports: - "8001:8001" depends_on: From e896836927e6d9ef33a085c1763a91e2914492e2 Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Wed, 3 Jun 2026 21:05:04 +0200 Subject: [PATCH 11/12] style: refactor nodes stats sidebar --- .../components/nodes/NodeDetailSheet.svelte | 482 +++++++++++------- 1 file changed, 310 insertions(+), 172 deletions(-) diff --git a/app/src/lib/components/nodes/NodeDetailSheet.svelte b/app/src/lib/components/nodes/NodeDetailSheet.svelte index 3f40e4d..f9372c4 100644 --- a/app/src/lib/components/nodes/NodeDetailSheet.svelte +++ b/app/src/lib/components/nodes/NodeDetailSheet.svelte @@ -15,12 +15,12 @@ let metrics = $state(null); let metricsError = $state(null); let metricsLoading = $state(false); - let activeTab = $state<'overview' | 'actions'>('overview'); + let activeTab = $state<'summary' | 'hardware' | 'workloads' | 'network' | 'tasks'>('summary'); let sshCopied = $state(false); $effect(() => { if (node && open) { - activeTab = 'overview'; + activeTab = 'summary'; metrics = null; metricsError = null; loadMetrics(node.id); @@ -44,35 +44,68 @@ return (bytes / 1_073_741_824).toFixed(1) + ' GB'; } - function bytesToMb(bytes: number | null): string { - if (bytes == null) return '-'; - return (bytes / 1_048_576).toFixed(0) + ' MB/s'; - } - function formatUptime(seconds: number | null): string { if (seconds == null) return '-'; const d = Math.floor(seconds / 86400); const h = Math.floor((seconds % 86400) / 3600); const m = Math.floor((seconds % 3600) / 60); - if (d > 0) return `${d}d ${h}h ${m}m`; + if (d > 0) return `${d} days, ${h}h ${m}m`; if (h > 0) return `${h}h ${m}m`; return `${m}m`; } - function pct(value: number | null): string { + function clampPct(value: number | null): number { + if (value == null) return 0; + return Math.min(Math.max(value, 0), 100); + } + + function pctStr(value: number | null): string { if (value == null) return '-'; return value.toFixed(1) + '%'; } - function statusClass(status: string): string { + function memPct(): number | null { + if (!metrics?.memory_total_bytes || !metrics?.memory_used_bytes) return null; + return (metrics.memory_used_bytes / metrics.memory_total_bytes) * 100; + } + + function diskPct(): number | null { + if (!metrics?.disk_total_bytes || !metrics?.disk_used_bytes) return null; + return (metrics.disk_used_bytes / metrics.disk_total_bytes) * 100; + } + + function netPct(): number { + const rx = metrics?.network_rx_bytes ?? 0; + const tx = metrics?.network_tx_bytes ?? 0; + return Math.min(((rx + tx) / 1_073_741_824) * 100, 100); + } + + function statusDotClass(status: string): string { switch (status.toLowerCase()) { - case 'online': return 'text-green-500'; - case 'offline': return 'text-red-500'; - case 'degraded': return 'text-yellow-500'; - default: return 'text-muted-foreground'; + case 'online': return 'bg-green-500'; + case 'offline': return 'bg-red-500'; + case 'degraded': return 'bg-yellow-500'; + default: return 'bg-muted-foreground'; } } + function gaugeStrokeDasharray(value: number, radius: number): string { + const circumference = 2 * Math.PI * radius; + const filled = (value / 100) * circumference; + return `${filled.toFixed(1)} ${circumference.toFixed(1)}`; + } + + function gaugeColor(value: number): string { + if (value > 80) return '#ef4444'; + if (value > 60) return '#eab308'; + return 'currentColor'; + } + + function refreshedLabel(timestamp: string): string { + const diff = Math.floor((Date.now() - new Date(timestamp).getTime()) / 1000); + return diff < 60 ? `refreshed ${diff}s ago` : `refreshed ${Math.floor(diff / 60)}m ago`; + } + async function copySshCommand() { if (!node?.ip_address) return; await navigator.clipboard.writeText(`ssh root@${node.ip_address}`); @@ -80,193 +113,298 @@ setTimeout(() => { sshCopied = false; }, 2000); } - function openSsh() { - if (!node?.ip_address) return; - window.location.href = `ssh://root@${node.ip_address}`; - } + const tabs: { id: typeof activeTab; label: string }[] = [ + { id: 'summary', label: 'Summary' }, + { id: 'hardware', label: 'Hardware' }, + { id: 'workloads', label: 'Workloads' }, + { id: 'network', label: 'Network' }, + { id: 'tasks', label: 'Tasks' }, + ]; +{#snippet gaugeCard(value: number, label: string, detail: string)} +
    +
    + + + + + {value.toFixed(0)}% +
    +
    +

    {label}

    +

    {detail}

    +
    +
    +{/snippet} + { if (!v) onClose(); }} > - + {#if node} - -
    -
    + +
    +
    + + + + +
    +
    {node.hostname} - {node.ip_address ?? 'no ip'} + {node.ip_address ?? 'no ip'} +
    +
    + + {node.status.toLowerCase()}
    - {node.status}
    -
    - - +
    + + + + + +
    + +
    + {#each tabs as tab} + + {/each}
    -
    - {#if activeTab === 'overview'} -
    -
    -

    Node Info

    -
    - ID - {node.id} - OS - {node.os_type} {node.os_version} - Arch - {node.architecture} - Agent - {node.agent_version} - Registered - {node.registered_at.slice(0, 16)} - Last heartbeat - {node.last_heartbeat ? node.last_heartbeat.slice(0, 16) : 'never'} +
    + {#if activeTab === 'summary'} +
    +
    +
    + Live Load + {#if metricsLoading} + Loading... + {:else if metrics?.timestamp} + + {refreshedLabel(metrics.timestamp)} + + {/if}
    -
    - -
    - -
    -

    Live Metrics

    - {#if metricsLoading} -

    Loading...

    - {:else if metricsError} -

    {metricsError}

    - {:else if metrics} -
    - {#if metrics.uptime_seconds != null} -
    -
    - Uptime - {formatUptime(metrics.uptime_seconds)} -
    -
    + {#if metricsError} +

    {metricsError}

    + {:else} +
    + {#if true} + {@const cpuVal = clampPct(metrics?.cpu_usage_percent ?? null)} + {@const cpuDetail = metrics?.cpu_model ?? ((metrics?.cpu_cores ?? '-') + ' cores')} + {@render gaugeCard(cpuVal, 'CPU', cpuDetail)} {/if} - -
    -
    - CPU{metrics.cpu_model ? ` — ${metrics.cpu_model}` : ''} - {pct(metrics.cpu_usage_percent)} -
    - {#if metrics.cpu_usage_percent != null} -
    -
    -
    - {/if} - {#if metrics.cpu_cores != null} - {metrics.cpu_cores} cores / {metrics.cpu_threads ?? '?'} threads - {/if} -
    - -
    -
    - Memory - {bytesToGb(metrics.memory_used_bytes)} / {bytesToGb(metrics.memory_total_bytes)} -
    - {#if metrics.memory_usage_percent != null} -
    -
    -
    - {/if} -
    - -
    -
    - Disk - {bytesToGb(metrics.disk_used_bytes)} / {bytesToGb(metrics.disk_total_bytes)} -
    - {#if metrics.disk_usage_percent != null} -
    -
    -
    - {/if} -
    - - {#if metrics.network_rx_bytes != null || metrics.network_tx_bytes != null} -
    - Network -
    - RX {bytesToMb(metrics.network_rx_bytes)} - TX {bytesToMb(metrics.network_tx_bytes)} -
    -
    + {#if true} + {@const memVal = clampPct(memPct())} + {@const memDetail = bytesToGb(metrics?.memory_total_bytes ?? null)} + {@render gaugeCard(memVal, 'Memory', memDetail)} {/if} - - {#if metrics.kernel_version} -
    - Kernel - {metrics.kernel_version} -
    + {#if true} + {@const diskVal = clampPct(diskPct())} + {@const diskDetail = bytesToGb(metrics?.disk_total_bytes ?? null)} + {@render gaugeCard(diskVal, 'Disk', diskDetail)} + {/if} + {#if true} + {@const nv = netPct()} + {@const rx = metrics?.network_rx_bytes} + {@const netDetail = rx != null ? ((rx / 1_048_576).toFixed(1) + ' MB/s RX') : '-'} + {@render gaugeCard(nv, 'Network', netDetail)} {/if}
    {/if} -
    +
    + +
    + +
    + Host & Lifecycle +
    +
    + Hostname + {node.hostname} +
    +
    + IP address + {node.ip_address ?? '-'} +
    +
    + OS + {node.os_type} {node.os_version} +
    + {#if metrics?.kernel_version} +
    + Kernel + {metrics.kernel_version} +
    + {/if} +
    + Architecture + {node.architecture} +
    +
    + Agent version + {node.agent_version} +
    +
    + Uptime + {formatUptime(metrics?.uptime_seconds ?? null)} +
    +
    + Registered + {node.registered_at.slice(0, 16)} +
    +
    + Last heartbeat + {node.last_heartbeat ? node.last_heartbeat.slice(0, 16) : 'never'} +
    +
    +
    - {:else if activeTab === 'actions'} -
    -
    -

    SSH Access

    -
    - {#if node.ip_address} -
    - ssh root@{node.ip_address} + {:else if activeTab === 'hardware'} +
    + {#if metricsLoading} +

    Loading...

    + {:else if metrics} +
    + CPU +
    +
    + Model + {metrics.cpu_model ?? '-'}
    -
    - - +
    + Cores + {metrics.cpu_cores ?? '-'}
    - {:else} -

    No IP address available

    - {/if} +
    + Threads + {metrics.cpu_threads ?? '-'} +
    +
    + Usage + {pctStr(metrics.cpu_usage_percent)} +
    +
    -
    +
    + Memory +
    +
    + Total + {bytesToGb(metrics.memory_total_bytes)} +
    +
    + Used + {bytesToGb(metrics.memory_used_bytes)} +
    +
    + Usage + {pctStr(memPct())} +
    +
    +
    +
    + Storage +
    +
    + Total + {bytesToGb(metrics.disk_total_bytes)} +
    +
    + Used + {bytesToGb(metrics.disk_used_bytes)} +
    +
    + Usage + {pctStr(diskPct())} +
    +
    +
    + {:else} +

    {metricsError ?? 'No data'}

    + {/if} +
    -
    + {:else if activeTab === 'workloads'} +
    +

    Workload scheduling coming soon.

    +
    -
    -

    Power Management

    -
    - - - -

    Power management requires agent support

    + {:else if activeTab === 'network'} +
    + {#if metrics} +
    + Interface +
    +
    + IP address + {node?.ip_address ?? '-'} +
    +
    + RX + {metrics.network_rx_bytes != null ? (metrics.network_rx_bytes / 1_048_576).toFixed(2) + ' MB/s' : '-'} +
    +
    + TX + {metrics.network_tx_bytes != null ? (metrics.network_tx_bytes / 1_048_576).toFixed(2) + ' MB/s' : '-'} +
    +
    -
    + {:else} +

    {metricsError ?? 'No data'}

    + {/if} +
    + + {:else if activeTab === 'tasks'} +
    +

    No active tasks.

    {/if}
    From 4e73dc5aa8cf0dce4f5b952f190296cdc6a32d9d Mon Sep 17 00:00:00 2001 From: CodeMaster4711 Date: Wed, 3 Jun 2026 21:20:26 +0200 Subject: [PATCH 12/12] feat: added graph with histroy --- app/src/lib/api/nodes.ts | 13 ++ .../components/nodes/NodeDetailSheet.svelte | 124 +++++++++++++----- app/src/routes/(app)/nodes/+page.svelte | 42 +++++- .../api-gateway/src/routes/system.rs | 69 +++++++++- 4 files changed, 209 insertions(+), 39 deletions(-) diff --git a/app/src/lib/api/nodes.ts b/app/src/lib/api/nodes.ts index b3470aa..64b6bd2 100644 --- a/app/src/lib/api/nodes.ts +++ b/app/src/lib/api/nodes.ts @@ -91,3 +91,16 @@ export async function getNodeMetricsLatest(token: string, id: string): Promise { + const res = await fetch(`${API_BASE}/system/stats/history?range=${range}`, { + headers: { Authorization: `Bearer ${token}` }, + }); + if (!res.ok) throw new Error(`health history fetch failed: ${res.status}`); + return res.json(); +} diff --git a/app/src/lib/components/nodes/NodeDetailSheet.svelte b/app/src/lib/components/nodes/NodeDetailSheet.svelte index f9372c4..85f6d9e 100644 --- a/app/src/lib/components/nodes/NodeDetailSheet.svelte +++ b/app/src/lib/components/nodes/NodeDetailSheet.svelte @@ -65,19 +65,42 @@ } function memPct(): number | null { - if (!metrics?.memory_total_bytes || !metrics?.memory_used_bytes) return null; - return (metrics.memory_used_bytes / metrics.memory_total_bytes) * 100; + if (metrics?.memory_usage_percent != null) return metrics.memory_usage_percent; + if (metrics?.memory_total_bytes != null && metrics?.memory_used_bytes != null && metrics.memory_total_bytes > 0) { + return (metrics.memory_used_bytes / metrics.memory_total_bytes) * 100; + } + return null; } function diskPct(): number | null { - if (!metrics?.disk_total_bytes || !metrics?.disk_used_bytes) return null; - return (metrics.disk_used_bytes / metrics.disk_total_bytes) * 100; + if (metrics?.disk_usage_percent != null) return metrics.disk_usage_percent; + if (metrics?.disk_total_bytes != null && metrics?.disk_used_bytes != null && metrics.disk_total_bytes > 0) { + return (metrics.disk_used_bytes / metrics.disk_total_bytes) * 100; + } + return null; + } + + function netRxGb(): number { + return (metrics?.network_rx_bytes ?? 0) / 1_073_741_824; + } + + function netTxGb(): number { + return (metrics?.network_tx_bytes ?? 0) / 1_073_741_824; + } + + function netRxPct(): number { + return Math.min((netRxGb() / 100) * 100, 100); + } + + function netTxPct(): number { + return Math.min((netTxGb() / 100) * 100, 100); } - function netPct(): number { - const rx = metrics?.network_rx_bytes ?? 0; - const tx = metrics?.network_tx_bytes ?? 0; - return Math.min(((rx + tx) / 1_073_741_824) * 100, 100); + function formatBytes(bytes: number | null): string { + if (bytes == null) return '-'; + if (bytes >= 1_073_741_824) return (bytes / 1_073_741_824).toFixed(1) + ' GB'; + if (bytes >= 1_048_576) return (bytes / 1_048_576).toFixed(1) + ' MB'; + return (bytes / 1024).toFixed(1) + ' KB'; } function statusDotClass(status: string): string { @@ -89,10 +112,10 @@ } } - function gaugeStrokeDasharray(value: number, radius: number): string { + function gaugeArc(value: number, radius: number): { dasharray: string; circumference: number } { const circumference = 2 * Math.PI * radius; const filled = (value / 100) * circumference; - return `${filled.toFixed(1)} ${circumference.toFixed(1)}`; + return { dasharray: `${filled.toFixed(1)} ${circumference.toFixed(1)}`, circumference }; } function gaugeColor(value: number): string { @@ -123,26 +146,28 @@ {#snippet gaugeCard(value: number, label: string, detail: string)} -
    -
    - - - - - {value.toFixed(0)}% -
    -
    -

    {label}

    -

    {detail}

    + {#if true} + {@const arc = gaugeArc(value, 20)} +
    +
    + + + + + {value.toFixed(0)}% +
    +
    +

    {label}

    +

    {detail}

    +
    -
    + {/if} {/snippet} +
    + + + + + + +
    +
    +

    Network

    +

    + RX {formatBytes(metrics?.network_rx_bytes ?? null)} +

    +

    + TX {formatBytes(metrics?.network_tx_bytes ?? null)} +

    +
    +
    {/if}
    {/if} diff --git a/app/src/routes/(app)/nodes/+page.svelte b/app/src/routes/(app)/nodes/+page.svelte index a351be7..2f42973 100644 --- a/app/src/routes/(app)/nodes/+page.svelte +++ b/app/src/routes/(app)/nodes/+page.svelte @@ -1,7 +1,7 @@