diff --git a/.env.example b/.env.example index f136dd3..90de1e0 100644 --- a/.env.example +++ b/.env.example @@ -1,13 +1,24 @@ +# Production identity PUBLIC_SITE_URL=https://trade.flamy.studio PUBLIC_SITE_NAME=Flamy Trade PUBLIC_SITE_DESCRIPTION=Публичная витрина ML-прогнозов для крипторынка. +PUBLIC_DASHBOARD_DATA_MODE=research-static +# SvelteKit adapter-node runtime HOST=0.0.0.0 PORT=3000 ORIGIN=https://trade.flamy.studio BODY_SIZE_LIMIT=1M SHUTDOWN_TIMEOUT=15 +APP_STOP_GRACE_PERIOD=20s +# Docker image provenance +APP_IMAGE_REPOSITORY=registry.example.com/flamy-trade +APP_IMAGE_TAG=local +BUILD_DATE= +VCS_REF= + +# Reverse proxy publishing APP_HOST_IP=10.20.0.20 APP_PUBLISHED_PORT=18082 -APP_IMAGE_TAG=local +NGINX_IMAGE=nginxinc/nginx-unprivileged:1.30.4-alpine-perl@sha256:36fa38fb8f34faba45e7e1857644d6561f2faf45e7ce6b15e97d1a2a1682a0cd diff --git a/.gitignore b/.gitignore index 4b9fea0..39bb16a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules .npm-cache .corepack +.pnpm-store # Output .output @@ -27,3 +28,4 @@ vite.config.ts.timestamp-* #IDE & AI .claude .idea +.vscode \ No newline at end of file diff --git a/README.md b/README.md index 9791c35..2fa1a3e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Flamy Trade -Публичный frontend для `trade.flamy.studio`: лендинг, блог и демонстрационный дашборд ML-прогнозов по крипторынку. +Публичный frontend для `trade.flamy.studio`: лендинг, блог и исследовательский дашборд ML-прогнозов по крипторынку. Проект построен на SvelteKit, Svelte 5 Runes, Tailwind CSS v4, TypeScript и `lightweight-charts`. @@ -38,94 +38,75 @@ pnpm preview # preview production build pnpm audit # аудит зависимостей ``` -`pnpm outdated` может показывать `@types/node` 26.x и TypeScript 7.x. Это не ошибка текущего стека: проект закреплён на Node 24 LTS, а `@sveltejs/kit` и `typescript-eslint` на текущих версиях требуют TypeScript `<6.1`. +`prepare` намеренно выполняет `svelte-kit sync` без подавления ошибок. Если синхронизация SvelteKit падает, установка зависимостей тоже должна завершаться ошибкой. ## Конфигурация -Основные изменяемые значения вынесены в `.env.example`. +`.env.example` описывает production-настройки. Для сервера скопируйте его в `.env` и заполните значения без локальных заглушек. -Публичные значения сайта: +Основные переменные: ```bash PUBLIC_SITE_URL=https://trade.flamy.studio PUBLIC_SITE_NAME=Flamy Trade PUBLIC_SITE_DESCRIPTION=Публичная витрина ML-прогнозов для крипторынка. -``` +PUBLIC_DASHBOARD_DATA_MODE=research-static -Runtime-переменные SvelteKit adapter-node: - -```bash HOST=0.0.0.0 PORT=3000 ORIGIN=https://trade.flamy.studio BODY_SIZE_LIMIT=1M SHUTDOWN_TIMEOUT=15 -``` +APP_STOP_GRACE_PERIOD=20s -Docker Compose: +APP_IMAGE_REPOSITORY=registry.example.com/flamy-trade +APP_IMAGE_TAG= +BUILD_DATE= +VCS_REF= -```bash APP_HOST_IP=10.20.0.20 APP_PUBLISHED_PORT=18082 -APP_IMAGE_TAG= +NGINX_IMAGE=nginxinc/nginx-unprivileged:1.30.4-alpine-perl@sha256:36fa38fb8f34faba45e7e1857644d6561f2faf45e7ce6b15e97d1a2a1682a0cd ``` +`PUBLIC_DASHBOARD_DATA_MODE=research-static` означает, что дашборд показывает исследовательские синтетические данные. Это production-поведение текущего публичного этапа, а не интеграция с реальным торговым API. + ## Структура ```text -src/lib/blog/posts.ts # статические статьи блога -src/lib/config/site.ts # единая конфигурация сайта и canonical URL -src/lib/stores/chartStore.ts # типы графика и демонстрационный provider -src/lib/components/Chart.svelte # lightweight-charts компонент -src/routes/healthz/+server.ts # health endpoint -src/routes/sitemap.xml/+server.ts # sitemap -docker/nginx/default.conf # project nginx -docs/deployment.md # runbook развёртывания +src/lib/blog/posts.ts # типизированные статьи блога +src/lib/config/site.ts # единая конфигурация сайта, canonical и metadata +src/lib/data/dashboard.ts # provider данных дашборда +src/lib/stores/chartStore.ts # типы графика и research-static генератор +src/lib/components/Chart.svelte # компонент lightweight-charts +src/routes/healthz/+server.ts # health endpoint +src/routes/robots.txt/+server.ts # runtime robots.txt +src/routes/sitemap.xml/+server.ts # runtime sitemap +docker/nginx/default.conf # nginx server config +docker/nginx/includes # общие nginx include-файлы +docs/deployment.md # runbook развёртывания ``` -## Данные дашборда - -Текущий provider в `chartStore.ts` генерирует демонстрационные данные. Он не является реальным торговым API и не меняет контракт будущего backend. - -Ожидаемая форма `ChartData`: - -```typescript -type ChartData = { - candles: Array<{ time: number; open: number; high: number; low: number; close: number }>; - prediction: Array<{ time: number; value: number }>; - signal: { - direction: 'long' | 'short'; - confidence: number; - entry: number; - tp: number; - sl: number; - }; - currentPrice: number; - change24h: number; - change24hPct: number; -}; -``` - -## Блог - -Статьи хранятся как типизированные блоки, а не как HTML-строки. Это позволяет рендерить контент без `{@html}` и без отдельной санитаризации. - ## Production -Production-сборка рассчитана на схему: +Production-схема: ```text Internet -> Caddy -> 10.20.0.20:18082 -> nginx -> app:3000 ``` +Публикуется только nginx. Node-приложение доступно только во внутренней Docker-сети. Nginx запускается через unprivileged image с `cap_drop: ALL`, `read_only` и `no-new-privileges`. + Подробный порядок развёртывания, Caddy block, smoke-check и rollback описаны в [docs/deployment.md](docs/deployment.md). +## Зависимости + +Renovate закрепляет версии и digest Docker-образов, а также ждёт 3 дня перед обновлением свежих релизов. TypeScript 6.x является осознанным compatibility hold до обновления peer constraints в SvelteKit/typescript-eslint. + ## Что не входит в текущий этап -Пока не подключаются: - - ML-runtime; -- реальный API; +- реальный торговый API; - S3; - база данных; - Redis; diff --git a/docker-compose.yml b/docker-compose.yml index 5fe69b0..bc7929c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,5 @@ +name: flamy_trade + services: app: build: @@ -6,10 +8,12 @@ services: args: BUILD_DATE: ${BUILD_DATE:-} VCS_REF: ${VCS_REF:-} - image: flamy-trade:${APP_IMAGE_TAG:-local} + image: ${APP_IMAGE_REPOSITORY:-flamy-trade}:${APP_IMAGE_TAG:-local} restart: unless-stopped init: true read_only: true + stop_signal: SIGTERM + stop_grace_period: ${APP_STOP_GRACE_PERIOD:-20s} environment: NODE_ENV: production HOST: 0.0.0.0 @@ -52,7 +56,7 @@ services: max-file: '3' nginx: - image: nginx:1.30.4-alpine@sha256:97d490c12ba55b4946b01546d1c3ed324e8d41ab1c9fcb2a616aa470620e5b46 + image: ${NGINX_IMAGE:-nginxinc/nginx-unprivileged:1.30.4-alpine-perl@sha256:36fa38fb8f34faba45e7e1857644d6561f2faf45e7ce6b15e97d1a2a1682a0cd} restart: unless-stopped init: true read_only: true @@ -68,6 +72,7 @@ services: app_protocol: http volumes: - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro + - ./docker/nginx/includes:/etc/nginx/includes:ro networks: - backend cpus: 0.10 diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf index e194ddb..c50bf79 100644 --- a/docker/nginx/default.conf +++ b/docker/nginx/default.conf @@ -8,44 +8,35 @@ server { server_name _; client_max_body_size 1m; + add_header_inherit merge; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always; - add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self'" always; - location /_app/immutable/ { + location = /healthz { + access_log off; proxy_pass http://app:3000; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Host $host; - proxy_set_header X-Forwarded-Proto $forwarded_proto; + include /etc/nginx/includes/proxy-headers.conf; + add_header Cache-Control "no-cache" always; + } + + location ^~ /_app/immutable/ { + proxy_pass http://app:3000; + include /etc/nginx/includes/proxy-headers.conf; add_header Cache-Control "public, max-age=31536000, immutable" always; } location ~* \.(?:css|js|mjs|svg|png|jpg|jpeg|gif|webp|ico|ttf|woff2?)$ { proxy_pass http://app:3000; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Host $host; - proxy_set_header X-Forwarded-Proto $forwarded_proto; + include /etc/nginx/includes/proxy-headers.conf; add_header Cache-Control "public, max-age=86400" always; } location / { proxy_pass http://app:3000; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Host $host; - proxy_set_header X-Forwarded-Proto $forwarded_proto; - proxy_set_header Connection ""; - add_header Cache-Control "no-store" always; + include /etc/nginx/includes/proxy-headers.conf; + add_header Cache-Control "no-cache" always; } } diff --git a/docker/nginx/includes/proxy-headers.conf b/docker/nginx/includes/proxy-headers.conf new file mode 100644 index 0000000..3c0e9b4 --- /dev/null +++ b/docker/nginx/includes/proxy-headers.conf @@ -0,0 +1,7 @@ +proxy_http_version 1.1; +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-Host $host; +proxy_set_header X-Forwarded-Proto $forwarded_proto; +proxy_set_header Connection ""; diff --git a/docs/deployment.md b/docs/deployment.md index 9ca54ac..d46b0f5 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -1,6 +1,6 @@ # Развёртывание Flamy Trade -Документ описывает production-развёртывание сайта `trade.flamy.studio` без ML-runtime и без будущего API. Эти части подключаются отдельно. +Документ описывает production-развёртывание сайта `trade.flamy.studio` без ML-runtime и будущего API. Эти части подключаются отдельным этапом. ## Схема @@ -9,11 +9,11 @@ Internet -> Router :80/:443 -> edge-proxy VM / Caddy -> 10.20.0.20:18082 - -> flamy_trade_nginx - -> flamy_trade_app:3000 + -> flamy_trade-nginx-1 + -> flamy_trade-app-1:3000 ``` -На VM публикуется только nginx. Node-приложение доступно только во внутренней Docker-сети. +Compose project name зафиксирован как `flamy_trade`. `container_name` не задаётся, чтобы не ломать стандартное управление Compose. ## Переменные @@ -23,16 +23,23 @@ Internet PUBLIC_SITE_URL=https://trade.flamy.studio PUBLIC_SITE_NAME=Flamy Trade PUBLIC_SITE_DESCRIPTION=Публичная витрина ML-прогнозов для крипторынка. +PUBLIC_DASHBOARD_DATA_MODE=research-static HOST=0.0.0.0 PORT=3000 ORIGIN=https://trade.flamy.studio BODY_SIZE_LIMIT=1M SHUTDOWN_TIMEOUT=15 +APP_STOP_GRACE_PERIOD=20s + +APP_IMAGE_REPOSITORY=registry.example.com/flamy-trade +APP_IMAGE_TAG= +BUILD_DATE= +VCS_REF= APP_HOST_IP=10.20.0.20 APP_PUBLISHED_PORT=18082 -APP_IMAGE_TAG= +NGINX_IMAGE=nginxinc/nginx-unprivileged:1.30.4-alpine-perl@sha256:36fa38fb8f34faba45e7e1857644d6561f2faf45e7ce6b15e97d1a2a1682a0cd ``` Перед фиксацией порта проверьте, что `18082` свободен: @@ -42,7 +49,7 @@ sudo ss -lntup | grep ':18082' docker ps --format 'table {{.Names}}\t{{.Ports}}' ``` -## Сборка +## Проверки перед сборкой ```bash pnpm install --frozen-lockfile @@ -51,14 +58,22 @@ pnpm lint pnpm check pnpm build pnpm audit +docker compose config ``` -`pnpm outdated` должен проверяться вручную. На текущем стеке допустимы только осознанные удержания: `@types/node` на ветке 24 под Node 24 LTS и TypeScript 6.x до обновления peer constraints в SvelteKit/typescript-eslint. +## Сборка -Docker: +Перед сборкой image задайте provenance: + +```bash +export BUILD_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)" +export VCS_REF="$(git rev-parse HEAD)" +export APP_IMAGE_TAG="$VCS_REF" +``` + +Сборка и запуск: ```bash -docker compose config docker compose build --pull docker compose up -d --wait docker compose ps @@ -76,6 +91,8 @@ trade.flamy.studio { reverse_proxy 10.20.0.20:18082 { header_up Host {host} header_up X-Real-IP {remote_host} + header_up X-Forwarded-For {remote_host} + header_up X-Forwarded-Proto {scheme} } } ``` @@ -90,45 +107,89 @@ sudo systemctl reload caddy ## Smoke-check -С docker-runtime: +С Docker-runtime: ```bash curl -fsS http://10.20.0.20:18082/healthz -curl -I http://10.20.0.20:18082/ +curl -fsSI http://10.20.0.20:18082/ +curl -fsSI http://10.20.0.20:18082/robots.txt +curl -fsSI http://10.20.0.20:18082/sitemap.xml ``` Снаружи: ```bash -curl -I http://trade.flamy.studio -curl -I https://trade.flamy.studio +curl -fsSI https://trade.flamy.studio/ curl -fsS https://trade.flamy.studio/healthz +curl -fsS https://trade.flamy.studio/robots.txt +curl -fsS https://trade.flamy.studio/sitemap.xml ``` Маршруты: ```text -/ 200 -/about 200 -/blog 200 -/blog/osnovy-upravleniya-riskami 200 -/dashboard 200 -/healthz 200 -/favicon.svg 200 -/robots.txt 200 -/sitemap.xml 200 -/nesuschestvuyuschiy-url 404 +/ 200 +/about 200 +/blog 200 +/blog/osnovy-upravleniya-riskami 200 +/dashboard 200 +/healthz 200 +/favicon.svg 200 +/robots.txt 200 +/sitemap.xml 200 +/nesuschestvuyuschiy-url 404 +``` + +Проверка headers: + +```bash +curl -fsSI https://trade.flamy.studio/ +curl -fsSI https://trade.flamy.studio/favicon.svg +curl -fsSI https://trade.flamy.studio/_app/immutable/.js +``` + +Ожидаемо: + +```text +X-Content-Type-Options: nosniff +Referrer-Policy: strict-origin-when-cross-origin +X-Frame-Options: SAMEORIGIN +Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=() +``` + +`Content-Security-Policy` задаётся SvelteKit и ожидается на HTML-ответах приложения. + +Для `/_app/immutable/*` ожидается: + +```text +Cache-Control: public, max-age=31536000, immutable +``` + +Для HTML: + +```text +Cache-Control: no-cache ``` ## Rollback -1. Каждый image получает тег git SHA через `APP_IMAGE_TAG`. -2. Предыдущий image не удаляется до успешного smoke-check. -3. Для отката поменяйте `APP_IMAGE_TAG` на предыдущий SHA. -4. Выполните: +Надёжный rollback должен опираться на immutable image tag: -```bash -docker compose up -d --no-build +```text +${APP_IMAGE_REPOSITORY}: ``` -Если проблема в маршрутизации, восстановите backup Caddyfile и выполните `sudo systemctl reload caddy`. +На production-сервере меняется только `APP_IMAGE_TAG`, затем выполняется: + +```bash +docker compose pull app +docker compose up -d --no-build --wait +``` + +Если проблема в маршрутизации, восстановите backup Caddyfile и выполните: + +```bash +sudo systemctl reload caddy +``` + +Предыдущий image не удаляется до успешного smoke-check нового релиза. diff --git a/package.json b/package.json index e2afaf5..cb0b55f 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "dev": "vite dev", "build": "vite build", "preview": "vite preview", - "prepare": "svelte-kit sync || echo ''", + "prepare": "svelte-kit sync", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "format:check": "prettier --check .", @@ -28,7 +28,7 @@ "@types/node": "24.12.4", "eslint": "10.7.0", "eslint-config-prettier": "10.1.8", - "eslint-plugin-svelte": "3.21.0", + "eslint-plugin-svelte": "3.20.0", "globals": "17.7.0", "prettier": "3.9.5", "prettier-plugin-svelte": "4.1.1", @@ -41,7 +41,7 @@ "vite": "8.1.5" }, "dependencies": { - "@sveltejs/kit": "2.70.1", + "@sveltejs/kit": "2.69.3", "clsx": "2.1.1", "gsap": "3.15.0", "lightweight-charts": "5.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1bf881d..adf94df 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: .: dependencies: '@sveltejs/kit': - specifier: 2.70.1 - version: 2.70.1(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) + specifier: 2.69.3 + version: 2.69.3(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) clsx: specifier: 2.1.1 version: 2.1.1 @@ -35,7 +35,7 @@ importers: version: 10.0.1(eslint@10.7.0(jiti@2.7.0)) '@sveltejs/adapter-node': specifier: 5.5.7 - version: 5.5.7(@sveltejs/kit@2.70.1(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0))) + version: 5.5.7(@sveltejs/kit@2.69.3(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0))) '@sveltejs/vite-plugin-svelte': specifier: 7.2.0 version: 7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) @@ -52,8 +52,8 @@ importers: specifier: 10.1.8 version: 10.1.8(eslint@10.7.0(jiti@2.7.0)) eslint-plugin-svelte: - specifier: 3.21.0 - version: 3.21.0(eslint@10.7.0(jiti@2.7.0))(svelte@5.56.6(@typescript-eslint/types@8.64.0)) + specifier: 3.20.0 + version: 3.20.0(eslint@10.7.0(jiti@2.7.0))(svelte@5.56.6(@typescript-eslint/types@8.64.0)) globals: specifier: 17.7.0 version: 17.7.0 @@ -71,7 +71,7 @@ importers: version: 5.56.6(@typescript-eslint/types@8.64.0) svelte-check: specifier: 4.7.3 - version: 4.7.3(picomatch@4.0.4)(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3) + version: 4.7.3(picomatch@4.0.5)(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3) tailwindcss: specifier: 4.3.3 version: 4.3.3 @@ -290,8 +290,8 @@ packages: '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - '@rollup/plugin-commonjs@29.0.2': - resolution: {integrity: sha512-S/ggWH1LU7jTyi9DxZOKyxpVd4hF/OZ0JrEbeLjXk/DFXwRny0tjD2c992zOUYQobLrVkRVMDdmHP16HKP7GRg==} + '@rollup/plugin-commonjs@29.0.3': + resolution: {integrity: sha512-ZaOxZceP7SOUW7Lqw5IRVweSQYWaeIPnXIGLiB690EBA3FGJTO40EEr2L5yZplJWsgTCogILRSpcAe7+U0Otdg==} engines: {node: '>=16.0.0 || 14 >= 14.17'} peerDependencies: rollup: ^2.68.0||^3.0.0||^4.0.0 @@ -326,8 +326,8 @@ packages: rollup: optional: true - '@rollup/pluginutils@5.3.0': - resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + '@rollup/pluginutils@5.4.0': + resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -335,149 +335,149 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.60.4': - resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} + '@rollup/rollup-android-arm-eabi@4.62.2': + resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.4': - resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} + '@rollup/rollup-android-arm64@4.62.2': + resolution: {integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.4': - resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} + '@rollup/rollup-darwin-arm64@4.62.2': + resolution: {integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.4': - resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} + '@rollup/rollup-darwin-x64@4.62.2': + resolution: {integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.4': - resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} + '@rollup/rollup-freebsd-arm64@4.62.2': + resolution: {integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.4': - resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} + '@rollup/rollup-freebsd-x64@4.62.2': + resolution: {integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} + '@rollup/rollup-linux-arm-gnueabihf@4.62.2': + resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} + '@rollup/rollup-linux-arm-musleabihf@4.62.2': + resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.60.4': - resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} + '@rollup/rollup-linux-arm64-gnu@4.62.2': + resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.60.4': - resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} + '@rollup/rollup-linux-arm64-musl@4.62.2': + resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.60.4': - resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} + '@rollup/rollup-linux-loong64-gnu@4.62.2': + resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.60.4': - resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} + '@rollup/rollup-linux-loong64-musl@4.62.2': + resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} + '@rollup/rollup-linux-ppc64-gnu@4.62.2': + resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.60.4': - resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} + '@rollup/rollup-linux-ppc64-musl@4.62.2': + resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} + '@rollup/rollup-linux-riscv64-gnu@4.62.2': + resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.60.4': - resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} + '@rollup/rollup-linux-riscv64-musl@4.62.2': + resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.60.4': - resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} + '@rollup/rollup-linux-s390x-gnu@4.62.2': + resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.60.4': - resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} + '@rollup/rollup-linux-x64-gnu@4.62.2': + resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.60.4': - resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} + '@rollup/rollup-linux-x64-musl@4.62.2': + resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.60.4': - resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} + '@rollup/rollup-openbsd-x64@4.62.2': + resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.60.4': - resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} + '@rollup/rollup-openharmony-arm64@4.62.2': + resolution: {integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.60.4': - resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} + '@rollup/rollup-win32-arm64-msvc@4.62.2': + resolution: {integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.4': - resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} + '@rollup/rollup-win32-ia32-msvc@4.62.2': + resolution: {integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.4': - resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} + '@rollup/rollup-win32-x64-gnu@4.62.2': + resolution: {integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.60.4': - resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} + '@rollup/rollup-win32-x64-msvc@4.62.2': + resolution: {integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==} cpu: [x64] os: [win32] '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - '@sveltejs/acorn-typescript@1.0.10': - resolution: {integrity: sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==} + '@sveltejs/acorn-typescript@1.0.11': + resolution: {integrity: sha512-LFuZUkjJ9iF7JZye/aG5XM0SFcQ5VyL0oVX4WJ9dc0Va3R3s0OauX1BESVCb+YN/ol8TAfqGDDAQsTG627Y5kw==} peerDependencies: acorn: ^8.9.0 @@ -486,8 +486,8 @@ packages: peerDependencies: '@sveltejs/kit': ^2.4.0 - '@sveltejs/kit@2.70.1': - resolution: {integrity: sha512-nY9SPHGOZro3doud9vZXDBwl9tCZIouuJztjgSHs6PAIrv9M/z5O7eOhPV5xU7CgVHA976Jwu3BA1hIFvXztkA==} + '@sveltejs/kit@2.69.3': + resolution: {integrity: sha512-cphwqMRcE19/9VkrIPr5qZhQ0SptSSDfDzRUpYHu9OJDFGuYBFyJzK+KQA27wB4YG32O/yF2QjBkDmTyo0vtCw==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -616,9 +616,6 @@ packages: '@types/esrecurse@4.3.1': resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} @@ -698,8 +695,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} engines: {node: '>=0.4.0'} hasBin: true @@ -718,8 +715,8 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + brace-expansion@5.0.7: + resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} engines: {node: 18 || 20 || >=22} chokidar@4.0.3: @@ -787,8 +784,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-svelte@3.21.0: - resolution: {integrity: sha512-2dkuAk77FzQn5Ad5bJvcS6gU9iRCjywzQv6wVBR7RNseZzDsxfaIu+yzah/hTBB2znDd8Hl4oOISdhQuNyjTdQ==} + eslint-plugin-svelte@3.20.0: + resolution: {integrity: sha512-AElKLVt7Hjy4d7ljwhrhw9hux60DCxCNkmK8cY/aAXvjs8tpR7PvU4DlyI/SA1PaJww1gh0wPGo2pbyURuEwxQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 || ^10.0.0 @@ -927,16 +924,16 @@ packages: gsap@3.15.0: resolution: {integrity: sha512-dMW4CWBTUK1AEEDeZc1g4xpPGIrSf9fJF960qbTZmN/QwZIWY5wgliS6JWl9/25fpTGJrMRtSjGtOmPnfjZB+A==} - hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} engines: {node: '>= 4'} imurmurhash@0.1.4: @@ -1100,16 +1097,17 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.12: - resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + nanoid@3.3.16: + resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + obug@2.1.4: + resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} + engines: {node: '>=12.20.0'} optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} @@ -1137,10 +1135,6 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} - picomatch@4.0.5: resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} @@ -1169,14 +1163,10 @@ packages: peerDependencies: postcss: ^8.4.29 - postcss-selector-parser@7.1.1: - resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + postcss-selector-parser@7.1.4: + resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==} engines: {node: '>=4'} - postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.19: resolution: {integrity: sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==} engines: {node: ^10 || ^12 || >=14} @@ -1270,8 +1260,8 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rollup@4.60.4: - resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} + rollup@4.62.2: + resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1279,13 +1269,13 @@ packages: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} - semver@7.8.0: - resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} hasBin: true - set-cookie-parser@3.1.0: - resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==} + set-cookie-parser@3.1.2: + resolution: {integrity: sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==} shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} @@ -1338,10 +1328,6 @@ packages: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} - tinyglobby@0.2.16: - resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} - engines: {node: '>=12.0.0'} - tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} @@ -1610,153 +1596,153 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-commonjs@29.0.2(rollup@4.60.4)': + '@rollup/plugin-commonjs@29.0.3(rollup@4.62.2)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.62.2) commondir: 1.0.1 estree-walker: 2.0.2 - fdir: 6.5.0(picomatch@4.0.4) + fdir: 6.5.0(picomatch@4.0.5) is-reference: 1.2.1 magic-string: 0.30.21 - picomatch: 4.0.4 + picomatch: 4.0.5 optionalDependencies: - rollup: 4.60.4 + rollup: 4.62.2 - '@rollup/plugin-json@6.1.0(rollup@4.60.4)': + '@rollup/plugin-json@6.1.0(rollup@4.62.2)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.62.2) optionalDependencies: - rollup: 4.60.4 + rollup: 4.62.2 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.4)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.62.2)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.62.2) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.12 optionalDependencies: - rollup: 4.60.4 + rollup: 4.62.2 - '@rollup/plugin-replace@6.0.3(rollup@4.60.4)': + '@rollup/plugin-replace@6.0.3(rollup@4.62.2)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) + '@rollup/pluginutils': 5.4.0(rollup@4.62.2) magic-string: 0.30.21 optionalDependencies: - rollup: 4.60.4 + rollup: 4.62.2 - '@rollup/pluginutils@5.3.0(rollup@4.60.4)': + '@rollup/pluginutils@5.4.0(rollup@4.62.2)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 - picomatch: 4.0.4 + picomatch: 4.0.5 optionalDependencies: - rollup: 4.60.4 + rollup: 4.62.2 - '@rollup/rollup-android-arm-eabi@4.60.4': + '@rollup/rollup-android-arm-eabi@4.62.2': optional: true - '@rollup/rollup-android-arm64@4.60.4': + '@rollup/rollup-android-arm64@4.62.2': optional: true - '@rollup/rollup-darwin-arm64@4.60.4': + '@rollup/rollup-darwin-arm64@4.62.2': optional: true - '@rollup/rollup-darwin-x64@4.60.4': + '@rollup/rollup-darwin-x64@4.62.2': optional: true - '@rollup/rollup-freebsd-arm64@4.60.4': + '@rollup/rollup-freebsd-arm64@4.62.2': optional: true - '@rollup/rollup-freebsd-x64@4.60.4': + '@rollup/rollup-freebsd-x64@4.62.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': + '@rollup/rollup-linux-arm-gnueabihf@4.62.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.4': + '@rollup/rollup-linux-arm-musleabihf@4.62.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.4': + '@rollup/rollup-linux-arm64-gnu@4.62.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.60.4': + '@rollup/rollup-linux-arm64-musl@4.62.2': optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.4': + '@rollup/rollup-linux-loong64-gnu@4.62.2': optional: true - '@rollup/rollup-linux-loong64-musl@4.60.4': + '@rollup/rollup-linux-loong64-musl@4.62.2': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.4': + '@rollup/rollup-linux-ppc64-gnu@4.62.2': optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.4': + '@rollup/rollup-linux-ppc64-musl@4.62.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.4': + '@rollup/rollup-linux-riscv64-gnu@4.62.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.4': + '@rollup/rollup-linux-riscv64-musl@4.62.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.4': + '@rollup/rollup-linux-s390x-gnu@4.62.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.60.4': + '@rollup/rollup-linux-x64-gnu@4.62.2': optional: true - '@rollup/rollup-linux-x64-musl@4.60.4': + '@rollup/rollup-linux-x64-musl@4.62.2': optional: true - '@rollup/rollup-openbsd-x64@4.60.4': + '@rollup/rollup-openbsd-x64@4.62.2': optional: true - '@rollup/rollup-openharmony-arm64@4.60.4': + '@rollup/rollup-openharmony-arm64@4.62.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.4': + '@rollup/rollup-win32-arm64-msvc@4.62.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.4': + '@rollup/rollup-win32-ia32-msvc@4.62.2': optional: true - '@rollup/rollup-win32-x64-gnu@4.60.4': + '@rollup/rollup-win32-x64-gnu@4.62.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.60.4': + '@rollup/rollup-win32-x64-msvc@4.62.2': optional: true '@standard-schema/spec@1.1.0': {} - '@sveltejs/acorn-typescript@1.0.10(acorn@8.16.0)': + '@sveltejs/acorn-typescript@1.0.11(acorn@8.17.0)': dependencies: - acorn: 8.16.0 + acorn: 8.17.0 - '@sveltejs/adapter-node@5.5.7(@sveltejs/kit@2.70.1(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))': + '@sveltejs/adapter-node@5.5.7(@sveltejs/kit@2.69.3(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))': dependencies: - '@rollup/plugin-commonjs': 29.0.2(rollup@4.60.4) - '@rollup/plugin-json': 6.1.0(rollup@4.60.4) - '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.4) - '@rollup/plugin-replace': 6.0.3(rollup@4.60.4) - '@sveltejs/kit': 2.70.1(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) - rollup: 4.60.4 + '@rollup/plugin-commonjs': 29.0.3(rollup@4.62.2) + '@rollup/plugin-json': 6.1.0(rollup@4.62.2) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.62.2) + '@rollup/plugin-replace': 6.0.3(rollup@4.62.2) + '@sveltejs/kit': 2.69.3(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) + rollup: 4.62.2 - '@sveltejs/kit@2.70.1(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0))': + '@sveltejs/kit@2.69.3(@sveltejs/vite-plugin-svelte@7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)))(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3)(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0))': dependencies: '@standard-schema/spec': 1.1.0 - '@sveltejs/acorn-typescript': 1.0.10(acorn@8.16.0) + '@sveltejs/acorn-typescript': 1.0.11(acorn@8.17.0) '@sveltejs/vite-plugin-svelte': 7.2.0(svelte@5.56.6(@typescript-eslint/types@8.64.0))(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) '@types/cookie': 0.6.0 - acorn: 8.16.0 + acorn: 8.17.0 cookie: 0.7.2 devalue: 5.8.1 esm-env: 1.2.2 kleur: 4.1.5 magic-string: 0.30.21 mrmime: 2.0.1 - set-cookie-parser: 3.1.0 + set-cookie-parser: 3.1.2 sirv: 3.0.2 svelte: 5.56.6(@typescript-eslint/types@8.64.0) vite: 8.1.5(@types/node@24.12.4)(jiti@2.7.0) @@ -1769,7 +1755,7 @@ snapshots: dependencies: deepmerge: 4.3.1 magic-string: 0.30.21 - obug: 2.1.1 + obug: 2.1.4 svelte: 5.56.6(@typescript-eslint/types@8.64.0) vite: 8.1.5(@types/node@24.12.4)(jiti@2.7.0) vitefu: 1.1.3(vite@8.1.5(@types/node@24.12.4)(jiti@2.7.0)) @@ -1851,8 +1837,6 @@ snapshots: '@types/esrecurse@4.3.1': {} - '@types/estree@1.0.8': {} - '@types/estree@1.0.9': {} '@types/json-schema@7.0.15': {} @@ -1874,7 +1858,7 @@ snapshots: '@typescript-eslint/utils': 8.64.0(eslint@10.7.0(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.64.0 eslint: 10.7.0(jiti@2.7.0) - ignore: 7.0.5 + ignore: 7.0.6 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 @@ -1933,8 +1917,8 @@ snapshots: '@typescript-eslint/visitor-keys': 8.64.0 debug: 4.4.3 minimatch: 10.2.5 - semver: 7.8.0 - tinyglobby: 0.2.16 + semver: 7.8.5 + tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -1956,11 +1940,11 @@ snapshots: '@typescript-eslint/types': 8.64.0 eslint-visitor-keys: 5.0.1 - acorn-jsx@5.3.2(acorn@8.16.0): + acorn-jsx@5.3.2(acorn@8.17.0): dependencies: - acorn: 8.16.0 + acorn: 8.17.0 - acorn@8.16.0: {} + acorn@8.17.0: {} ajv@6.15.0: dependencies: @@ -1975,7 +1959,7 @@ snapshots: balanced-match@4.0.4: {} - brace-expansion@5.0.6: + brace-expansion@5.0.7: dependencies: balanced-match: 4.0.4 @@ -2022,7 +2006,7 @@ snapshots: dependencies: eslint: 10.7.0(jiti@2.7.0) - eslint-plugin-svelte@3.21.0(eslint@10.7.0(jiti@2.7.0))(svelte@5.56.6(@typescript-eslint/types@8.64.0)): + eslint-plugin-svelte@3.20.0(eslint@10.7.0(jiti@2.7.0))(svelte@5.56.6(@typescript-eslint/types@8.64.0)): dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.7.0(jiti@2.7.0)) '@jridgewell/sourcemap-codec': 1.5.5 @@ -2030,10 +2014,10 @@ snapshots: esutils: 2.0.3 globals: 16.5.0 known-css-properties: 0.37.0 - postcss: 8.5.15 - postcss-load-config: 3.1.4(postcss@8.5.15) - postcss-safe-parser: 7.0.1(postcss@8.5.15) - semver: 7.8.0 + postcss: 8.5.19 + postcss-load-config: 3.1.4(postcss@8.5.19) + postcss-safe-parser: 7.0.1(postcss@8.5.19) + semver: 7.8.5 svelte-eslint-parser: 1.8.0(svelte@5.56.6(@typescript-eslint/types@8.64.0)) optionalDependencies: svelte: 5.56.6(@typescript-eslint/types@8.64.0) @@ -2099,14 +2083,14 @@ snapshots: espree@10.4.0: dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) eslint-visitor-keys: 4.2.1 espree@11.2.0: dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) eslint-visitor-keys: 5.0.1 esquery@1.7.0: @@ -2137,9 +2121,9 @@ snapshots: fast-levenshtein@2.0.6: {} - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.5): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.5 file-entry-cache@8.0.0: dependencies: @@ -2174,19 +2158,19 @@ snapshots: gsap@3.15.0: {} - hasown@2.0.3: + hasown@2.0.4: dependencies: function-bind: 1.1.2 ignore@5.3.2: {} - ignore@7.0.5: {} + ignore@7.0.6: {} imurmurhash@0.1.4: {} is-core-module@2.16.2: dependencies: - hasown: 2.0.3 + hasown: 2.0.4 is-extglob@2.1.1: {} @@ -2294,7 +2278,7 @@ snapshots: minimatch@10.2.5: dependencies: - brace-expansion: 5.0.6 + brace-expansion: 5.0.7 mri@1.2.0: {} @@ -2302,11 +2286,11 @@ snapshots: ms@2.1.3: {} - nanoid@3.3.12: {} + nanoid@3.3.16: {} natural-compare@1.4.0: {} - obug@2.1.1: {} + obug@2.1.4: {} optionator@0.9.4: dependencies: @@ -2333,39 +2317,31 @@ snapshots: picocolors@1.1.1: {} - picomatch@4.0.4: {} - picomatch@4.0.5: {} - postcss-load-config@3.1.4(postcss@8.5.15): + postcss-load-config@3.1.4(postcss@8.5.19): dependencies: lilconfig: 2.1.0 yaml: 1.10.3 optionalDependencies: - postcss: 8.5.15 + postcss: 8.5.19 - postcss-safe-parser@7.0.1(postcss@8.5.15): + postcss-safe-parser@7.0.1(postcss@8.5.19): dependencies: - postcss: 8.5.15 + postcss: 8.5.19 - postcss-scss@4.0.9(postcss@8.5.15): + postcss-scss@4.0.9(postcss@8.5.19): dependencies: - postcss: 8.5.15 + postcss: 8.5.19 - postcss-selector-parser@7.1.1: + postcss-selector-parser@7.1.4: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss@8.5.15: - dependencies: - nanoid: 3.3.12 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.19: dependencies: - nanoid: 3.3.12 + nanoid: 3.3.16 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -2416,44 +2392,44 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.1.5 '@rolldown/binding-win32-x64-msvc': 1.1.5 - rollup@4.60.4: + rollup@4.62.2: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.4 - '@rollup/rollup-android-arm64': 4.60.4 - '@rollup/rollup-darwin-arm64': 4.60.4 - '@rollup/rollup-darwin-x64': 4.60.4 - '@rollup/rollup-freebsd-arm64': 4.60.4 - '@rollup/rollup-freebsd-x64': 4.60.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 - '@rollup/rollup-linux-arm-musleabihf': 4.60.4 - '@rollup/rollup-linux-arm64-gnu': 4.60.4 - '@rollup/rollup-linux-arm64-musl': 4.60.4 - '@rollup/rollup-linux-loong64-gnu': 4.60.4 - '@rollup/rollup-linux-loong64-musl': 4.60.4 - '@rollup/rollup-linux-ppc64-gnu': 4.60.4 - '@rollup/rollup-linux-ppc64-musl': 4.60.4 - '@rollup/rollup-linux-riscv64-gnu': 4.60.4 - '@rollup/rollup-linux-riscv64-musl': 4.60.4 - '@rollup/rollup-linux-s390x-gnu': 4.60.4 - '@rollup/rollup-linux-x64-gnu': 4.60.4 - '@rollup/rollup-linux-x64-musl': 4.60.4 - '@rollup/rollup-openbsd-x64': 4.60.4 - '@rollup/rollup-openharmony-arm64': 4.60.4 - '@rollup/rollup-win32-arm64-msvc': 4.60.4 - '@rollup/rollup-win32-ia32-msvc': 4.60.4 - '@rollup/rollup-win32-x64-gnu': 4.60.4 - '@rollup/rollup-win32-x64-msvc': 4.60.4 + '@rollup/rollup-android-arm-eabi': 4.62.2 + '@rollup/rollup-android-arm64': 4.62.2 + '@rollup/rollup-darwin-arm64': 4.62.2 + '@rollup/rollup-darwin-x64': 4.62.2 + '@rollup/rollup-freebsd-arm64': 4.62.2 + '@rollup/rollup-freebsd-x64': 4.62.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.62.2 + '@rollup/rollup-linux-arm-musleabihf': 4.62.2 + '@rollup/rollup-linux-arm64-gnu': 4.62.2 + '@rollup/rollup-linux-arm64-musl': 4.62.2 + '@rollup/rollup-linux-loong64-gnu': 4.62.2 + '@rollup/rollup-linux-loong64-musl': 4.62.2 + '@rollup/rollup-linux-ppc64-gnu': 4.62.2 + '@rollup/rollup-linux-ppc64-musl': 4.62.2 + '@rollup/rollup-linux-riscv64-gnu': 4.62.2 + '@rollup/rollup-linux-riscv64-musl': 4.62.2 + '@rollup/rollup-linux-s390x-gnu': 4.62.2 + '@rollup/rollup-linux-x64-gnu': 4.62.2 + '@rollup/rollup-linux-x64-musl': 4.62.2 + '@rollup/rollup-openbsd-x64': 4.62.2 + '@rollup/rollup-openharmony-arm64': 4.62.2 + '@rollup/rollup-win32-arm64-msvc': 4.62.2 + '@rollup/rollup-win32-ia32-msvc': 4.62.2 + '@rollup/rollup-win32-x64-gnu': 4.62.2 + '@rollup/rollup-win32-x64-msvc': 4.62.2 fsevents: 2.3.3 sade@1.8.1: dependencies: mri: 1.2.0 - semver@7.8.0: {} + semver@7.8.5: {} - set-cookie-parser@3.1.0: {} + set-cookie-parser@3.1.2: {} shebang-command@2.0.0: dependencies: @@ -2471,12 +2447,12 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.7.3(picomatch@4.0.4)(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3): + svelte-check@4.7.3(picomatch@4.0.5)(svelte@5.56.6(@typescript-eslint/types@8.64.0))(typescript@6.0.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 '@sveltejs/load-config': 0.2.0 chokidar: 4.0.3 - fdir: 6.5.0(picomatch@4.0.4) + fdir: 6.5.0(picomatch@4.0.5) picocolors: 1.1.1 sade: 1.8.1 svelte: 5.56.6(@typescript-eslint/types@8.64.0) @@ -2489,10 +2465,10 @@ snapshots: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 espree: 10.4.0 - postcss: 8.5.15 - postcss-scss: 4.0.9(postcss@8.5.15) - postcss-selector-parser: 7.1.1 - semver: 7.8.0 + postcss: 8.5.19 + postcss-scss: 4.0.9(postcss@8.5.19) + postcss-selector-parser: 7.1.4 + semver: 7.8.5 optionalDependencies: svelte: 5.56.6(@typescript-eslint/types@8.64.0) @@ -2500,10 +2476,10 @@ snapshots: dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 - '@sveltejs/acorn-typescript': 1.0.10(acorn@8.16.0) + '@sveltejs/acorn-typescript': 1.0.11(acorn@8.17.0) '@types/estree': 1.0.9 '@types/trusted-types': 2.0.7 - acorn: 8.16.0 + acorn: 8.17.0 aria-query: 5.3.1 axobject-query: 4.1.0 clsx: 2.1.1 @@ -2523,15 +2499,10 @@ snapshots: tapable@2.3.3: {} - tinyglobby@0.2.16: - dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 totalist@3.0.1: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5fff66b..0d87beb 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,10 +1,6 @@ packages: - . -minimumReleaseAgeExclude: - - '@sveltejs/kit@2.70.1' - - eslint-plugin-svelte@3.21.0 - overrides: cookie: 0.7.2 diff --git a/renovate.json b/renovate.json index c072508..1b58611 100644 --- a/renovate.json +++ b/renovate.json @@ -3,6 +3,7 @@ "extends": ["config:recommended"], "dependencyDashboard": true, "labels": ["dependencies"], + "minimumReleaseAge": "3 days", "packageRules": [ { "matchManagers": ["npm"], diff --git a/src/lib/blog/posts.ts b/src/lib/blog/posts.ts index 54bcbaa..340e208 100644 --- a/src/lib/blog/posts.ts +++ b/src/lib/blog/posts.ts @@ -39,7 +39,7 @@ export const posts: Post[] = [ { type: 'heading', text: 'Stop Loss: где ваша позиция неправа' }, { type: 'paragraph', - text: 'Stop Loss — уровень, при достижении которого позиция закрывается автоматически. Это не признание ошибки, а часть стратегии. На графиках Flamy AI уровень SL рассчитывается моделью на основе исторической волатильности инструмента.' + text: 'Stop Loss — уровень, при достижении которого позиция закрывается автоматически. Это не признание ошибки, а часть стратегии. На графиках Flamy Trade уровень SL рассчитывается моделью на основе исторической волатильности инструмента.' }, { type: 'heading', text: 'Take Profit: когда забирать прибыль' }, { @@ -70,13 +70,13 @@ export const posts: Post[] = [ id: 2, slug: 'kak-chitat-grafiki-flamy-ai', date: '2026-05-17', - title: 'Как читать графики Flamy AI', - description: 'Краткое объяснение свечей, прогнозной зоны, TP и SL на графиках Flamy AI.', + title: 'Как читать графики Flamy Trade', + description: 'Краткое объяснение свечей, прогнозной зоны, TP и SL на графиках Flamy Trade.', tags: ['ML', 'FORECAST', 'CHARTS'], content: [ { type: 'paragraph', - text: 'Графики Flamy AI содержат три слоя: исторические свечи, прогнозную зону и уровни торгового плана. Разберём каждый из них.' + text: 'Графики Flamy Trade содержат три слоя: исторические свечи, прогнозную зону и уровни торгового плана. Разберём каждый из них.' }, { type: 'heading', text: 'Исторические свечи' }, { diff --git a/src/lib/components/Chart.svelte b/src/lib/components/Chart.svelte index 27fd733..bb9adea 100644 --- a/src/lib/components/Chart.svelte +++ b/src/lib/components/Chart.svelte @@ -7,6 +7,7 @@ CrosshairMode, LineStyle, type IChartApi, + type IPriceLine, type ISeriesApi, type MouseEventParams, type UTCTimestamp @@ -25,8 +26,7 @@ let chart: IChartApi | undefined; let candleSeries: ISeriesApi<'Candlestick'> | undefined; let predSeries: ISeriesApi<'Line'> | undefined; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - let priceLines: any[] = []; + let priceLines: IPriceLine[] = []; type Tooltip = { visible: boolean; diff --git a/src/lib/components/layout/Header.svelte b/src/lib/components/layout/Header.svelte index 46d1a9e..470c021 100644 --- a/src/lib/components/layout/Header.svelte +++ b/src/lib/components/layout/Header.svelte @@ -1,4 +1,6 @@ + +
@@ -37,6 +67,7 @@ {link.text} @@ -46,10 +77,13 @@ +{/if} diff --git a/src/lib/components/ui/Logo.svelte b/src/lib/components/ui/Logo.svelte index 1b45ef4..23b647f 100644 --- a/src/lib/components/ui/Logo.svelte +++ b/src/lib/components/ui/Logo.svelte @@ -2,7 +2,7 @@ - Логотип + FLAMYTRADE diff --git a/src/lib/config/site.ts b/src/lib/config/site.ts index 6508cba..9140ff1 100644 --- a/src/lib/config/site.ts +++ b/src/lib/config/site.ts @@ -6,6 +6,12 @@ export const site = { description: env.PUBLIC_SITE_DESCRIPTION || 'Публичная витрина ML-прогнозов для крипторынка.' }; +export type PageMeta = { + title: string; + description: string; + url: string; +}; + export function pageTitle(title?: string): string { return title ? `${title} | ${site.name}` : site.name; } @@ -14,3 +20,19 @@ export function canonical(path = '/'): string { const normalizedPath = path.startsWith('/') ? path : `/${path}`; return `${site.url}${normalizedPath}`; } + +export function pageMeta({ + title, + description = site.description, + path = '/' +}: { + title?: string; + description?: string; + path?: string; +} = {}): PageMeta { + return { + title: pageTitle(title), + description, + url: canonical(path) + }; +} diff --git a/src/lib/data/dashboard.ts b/src/lib/data/dashboard.ts new file mode 100644 index 0000000..d926b12 --- /dev/null +++ b/src/lib/data/dashboard.ts @@ -0,0 +1,29 @@ +import { env } from '$env/dynamic/public'; +import { + generateChartData, + SYMBOLS, + TIMEFRAMES, + type ChartData, + type TimeframeId +} from '$lib/stores/chartStore'; + +const supportedModes = ['research-static'] as const; + +export type DashboardDataMode = (typeof supportedModes)[number]; + +export const dashboardDataMode: DashboardDataMode = supportedModes.includes( + env.PUBLIC_DASHBOARD_DATA_MODE as DashboardDataMode +) + ? (env.PUBLIC_DASHBOARD_DATA_MODE as DashboardDataMode) + : 'research-static'; + +export const dashboardDataNotice = + dashboardDataMode === 'research-static' + ? 'Исследовательские синтетические данные' + : 'Исследовательские данные'; + +export function getDashboardChartData(symbolId: string, timeframeId: TimeframeId): ChartData { + return generateChartData(symbolId, timeframeId); +} + +export { SYMBOLS, TIMEFRAMES }; diff --git a/src/routes/(sections)/Hero.svelte b/src/routes/(sections)/Hero.svelte index 3db31fc..b67ec91 100644 --- a/src/routes/(sections)/Hero.svelte +++ b/src/routes/(sections)/Hero.svelte @@ -70,10 +70,6 @@
- - diff --git a/src/routes/+error.svelte b/src/routes/+error.svelte index 8845b33..92ae113 100644 --- a/src/routes/+error.svelte +++ b/src/routes/+error.svelte @@ -1,10 +1,25 @@ - {pageTitle('Страница не найдена')} + {pageTitle(title)} +
@@ -13,10 +28,10 @@ Ошибка {page.status}

- Страница не найдена + {title}

- Проверьте адрес или вернитесь к публичному дашборду Flamy Trade. + {description}

- {pageTitle()} - - - - - - - -
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index d30ca57..1b78d86 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -7,16 +7,21 @@ import BlogPreview from './(sections)/BlogPreview.svelte'; import Cta from './(sections)/Cta.svelte'; import { posts } from '$lib/blog/posts'; - import { canonical, pageTitle, site } from '$lib/config/site'; + import { pageMeta } from '$lib/config/site'; + + const meta = pageMeta(); - {pageTitle()} - - - - - + {meta.title} + + + + + + + +
diff --git a/src/routes/about/+page.svelte b/src/routes/about/+page.svelte index 501ef4a..ca4a2bc 100644 --- a/src/routes/about/+page.svelte +++ b/src/routes/about/+page.svelte @@ -1,23 +1,27 @@ - - {pageTitle('О проекте')} - - - - - + {meta.title} + + + + + + + +
@@ -39,10 +43,6 @@ Публичная витрина результатов ML-модели, обученной на исторических рыночных данных.

- -
@@ -74,7 +74,6 @@ {:else} -
- ⚠ Дисклеймер + Дисклеймер

Материалы являются результатом работы исследовательской ML-модели и используются в diff --git a/src/routes/about/_data.ts b/src/routes/about/_data.ts index 0995530..5869637 100644 --- a/src/routes/about/_data.ts +++ b/src/routes/about/_data.ts @@ -19,7 +19,7 @@ export const about: About[] = [ desc: 'Назначение', title: 'Исследовательская платформа', text: [ - 'Flamy AI — публичная витрина результатов ML-модели, обученной на исторических рыночных данных. Показывает прогнозы по крипто-инструментам: направление, уровни входа, Take Profit и Stop Loss.', + 'Flamy Trade — публичная витрина результатов ML-модели, обученной на исторических рыночных данных. Показывает прогнозы по крипто-инструментам: направление, уровни входа, Take Profit и Stop Loss.', 'Платформа создана для изучения поведения ML-модели в рыночных условиях — не для торговли реальными средствами.' ] }, diff --git a/src/routes/blog/+page.svelte b/src/routes/blog/+page.svelte index 80732a3..afb0e20 100644 --- a/src/routes/blog/+page.svelte +++ b/src/routes/blog/+page.svelte @@ -1,7 +1,14 @@ - - {pageTitle('Блог')} - - - - - + {meta.title} + + + + + + + +

@@ -47,10 +51,6 @@ Гайды по чтению графиков, управлению рисками и работе с ML-прогнозами.

- -
@@ -139,7 +146,7 @@ font-size: 1.25rem; font-weight: 800; color: var(--color-title); - letter-spacing: -0.025em; + letter-spacing: 0; line-height: 1.2; margin-top: 2.25em; margin-bottom: 0.75em; @@ -149,7 +156,7 @@ font-size: 1.0625rem; font-weight: 700; color: var(--color-title); - letter-spacing: -0.02em; + letter-spacing: 0; margin-top: 1.75em; margin-bottom: 0.5em; } diff --git a/src/routes/blog/[slug]/+page.ts b/src/routes/blog/[slug]/+page.ts index acb118c..133384a 100644 --- a/src/routes/blog/[slug]/+page.ts +++ b/src/routes/blog/[slug]/+page.ts @@ -1,4 +1,4 @@ -import { error } from '@sveltejs/kit'; +import { error } from '@sveltejs/kit'; import { getPostBySlug } from '$lib/blog/posts'; import type { PageLoad } from './$types'; diff --git a/src/routes/dashboard/+page.svelte b/src/routes/dashboard/+page.svelte index d3f6f8f..97f2dbb 100644 --- a/src/routes/dashboard/+page.svelte +++ b/src/routes/dashboard/+page.svelte @@ -1,17 +1,30 @@ - {pageTitle('Дашборд')} - - - - - + {meta.title} + + + + + + + +
@@ -89,7 +99,7 @@ Дашборд

- ML-прогноз · Горизонт 19 свечей · Таймфрейм 5M + {dashboardDataNotice} · Горизонт 19 свечей · Таймфрейм {activeTimeframe.toUpperCase()}

@@ -112,6 +122,7 @@ : 'border-transparent text-desc hover:text-title' )} onclick={() => (activeSymbol = s.id)} + aria-pressed={activeSymbol === s.id} > {s.short} @@ -126,6 +137,7 @@ activeTimeframe === tf.id ? 'bg-bg-h text-title' : 'text-desc hover:text-title' )} onclick={() => (activeTimeframe = tf.id)} + aria-pressed={activeTimeframe === tf.id} > {tf.label} @@ -177,7 +189,14 @@ > Уверенность -
+
- не является инвестиционной рекомендацией + исследовательские данные · не является инвестиционной рекомендацией
- -
diff --git a/src/routes/robots.txt/+server.ts b/src/routes/robots.txt/+server.ts new file mode 100644 index 0000000..08a53b9 --- /dev/null +++ b/src/routes/robots.txt/+server.ts @@ -0,0 +1,16 @@ +import { canonical } from '$lib/config/site'; + +export const GET = () => { + const body = `User-agent: * +Allow: / + +Sitemap: ${canonical('/sitemap.xml')} +`; + + return new Response(body, { + headers: { + 'content-type': 'text/plain; charset=utf-8', + 'cache-control': 'public, max-age=3600' + } + }); +}; diff --git a/static/robots.txt b/static/robots.txt deleted file mode 100644 index c5ee0f8..0000000 --- a/static/robots.txt +++ /dev/null @@ -1,4 +0,0 @@ -User-agent: * -Allow: / - -Sitemap: https://trade.flamy.studio/sitemap.xml diff --git a/svelte.config.js b/svelte.config.js index a1656f4..ede7693 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -6,7 +6,24 @@ const config = { // Force runes mode for the project, except for libraries. Can be removed in svelte 6. runes: ({ filename }) => (filename.split(/[/\\]/).includes('node_modules') ? undefined : true) }, - kit: { adapter: adapter() } + kit: { + adapter: adapter(), + csp: { + mode: 'auto', + directives: { + 'default-src': ['self'], + 'script-src': ['self'], + 'style-src': ['self', 'unsafe-inline'], + 'img-src': ['self', 'data:'], + 'font-src': ['self'], + 'connect-src': ['self'], + 'object-src': ['none'], + 'base-uri': ['self'], + 'frame-ancestors': ['self'], + 'form-action': ['self'] + } + } + } }; export default config;