From abac077541fd6de8bda7787a82374b6c60e41a2f Mon Sep 17 00:00:00 2001 From: Stan Runge Date: Fri, 25 Sep 2026 00:44:06 +0000 Subject: [PATCH] ui changes and cs prices --- bun.lock | 33 +- components.json | 8 +- package-lock.json | 814 ++++++------------ package.json | 9 + scripts/cs-prices-migration.sql | 45 + scripts/ingest-cs-prices.ts | 287 ++++++ scripts/migrate-cs-prices.ts | 13 + src/app.css | 116 ++- src/app.html | 12 +- src/lib/assets/experience/3webapps.webp | Bin 0 -> 9058 bytes src/lib/assets/experience/cargill.webp | Bin 0 -> 18910 bytes src/lib/assets/experience/finance-plus.webp | Bin 0 -> 8916 bytes src/lib/assets/experience/h5mag.webp | Bin 0 -> 10852 bytes .../experience/the-hague-university.webp | Bin 0 -> 12096 bytes src/lib/assets/projects/cs-prices.webp | Bin 0 -> 11190 bytes src/lib/assets/projects/osu-map-finder.webp | Bin 0 -> 26074 bytes src/lib/assets/projects/vash-esports.webp | Bin 0 -> 11780 bytes src/lib/components/AuthForm.svelte | 168 ++-- src/lib/components/CopyButton.svelte | 11 +- src/lib/components/ProgressBar.svelte | 32 +- src/lib/components/ProjectIcon.svelte | 54 ++ .../components/ui/alert/alert-action.svelte | 20 + .../ui/alert/alert-description.svelte | 23 + .../components/ui/alert/alert-title.svelte | 23 + src/lib/components/ui/alert/alert.svelte | 44 + src/lib/components/ui/alert/index.ts | 17 + src/lib/components/ui/badge/badge.svelte | 50 ++ src/lib/components/ui/badge/index.ts | 2 + src/lib/components/ui/button/button.svelte | 108 ++- src/lib/components/ui/button/index.ts | 53 +- src/lib/components/ui/card/card-action.svelte | 20 + .../components/ui/card/card-content.svelte | 20 + .../ui/card/card-description.svelte | 20 + src/lib/components/ui/card/card-footer.svelte | 23 + src/lib/components/ui/card/card-header.svelte | 23 + src/lib/components/ui/card/card-title.svelte | 23 + src/lib/components/ui/card/card.svelte | 25 + src/lib/components/ui/card/index.ts | 25 + .../components/ui/checkbox/checkbox.svelte | 39 + src/lib/components/ui/checkbox/index.ts | 6 + .../ui/command/command-dialog.svelte | 51 +- .../ui/command/command-empty.svelte | 19 +- .../ui/command/command-group.svelte | 29 +- .../ui/command/command-input.svelte | 47 +- .../components/ui/command/command-item.svelte | 29 +- .../ui/command/command-link-item.svelte | 20 + .../components/ui/command/command-list.svelte | 23 +- .../ui/command/command-loading.svelte | 7 + .../ui/command/command-separator.svelte | 17 +- .../ui/command/command-shortcut.svelte | 23 +- src/lib/components/ui/command/command.svelte | 30 +- src/lib/components/ui/command/index.ts | 12 +- .../components/ui/dialog/dialog-close.svelte | 11 + .../ui/dialog/dialog-content.svelte | 58 +- .../ui/dialog/dialog-description.svelte | 22 +- .../components/ui/dialog/dialog-footer.svelte | 32 +- .../components/ui/dialog/dialog-header.svelte | 21 +- .../ui/dialog/dialog-overlay.svelte | 25 +- .../components/ui/dialog/dialog-portal.svelte | 7 +- .../components/ui/dialog/dialog-title.svelte | 19 +- .../ui/dialog/dialog-trigger.svelte | 11 + src/lib/components/ui/dialog/dialog.svelte | 7 + src/lib/components/ui/dialog/index.ts | 17 +- .../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 | 23 + .../dropdown-menu-sub-content.svelte | 20 + .../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 + src/lib/components/ui/dropdown-menu/index.ts | 54 ++ src/lib/components/ui/input-group/index.ts | 22 + .../ui/input-group/input-group-addon.svelte | 53 ++ .../ui/input-group/input-group-button.svelte | 49 ++ .../ui/input-group/input-group-input.svelte | 23 + .../ui/input-group/input-group-text.svelte | 22 + .../input-group/input-group-textarea.svelte | 23 + .../ui/input-group/input-group.svelte | 24 + src/lib/components/ui/input/index.ts | 7 + src/lib/components/ui/input/input.svelte | 48 ++ src/lib/components/ui/label/index.ts | 7 + src/lib/components/ui/label/label.svelte | 20 + src/lib/components/ui/popover/index.ts | 21 +- .../ui/popover/popover-close.svelte | 7 + .../ui/popover/popover-content.svelte | 43 +- .../ui/popover/popover-description.svelte | 20 + .../ui/popover/popover-header.svelte | 20 + .../ui/popover/popover-portal.svelte | 7 + .../ui/popover/popover-title.svelte | 15 + .../ui/popover/popover-trigger.svelte | 17 + src/lib/components/ui/popover/popover.svelte | 7 + src/lib/components/ui/progress/index.ts | 7 + .../components/ui/progress/progress.svelte | 30 + src/lib/components/ui/select/index.ts | 40 + .../ui/select/select-content.svelte | 45 + .../ui/select/select-group-heading.svelte | 21 + .../components/ui/select/select-group.svelte | 17 + .../components/ui/select/select-item.svelte | 42 + .../components/ui/select/select-label.svelte | 20 + .../components/ui/select/select-portal.svelte | 7 + .../select/select-scroll-down-button.svelte | 23 + .../ui/select/select-scroll-up-button.svelte | 23 + .../ui/select/select-separator.svelte | 18 + .../ui/select/select-trigger.svelte | 29 + .../components/ui/select/select-value.svelte | 7 + src/lib/components/ui/select/select.svelte | 11 + src/lib/components/ui/separator/index.ts | 7 + .../components/ui/separator/separator.svelte | 21 + 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 | 20 + .../components/ui/sheet/sheet-portal.svelte | 7 + .../components/ui/sheet/sheet-title.svelte | 17 + .../components/ui/sheet/sheet-trigger.svelte | 7 + src/lib/components/ui/sheet/sheet.svelte | 7 + src/lib/components/ui/skeleton/index.ts | 7 + .../components/ui/skeleton/skeleton.svelte | 17 + src/lib/components/ui/table/index.ts | 2 +- src/lib/components/ui/table/table-body.svelte | 10 +- .../components/ui/table/table-caption.svelte | 10 +- src/lib/components/ui/table/table-cell.svelte | 6 +- .../components/ui/table/table-footer.svelte | 10 +- src/lib/components/ui/table/table-head.svelte | 6 +- .../components/ui/table/table-header.svelte | 10 +- src/lib/components/ui/table/table-row.svelte | 6 +- src/lib/components/ui/table/table.svelte | 12 +- src/lib/components/ui/tabs/index.ts | 18 + .../components/ui/tabs/tabs-content.svelte | 17 + src/lib/components/ui/tabs/tabs-list.svelte | 40 + .../components/ui/tabs/tabs-trigger.svelte | 23 + src/lib/components/ui/tabs/tabs.svelte | 19 + src/lib/components/ui/textarea/index.ts | 7 + .../components/ui/textarea/textarea.svelte | 22 + src/lib/cs-prices/PriceChart.svelte | 138 +++ src/lib/cs-prices/steam.test.ts | 12 + src/lib/cs-prices/steam.ts | 23 + src/lib/cs-prices/taxonomy.test.ts | 48 ++ src/lib/cs-prices/taxonomy.ts | 72 ++ src/lib/derby/data.ts | 111 ++- src/lib/derby/generic.ts | 37 +- src/lib/derby/model.test.ts | 5 +- src/lib/derby/model.ts | 27 +- src/lib/derby/practice.ts | 9 +- src/lib/derby/races.ts | 293 ++++++- src/lib/map-finder/MapCard.svelte | 8 +- src/lib/projects.ts | 6 + src/lib/seo.ts | 5 + src/lib/server/db/schema/cs-prices.ts | 81 ++ src/lib/server/db/schema/index.ts | 1 + src/lib/server/db/seed.ts | 7 +- src/lib/utils.ts | 6 + src/lib/world-opinions/CultureMap.svelte | 19 +- src/lib/world-opinions/PartyCompass.svelte | 8 +- src/routes/+layout.svelte | 291 ++++--- src/routes/+page.svelte | 191 ++-- src/routes/account/+page.svelte | 73 +- src/routes/blog/+page.svelte | 44 +- src/routes/blog/[slug]/edit/+page.svelte | 53 +- src/routes/lists/+page.svelte | 62 +- src/routes/projects/+page.svelte | 92 +- src/routes/projects/animaldex/+page.svelte | 73 +- .../projects/animaldex/admin/+page.server.ts | 2 +- .../projects/animaldex/admin/+page.svelte | 25 +- .../api/animals/[id]/moderate/+server.ts | 2 +- .../projects/animaldex/register/+page.svelte | 57 +- src/routes/projects/cs-prices/+page.server.ts | 26 + src/routes/projects/cs-prices/+page.svelte | 657 ++++++++++++++ .../projects/cs-prices/api/search/+server.ts | 24 + .../projects/cs-prices/api/series/+server.ts | 68 ++ src/routes/projects/derby/+page.svelte | 263 +++--- src/routes/projects/derby/[race]/+page.svelte | 219 +++-- src/routes/projects/game-tracker/+page.svelte | 122 +-- .../call-of-duty/[slug]/+page.svelte | 20 +- .../game-tracker/pokemon/+page.svelte | 27 +- .../pokemon/locations/+page.svelte | 39 +- .../locations/[id=integer]/+page.svelte | 26 +- .../projects/language-learner/+page.svelte | 94 +- .../projects/money-tracker/+page.svelte | 38 +- src/routes/projects/progress/+page.svelte | 200 ++--- .../projects/progress/[id]/+page.svelte | 280 +++--- .../projects/progress/create/+page.svelte | 29 +- .../projects/progress/topics/+page.svelte | 52 +- .../progress/topics/[id]/+page.svelte | 35 +- .../spotify-beatmap-finder/+page.svelte | 49 +- .../projects/world-opinions/+page.svelte | 15 +- tsconfig.json | 12 +- 200 files changed, 6236 insertions(+), 2311 deletions(-) create mode 100644 scripts/cs-prices-migration.sql create mode 100644 scripts/ingest-cs-prices.ts create mode 100644 scripts/migrate-cs-prices.ts create mode 100644 src/lib/assets/experience/3webapps.webp create mode 100644 src/lib/assets/experience/cargill.webp create mode 100644 src/lib/assets/experience/finance-plus.webp create mode 100644 src/lib/assets/experience/h5mag.webp create mode 100644 src/lib/assets/experience/the-hague-university.webp create mode 100644 src/lib/assets/projects/cs-prices.webp create mode 100644 src/lib/assets/projects/osu-map-finder.webp create mode 100644 src/lib/assets/projects/vash-esports.webp create mode 100644 src/lib/components/ProjectIcon.svelte create mode 100644 src/lib/components/ui/alert/alert-action.svelte create mode 100644 src/lib/components/ui/alert/alert-description.svelte create mode 100644 src/lib/components/ui/alert/alert-title.svelte create mode 100644 src/lib/components/ui/alert/alert.svelte create mode 100644 src/lib/components/ui/alert/index.ts create mode 100644 src/lib/components/ui/badge/badge.svelte create mode 100644 src/lib/components/ui/badge/index.ts create mode 100644 src/lib/components/ui/card/card-action.svelte create mode 100644 src/lib/components/ui/card/card-content.svelte create mode 100644 src/lib/components/ui/card/card-description.svelte create mode 100644 src/lib/components/ui/card/card-footer.svelte create mode 100644 src/lib/components/ui/card/card-header.svelte create mode 100644 src/lib/components/ui/card/card-title.svelte create mode 100644 src/lib/components/ui/card/card.svelte create mode 100644 src/lib/components/ui/card/index.ts create mode 100644 src/lib/components/ui/checkbox/checkbox.svelte create mode 100644 src/lib/components/ui/checkbox/index.ts create mode 100644 src/lib/components/ui/command/command-link-item.svelte create mode 100644 src/lib/components/ui/command/command-loading.svelte create mode 100644 src/lib/components/ui/dialog/dialog-close.svelte create mode 100644 src/lib/components/ui/dialog/dialog-trigger.svelte create mode 100644 src/lib/components/ui/dialog/dialog.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu.svelte create mode 100644 src/lib/components/ui/dropdown-menu/index.ts create mode 100644 src/lib/components/ui/input-group/index.ts create mode 100644 src/lib/components/ui/input-group/input-group-addon.svelte create mode 100644 src/lib/components/ui/input-group/input-group-button.svelte create mode 100644 src/lib/components/ui/input-group/input-group-input.svelte create mode 100644 src/lib/components/ui/input-group/input-group-text.svelte create mode 100644 src/lib/components/ui/input-group/input-group-textarea.svelte create mode 100644 src/lib/components/ui/input-group/input-group.svelte create mode 100644 src/lib/components/ui/input/index.ts create mode 100644 src/lib/components/ui/input/input.svelte create mode 100644 src/lib/components/ui/label/index.ts create mode 100644 src/lib/components/ui/label/label.svelte create mode 100644 src/lib/components/ui/popover/popover-close.svelte create mode 100644 src/lib/components/ui/popover/popover-description.svelte create mode 100644 src/lib/components/ui/popover/popover-header.svelte create mode 100644 src/lib/components/ui/popover/popover-portal.svelte create mode 100644 src/lib/components/ui/popover/popover-title.svelte create mode 100644 src/lib/components/ui/popover/popover-trigger.svelte create mode 100644 src/lib/components/ui/popover/popover.svelte create mode 100644 src/lib/components/ui/progress/index.ts create mode 100644 src/lib/components/ui/progress/progress.svelte create mode 100644 src/lib/components/ui/select/index.ts create mode 100644 src/lib/components/ui/select/select-content.svelte create mode 100644 src/lib/components/ui/select/select-group-heading.svelte create mode 100644 src/lib/components/ui/select/select-group.svelte create mode 100644 src/lib/components/ui/select/select-item.svelte create mode 100644 src/lib/components/ui/select/select-label.svelte create mode 100644 src/lib/components/ui/select/select-portal.svelte create mode 100644 src/lib/components/ui/select/select-scroll-down-button.svelte create mode 100644 src/lib/components/ui/select/select-scroll-up-button.svelte create mode 100644 src/lib/components/ui/select/select-separator.svelte create mode 100644 src/lib/components/ui/select/select-trigger.svelte create mode 100644 src/lib/components/ui/select/select-value.svelte create mode 100644 src/lib/components/ui/select/select.svelte create mode 100644 src/lib/components/ui/separator/index.ts create mode 100644 src/lib/components/ui/separator/separator.svelte create mode 100644 src/lib/components/ui/sheet/index.ts create mode 100644 src/lib/components/ui/sheet/sheet-close.svelte create mode 100644 src/lib/components/ui/sheet/sheet-content.svelte create mode 100644 src/lib/components/ui/sheet/sheet-description.svelte create mode 100644 src/lib/components/ui/sheet/sheet-footer.svelte create mode 100644 src/lib/components/ui/sheet/sheet-header.svelte create mode 100644 src/lib/components/ui/sheet/sheet-overlay.svelte create mode 100644 src/lib/components/ui/sheet/sheet-portal.svelte create mode 100644 src/lib/components/ui/sheet/sheet-title.svelte create mode 100644 src/lib/components/ui/sheet/sheet-trigger.svelte create mode 100644 src/lib/components/ui/sheet/sheet.svelte create mode 100644 src/lib/components/ui/skeleton/index.ts create mode 100644 src/lib/components/ui/skeleton/skeleton.svelte create mode 100644 src/lib/components/ui/tabs/index.ts create mode 100644 src/lib/components/ui/tabs/tabs-content.svelte create mode 100644 src/lib/components/ui/tabs/tabs-list.svelte create mode 100644 src/lib/components/ui/tabs/tabs-trigger.svelte create mode 100644 src/lib/components/ui/tabs/tabs.svelte create mode 100644 src/lib/components/ui/textarea/index.ts create mode 100644 src/lib/components/ui/textarea/textarea.svelte create mode 100644 src/lib/cs-prices/PriceChart.svelte create mode 100644 src/lib/cs-prices/steam.test.ts create mode 100644 src/lib/cs-prices/steam.ts create mode 100644 src/lib/cs-prices/taxonomy.test.ts create mode 100644 src/lib/cs-prices/taxonomy.ts create mode 100644 src/lib/server/db/schema/cs-prices.ts create mode 100644 src/routes/projects/cs-prices/+page.server.ts create mode 100644 src/routes/projects/cs-prices/+page.svelte create mode 100644 src/routes/projects/cs-prices/api/search/+server.ts create mode 100644 src/routes/projects/cs-prices/api/series/+server.ts diff --git a/bun.lock b/bun.lock index c602a0b..e3fc3dd 100644 --- a/bun.lock +++ b/bun.lock @@ -13,6 +13,7 @@ "ai": "^7.0.85", "d3-geo": "^3.1.1", "drizzle-orm": "^1.0.0-rc.4", + "echarts": "^6.1.0", "highlight.js": "^11.12.0", "marked": "^18.0.11", "marked-highlight": "^2.2.4", @@ -24,7 +25,10 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", + "@fontsource-variable/montserrat": "^5.3.0", "@iconify-json/simple-icons": "^1.2.94", + "@internationalized/date": "^3.12.0", + "@lucide/svelte": "^1.48.0", "@playwright/test": "^1.62.1", "@sveltejs/enhanced-img": "^0.11.0", "@sveltejs/kit": "^2.70.3", @@ -40,6 +44,7 @@ "bits-ui": "^2.19.0", "clsx": "^2.1.1", "cmdk-sv": "^0.0.19", + "cn": "^0.4.0", "drizzle-kit": "^1.0.0-rc.4", "eslint": "^10.9.1", "eslint-config-prettier": "^10.1.8", @@ -48,11 +53,13 @@ "lucide-svelte": "^1.0.1", "prettier": "3.9.6", "prettier-plugin-svelte": "^4.1.1", + "shadcn-svelte": "^1.7.0", "svelte": "^5.57.0", "svelte-check": "4.7.6", "tailwind-merge": "^3.6.0", "tailwind-variants": "^3.3.1", "tailwindcss": "^4.3.3", + "tw-animate-css": "^1.4.0", "typescript": "~6", "typescript-eslint": "8.68.0", "unplugin-icons": "^23.0.1", @@ -206,6 +213,8 @@ "@floating-ui/utils": ["@floating-ui/utils@0.2.12", "", {}, "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww=="], + "@fontsource-variable/montserrat": ["@fontsource-variable/montserrat@5.3.0", "", {}, "sha512-7PaZoxaxrWLAyrhO46v65An9LhUhfkTExWLhfbywYZCnZEgg/W1rEHnlNmZKjNZ3nJTVYyicqxlJt10z/26yTA=="], + "@humanfs/core": ["@humanfs/core@0.19.2", "", { "dependencies": { "@humanfs/types": "^0.15.0" } }, "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA=="], "@humanfs/node": ["@humanfs/node@0.16.8", "", { "dependencies": { "@humanfs/core": "^0.19.2", "@humanfs/types": "^0.15.0", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ=="], @@ -286,6 +295,8 @@ "@js-temporal/polyfill": ["@js-temporal/polyfill@0.5.1", "", { "dependencies": { "jsbi": "^4.3.0" } }, "sha512-hloP58zRVCRSpgDxmqCWJNlizAlUgJFqG2ypq79DCvyv9tHjRYMDOcPFjzfl/A1/YxDvRCZz8wvZvmapQnKwFQ=="], + "@lucide/svelte": ["@lucide/svelte@1.48.0", "", { "peerDependencies": { "svelte": "^5" } }, "sha512-bLimVDjehxu3fpu9XEUpqEkBk2sJAHAT2sVcLHhlM70EdNsXuj9ZnYENWv5xgw3+05h4i5TirAxTiTgnZZf8gw=="], + "@mapbox/jsonlint-lines-primitives": ["@mapbox/jsonlint-lines-primitives@2.0.3", "", {}, "sha512-0SElaV0uMxEnxzBhhX9WTuPyUeMsAN/SS0i16tjuba4/mio63MG9khjC1a0JAiPGXAwvwm4UfHJURCN7nyudQg=="], "@mapbox/point-geometry": ["@mapbox/point-geometry@1.1.0", "", {}, "sha512-YGcBz1cg4ATXDCM/71L9xveh4dynfGmcLDqufR+nQQy3fKwsAZsWd/x4621/6uJaeB9mwOHE6hPeDgXz9uViUQ=="], @@ -630,7 +641,9 @@ "cmdk-sv": ["cmdk-sv@0.0.19", "", { "dependencies": { "bits-ui": "^0.21.12", "nanoid": "^5.0.7" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.1" } }, "sha512-Vm6+/up5nQbwGmNw0uYFbXTrbpF460/FhMohTskzzszMtIR/u/78haucSmJWjjp9bW0wxpHXZWa6fk+Lj1tKnA=="], - "commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + "cn": ["cn@0.4.0", "", { "bin": { "cn": "bin/cn.mjs" } }, "sha512-qOAeUhPwPzBxx6jaeQdo646XIKliKHc2j1ZF7Ngb1o0pJZKH5gq8FkA0aVdUdPFUDXNXyUCXpCtoJISo6dhizg=="], + + "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], "commondir": ["commondir@1.0.1", "", {}, "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="], @@ -668,6 +681,8 @@ "earcut": ["earcut@3.2.3", "", {}, "sha512-vnS4AVwp1KHAF13i1vp1/2D5evWy3k5u/iW/B81QVsUZtV8cv2tU0b2VNFlqvh4kYwrFMDdjPCfAmfyJW9y14Q=="], + "echarts": ["echarts@6.1.0", "", { "dependencies": { "tslib": "2.3.0", "zrender": "6.1.0" } }, "sha512-q0yaFPggC9FUdsWH4blavRWFmxdrIodbkoKNAjJudAI6CA9gNPxHtV2RcZNEepZVlk4yvBYkOkbk6HIVpIyHZA=="], + "electron-to-chromium": ["electron-to-chromium@1.5.416", "", {}, "sha512-K6bvB2BjnNrugtIih6ewlbBI9DXa976jIdiIlRLHhBoEI9a4JaQjjHyF+A1IQI543aQYR4LnmOrT/K5fZj0aPA=="], "enhanced-resolve": ["enhanced-resolve@5.24.5", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A=="], @@ -876,6 +891,8 @@ "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], + "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], + "node-releases": ["node-releases@2.0.54", "", {}, "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ=="], "obug": ["obug@2.1.4", "", {}, "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA=="], @@ -974,6 +991,8 @@ "set-cookie-parser": ["set-cookie-parser@3.1.2", "", {}, "sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw=="], + "shadcn-svelte": ["shadcn-svelte@1.7.0", "", { "dependencies": { "cn": "^0.3.0", "commander": "^14.0.0", "node-fetch-native": "^1.6.4", "postcss": "^8.5.10" }, "peerDependencies": { "svelte": "^5.0.0" }, "bin": { "shadcn-svelte": "dist/index.mjs" } }, "sha512-AK3ZsYOL8PN/RxcEBCHGvQj2TrLfaaBsbw0QohyEb3nn/yPNDRC/+9iSjnTp/uKEe+tAi0tBxB/Yhzno0N7EEg=="], + "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "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" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], @@ -1032,6 +1051,8 @@ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="], + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], @@ -1084,6 +1105,8 @@ "zod": ["zod@4.5.4", "", {}, "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA=="], + "zrender": ["zrender@6.1.0", "", { "dependencies": { "tslib": "2.3.0" } }, "sha512-oEGMDB6pOP2S6OwRR4PdVv610zrjnA3Bh+JnSG12fYJlBKjtNAoEb5fSUoCOOINlH96I2fU38/A2UpRKs67xYQ=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@maplibre/vt-pbf/pbf": ["pbf@5.1.2", "", { "dependencies": { "resolve-protobuf-schema": "^2.1.0" }, "bin": "bin/pbf" }, "sha512-mnvGdvOrIvJOBGUEdGkrVXjN8E/VkIJCkf2eS1DH2yv82ORUlLttmDt0rWY38yYZmVwciZwBUvHM20qxBZf40w=="], @@ -1110,6 +1133,8 @@ "cmdk-sv/bits-ui": ["bits-ui@0.21.16", "", { "dependencies": { "@internationalized/date": "^3.5.1", "@melt-ui/svelte": "0.76.2", "nanoid": "^5.0.5" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.118" } }, "sha512-XFZ7/bK7j/K+5iktxX/ZpmoFHjYjpPzP5EOO/4bWiaFg5TG1iMcfjDhlBTQnJxD6BoVoHuqeZPHZvaTgF4Iv3Q=="], + "echarts/tslib": ["tslib@2.3.0", "", {}, "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="], + "eslint-plugin-compat/globals": ["globals@15.15.0", "", {}, "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg=="], "eslint-plugin-svelte/globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="], @@ -1128,6 +1153,8 @@ "rollup/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], + "shadcn-svelte/cn": ["cn@0.3.3", "", { "bin": { "cn": "bin/cn.mjs" } }, "sha512-OEiyJkSpYm2kOuNOKQ+c2wmzZRG8orrb9fnObtHTbCGNx/E9KLnGcmcocItOzREKk5KzQN5I2e3BUCj563KEpw=="], + "svelte-eslint-parser/eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], "svelte-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], @@ -1136,6 +1163,10 @@ "svelte-eslint-parser/postcss-selector-parser": ["postcss-selector-parser@7.1.5", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw=="], + "topojson-client/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + + "zrender/tslib": ["tslib@2.3.0", "", {}, "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="], + "@tailwindcss/node/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], "@tailwindcss/node/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], diff --git a/components.json b/components.json index 62c62c7..44fad99 100644 --- a/components.json +++ b/components.json @@ -2,7 +2,7 @@ "$schema": "https://shadcn-svelte.com/schema.json", "tailwind": { "css": "src/app.css", - "baseColor": "slate" + "baseColor": "neutral" }, "aliases": { "components": "$lib/components", @@ -12,5 +12,9 @@ "lib": "$lib" }, "typescript": true, - "registry": "https://tw3.shadcn-svelte.com/registry/default" + "registry": "https://shadcn-svelte.com/registry", + "style": "vega", + "iconLibrary": "lucide", + "menuColor": "default", + "menuAccent": "subtle" } diff --git a/package-lock.json b/package-lock.json index 460f1fe..ac50770 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "ai": "^7.0.85", "d3-geo": "^3.1.1", "drizzle-orm": "^1.0.0-rc.4", + "echarts": "^6.1.0", "highlight.js": "^11.12.0", "marked": "^18.0.11", "marked-highlight": "^2.2.4", @@ -27,7 +28,10 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", + "@fontsource-variable/montserrat": "^5.3.0", "@iconify-json/simple-icons": "^1.2.94", + "@internationalized/date": "^3.12.0", + "@lucide/svelte": "^1.48.0", "@playwright/test": "^1.62.1", "@sveltejs/enhanced-img": "^0.11.0", "@sveltejs/kit": "^2.70.3", @@ -43,6 +47,7 @@ "bits-ui": "^2.19.0", "clsx": "^2.1.1", "cmdk-sv": "^0.0.19", + "cn": "^0.4.0", "drizzle-kit": "^1.0.0-rc.4", "eslint": "^10.9.1", "eslint-config-prettier": "^10.1.8", @@ -51,11 +56,13 @@ "lucide-svelte": "^1.0.1", "prettier": "3.9.6", "prettier-plugin-svelte": "^4.1.1", + "shadcn-svelte": "^1.7.0", "svelte": "^5.57.0", "svelte-check": "4.7.6", "tailwind-merge": "^3.6.0", "tailwind-variants": "^3.3.1", "tailwindcss": "^4.3.3", + "tw-animate-css": "^1.4.0", "typescript": "~6", "typescript-eslint": "8.68.0", "unplugin-icons": "^23.0.1", @@ -626,452 +633,11 @@ "tslib": "^2.4.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", - "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", - "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", - "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", - "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", - "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", - "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", - "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", - "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", - "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", - "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", - "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", - "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", - "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", - "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", - "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", - "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", - "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", - "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", - "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", - "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", - "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", - "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", - "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", - "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", - "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", - "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "peer": true, - "engines": { - "node": ">=18" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "dev": true, "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -1090,6 +656,7 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1102,6 +669,7 @@ "version": "4.12.2", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -1111,6 +679,7 @@ "version": "0.23.5", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^3.0.5", @@ -1125,6 +694,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.7.0.tgz", "integrity": "sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/core": "^1.2.1" @@ -1137,6 +707,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" @@ -1170,6 +741,7 @@ "version": "3.0.5", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, "license": "Apache-2.0", "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" @@ -1179,6 +751,7 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/core": "^1.2.1", @@ -1216,10 +789,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@fontsource-variable/montserrat": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource-variable/montserrat/-/montserrat-5.3.0.tgz", + "integrity": "sha512-7PaZoxaxrWLAyrhO46v65An9LhUhfkTExWLhfbywYZCnZEgg/W1rEHnlNmZKjNZ3nJTVYyicqxlJt10z/26yTA==", + "dev": true, + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@humanfs/core": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@humanfs/types": "^0.15.0" @@ -1232,6 +816,7 @@ "version": "0.16.8", "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@humanfs/core": "^0.19.2", @@ -1246,6 +831,7 @@ "version": "0.15.0", "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18.0" @@ -1255,6 +841,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=12.22" @@ -1268,6 +855,7 @@ "version": "0.4.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18" @@ -1810,6 +1398,7 @@ "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==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -1820,6 +1409,7 @@ "version": "2.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -1830,6 +1420,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1845,6 +1436,7 @@ "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1864,6 +1456,16 @@ "node": ">=12" } }, + "node_modules/@lucide/svelte": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-1.48.0.tgz", + "integrity": "sha512-bLimVDjehxu3fpu9XEUpqEkBk2sJAHAT2sVcLHhlM70EdNsXuj9ZnYENWv5xgw3+05h4i5TirAxTiTgnZZf8gw==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "svelte": "^5" + } + }, "node_modules/@mapbox/jsonlint-lines-primitives": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.3.tgz", @@ -2058,6 +1660,7 @@ "version": "0.147.0", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.147.0.tgz", "integrity": "sha512-IJ3s6ltHLp45S0bh7phkX+gJO7A1Wuz2EaqpAhb8WjqDwbzMiWKHhyyT42tskaWjEYXtHtVCPpnBJVT9+dcRLg==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" @@ -2083,6 +1686,7 @@ "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-arm-eabi": { @@ -2092,6 +1696,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2108,6 +1713,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2124,6 +1730,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2140,6 +1747,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2156,6 +1764,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2172,6 +1781,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2188,6 +1798,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2204,6 +1815,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2220,6 +1832,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2236,6 +1849,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2252,6 +1866,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2268,6 +1883,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2284,6 +1900,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2300,6 +1917,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2316,6 +1934,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2329,6 +1948,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, "license": "MIT" }, "node_modules/@rollup/plugin-commonjs": { @@ -2860,6 +2480,7 @@ "version": "1.0.13", "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.13.tgz", "integrity": "sha512-wgKggnhZVL9Bfx1OaKKTrYY9BFRk6C8UAkQNUcIv1+llzYrIqy+RZm5HPKzn0NpEBvTVhTqB4kQyllZywsRBRQ==", + "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^8.9.0" @@ -2904,6 +2525,7 @@ "version": "2.70.3", "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.70.3.tgz", "integrity": "sha512-UDvEYuZqAMbfB/oXIoqKvbKcb7YczK5zYrzmsGV1zRJk03jntwp8dXiYoIJotxAndsKvcPFtx9H1GRSKFdSHgg==", + "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", @@ -2955,6 +2577,7 @@ "version": "7.3.0", "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-7.3.0.tgz", "integrity": "sha512-QbRoJyD92e9R0ufeQIWRHrCC0ObcqSv/aBDdrQMoU+sypav3cDx5wytdQ6GLdXjEMO6xjrXGzfkUygng8JMv0A==", + "dev": true, "license": "MIT", "dependencies": { "deepmerge": "^4.3.1", @@ -2974,6 +2597,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.2.3.tgz", "integrity": "sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -3369,6 +2993,7 @@ "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/d3-geo": { @@ -3403,6 +3028,7 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, "license": "MIT" }, "node_modules/@types/estree": { @@ -3421,13 +3047,14 @@ "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" }, "node_modules/@types/node": { "version": "26.4.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz", "integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "undici-types": "~8.3.0" @@ -3437,7 +3064,7 @@ "version": "8.23.1", "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.23.1.tgz", "integrity": "sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -3622,7 +3249,7 @@ "version": "8.68.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.68.0.tgz", "integrity": "sha512-9RnpsGJjrAllCMefGVVsImJM24YurhC0Q1h4UbvivtvOqXmR/vEJge2OoE++z9m6hyg8T1Q8t5SNT6tHSbrxcg==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4220,6 +3847,7 @@ "version": "8.18.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -4232,6 +3860,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -4258,6 +3887,7 @@ "version": "6.15.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -4274,6 +3904,7 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">= 0.4" @@ -4308,6 +3939,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">= 0.4" @@ -4317,6 +3949,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, "license": "MIT", "engines": { "node": "18 || 20 || >=22" @@ -4506,6 +4139,7 @@ "version": "5.0.9", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -4651,6 +4285,19 @@ "svelte": ">=3 <5" } }, + "node_modules/cn": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cn/-/cn-0.4.0.tgz", + "integrity": "sha512-qOAeUhPwPzBxx6jaeQdo646XIKliKHc2j1ZF7Ngb1o0pJZKH5gq8FkA0aVdUdPFUDXNXyUCXpCtoJISo6dhizg==", + "dev": true, + "license": "MIT", + "bin": { + "cn": "bin/cn.mjs" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -4681,6 +4328,7 @@ "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" @@ -4690,6 +4338,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -4741,6 +4390,7 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -4758,6 +4408,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, "license": "MIT" }, "node_modules/deepmerge": { @@ -4790,6 +4441,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -4799,6 +4451,7 @@ "version": "5.9.2", "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.2.tgz", "integrity": "sha512-po4PAY5c53tw5XMocSnf8A/5OHhbbUftpr93aEN6BBoAdntUmK7vu7wOATqvt7cXO7m1Cl4gMVn6p7n6n4mj0w==", + "dev": true, "license": "MIT" }, "node_modules/drizzle-kit": { @@ -5510,6 +5163,22 @@ "integrity": "sha512-vnS4AVwp1KHAF13i1vp1/2D5evWy3k5u/iW/B81QVsUZtV8cv2tU0b2VNFlqvh4kYwrFMDdjPCfAmfyJW9y14Q==", "license": "ISC" }, + "node_modules/echarts": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/echarts/-/echarts-6.1.0.tgz", + "integrity": "sha512-q0yaFPggC9FUdsWH4blavRWFmxdrIodbkoKNAjJudAI6CA9gNPxHtV2RcZNEepZVlk4yvBYkOkbk6HIVpIyHZA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "6.1.0" + } + }, + "node_modules/echarts/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, "node_modules/electron-to-chromium": { "version": "1.5.416", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.416.tgz", @@ -5546,49 +5215,6 @@ "dev": true, "license": "MIT" }, - "node_modules/esbuild": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", - "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "peer": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.2", - "@esbuild/android-arm": "0.28.2", - "@esbuild/android-arm64": "0.28.2", - "@esbuild/android-x64": "0.28.2", - "@esbuild/darwin-arm64": "0.28.2", - "@esbuild/darwin-x64": "0.28.2", - "@esbuild/freebsd-arm64": "0.28.2", - "@esbuild/freebsd-x64": "0.28.2", - "@esbuild/linux-arm": "0.28.2", - "@esbuild/linux-arm64": "0.28.2", - "@esbuild/linux-ia32": "0.28.2", - "@esbuild/linux-loong64": "0.28.2", - "@esbuild/linux-mips64el": "0.28.2", - "@esbuild/linux-ppc64": "0.28.2", - "@esbuild/linux-riscv64": "0.28.2", - "@esbuild/linux-s390x": "0.28.2", - "@esbuild/linux-x64": "0.28.2", - "@esbuild/netbsd-arm64": "0.28.2", - "@esbuild/netbsd-x64": "0.28.2", - "@esbuild/openbsd-arm64": "0.28.2", - "@esbuild/openbsd-x64": "0.28.2", - "@esbuild/openharmony-arm64": "0.28.2", - "@esbuild/sunos-x64": "0.28.2", - "@esbuild/win32-arm64": "0.28.2", - "@esbuild/win32-ia32": "0.28.2", - "@esbuild/win32-x64": "0.28.2" - } - }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -5602,6 +5228,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -5614,6 +5241,7 @@ "version": "10.9.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.9.1.tgz", "integrity": "sha512-9VaAkDURekixUQJy0oJYl2DcN6oKMfxay7XzaGYAWQwsb6qfKf+x76R2k1L8kb1boc+FyCAaTA9GmiKaaiaF+A==", + "dev": true, "license": "MIT", "workspaces": [ "packages/*" @@ -5768,6 +5396,7 @@ "version": "9.1.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "@types/esrecurse": "^4.3.1", @@ -5786,6 +5415,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, "license": "Apache-2.0", "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" @@ -5804,6 +5434,7 @@ "version": "11.2.0", "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.16.0", @@ -5821,6 +5452,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -5833,6 +5465,7 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.3.6.tgz", "integrity": "sha512-yc0OC12UjPqLoc+fe+v5GNs4TOjAigUw3sTikfC+xeBPGUw7gDRz3DtYaqEhxyMVJojcSWJw7jT0QWR+CbuE/A==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -5850,6 +5483,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -5862,6 +5496,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -5877,6 +5512,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -5921,18 +5557,21 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, "license": "MIT" }, "node_modules/fdir": { @@ -5956,6 +5595,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, "license": "MIT", "dependencies": { "flat-cache": "^4.0.0" @@ -5984,6 +5624,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, "license": "MIT", "dependencies": { "flatted": "^3.2.9", @@ -5997,6 +5638,7 @@ "version": "3.4.4", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", + "dev": true, "license": "ISC" }, "node_modules/focus-trap": { @@ -6055,6 +5697,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -6108,6 +5751,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 4" @@ -6138,6 +5782,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" @@ -6177,6 +5822,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -6186,6 +5832,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -6213,13 +5860,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, "license": "ISC" }, "node_modules/jiti": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", - "devOptional": true, + "dev": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -6252,6 +5900,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, "license": "MIT" }, "node_modules/json-schema": { @@ -6264,12 +5913,14 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, "license": "MIT" }, "node_modules/json-stringify-pretty-compact": { @@ -6288,6 +5939,7 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" @@ -6297,6 +5949,7 @@ "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" @@ -6323,6 +5976,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", @@ -6625,6 +6279,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "dev": true, "license": "MIT" }, "node_modules/locate-path": { @@ -6743,6 +6398,7 @@ "version": "10.2.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.8" @@ -6872,6 +6528,7 @@ "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" @@ -6881,6 +6538,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, "license": "MIT" }, "node_modules/murmurhash-js": { @@ -6928,6 +6586,14 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "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/node-releases": { @@ -6943,6 +6609,7 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "dev": true, "funding": [ "https://github.com/sponsors/sxzz", "https://opencollective.com/debug" @@ -6956,6 +6623,7 @@ "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, "license": "MIT", "dependencies": { "deep-is": "^0.1.3", @@ -7019,6 +6687,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -7053,7 +6722,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "devOptional": true, + "dev": true, "license": "ISC", "engines": { "node": ">=4.0.0" @@ -7063,14 +6732,14 @@ "version": "1.16.0", "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.16.0.tgz", "integrity": "sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/pg-types": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "pg-int8": "1.0.1", @@ -7149,6 +6818,7 @@ "version": "8.5.26", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", + "dev": true, "funding": [ { "type": "opencollective", @@ -7285,6 +6955,7 @@ "version": "3.3.18", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "dev": true, "funding": [ { "type": "github", @@ -7316,7 +6987,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -7326,7 +6997,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7336,7 +7007,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7346,7 +7017,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "xtend": "^4.0.0" @@ -7365,6 +7036,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8.0" @@ -7410,6 +7082,7 @@ "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" @@ -7508,6 +7181,7 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.6.tgz", "integrity": "sha512-vMM4q3aixf46GiF1Kok8jDPFsEpXgFWGjUHXNkNHNm+Y2adXAG2dbX91jkti3i0ZRsOlcmbuzAz1poObSHCmUA==", + "dev": true, "license": "MIT", "dependencies": { "@oxc-project/types": "=0.147.0", @@ -7643,8 +7317,51 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.2.tgz", "integrity": "sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==", + "dev": true, "license": "MIT" }, + "node_modules/shadcn-svelte": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/shadcn-svelte/-/shadcn-svelte-1.7.0.tgz", + "integrity": "sha512-AK3ZsYOL8PN/RxcEBCHGvQj2TrLfaaBsbw0QohyEb3nn/yPNDRC/+9iSjnTp/uKEe+tAi0tBxB/Yhzno0N7EEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cn": "^0.3.0", + "commander": "^14.0.0", + "node-fetch-native": "^1.6.4", + "postcss": "^8.5.10" + }, + "bin": { + "shadcn-svelte": "dist/index.mjs" + }, + "peerDependencies": { + "svelte": "^5.0.0" + } + }, + "node_modules/shadcn-svelte/node_modules/cn": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/cn/-/cn-0.3.3.tgz", + "integrity": "sha512-OEiyJkSpYm2kOuNOKQ+c2wmzZRG8orrb9fnObtHTbCGNx/E9KLnGcmcocItOzREKk5KzQN5I2e3BUCj563KEpw==", + "dev": true, + "license": "MIT", + "bin": { + "cn": "bin/cn.mjs" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/shadcn-svelte/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/sharp": { "version": "0.34.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", @@ -7694,6 +7411,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -7706,6 +7424,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -7722,6 +7441,7 @@ "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", @@ -7736,6 +7456,7 @@ "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==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -7780,6 +7501,7 @@ "version": "5.57.0", "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.57.0.tgz", "integrity": "sha512-NdbDn7fl4be1ViUG0oq/lvG6OZy3oENolV2ONjiqqsfVoeAfzaQAKUcEX3MrQod/Bebv1PgwET9rfXhgn9s4Kg==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.4", @@ -7944,6 +7666,7 @@ "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" @@ -8032,6 +7755,7 @@ "version": "0.2.17", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -8078,6 +7802,7 @@ "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" @@ -8102,45 +7827,21 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, - "node_modules/tsx": { - "version": "4.23.13", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.13.tgz", - "integrity": "sha512-BL5MGkRln6aDYhb0xbQlEAGw743BaZYWdbWtdJOBriYJboKgUUYCadFp2/FpBBZquBC/ezNBn7wMMPx7FDZUDw==", + "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", - "optional": true, - "peer": true, - "dependencies": { - "esbuild": "~0.28.0" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, - "node_modules/tsx/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" - ], - "peer": true, - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" } }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" @@ -8153,7 +7854,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -8207,7 +7908,7 @@ "version": "8.3.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/unplugin": { @@ -8297,6 +7998,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -8326,6 +8028,7 @@ "version": "8.2.2", "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", + "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.33.0", @@ -8418,6 +8121,7 @@ "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, @@ -8432,6 +8136,7 @@ "version": "1.33.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -8464,6 +8169,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8484,6 +8190,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8504,6 +8211,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8524,6 +8232,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8544,6 +8253,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8564,6 +8274,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8584,6 +8295,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8604,6 +8316,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8624,6 +8337,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8644,6 +8358,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8664,6 +8379,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8681,6 +8397,7 @@ "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/*", @@ -8797,6 +8514,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -8829,6 +8547,7 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8844,29 +8563,12 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "devOptional": true, + "dev": true, "license": "MIT", "engines": { "node": ">=0.4" } }, - "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -8883,6 +8585,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz", "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==", + "dev": true, "license": "MIT" }, "node_modules/zod": { @@ -8893,6 +8596,21 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } + }, + "node_modules/zrender": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/zrender/-/zrender-6.1.0.tgz", + "integrity": "sha512-oEGMDB6pOP2S6OwRR4PdVv610zrjnA3Bh+JnSG12fYJlBKjtNAoEb5fSUoCOOINlH96I2fU38/A2UpRKs67xYQ==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } + }, + "node_modules/zrender/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" } } } diff --git a/package.json b/package.json index 248fcfe..262801a 100755 --- a/package.json +++ b/package.json @@ -23,6 +23,8 @@ "db:migrate:foundation": "bun scripts/migrate-foundation.ts", "db:migrate:money-tracker": "bun scripts/migrate-money-tracker.ts", "db:migrate:game-tracker": "bun scripts/migrate-game-tracker.ts", + "db:migrate:cs-prices": "bun scripts/migrate-cs-prices.ts", + "cs-prices:ingest": "bun scripts/ingest-cs-prices.ts", "auth:role": "bun scripts/set-admin.ts", "catalog:build": "python3 scripts/build-pokemon-catalog.py", "catalog:cod": "python3 scripts/build-cod-catalog.py && prettier --write data/call-of-duty.json", @@ -30,7 +32,10 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", + "@fontsource-variable/montserrat": "^5.3.0", "@iconify-json/simple-icons": "^1.2.94", + "@internationalized/date": "^3.12.0", + "@lucide/svelte": "^1.48.0", "@playwright/test": "^1.62.1", "@sveltejs/enhanced-img": "^0.11.0", "@sveltejs/kit": "^2.70.3", @@ -46,6 +51,7 @@ "bits-ui": "^2.19.0", "clsx": "^2.1.1", "cmdk-sv": "^0.0.19", + "cn": "^0.4.0", "drizzle-kit": "^1.0.0-rc.4", "eslint": "^10.9.1", "eslint-config-prettier": "^10.1.8", @@ -54,11 +60,13 @@ "lucide-svelte": "^1.0.1", "prettier": "3.9.6", "prettier-plugin-svelte": "^4.1.1", + "shadcn-svelte": "^1.7.0", "svelte": "^5.57.0", "svelte-check": "4.7.6", "tailwind-merge": "^3.6.0", "tailwind-variants": "^3.3.1", "tailwindcss": "^4.3.3", + "tw-animate-css": "^1.4.0", "typescript": "~6", "typescript-eslint": "8.68.0", "unplugin-icons": "^23.0.1", @@ -75,6 +83,7 @@ "ai": "^7.0.85", "d3-geo": "^3.1.1", "drizzle-orm": "^1.0.0-rc.4", + "echarts": "^6.1.0", "highlight.js": "^11.12.0", "marked": "^18.0.11", "marked-highlight": "^2.2.4", diff --git a/scripts/cs-prices-migration.sql b/scripts/cs-prices-migration.sql new file mode 100644 index 0000000..44b8f03 --- /dev/null +++ b/scripts/cs-prices-migration.sql @@ -0,0 +1,45 @@ +CREATE TABLE IF NOT EXISTS cs_market_items ( + id serial PRIMARY KEY, + market_hash_name text NOT NULL, + name text NOT NULL, + icon_url text, + item_type text, + first_seen_at timestamptz NOT NULL DEFAULT now(), + last_seen_at timestamptz NOT NULL DEFAULT now() +); +CREATE UNIQUE INDEX IF NOT EXISTS cs_market_items_hash_idx ON cs_market_items (market_hash_name); +CREATE INDEX IF NOT EXISTS cs_market_items_name_idx ON cs_market_items (name); + +CREATE TABLE IF NOT EXISTS cs_item_dimensions ( + item_id integer NOT NULL REFERENCES cs_market_items(id) ON DELETE CASCADE, + key text NOT NULL, + value text NOT NULL +); +CREATE UNIQUE INDEX IF NOT EXISTS cs_item_dimensions_unique_idx ON cs_item_dimensions (item_id, key); +CREATE INDEX IF NOT EXISTS cs_item_dimensions_filter_idx ON cs_item_dimensions (key, value, item_id); + +CREATE TABLE IF NOT EXISTS cs_price_streams ( + source text NOT NULL, + currency text NOT NULL, + kind text NOT NULL +); +CREATE UNIQUE INDEX IF NOT EXISTS cs_price_streams_unique_idx + ON cs_price_streams (source, currency, kind); + +CREATE TABLE IF NOT EXISTS cs_price_observations ( + id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, + item_id integer NOT NULL REFERENCES cs_market_items(id) ON DELETE CASCADE, + source text NOT NULL, + currency text NOT NULL, + observed_at timestamptz NOT NULL, + price_cents integer NOT NULL CHECK (price_cents >= 0), + volume integer CHECK (volume IS NULL OR volume >= 0), + kind text NOT NULL, + imported_at timestamptz NOT NULL DEFAULT now() +); +CREATE UNIQUE INDEX IF NOT EXISTS cs_price_observations_unique_idx + ON cs_price_observations (item_id, source, currency, observed_at, kind); +CREATE INDEX IF NOT EXISTS cs_price_observations_lookup_idx + ON cs_price_observations (item_id, source, currency, observed_at); +CREATE INDEX IF NOT EXISTS cs_price_observations_time_idx + ON cs_price_observations (observed_at); diff --git a/scripts/ingest-cs-prices.ts b/scripts/ingest-cs-prices.ts new file mode 100644 index 0000000..f84f99f --- /dev/null +++ b/scripts/ingest-cs-prices.ts @@ -0,0 +1,287 @@ +/** + * Steam Community Market ingestion. Run after db:migrate:cs-prices. + * + * bun scripts/ingest-cs-prices.ts catalog [--limit=500] [--start=0] + * STEAM_SESSIONID=... STEAM_LOGIN_SECURE=... bun scripts/ingest-cs-prices.ts history [--limit=100] [--start=0] + * bun scripts/ingest-cs-prices.ts import ./observations.jsonl + * + * The first two modes use Steam's public market web endpoints, which are not a + * contracted API and may rate limit or change. `import` remains provider-neutral. + */ +import { readFile } from 'node:fs/promises'; +import postgres from 'postgres'; +import { dimensionsFromName, type Dimensions } from '../src/lib/cs-prices/taxonomy'; +import { steamDate } from '../src/lib/cs-prices/steam'; + +if (!process.env.DB_URL) throw new Error('DB_URL is required'); +const sql = postgres(process.env.DB_URL, { max: 1 }); +const mode = process.argv[2]; +const flags = new Map( + process.argv + .slice(3) + .filter((arg) => arg.startsWith('--')) + .map((arg) => { + const [key, value] = arg.slice(2).split('='); + return [key, value ?? '']; + }) +); +const start = Math.max(0, Number(flags.get('start') ?? 0)); +const limit = Math.max(1, Number(flags.get('limit') ?? 1_000_000_000)); +const delayMs = Math.max(1000, Number(flags.get('delay-ms') ?? 2000)); +const sweepTime = new Date(); +const knownStreams = new Set(); + +type Observation = { + marketHashName: string; + name?: string; + source: string; + currency: string; + observedAt: string; + priceCents: number; + volume?: number | null; + kind: string; + dimensions?: Dimensions; +}; + +function validObservation(value: unknown): Observation { + if (!value || typeof value !== 'object') throw new Error('Observation must be an object'); + const row = value as Record; + for (const key of ['marketHashName', 'source', 'currency', 'observedAt', 'kind']) { + if (typeof row[key] !== 'string' || !row[key]) throw new Error(`Invalid ${key}`); + } + if (!/^[a-z0-9][a-z0-9-]{0,79}$/.test(row.source as string)) throw new Error('Invalid source'); + if (!/^[a-z0-9][a-z0-9-]{0,79}$/.test(row.kind as string)) throw new Error('Invalid kind'); + if (!/^[A-Z]{3}$/.test(row.currency as string)) throw new Error('Invalid currency'); + if (row.name != null && typeof row.name !== 'string') throw new Error('Invalid name'); + if ( + !Number.isInteger(row.priceCents) || + (row.priceCents as number) < 0 || + (row.priceCents as number) > 2_147_483_647 + ) + throw new Error('Invalid priceCents'); + if ( + row.volume != null && + (!Number.isInteger(row.volume) || + (row.volume as number) < 0 || + (row.volume as number) > 2_147_483_647) + ) + throw new Error('Invalid volume'); + if (Number.isNaN(Date.parse(row.observedAt as string))) throw new Error('Invalid observedAt'); + if ( + row.dimensions != null && + (typeof row.dimensions !== 'object' || + Array.isArray(row.dimensions) || + Object.values(row.dimensions).some((value) => typeof value !== 'string')) + ) + throw new Error('Invalid dimensions'); + return row as Observation; +} + +async function itemId( + name: string, + displayName = name, + iconUrl?: string, + itemType?: string, + extraDimensions: Dimensions = {} +) { + const [row] = await sql<{ id: number }[]>` + INSERT INTO cs_market_items (market_hash_name, name, icon_url, item_type) + VALUES (${name}, ${displayName}, ${iconUrl ?? null}, ${itemType ?? null}) + ON CONFLICT (market_hash_name) DO UPDATE SET + name = EXCLUDED.name, + icon_url = COALESCE(EXCLUDED.icon_url, cs_market_items.icon_url), + item_type = COALESCE(EXCLUDED.item_type, cs_market_items.item_type), + last_seen_at = now() + RETURNING id`; + const inferred = dimensionsFromName(name); + if (itemType) inferred.steam_type = itemType; + for (const [key, value] of Object.entries(inferred)) { + if (!/^[a-z][a-z0-9_]*$/.test(key) || !value) continue; + await sql` + INSERT INTO cs_item_dimensions (item_id, key, value) VALUES (${row.id}, ${key}, ${value}) + ON CONFLICT (item_id, key) DO NOTHING`; + } + for (const [key, value] of Object.entries(extraDimensions)) { + if (!/^[a-z][a-z0-9_]*$/.test(key) || !value) continue; + await sql` + INSERT INTO cs_item_dimensions (item_id, key, value) VALUES (${row.id}, ${key}, ${value}) + ON CONFLICT (item_id, key) DO UPDATE SET value = EXCLUDED.value`; + } + return row.id; +} + +async function saveObservation(row: Observation, knownItemId?: number) { + const item = + knownItemId ?? + (await itemId(row.marketHashName, row.name, undefined, undefined, row.dimensions)); + await ensureStream(row.source, row.currency, row.kind); + await sql` + INSERT INTO cs_price_observations + (item_id, source, currency, observed_at, price_cents, volume, kind) + VALUES (${item}, ${row.source}, ${row.currency}, ${new Date(row.observedAt)}, + ${row.priceCents}, ${row.volume ?? null}, ${row.kind}) + ON CONFLICT (item_id, source, currency, observed_at, kind) DO UPDATE SET + price_cents = EXCLUDED.price_cents, + volume = EXCLUDED.volume`; +} + +async function ensureStream(source: string, currency: string, kind: string) { + const key = `${source}\0${currency}\0${kind}`; + if (knownStreams.has(key)) return; + await sql`INSERT INTO cs_price_streams (source, currency, kind) + VALUES (${source}, ${currency}, ${kind}) ON CONFLICT DO NOTHING`; + knownStreams.add(key); +} + +async function saveHistoryRows( + item: { id: number; market_hash_name: string }, + prices: [string, number, string][] +) { + await ensureStream('steam-market', 'USD', 'sale-median'); + const rows = prices + .filter(([, price]) => Number.isFinite(price) && price >= 0) + .map(([date, price, volume]) => ({ + item_id: item.id, + source: 'steam-market', + currency: 'USD', + observed_at: new Date(steamDate(date)), + price_cents: Math.round(price * 100), + volume: Number(volume.replaceAll(',', '')) || 0, + kind: 'sale-median' + })); + for (let offset = 0; offset < rows.length; offset += 500) { + await sql`INSERT INTO cs_price_observations ${sql(rows.slice(offset, offset + 500))} + ON CONFLICT (item_id, source, currency, observed_at, kind) DO UPDATE SET + price_cents = EXCLUDED.price_cents, volume = EXCLUDED.volume`; + } +} + +async function steamJson(url: URL, authenticated = false): Promise { + for (let attempt = 0; attempt < 5; attempt++) { + const cookie = authenticated + ? `sessionid=${process.env.STEAM_SESSIONID ?? ''}; steamLoginSecure=${process.env.STEAM_LOGIN_SECURE ?? ''}` + : undefined; + const response = await fetch(url, { + headers: { + 'User-Agent': 'cs-prices/1.0 personal historical archive', + ...(cookie ? { Cookie: cookie } : {}) + } + }); + if (response.ok) { + const json = await response.json(); + if (!json || json.success === false) throw new Error(`Steam rejected ${url.pathname}`); + return json as T; + } + if (response.status !== 429 && response.status < 500) + throw new Error(`Steam HTTP ${response.status}`); + await new Promise((resolve) => setTimeout(resolve, delayMs * 2 ** attempt)); + } + throw new Error(`Steam request failed after retries: ${url.pathname}`); +} + +const pause = () => new Promise((resolve) => setTimeout(resolve, delayMs)); + +async function catalog() { + let offset = start; + let processed = 0; + while (processed < limit) { + const url = new URL('https://steamcommunity.com/market/search/render/'); + url.search = new URLSearchParams({ + appid: '730', + currency: '1', + country: 'US', + norender: '1', + count: String(Math.min(100, limit - processed)), + start: String(offset), + sort_column: 'name', + sort_dir: 'asc' + }).toString(); + const page = await steamJson<{ + total_count: number; + results: { + hash_name: string; + name: string; + sell_price?: number; + sell_listings?: number; + asset_description?: { icon_url?: string; type?: string }; + }[]; + }>(url); + if (!page.results?.length) break; + for (const entry of page.results) { + if (!entry.hash_name) continue; + const id = await itemId( + entry.hash_name, + entry.name || entry.hash_name, + entry.asset_description?.icon_url, + entry.asset_description?.type + ); + if (Number.isSafeInteger(entry.sell_price) && (entry.sell_price ?? -1) >= 0) { + await saveObservation( + { + marketHashName: entry.hash_name, + source: 'steam-market', + currency: 'USD', + observedAt: sweepTime.toISOString(), + priceCents: entry.sell_price!, + volume: entry.sell_listings, + kind: 'lowest-listing' + }, + id + ); + } + } + processed += page.results.length; + offset += page.results.length; + console.log(`Catalog: ${offset}/${page.total_count} listings`); + if (offset >= page.total_count) break; + await pause(); + } +} + +async function history() { + if (!process.env.STEAM_SESSIONID || !process.env.STEAM_LOGIN_SECURE) + throw new Error('STEAM_SESSIONID and STEAM_LOGIN_SECURE are required for Steam history'); + const items = await sql<{ id: number; market_hash_name: string }[]>` + SELECT id, market_hash_name FROM cs_market_items ORDER BY id LIMIT ${limit} OFFSET ${start}`; + let done = 0; + for (const item of items) { + const url = new URL('https://steamcommunity.com/market/pricehistory/'); + url.search = new URLSearchParams({ + appid: '730', + market_hash_name: item.market_hash_name, + currency: '1', + country: 'US' + }).toString(); + const data = await steamJson<{ prices: [string, number, string][] }>(url, true); + await saveHistoryRows(item, data.prices ?? []); + console.log( + `History: ${++done}/${items.length} ${item.market_hash_name} (${data.prices?.length ?? 0} points)` + ); + await pause(); + } +} + +async function importFile(path: string) { + const lines = (await readFile(path, 'utf8')).split(/\r?\n/); + let imported = 0; + for (const [index, line] of lines.entries()) { + if (!line.trim()) continue; + try { + await saveObservation(validObservation(JSON.parse(line))); + imported++; + } catch (cause) { + throw new Error(`Invalid observation on line ${index + 1}: ${String(cause)}`, { cause }); + } + } + console.log(`Imported ${imported} observations`); +} + +try { + if (mode === 'catalog') await catalog(); + else if (mode === 'history') await history(); + else if (mode === 'import' && process.argv[3]) await importFile(process.argv[3]); + else throw new Error('Usage: ingest-cs-prices.ts catalog|history|import '); + await sql`ANALYZE cs_market_items, cs_item_dimensions, cs_price_observations`; +} finally { + await sql.end(); +} diff --git a/scripts/migrate-cs-prices.ts b/scripts/migrate-cs-prices.ts new file mode 100644 index 0000000..63b6260 --- /dev/null +++ b/scripts/migrate-cs-prices.ts @@ -0,0 +1,13 @@ +import { readFile } from 'node:fs/promises'; +import postgres from 'postgres'; + +if (!process.env.DB_URL) throw new Error('DB_URL is required'); +const client = postgres(process.env.DB_URL, { max: 1 }); +try { + await client.begin(async (tx) => { + await tx.unsafe(await readFile(new URL('./cs-prices-migration.sql', import.meta.url), 'utf8')); + }); + console.log('CS prices migration applied'); +} finally { + await client.end(); +} diff --git a/src/app.css b/src/app.css index d75ac61..f4265be 100755 --- a/src/app.css +++ b/src/app.css @@ -1,4 +1,9 @@ @import 'tailwindcss'; +@import 'tw-animate-css'; +@import 'shadcn-svelte/tailwind.css'; +@import '@fontsource-variable/montserrat'; + +@custom-variant dark (&:is(.dark *)); @plugin '@tailwindcss/typography'; @theme { @@ -11,13 +16,50 @@ --color-text-muted: #a1a1a1; --color-text-dim: #888; --color-text-ghost: #666; - --color-accent: #ededed; + --color-accent: var(--accent); --color-accent-hover: #fff; --color-danger: #b44; - --font-heading: Montserrat, Arial, Helvetica, sans-serif; + --font-heading: 'Montserrat Variable', Arial, Helvetica, sans-serif; --font-mono: 'IBM Plex Mono', 'Courier New', monospace; - --font-body: Montserrat, Arial, Helvetica, sans-serif; + --font-body: 'Montserrat Variable', Arial, Helvetica, sans-serif; + --font-sans: 'Montserrat Variable', sans-serif; + --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-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --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); } :root { @@ -28,6 +70,38 @@ --site-text: #ededed; --site-muted: #a1a1a1; --site-border: #292929; + --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.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); } :root[data-theme='light'] { @@ -116,10 +190,12 @@ box-sizing: border-box; margin: 0; padding: 0; + @apply border-border outline-ring/50; } html { scroll-behavior: smooth; + @apply font-sans; } section[id] { @@ -134,6 +210,7 @@ line-height: 1.6; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + @apply bg-background text-foreground; } button, @@ -143,6 +220,14 @@ font: inherit; } + input:not([data-slot]):not([type='checkbox']):not([type='radio']):not([type='file']):not( + [type='hidden'] + ), + textarea:not([data-slot]), + select:not([data-slot]) { + @apply rounded-md border border-input bg-background px-2.5 py-1 text-foreground shadow-xs; + } + :focus-visible { outline: 2px solid var(--site-text); outline-offset: 3px; @@ -157,3 +242,28 @@ text-decoration: none; } } + +/* Keep the site's black and white palette across every shadcn component. */ +.dark { + --background: #000; + --foreground: #ededed; + --card: #0a0a0a; + --card-foreground: #ededed; + --popover: #0a0a0a; + --popover-foreground: #ededed; + --primary: #ededed; + --primary-foreground: #000; + --secondary: #171717; + --secondary-foreground: #ededed; + --muted: #171717; + --muted-foreground: #a1a1a1; + --accent: #171717; + --accent-foreground: #ededed; + --border: #292929; + --input: #292929; + --ring: #ededed; + --sidebar: #0a0a0a; + --sidebar-foreground: #ededed; + --sidebar-accent: #171717; + --sidebar-border: #292929; +} diff --git a/src/app.html b/src/app.html index 3eff41c..9f060b5 100755 --- a/src/app.html +++ b/src/app.html @@ -1,5 +1,5 @@ - + @@ -37,12 +41,6 @@ - - - %sveltekit.head% diff --git a/src/lib/assets/experience/3webapps.webp b/src/lib/assets/experience/3webapps.webp new file mode 100644 index 0000000000000000000000000000000000000000..04e8550ae94ff85b6ef0730bc918c48255e5feb9 GIT binary patch literal 9058 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 K7W7C-0PtU-D>|D1 literal 0 HcmV?d00001 diff --git a/src/lib/assets/experience/cargill.webp b/src/lib/assets/experience/cargill.webp new file mode 100644 index 0000000000000000000000000000000000000000..60010e73035cbf7e9b14a968dc2d4296e14eddf2 GIT binary patch literal 18910 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 - - - - {#if menuOpen} - + + {@render themeIcon()} {#if data.user} - (menuOpen = false)}>account -
+ +
+ +
{:else} - (menuOpen = false)}>sign in - (menuOpen = false)}>register + + {/if} - - - - {/if} +
+ + +
{@render children()}