From 037928c77874a4335bc46eb0718cf4c467511045 Mon Sep 17 00:00:00 2001 From: R524809 Date: Thu, 3 Sep 2026 13:11:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(api):=20=E5=BC=80=E5=8F=91auth=E3=80=81log?= =?UTF-8?q?in=E7=AD=89=E6=8E=A5=E5=8F=A3=EF=BC=8C=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 69 +- .prettierrc | 9 + apps/api/.prettierrc | 9 + apps/api/package.json | 53 +- apps/api/src/app.module.ts | 39 +- apps/api/src/auth/auth.controller.ts | 206 + apps/api/src/auth/auth.crypto.ts | 91 + apps/api/src/auth/auth.guard.ts | 21 + apps/api/src/auth/auth.module.ts | 10 + apps/api/src/auth/auth.service.ts | 340 + apps/api/src/common/api-error.filter.ts | 61 + apps/api/src/common/api-error.ts | 12 + apps/api/src/config/app-config.module.ts | 124 + apps/api/src/database/database.module.ts | 24 + apps/api/src/logging/app-logger.ts | 60 + apps/api/src/main.ts | 149 +- .../src/security/auth-rate-limiter.service.ts | 102 + apps/api/src/security/security.module.ts | 6 + apps/api/tsconfig.json | 18 +- apps/extension/entrypoints/background.ts | 2 +- apps/extension/package.json | 42 +- apps/extension/tsconfig.json | 12 +- apps/extension/wxt.config.ts | 40 +- apps/web/index.html | 18 +- apps/web/package.json | 50 +- apps/web/prettier.config.mjs | 19 + apps/web/src/App.tsx | 38 +- apps/web/src/components/PagePlaceholder.tsx | 26 +- apps/web/src/config/env.ts | 14 +- apps/web/src/index.css | 52 +- apps/web/src/layouts/AuthLayout.css | 86 +- apps/web/src/layouts/AuthLayout.tsx | 50 +- apps/web/src/layouts/MainLayout.css | 138 +- apps/web/src/layouts/MainLayout.tsx | 187 +- apps/web/src/layouts/SidebarMenu.css | 124 +- apps/web/src/layouts/SidebarMenu.tsx | 90 +- apps/web/src/layouts/menuConfig.tsx | 141 +- apps/web/src/main.tsx | 6 +- apps/web/src/pages/auth/LoginPage.tsx | 150 +- apps/web/src/pages/auth/RegisterPage.tsx | 257 +- .../src/pages/collection/CollectionPage.tsx | 2 +- .../online-products/OnlineProductsPage.tsx | 8 +- apps/web/src/pages/pricing/PricingPage.tsx | 5 +- .../src/pages/products/ProductEditPage.tsx | 14 +- apps/web/src/pages/shops/ShopsPage.tsx | 5 +- .../src/pages/watermarks/WatermarksPage.tsx | 5 +- apps/web/src/router/index.tsx | 39 +- apps/web/src/services/api.ts | 152 +- apps/web/src/services/auth.ts | 17 +- apps/web/src/services/authToken.ts | 14 +- apps/web/src/types/auth.ts | 56 +- apps/web/src/utils/validators.ts | 8 +- apps/web/tsconfig.json | 38 +- apps/web/vite.config.ts | 28 +- apps/worker/package.json | 38 +- apps/worker/src/main.ts | 19 +- apps/worker/tsconfig.json | 14 +- docs/api/README.md | 4 + docs/api/conventions.md | 19 + docs/architecture/database-security.md | 19 +- docs/project/HANDOFF.md | 1 + infra/README.md | 7 +- infra/compose.yaml | 79 +- infra/postgres/init/001-roles.sh | 19 + package.json | 12 +- packages/contracts/package.json | 36 +- packages/contracts/src/auth.ts | 36 + packages/contracts/src/collection.ts | 32 +- packages/contracts/src/index.ts | 1 + packages/contracts/tsconfig.json | 12 +- .../database/migrations/001_foundation.sql | 678 ++ .../database/migrations/002_seed_global.sql | 17 + packages/database/package.json | 34 +- packages/database/src/index.ts | 7 +- packages/database/src/migrate.ts | 70 + packages/database/src/pool.ts | 59 + packages/database/tsconfig.json | 12 +- pnpm-lock.yaml | 9802 ++++++++++------- pnpm-workspace.yaml | 1 + prettier.config.mjs | 5 - tsconfig.base.json | 24 +- turbo.json | 42 +- 82 files changed, 9199 insertions(+), 5236 deletions(-) create mode 100644 .prettierrc create mode 100644 apps/api/.prettierrc create mode 100644 apps/api/src/auth/auth.controller.ts create mode 100644 apps/api/src/auth/auth.crypto.ts create mode 100644 apps/api/src/auth/auth.guard.ts create mode 100644 apps/api/src/auth/auth.module.ts create mode 100644 apps/api/src/auth/auth.service.ts create mode 100644 apps/api/src/common/api-error.filter.ts create mode 100644 apps/api/src/common/api-error.ts create mode 100644 apps/api/src/config/app-config.module.ts create mode 100644 apps/api/src/database/database.module.ts create mode 100644 apps/api/src/logging/app-logger.ts create mode 100644 apps/api/src/security/auth-rate-limiter.service.ts create mode 100644 apps/api/src/security/security.module.ts create mode 100644 apps/web/prettier.config.mjs create mode 100755 infra/postgres/init/001-roles.sh create mode 100644 packages/contracts/src/auth.ts create mode 100644 packages/database/migrations/001_foundation.sql create mode 100644 packages/database/migrations/002_seed_global.sql create mode 100644 packages/database/src/migrate.ts create mode 100644 packages/database/src/pool.ts delete mode 100644 prettier.config.mjs diff --git a/.env.example b/.env.example index 6b86fe9..6a605fe 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,67 @@ -POSTGRES_USER=atlas_app_login -POSTGRES_PASSWORD=change-me-local-only +# Local PostgreSQL bootstrap administrator. It creates roles but must never be used by API or Worker. +POSTGRES_ADMIN_USER=atlas_admin +POSTGRES_ADMIN_PASSWORD=change-me-local-only +# Database name and host port exposed by local Docker Compose. POSTGRES_DB=atlas POSTGRES_PORT=5432 -REDIS_URL=redis://localhost:6379 -MINIO_ROOT_USER=atlas_minio_local -MINIO_ROOT_PASSWORD=change-me-local-only -MINIO_PORT=9000 -MINIO_CONSOLE_PORT=9001 + +# Password for the schema-owning migrator role; only the migration runner may use it. +ATLAS_MIGRATOR_PASSWORD=change-me-local-only +# Password for the least-privileged API/Worker login role. +ATLAS_APP_PASSWORD=change-me-local-only +# API/Worker application connection. This role has no table ownership and is constrained by RLS. +DATABASE_URL=postgresql://atlas_app_login:change-me-local-only@localhost:5432/atlas +# Migration-only connection. Do not put this value in production API or Worker environments. +MIGRATOR_DATABASE_URL=postgresql://atlas_migrator:change-me-local-only@localhost:5432/atlas + +# Runtime mode controls production-only safeguards such as Secure cookies. +NODE_ENV=development +# Browser origin allowed to send credentialed requests to this API. +WEB_ORIGIN=http://localhost:8100 +# HTTP listener port for the NestJS API. API_PORT=8200 + +# HMAC signing secret for short-lived access JWTs; replace with a unique 32+ character secret. +AUTH_JWT_SECRET=replace-with-a-random-secret-of-at-least-32-characters +# Separate HMAC secret used to pseudonymize IP/email values in Redis rate-limit keys. +AUTH_RATE_LIMIT_KEY_SECRET=replace-with-a-different-random-secret-of-at-least-32-characters +# Server-side minimum password length. The browser must not weaken this rule. +AUTH_PASSWORD_MIN_LENGTH=12 +# Maximum JSON or URL-encoded request size in bytes. Media files must use object-storage direct upload. +API_BODY_LIMIT_BYTES=1048576 +# Shared fixed-window duration for authentication rate limits, in seconds. +AUTH_RATE_LIMIT_WINDOW_SECONDS=900 +# Maximum login attempts per IP inside the window. +AUTH_LOGIN_IP_LIMIT=10 +# Maximum login attempts per normalized email inside the window. +AUTH_LOGIN_EMAIL_LIMIT=5 +# Maximum registration attempts per IP inside the window. +AUTH_REGISTER_IP_LIMIT=5 +# Maximum registration attempts per normalized email inside the window. +AUTH_REGISTER_EMAIL_LIMIT=3 +# Maximum refresh attempts per IP inside the window; refresh tokens have no trusted email before validation. +AUTH_REFRESH_IP_LIMIT=30 + +# Comma-separated trusted reverse-proxy IPs/CIDRs. Keep empty for direct local access; never set to true. +TRUSTED_PROXY_CIDRS= +# Whether to expose Swagger UI at /api-docs. +SWAGGER_ENABLED=true +# Minimum structured-log severity: error, warn, log, or debug. +LOG_LEVEL=log + +# Redis endpoint used by BullMQ and shared authentication rate limits. +REDIS_URL=redis://localhost:6379 + +# Local MinIO root account; it is only for Docker bootstrap, not browser credentials. +MINIO_ROOT_USER=atlas_minio_local +# Local MinIO root password; replace outside disposable local development. +MINIO_ROOT_PASSWORD=change-me-local-only +# S3-compatible API port for local MinIO. +MINIO_PORT=9000 +# MinIO administrative console port. +MINIO_CONSOLE_PORT=9001 + +# Local Vite frontend port. WEB_PORT=8100 +# Local WXT browser-extension development port. EXTENSION_PORT=8110 diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..6ed4756 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "always", + "printWidth": 80, + "tabWidth": 4, + "useTabs": false +} diff --git a/apps/api/.prettierrc b/apps/api/.prettierrc new file mode 100644 index 0000000..6ed4756 --- /dev/null +++ b/apps/api/.prettierrc @@ -0,0 +1,9 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "bracketSpacing": true, + "arrowParens": "always", + "printWidth": 80, + "tabWidth": 4, + "useTabs": false +} diff --git a/apps/api/package.json b/apps/api/package.json index 4ca8230..8b3fc44 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,25 +1,32 @@ { - "name": "@atlas/api", - "version": "0.1.0", - "private": true, - "type": "module", - "scripts": { - "build": "tsc -p tsconfig.json", - "dev": "tsx watch src/main.ts", - "start": "node dist/main.js", - "typecheck": "tsc -p tsconfig.json --noEmit" - }, - "dependencies": { - "@atlas/contracts": "workspace:*", - "@nestjs/common": "12.0.1", - "@nestjs/core": "12.0.1", - "@nestjs/platform-express": "12.0.1", - "reflect-metadata": "0.2.2", - "rxjs": "7.8.2" - }, - "devDependencies": { - "@types/node": "26.3.0", - "tsx": "4.23.13", - "typescript": "7.0.2" - } + "name": "@atlas/api", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "build": "tsc -p tsconfig.json", + "dev": "tsx watch src/main.ts", + "start": "node dist/main.js", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "@atlas/contracts": "workspace:*", + "@atlas/database": "workspace:*", + "@nestjs/common": "12.0.1", + "@nestjs/config": "12.0.0", + "@nestjs/core": "12.0.1", + "@nestjs/platform-express": "12.0.1", + "@nestjs/swagger": "12.0.1", + "helmet": "8.3.0", + "ioredis": "6.0.0", + "reflect-metadata": "0.2.2", + "rxjs": "7.8.2", + "zod": "4.5.4" + }, + "devDependencies": { + "@types/express": "5.0.6", + "@types/node": "26.3.0", + "tsx": "4.23.13", + "typescript": "7.0.2" + } } diff --git a/apps/api/src/app.module.ts b/apps/api/src/app.module.ts index 6b78d2a..ab85830 100644 --- a/apps/api/src/app.module.ts +++ b/apps/api/src/app.module.ts @@ -1,12 +1,37 @@ -import { Controller, Get, Module } from '@nestjs/common'; +import { Controller, Get, Inject, Module } from '@nestjs/common'; +import type { Database } from '@atlas/database'; +import { AuthModule } from './auth/auth.module.js'; +import { ApiError } from './common/api-error.js'; +import { AppConfigModule } from './config/app-config.module.js'; +import { DATABASE, DatabaseModule } from './database/database.module.js'; +import { SecurityModule } from './security/security.module.js'; -@Controller('health') +@Controller() class HealthController { - @Get() - check() { - return { status: 'ok', service: 'api' }; - } + public constructor(@Inject(DATABASE) private readonly database: Database) {} + + @Get('health') + check() { + return { status: 'ok', service: 'api' }; + } + + @Get('ready') + async ready() { + try { + await this.database.query('SELECT 1'); + return { status: 'ready', service: 'api' }; + } catch { + throw new ApiError( + 503, + 'DEPENDENCY_UNAVAILABLE', + '服务依赖暂不可用', + ); + } + } } -@Module({ controllers: [HealthController] }) +@Module({ + imports: [AppConfigModule, DatabaseModule, SecurityModule, AuthModule], + controllers: [HealthController], +}) export class AppModule {} diff --git a/apps/api/src/auth/auth.controller.ts b/apps/api/src/auth/auth.controller.ts new file mode 100644 index 0000000..65ab4da --- /dev/null +++ b/apps/api/src/auth/auth.controller.ts @@ -0,0 +1,206 @@ +import { + Body, + Controller, + Get, + HttpCode, + Post, + Req, + Res, + UseGuards, +} from '@nestjs/common'; +import { + ApiBearerAuth, + ApiBody, + ApiNoContentResponse, + ApiOkResponse, + ApiOperation, + ApiTags, + ApiUnauthorizedResponse, +} from '@nestjs/swagger'; +import { createHash } from 'node:crypto'; +import { loginRequestSchema, registerRequestSchema } from '@atlas/contracts'; +import { ApiError } from '../common/api-error.js'; +import { AccessTokenGuard, type AuthenticatedRequest } from './auth.guard.js'; +import { AuthService, type RequestMetadata } from './auth.service.js'; + +const refreshCookie = 'atlas_refresh'; +type HttpRequest = { + header: (name: string) => string | undefined; + ip?: string; +}; +type HttpResponse = { + cookie: ( + name: string, + value: string, + options: Record, + ) => void; + clearCookie: (name: string, options: Record) => void; +}; + +@ApiTags('Authentication') +@Controller('auth') +export class AuthController { + public constructor(private readonly authService: AuthService) {} + + @Post('register') + @ApiOperation({ summary: '注册账户并创建个人工作空间' }) + @ApiBody({ + schema: { + example: { + email: 'owner@example.com', + password: 'a-strong-password', + password_confirmation: 'a-strong-password', + display_name: 'Joey', + }, + }, + }) + public async register( + @Body() body: unknown, + @Req() request: HttpRequest, + @Res({ passthrough: true }) response: HttpResponse, + ) { + const result = await this.authService.register( + parse(registerRequestSchema, body), + metadata(request), + ); + setRefreshCookie(response, result.refreshToken); + return { data: result.payload }; + } + + @Post('login') + @ApiOperation({ summary: '使用邮箱和密码登录' }) + @ApiBody({ + schema: { + example: { + email: 'owner@example.com', + password: 'a-strong-password', + }, + }, + }) + public async login( + @Body() body: unknown, + @Req() request: HttpRequest, + @Res({ passthrough: true }) response: HttpResponse, + ) { + const result = await this.authService.login( + parse(loginRequestSchema, body), + metadata(request), + ); + setRefreshCookie(response, result.refreshToken); + return { data: result.payload }; + } + + @Post('refresh') + @ApiOperation({ summary: '轮换 refresh cookie 并获取新的 access token' }) + public async refresh( + @Req() request: HttpRequest, + @Res({ passthrough: true }) response: HttpResponse, + ) { + try { + const result = await this.authService.refresh( + readCookie(request.header('cookie'), refreshCookie), + metadata(request), + ); + setRefreshCookie(response, result.refreshToken); + return { + data: { + access_token: result.payload.access_token, + access_token_expires_in: + result.payload.access_token_expires_in, + }, + }; + } catch (error) { + clearRefreshCookie(response); + throw error; + } + } + + @Post('logout') + @HttpCode(204) + @UseGuards(AccessTokenGuard) + @ApiBearerAuth('access-token') + @ApiOperation({ summary: '撤销当前登录会话' }) + @ApiNoContentResponse({ description: '会话已撤销' }) + @ApiUnauthorizedResponse({ description: 'access token 无效或已过期' }) + public async logout( + @Req() request: AuthenticatedRequest, + @Res({ passthrough: true }) response: HttpResponse, + ) { + await this.authService.logout(request.auth.sessionId); + clearRefreshCookie(response); + } + + @Get('me') + @UseGuards(AccessTokenGuard) + @ApiBearerAuth('access-token') + @ApiOperation({ summary: '获取当前用户、工作空间和页头初始上下文' }) + @ApiOkResponse({ description: '当前身份和工作空间' }) + @ApiUnauthorizedResponse({ description: 'access token 无效或已过期' }) + public async me(@Req() request: AuthenticatedRequest) { + return { data: await this.authService.me(request.auth.userId) }; + } +} + +function parse< + T extends { + safeParse: (value: unknown) => { + success: boolean; + data?: unknown; + error?: { issues: Array<{ path: PropertyKey[]; message: string }> }; + }; + }, +>(schema: T, value: unknown) { + const result = schema.safeParse(value); + if (result.success) + return result.data as ReturnType extends { + data: infer Data; + } + ? Data + : never; + throw new ApiError( + 422, + 'VALIDATION_FAILED', + '请求参数不符合要求', + result.error?.issues.map((issue) => ({ + field: issue.path.join('.'), + code: 'INVALID_FIELD', + message: issue.message, + })), + ); +} +function metadata(request: HttpRequest): RequestMetadata { + return { + ip: request.ip ?? null, + ipHash: request.ip + ? createHash('sha256').update(request.ip).digest('base64url') + : null, + userAgent: request.header('user-agent') ?? null, + }; +} +function cookieOptions() { + return { + httpOnly: true, + secure: process.env.NODE_ENV === 'production', + sameSite: 'lax' as const, + path: '/api/auth', + maxAge: 30 * 24 * 60 * 60 * 1000, + }; +} +function setRefreshCookie(response: HttpResponse, token: string) { + response.cookie(refreshCookie, token, cookieOptions()); +} +function clearRefreshCookie(response: HttpResponse) { + response.clearCookie(refreshCookie, { + httpOnly: true, + secure: process.env.NODE_ENV === 'production', + sameSite: 'lax', + path: '/api/auth', + }); +} +function readCookie(header: string | undefined, name: string) { + return header + ?.split(';') + .map((part) => part.trim()) + .find((part) => part.startsWith(`${name}=`)) + ?.slice(name.length + 1); +} diff --git a/apps/api/src/auth/auth.crypto.ts b/apps/api/src/auth/auth.crypto.ts new file mode 100644 index 0000000..bf3735a --- /dev/null +++ b/apps/api/src/auth/auth.crypto.ts @@ -0,0 +1,91 @@ +import { + createHash, + createHmac, + randomBytes, + scrypt as scryptCallback, + timingSafeEqual, +} from 'node:crypto'; +import { promisify } from 'node:util'; + +const scrypt = promisify(scryptCallback) as ( + password: string, + salt: string, + keyLength: number, + options: { N: number; r: number; p: number; maxmem: number }, +) => Promise; +const scryptOptions = { N: 16_384, r: 8, p: 1, maxmem: 32 * 1024 * 1024 }; + +export async function hashPassword(password: string): Promise { + // The random salt and expensive KDF keep a database leak from exposing passwords directly. + const salt = randomBytes(16).toString('base64url'); + const derived = (await scrypt(password, salt, 64, scryptOptions)) as Buffer; + return `scrypt$${salt}$${derived.toString('base64url')}`; +} + +export async function verifyPassword( + password: string, + encoded: string, +): Promise { + const [algorithm, salt, expected] = encoded.split('$'); + if (algorithm !== 'scrypt' || !salt || !expected) return false; + const actual = (await scrypt(password, salt, 64, scryptOptions)) as Buffer; + const expectedBuffer = Buffer.from(expected, 'base64url'); + return ( + expectedBuffer.length === actual.length && + timingSafeEqual(expectedBuffer, actual) + ); +} + +export function createOpaqueToken(): string { + return randomBytes(48).toString('base64url'); +} +export function tokenHash(token: string): string { + return createHash('sha256').update(token).digest('base64url'); +} + +export type AccessTokenClaims = { + sub: string; + sid: string; + exp: number; + iat: number; +}; +export function signAccessToken( + claims: AccessTokenClaims, + secret: string, +): string { + // Access tokens are short-lived; refresh sessions remain revocable in PostgreSQL. + const header = Buffer.from( + JSON.stringify({ alg: 'HS256', typ: 'JWT' }), + ).toString('base64url'); + const payload = Buffer.from(JSON.stringify(claims)).toString('base64url'); + const signature = createHmac('sha256', secret) + .update(`${header}.${payload}`) + .digest('base64url'); + return `${header}.${payload}.${signature}`; +} +export function verifyAccessToken( + token: string, + secret: string, +): AccessTokenClaims | null { + const [header, payload, signature] = token.split('.'); + if (!header || !payload || !signature) return null; + const expected = createHmac('sha256', secret) + .update(`${header}.${payload}`) + .digest(); + const actual = Buffer.from(signature, 'base64url'); + if (actual.length !== expected.length || !timingSafeEqual(actual, expected)) + return null; + try { + const claims = JSON.parse( + Buffer.from(payload, 'base64url').toString('utf8'), + ) as AccessTokenClaims; + return typeof claims.sub === 'string' && + typeof claims.sid === 'string' && + typeof claims.exp === 'number' && + claims.exp > Math.floor(Date.now() / 1000) + ? claims + : null; + } catch { + return null; + } +} diff --git a/apps/api/src/auth/auth.guard.ts b/apps/api/src/auth/auth.guard.ts new file mode 100644 index 0000000..7cb5f29 --- /dev/null +++ b/apps/api/src/auth/auth.guard.ts @@ -0,0 +1,21 @@ +import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; +import { AuthService } from './auth.service.js'; + +export type AuthenticatedRequest = { + header: (name: string) => string | undefined; + auth: { userId: string; sessionId: string }; +}; + +@Injectable() +export class AccessTokenGuard implements CanActivate { + public constructor(private readonly authService: AuthService) {} + public async canActivate(context: ExecutionContext) { + const request = context + .switchToHttp() + .getRequest(); + request.auth = await this.authService.authenticate( + request.header('authorization'), + ); + return true; + } +} diff --git a/apps/api/src/auth/auth.module.ts b/apps/api/src/auth/auth.module.ts new file mode 100644 index 0000000..183cdef --- /dev/null +++ b/apps/api/src/auth/auth.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { AuthController } from './auth.controller.js'; +import { AccessTokenGuard } from './auth.guard.js'; +import { AuthService } from './auth.service.js'; + +@Module({ + controllers: [AuthController], + providers: [AuthService, AccessTokenGuard], +}) +export class AuthModule {} diff --git a/apps/api/src/auth/auth.service.ts b/apps/api/src/auth/auth.service.ts new file mode 100644 index 0000000..98d9d31 --- /dev/null +++ b/apps/api/src/auth/auth.service.ts @@ -0,0 +1,340 @@ +import { Inject, Injectable, UnauthorizedException } from '@nestjs/common'; +import type { + AuthSessionResponse, + AuthUser, + LoginRequest, + RegisterRequest, + Workspace, +} from '@atlas/contracts'; +import type { Database, DatabaseTransaction } from '@atlas/database'; +import { ApiError } from '../common/api-error.js'; +import { APP_CONFIG, type AppConfig } from '../config/app-config.module.js'; +import { DATABASE } from '../database/database.module.js'; +import { AuthRateLimiter } from '../security/auth-rate-limiter.service.js'; +import { + createOpaqueToken, + hashPassword, + signAccessToken, + tokenHash, + verifyAccessToken, + verifyPassword, +} from './auth.crypto.js'; + +type UserRow = { + id: string; + email: string; + display_name: string | null; + email_verified_at: Date | null; + created_at: Date; + status: 'active' | 'disabled' | 'pending_review'; + password_hash: string; +}; +type WorkspaceRow = { id: string; name: string; role: Workspace['role'] }; + +@Injectable() +export class AuthService { + private readonly accessTtlSeconds = 900; + private readonly refreshTtlDays = 30; + + public constructor( + @Inject(DATABASE) private readonly database: Database, + @Inject(APP_CONFIG) private readonly config: AppConfig, + private readonly rateLimiter: AuthRateLimiter, + ) {} + + public async register(input: RegisterRequest, metadata: RequestMetadata) { + if (input.password !== input.password_confirmation) + throw validationError( + 'password_confirmation', + 'PASSWORD_CONFIRMATION_MISMATCH', + '两次输入的密码不一致', + ); + if (input.password.length < this.config.AUTH_PASSWORD_MIN_LENGTH) + throw validationError( + 'password', + 'PASSWORD_TOO_SHORT', + `密码至少需要 ${this.config.AUTH_PASSWORD_MIN_LENGTH} 个字符`, + ); + const email = input.email.trim().toLowerCase(); + // Apply the shared limiter before spending CPU on password hashing or querying account existence. + await this.rateLimiter.consume('register', { ip: metadata.ip, email }); + const passwordHash = await hashPassword(input.password); + try { + return await this.database.transaction(async (transaction) => { + // A user must never exist without its initial tenant and owner membership. + const user = await insertUser( + transaction, + email, + passwordHash, + input.display_name?.trim() || null, + ); + const workspace = await createPersonalWorkspace( + transaction, + user.id, + user.display_name ?? email, + ); + return this.createSessionResponse( + transaction, + user, + workspace, + metadata, + ); + }); + } catch (error: unknown) { + if (isUniqueViolation(error)) + throw new ApiError( + 409, + 'EMAIL_ALREADY_REGISTERED', + '该邮箱已注册', + [ + { + field: 'email', + code: 'EMAIL_ALREADY_REGISTERED', + message: '该邮箱已注册', + }, + ], + ); + throw error; + } + } + + public async login(input: LoginRequest, metadata: RequestMetadata) { + const email = input.email.trim().toLowerCase(); + // Use the same normalized value for the limiter and citext account lookup. + await this.rateLimiter.consume('login', { ip: metadata.ip, email }); + const result = await this.database.query( + 'SELECT id, email, display_name, email_verified_at, created_at, status, password_hash FROM atlas.users WHERE email = $1', + [email], + ); + const user = result.rows[0]; + if ( + !user || + !(await verifyPassword(input.password, user.password_hash)) + ) + throw new ApiError(401, 'INVALID_CREDENTIALS', '邮箱或密码错误'); + if (user.status === 'disabled') + throw new ApiError(403, 'ACCOUNT_DISABLED', '账户已停用'); + const workspace = await this.findWorkspace(user.id); + return this.database.transaction(async (transaction) => { + await transaction.query( + 'UPDATE atlas.users SET last_login_at = now() WHERE id = $1', + [user.id], + ); + return this.createSessionResponse( + transaction, + user, + workspace, + metadata, + ); + }); + } + + public async refresh( + refreshToken: string | undefined, + metadata: RequestMetadata, + ) { + // Refresh has no trusted email until its opaque token is validated, so it is IP-scoped only. + await this.rateLimiter.consume('refresh', { ip: metadata.ip }); + if (!refreshToken) + throw new ApiError(401, 'SESSION_EXPIRED', '登录会话已过期'); + return this.database.transaction(async (transaction) => { + const sessions = await transaction.query< + UserRow & { session_id: string } + >( + `SELECT u.id, u.email, u.display_name, u.email_verified_at, u.created_at, u.status, u.password_hash, s.id AS session_id + FROM atlas.user_sessions s JOIN atlas.users u ON u.id = s.user_id + WHERE s.refresh_token_hash = $1 AND s.revoked_at IS NULL AND s.expires_at > now() FOR UPDATE`, + [tokenHash(refreshToken)], + ); + const user = sessions.rows[0]; + if (!user || user.status !== 'active') + throw new ApiError(401, 'SESSION_EXPIRED', '登录会话已过期'); + // Row locking makes a refresh token single-use even when two browser requests arrive together. + await transaction.query( + 'UPDATE atlas.user_sessions SET revoked_at = now() WHERE id = $1', + [user.session_id], + ); + const workspace = await findWorkspaceInTransaction( + transaction, + user.id, + ); + return this.createSessionResponse( + transaction, + user, + workspace, + metadata, + ); + }); + } + + public async logout(sessionId: string) { + await this.database.query( + 'UPDATE atlas.user_sessions SET revoked_at = now() WHERE id = $1 AND revoked_at IS NULL', + [sessionId], + ); + } + + public async authenticate(accessToken: string | undefined) { + const token = accessToken?.replace(/^Bearer\s+/i, ''); + const claims = token + ? verifyAccessToken(token, this.config.AUTH_JWT_SECRET) + : null; + if (!claims) throw new UnauthorizedException(); + const active = await this.database.query( + 'SELECT 1 FROM atlas.user_sessions WHERE id = $1 AND user_id = $2 AND revoked_at IS NULL AND expires_at > now()', + [claims.sid, claims.sub], + ); + if (!active.rowCount) throw new UnauthorizedException(); + return { userId: claims.sub, sessionId: claims.sid }; + } + + public async me(userId: string) { + const workspace = await this.findWorkspace(userId); + const users = await this.database.query( + 'SELECT id, email, display_name, email_verified_at, created_at, status, password_hash FROM atlas.users WHERE id = $1', + [userId], + ); + const user = users.rows[0]; + if (!user) throw new UnauthorizedException(); + const platforms = await this.database.workspaceTransaction( + workspace.id, + async (transaction) => { + const rows = await transaction.query<{ + id: string; + code: string; + name: string; + }>( + "SELECT id, code, name FROM atlas.platforms WHERE status = 'active' ORDER BY CASE WHEN code = 'OZON' THEN 0 ELSE 1 END, name", + ); + return rows.rows; + }, + ); + return { + user: publicUser(user), + workspace, + platforms, + suggested_context: { + platform_id: platforms[0]?.id ?? null, + default_store: null, + }, + }; + } + + private async findWorkspace(userId: string) { + const result = await this.database.query( + `SELECT w.id, w.name, m.role FROM atlas.workspace_memberships m JOIN atlas.workspaces w ON w.id = m.workspace_id WHERE m.user_id = $1 AND w.status = 'active' ORDER BY m.joined_at LIMIT 1`, + [userId], + ); + return requireWorkspace(result.rows[0]); + } + private async createSessionResponse( + transaction: DatabaseTransaction, + user: UserRow, + workspace: WorkspaceRow, + metadata: RequestMetadata, + ) { + const refreshToken = createOpaqueToken(); + const session = await transaction.query<{ id: string }>( + `INSERT INTO atlas.user_sessions (user_id, refresh_token_hash, expires_at, ip_hash, user_agent) + VALUES ($1, $2, now() + ($3 || ' days')::interval, $4, $5) RETURNING id`, + [ + user.id, + tokenHash(refreshToken), + this.refreshTtlDays, + metadata.ipHash, + metadata.userAgent, + ], + ); + const now = Math.floor(Date.now() / 1000); + const accessToken = signAccessToken( + { + sub: user.id, + sid: session.rows[0].id, + iat: now, + exp: now + this.accessTtlSeconds, + }, + this.config.AUTH_JWT_SECRET, + ); + const payload: AuthSessionResponse = { + access_token: accessToken, + access_token_expires_in: this.accessTtlSeconds, + user: publicUser(user), + workspace, + }; + return { payload, refreshToken }; + } +} + +export type RequestMetadata = { + ip: string | null; + ipHash: string | null; + userAgent: string | null; +}; +function validationError(field: string, code: string, message: string) { + return new ApiError(422, 'VALIDATION_FAILED', '请求参数不符合要求', [ + { field, code, message }, + ]); +} +function isUniqueViolation(error: unknown): error is { code: string } { + return ( + typeof error === 'object' && + error !== null && + 'code' in error && + (error as { code: string }).code === '23505' + ); +} +function publicUser(user: UserRow): AuthUser { + return { + id: user.id, + email: user.email, + display_name: user.display_name, + email_verified_at: user.email_verified_at?.toISOString() ?? null, + created_at: user.created_at.toISOString(), + }; +} +async function insertUser( + transaction: DatabaseTransaction, + email: string, + passwordHash: string, + displayName: string | null, +) { + const result = await transaction.query( + 'INSERT INTO atlas.users (email, password_hash, display_name) VALUES ($1, $2, $3) RETURNING id, email, display_name, email_verified_at, created_at, status, password_hash', + [email, passwordHash, displayName], + ); + return result.rows[0]; +} +async function createPersonalWorkspace( + transaction: DatabaseTransaction, + userId: string, + label: string, +) { + const workspace = await transaction.query<{ id: string; name: string }>( + 'INSERT INTO atlas.workspaces (name, slug) VALUES ($1, $2) RETURNING id, name', + [`${label} 的工作空间`, `personal-${userId}`], + ); + await transaction.query( + "INSERT INTO atlas.workspace_memberships (workspace_id, user_id, role) VALUES ($1, $2, 'owner')", + [workspace.rows[0].id, userId], + ); + return { ...workspace.rows[0], role: 'owner' as const }; +} +async function findWorkspaceInTransaction( + transaction: DatabaseTransaction, + userId: string, +): Promise { + const result = await transaction.query( + `SELECT w.id, w.name, m.role FROM atlas.workspace_memberships m JOIN atlas.workspaces w ON w.id = m.workspace_id WHERE m.user_id = $1 AND w.status = 'active' ORDER BY m.joined_at LIMIT 1`, + [userId], + ); + return requireWorkspace(result.rows[0]); +} +function requireWorkspace(workspace: WorkspaceRow | undefined): WorkspaceRow { + if (!workspace) + throw new ApiError( + 403, + 'WORKSPACE_MEMBERSHIP_REQUIRED', + '当前账户没有可用工作空间', + ); + return workspace; +} diff --git a/apps/api/src/common/api-error.filter.ts b/apps/api/src/common/api-error.filter.ts new file mode 100644 index 0000000..4cc29e4 --- /dev/null +++ b/apps/api/src/common/api-error.filter.ts @@ -0,0 +1,61 @@ +import { + ArgumentsHost, + Catch, + ExceptionFilter, + HttpException, +} from '@nestjs/common'; +import { randomUUID } from 'node:crypto'; +import { ApiError } from './api-error.js'; +import { AppLogger } from '../logging/app-logger.js'; + +@Catch() +export class ApiErrorFilter implements ExceptionFilter { + public constructor(private readonly logger: AppLogger) {} + + public catch(exception: unknown, host: ArgumentsHost) { + const response = host.switchToHttp().getResponse<{ + status: (status: number) => { + json: (body: unknown) => unknown; + }; + }>(); + const request = host.switchToHttp().getRequest<{ + requestId?: string; + method?: string; + originalUrl?: string; + }>(); + const requestId = request.requestId ?? `req_${randomUUID()}`; + if (exception instanceof ApiError) { + const body = exception.getResponse() as { + error: Record; + }; + return response + .status(exception.getStatus()) + .json({ error: { ...body.error, request_id: requestId } }); + } + if (exception instanceof HttpException) { + return response.status(exception.getStatus()).json({ + error: { + code: 'HTTP_ERROR', + message: '请求无法处理', + request_id: requestId, + }, + }); + } + this.logger.error( + 'unhandled_exception', + exception instanceof Error ? exception.stack : undefined, + { + request_id: requestId, + method: request.method, + path: request.originalUrl, + }, + ); + return response.status(500).json({ + error: { + code: 'INTERNAL_ERROR', + message: '服务器暂时无法处理请求', + request_id: requestId, + }, + }); + } +} diff --git a/apps/api/src/common/api-error.ts b/apps/api/src/common/api-error.ts new file mode 100644 index 0000000..69db470 --- /dev/null +++ b/apps/api/src/common/api-error.ts @@ -0,0 +1,12 @@ +import { HttpException, HttpStatus } from '@nestjs/common'; + +export class ApiError extends HttpException { + public constructor( + status: HttpStatus, + code: string, + message: string, + details?: unknown[], + ) { + super({ error: { code, message, details } }, status); + } +} diff --git a/apps/api/src/config/app-config.module.ts b/apps/api/src/config/app-config.module.ts new file mode 100644 index 0000000..92dc6f5 --- /dev/null +++ b/apps/api/src/config/app-config.module.ts @@ -0,0 +1,124 @@ +import { existsSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { Global, Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; +import { z } from 'zod'; + +export const APP_CONFIG = Symbol('APP_CONFIG'); + +function findEnvironmentFile(): string { + const directories = [ + process.cwd(), + resolve(process.cwd(), '..'), + resolve(process.cwd(), '../..'), + ]; + const environmentFile = directories + .map((directory) => resolve(directory, '.env')) + .find((file) => existsSync(file)); + + return environmentFile ?? resolve(process.cwd(), '.env'); +} + +// This schema is the only supported source for API runtime settings. Defaults are +// intentionally limited to non-secret local-development values. +const environmentSchema = z.object({ + NODE_ENV: z + .enum(['development', 'test', 'production']) + .default('development'), + API_PORT: z.coerce.number().int().min(1).max(65_535).default(8200), + WEB_ORIGIN: z.url().default('http://localhost:8100'), + DATABASE_URL: z.url(), + REDIS_URL: z.url(), + AUTH_JWT_SECRET: z.string().min(32), + AUTH_RATE_LIMIT_KEY_SECRET: z.string().min(32), + AUTH_PASSWORD_MIN_LENGTH: z.coerce + .number() + .int() + .min(12) + .max(256) + .default(12), + API_BODY_LIMIT_BYTES: z.coerce + .number() + .int() + .min(1_024) + .max(10 * 1024 * 1024) + .default(1_048_576), + AUTH_RATE_LIMIT_WINDOW_SECONDS: z.coerce + .number() + .int() + .min(1) + .max(86_400) + .default(900), + AUTH_LOGIN_IP_LIMIT: z.coerce.number().int().min(1).max(1000).default(10), + AUTH_LOGIN_EMAIL_LIMIT: z.coerce.number().int().min(1).max(1000).default(5), + AUTH_REGISTER_IP_LIMIT: z.coerce.number().int().min(1).max(1000).default(5), + AUTH_REGISTER_EMAIL_LIMIT: z.coerce + .number() + .int() + .min(1) + .max(1000) + .default(3), + AUTH_REFRESH_IP_LIMIT: z.coerce + .number() + .int() + .min(1) + .max(10_000) + .default(30), + TRUSTED_PROXY_CIDRS: z.string().default(''), + SWAGGER_ENABLED: z.enum(['true', 'false']).default('true'), + LOG_LEVEL: z.enum(['error', 'warn', 'log', 'debug']).default('log'), +}); + +type Environment = z.infer; +export type AppConfig = Omit< + Environment, + 'TRUSTED_PROXY_CIDRS' | 'SWAGGER_ENABLED' +> & { + trustedProxyCidrs: string[]; + swaggerEnabled: boolean; +}; + +function validateEnvironment( + environment: Record, +): Environment { + const result = environmentSchema.safeParse(environment); + if (result.success) return result.data; + // Fail before Nest opens a listener; a half-configured API is unsafe to run. + throw new Error( + `Invalid environment configuration: ${result.error.issues.map((issue) => issue.path.join('.')).join(', ')}`, + ); +} + +function createAppConfig(environment: Environment): AppConfig { + return { + ...environment, + // Express only trusts forwarding headers when this explicit allowlist is non-empty. + trustedProxyCidrs: environment.TRUSTED_PROXY_CIDRS.split(',') + .map((value) => value.trim()) + .filter(Boolean), + swaggerEnabled: environment.SWAGGER_ENABLED === 'true', + }; +} + +@Global() +@Module({ + imports: [ + ConfigModule.forRoot({ + isGlobal: true, + cache: true, + // Turbo runs this workspace's scripts from apps/api, while the + // shared development environment lives at the repository root. + envFilePath: findEnvironmentFile(), + }), + ], + providers: [ + { + provide: APP_CONFIG, + // Export a normalized immutable config object so services never read process.env directly. + useFactory: (): AppConfig => + createAppConfig(validateEnvironment(process.env)), + }, + ], + exports: [APP_CONFIG], +}) +export class AppConfigModule {} diff --git a/apps/api/src/database/database.module.ts b/apps/api/src/database/database.module.ts new file mode 100644 index 0000000..ea5adec --- /dev/null +++ b/apps/api/src/database/database.module.ts @@ -0,0 +1,24 @@ +import { Global, Inject, Module, OnModuleDestroy } from '@nestjs/common'; +import { createApplicationDatabase, type Database } from '@atlas/database'; +import { APP_CONFIG, type AppConfig } from '../config/app-config.module.js'; + +export const DATABASE = Symbol('DATABASE'); + +@Global() +@Module({ + providers: [ + { + provide: DATABASE, + inject: [APP_CONFIG], + useFactory: (config: AppConfig): Database => + createApplicationDatabase(config.DATABASE_URL), + }, + ], + exports: [DATABASE], +}) +export class DatabaseModule implements OnModuleDestroy { + public constructor(@Inject(DATABASE) private readonly database: Database) {} + public async onModuleDestroy() { + await this.database.close(); + } +} diff --git a/apps/api/src/logging/app-logger.ts b/apps/api/src/logging/app-logger.ts new file mode 100644 index 0000000..28efb20 --- /dev/null +++ b/apps/api/src/logging/app-logger.ts @@ -0,0 +1,60 @@ +import type { LoggerService } from '@nestjs/common'; + +type LogLevel = 'error' | 'warn' | 'log' | 'debug'; +const severity: Record = { + error: 0, + warn: 1, + log: 2, + debug: 3, +}; +const sensitiveKeys = /authorization|cookie|password|secret|token|api[_-]?key/i; + +export class AppLogger implements LoggerService { + public constructor(private readonly minimumLevel: LogLevel) {} + + public log(message: unknown, context?: unknown): void { + this.write('log', message, context); + } + + public error(message: unknown, stack?: string, context?: unknown): void { + this.write('error', message, { stack, context }); + } + + public warn(message: unknown, context?: unknown): void { + this.write('warn', message, context); + } + + public debug(message: unknown, context?: unknown): void { + this.write('debug', message, context); + } + + public verbose(message: unknown, context?: unknown): void { + this.debug(message, context); + } + + private write(level: LogLevel, message: unknown, context?: unknown): void { + if (severity[level] > severity[this.minimumLevel]) return; + const entry = { + timestamp: new Date().toISOString(), + level, + message: typeof message === 'string' ? message : sanitize(message), + context: sanitize(context), + }; + const output = JSON.stringify(entry); + if (level === 'error') console.error(output); + else console.log(output); + } +} + +function sanitize(value: unknown): unknown { + if (Array.isArray(value)) return value.map(sanitize); + if (value && typeof value === 'object') { + return Object.fromEntries( + Object.entries(value).map(([key, child]) => [ + key, + sensitiveKeys.test(key) ? '[REDACTED]' : sanitize(child), + ]), + ); + } + return value; +} diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index 6d2f7e8..f443d3e 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -1,12 +1,151 @@ import 'reflect-metadata'; +import { execFile } from 'node:child_process'; +import { randomUUID } from 'node:crypto'; import { NestFactory } from '@nestjs/core'; +import { NestExpressApplication } from '@nestjs/platform-express'; +import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; +import type { NextFunction, Request, Response } from 'express'; +import helmet from 'helmet'; import { AppModule } from './app.module.js'; +import { ApiErrorFilter } from './common/api-error.filter.js'; +import { APP_CONFIG, type AppConfig } from './config/app-config.module.js'; +import { AppLogger } from './logging/app-logger.js'; -async function bootstrap() { - const app = await NestFactory.create(AppModule); - app.enableCors({ origin: process.env.WEB_ORIGIN ?? 'http://localhost:8100' }); - await app.listen(Number(process.env.API_PORT ?? 8200)); +type RequestWithId = Request & { + requestId?: string; +}; + +function openSwaggerInDevelopment(config: AppConfig, logger: AppLogger): void { + if ( + config.NODE_ENV !== 'development' || + !config.swaggerEnabled || + process.platform !== 'darwin' + ) { + return; + } + + const swaggerUrl = `http://localhost:${config.API_PORT}/api-docs`; + // 只在本机开发时打开浏览器,生产环境和非 macOS 主机不执行外部进程。 + execFile('open', [swaggerUrl], (error) => { + if (error) { + logger.warn('swagger_auto_open_failed', { + error: error.message, + url: swaggerUrl, + }); + } + }); } -void bootstrap(); +async function bootstrap() { + const app = await NestFactory.create(AppModule, { + bodyParser: false, + // Keep Nest's bootstrap errors visible until AppLogger is installed below. + logger: ['error', 'warn', 'log'], + }); + const config = app.get(APP_CONFIG); + const logger = new AppLogger(config.LOG_LEVEL); + app.useLogger(logger); + + if (config.trustedProxyCidrs.length > 0) { + // Never trust forwarded headers unless the deployment names its proxy networks explicitly. + app.getHttpAdapter() + .getInstance() + .set('trust proxy', config.trustedProxyCidrs); + } + + app.enableCors({ + origin: config.WEB_ORIGIN, + credentials: true, + methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], + allowedHeaders: [ + 'Authorization', + 'Content-Type', + 'Idempotency-Key', + 'If-Match', + 'X-Atlas-Platform-Id', + 'X-Request-Id', + ], + exposedHeaders: ['X-Request-Id'], + }); + app.use(helmet({ contentSecurityPolicy: false })); + app.useBodyParser('json', { limit: config.API_BODY_LIMIT_BYTES }); + app.useBodyParser('urlencoded', { + limit: config.API_BODY_LIMIT_BYTES, + extended: true, + }); + app.use( + (request: RequestWithId, response: Response, next: NextFunction) => { + const typedRequest = request; + const typedResponse = response; + const suppliedId = typedRequest.headers['x-request-id']; + const requestId = + typeof suppliedId === 'string' && + /^[A-Za-z0-9_-]{8,128}$/.test(suppliedId) + ? suppliedId + : `req_${randomUUID()}`; + const startedAt = performance.now(); + typedRequest.requestId = requestId; + typedResponse.setHeader('X-Request-Id', requestId); + typedResponse.on('finish', () => { + logger.log('http_request_completed', { + request_id: requestId, + method: typedRequest.method, + path: typedRequest.originalUrl, + status_code: typedResponse.statusCode, + duration_ms: Math.round(performance.now() - startedAt), + }); + }); + next(); + }, + ); + app.useGlobalFilters(new ApiErrorFilter(logger)); + app.setGlobalPrefix('api', { exclude: ['health', 'ready'] }); + app.enableShutdownHooks(); + + if (config.swaggerEnabled) { + const swaggerConfig = new DocumentBuilder() + .setTitle('Atlas Seller Kit API') + .setDescription('Atlas 卖家工作台 HTTP API 文档') + .setVersion('0.1.0') + .addBearerAuth( + { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' }, + 'access-token', + ) + .build(); + const swaggerDocument = SwaggerModule.createDocument( + app, + swaggerConfig, + ); + SwaggerModule.setup('api-docs', app, swaggerDocument, { + swaggerOptions: { persistAuthorization: true }, + }); + } + + await app.listen(config.API_PORT); + logger.log('api_started', { + port: config.API_PORT, + swagger_enabled: config.swaggerEnabled, + }); + openSwaggerInDevelopment(config, logger); +} + +void bootstrap().catch((error: unknown) => { + const details = + error instanceof Error + ? { + name: error.name, + message: error.message, + stack: error.stack, + } + : error; + console.error( + JSON.stringify({ + timestamp: new Date().toISOString(), + level: 'error', + message: 'api_startup_failed', + error: details, + }), + ); + process.exitCode = 1; +}); diff --git a/apps/api/src/security/auth-rate-limiter.service.ts b/apps/api/src/security/auth-rate-limiter.service.ts new file mode 100644 index 0000000..43b85de --- /dev/null +++ b/apps/api/src/security/auth-rate-limiter.service.ts @@ -0,0 +1,102 @@ +import { Inject, Injectable, OnModuleDestroy } from '@nestjs/common'; +import { createHmac } from 'node:crypto'; +import { Redis } from 'ioredis'; +import { ApiError } from '../common/api-error.js'; +import { APP_CONFIG, type AppConfig } from '../config/app-config.module.js'; + +type AuthAction = 'login' | 'register' | 'refresh'; +type Limit = { ip: number; email?: number }; + +@Injectable() +export class AuthRateLimiter implements OnModuleDestroy { + private readonly redis: Redis; + + public constructor(@Inject(APP_CONFIG) private readonly config: AppConfig) { + // Redis makes counters shared across API processes instead of resetting per instance. + this.redis = new Redis(config.REDIS_URL, { + enableOfflineQueue: false, + maxRetriesPerRequest: 1, + }); + } + + public async consume( + action: AuthAction, + identifiers: { ip: string | null; email?: string }, + ): Promise { + const limit = this.limitFor(action); + await this.consumeBucket( + action, + 'ip', + identifiers.ip ?? 'unknown', + limit.ip, + ); + if (identifiers.email && limit.email) { + await this.consumeBucket( + action, + 'email', + identifiers.email, + limit.email, + ); + } + } + + public async onModuleDestroy(): Promise { + await this.redis.quit(); + } + + private async consumeBucket( + action: AuthAction, + dimension: 'ip' | 'email', + identifier: string, + limit: number, + ): Promise { + const digest = createHmac( + 'sha256', + this.config.AUTH_RATE_LIMIT_KEY_SECRET, + ) + .update(identifier) + .digest('base64url'); + // The raw IP/email never becomes part of a Redis key or a loggable identifier. + const key = `atlas:auth-rate-limit:${action}:${dimension}:${digest}`; + try { + // INCR + first-write EXPIRE must be atomic or concurrent requests could leave a key unexpired. + const count = await this.redis.eval( + "local value = redis.call('INCR', KEYS[1]); if value == 1 then redis.call('EXPIRE', KEYS[1], ARGV[1]); end; return value;", + 1, + key, + this.config.AUTH_RATE_LIMIT_WINDOW_SECONDS, + ); + if (Number(count) > limit) { + throw new ApiError( + 429, + 'AUTH_RATE_LIMITED', + '请求过于频繁,请稍后重试', + ); + } + } catch (error) { + if (error instanceof ApiError) throw error; + // Authentication fails closed: silently bypassing a broken shared limiter enables brute-force attacks. + throw new ApiError( + 503, + 'AUTH_RATE_LIMIT_UNAVAILABLE', + '认证服务暂时不可用', + ); + } + } + + private limitFor(action: AuthAction): Limit { + if (action === 'login') { + return { + ip: this.config.AUTH_LOGIN_IP_LIMIT, + email: this.config.AUTH_LOGIN_EMAIL_LIMIT, + }; + } + if (action === 'register') { + return { + ip: this.config.AUTH_REGISTER_IP_LIMIT, + email: this.config.AUTH_REGISTER_EMAIL_LIMIT, + }; + } + return { ip: this.config.AUTH_REFRESH_IP_LIMIT }; + } +} diff --git a/apps/api/src/security/security.module.ts b/apps/api/src/security/security.module.ts new file mode 100644 index 0000000..f2b1394 --- /dev/null +++ b/apps/api/src/security/security.module.ts @@ -0,0 +1,6 @@ +import { Global, Module } from '@nestjs/common'; +import { AuthRateLimiter } from './auth-rate-limiter.service.js'; + +@Global() +@Module({ providers: [AuthRateLimiter], exports: [AuthRateLimiter] }) +export class SecurityModule {} diff --git a/apps/api/tsconfig.json b/apps/api/tsconfig.json index 40e11b0..cb7d79f 100644 --- a/apps/api/tsconfig.json +++ b/apps/api/tsconfig.json @@ -1,11 +1,11 @@ { - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "types": ["node"], - "experimentalDecorators": true, - "emitDecoratorMetadata": true - }, - "include": ["src/**/*.ts"] + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "types": ["node"], + "experimentalDecorators": true, + "emitDecoratorMetadata": true + }, + "include": ["src/**/*.ts"] } diff --git a/apps/extension/entrypoints/background.ts b/apps/extension/entrypoints/background.ts index 25fbb61..ea87781 100644 --- a/apps/extension/entrypoints/background.ts +++ b/apps/extension/entrypoints/background.ts @@ -1,3 +1,3 @@ export default defineBackground(() => { - console.info('Atlas collector background started.'); + console.info('Atlas collector background started.'); }); diff --git a/apps/extension/package.json b/apps/extension/package.json index d4dc050..3a26551 100644 --- a/apps/extension/package.json +++ b/apps/extension/package.json @@ -1,23 +1,23 @@ { - "name": "@atlas/extension", - "version": "0.1.0", - "private": true, - "type": "module", - "scripts": { - "build": "wxt build", - "dev": "wxt", - "typecheck": "wxt prepare && tsc -p tsconfig.json --noEmit" - }, - "dependencies": { - "@atlas/contracts": "workspace:*", - "@wxt-dev/module-react": "1.2.2", - "react": "19.2.8", - "react-dom": "19.2.8" - }, - "devDependencies": { - "@types/react": "19.2.18", - "@types/react-dom": "19.2.5", - "typescript": "7.0.2", - "wxt": "0.21.4" - } + "name": "@atlas/extension", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "build": "wxt build", + "dev": "wxt", + "typecheck": "wxt prepare && tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "@atlas/contracts": "workspace:*", + "@wxt-dev/module-react": "1.2.2", + "react": "19.2.8", + "react-dom": "19.2.8" + }, + "devDependencies": { + "@types/react": "19.2.18", + "@types/react-dom": "19.2.5", + "typescript": "7.0.2", + "wxt": "0.21.4" + } } diff --git a/apps/extension/tsconfig.json b/apps/extension/tsconfig.json index 58bbfdc..c65e3a8 100644 --- a/apps/extension/tsconfig.json +++ b/apps/extension/tsconfig.json @@ -1,8 +1,8 @@ { - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "jsx": "react-jsx", - "noEmit": true - }, - "include": ["**/*.ts", "**/*.tsx", ".wxt/**/*.ts"] + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "jsx": "react-jsx", + "noEmit": true + }, + "include": ["**/*.ts", "**/*.tsx", ".wxt/**/*.ts"] } diff --git a/apps/extension/wxt.config.ts b/apps/extension/wxt.config.ts index 3949257..2685756 100644 --- a/apps/extension/wxt.config.ts +++ b/apps/extension/wxt.config.ts @@ -1,25 +1,25 @@ import { defineConfig } from 'wxt'; export default defineConfig({ - modules: ['@wxt-dev/module-react'], - // 扩展 dev server 固定 8110:默认取 3000–3010 第一个空闲端口,会漂移且易与常见服务冲突 - dev: { - server: { - port: Number(process.env.EXTENSION_PORT ?? 8110), - strictPort: true, + modules: ['@wxt-dev/module-react'], + // 扩展 dev server 固定 8110:默认取 3000–3010 第一个空闲端口,会漂移且易与常见服务冲突 + dev: { + server: { + port: Number(process.env.EXTENSION_PORT ?? 8110), + strictPort: true, + }, + }, + manifest: { + name: 'Atlas Seller Kit Collector', + description: '将已确认的来源商品采集到 Atlas 工作空间。', + permissions: ['storage', 'identity'], + host_permissions: [ + '*://*.ozon.ru/*', + '*://*.ozon.kz/*', + '*://*.ozon.by/*', + '*://*.1688.com/*', + '*://*.taobao.com/*', + '*://*.tmall.com/*', + ], }, - }, - manifest: { - name: 'Atlas Seller Kit Collector', - description: '将已确认的来源商品采集到 Atlas 工作空间。', - permissions: ['storage', 'identity'], - host_permissions: [ - '*://*.ozon.ru/*', - '*://*.ozon.kz/*', - '*://*.ozon.by/*', - '*://*.1688.com/*', - '*://*.taobao.com/*', - '*://*.tmall.com/*', - ], - }, }); diff --git a/apps/web/index.html b/apps/web/index.html index 6181cfd..9c5b5cd 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -1,12 +1,12 @@ - - - - Atlas Seller Kit - - -
- - + + + + Atlas Seller Kit + + +
+ + diff --git a/apps/web/package.json b/apps/web/package.json index 196a49d..15752f3 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,27 +1,27 @@ { - "name": "@atlas/web", - "version": "0.1.0", - "private": true, - "type": "module", - "scripts": { - "build": "tsc -b && vite build", - "dev": "vite", - "typecheck": "tsc -b --pretty false" - }, - "dependencies": { - "@ant-design/icons": "6.3.4", - "antd": "6.6.2", - "axios": "1.20.0", - "react": "19.2.8", - "react-dom": "19.2.8", - "react-router-dom": "7.18.3" - }, - "devDependencies": { - "@types/node": "26.3.0", - "@types/react": "19.2.18", - "@types/react-dom": "19.2.5", - "@vitejs/plugin-react": "6.1.1", - "typescript": "7.0.2", - "vite": "8.2.2" - } + "name": "@atlas/web", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "build": "tsc -b && vite build", + "dev": "vite", + "typecheck": "tsc -b --pretty false" + }, + "dependencies": { + "@ant-design/icons": "6.3.4", + "antd": "6.6.2", + "axios": "1.20.0", + "react": "19.2.8", + "react-dom": "19.2.8", + "react-router-dom": "7.18.3" + }, + "devDependencies": { + "@types/node": "26.3.0", + "@types/react": "19.2.18", + "@types/react-dom": "19.2.5", + "@vitejs/plugin-react": "6.1.1", + "typescript": "7.0.2", + "vite": "8.2.2" + } } diff --git a/apps/web/prettier.config.mjs b/apps/web/prettier.config.mjs new file mode 100644 index 0000000..fdce617 --- /dev/null +++ b/apps/web/prettier.config.mjs @@ -0,0 +1,19 @@ +/** + * @see https://prettier.io/docs/en/configuration.html + * @type {import("prettier").Config} + */ +export default { + printWidth: 100, + tabWidth: 4, + useTabs: false, + semi: true, + singleQuote: true, + quoteProps: 'as-needed', + jsxSingleQuote: false, + trailingComma: 'es5', + bracketSpacing: true, + jsxBracketSameLine: false, + arrowParens: 'always', + endOfLine: 'lf', + embeddedLanguageFormatting: 'auto', +}; diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index 94f2831..537bf7b 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -5,25 +5,25 @@ import { router } from './router'; import './App.css'; function App() { - return ( - - - - - - ); + return ( + + + + + + ); } export default App; diff --git a/apps/web/src/components/PagePlaceholder.tsx b/apps/web/src/components/PagePlaceholder.tsx index 7e54da1..0f8d5e8 100644 --- a/apps/web/src/components/PagePlaceholder.tsx +++ b/apps/web/src/components/PagePlaceholder.tsx @@ -1,23 +1,23 @@ import { Card, Empty } from 'antd'; interface PagePlaceholderProps { - title: string; - description: string; + title: string; + description: string; } /** 业务模块实现前的统一占位页 */ const PagePlaceholder = ({ title, description }: PagePlaceholderProps) => ( - - -
{title}
-
{description}
- - } - /> -
+ + +
{title}
+
{description}
+ + } + /> +
); export default PagePlaceholder; diff --git a/apps/web/src/config/env.ts b/apps/web/src/config/env.ts index d6e68ea..ee068f5 100644 --- a/apps/web/src/config/env.ts +++ b/apps/web/src/config/env.ts @@ -3,14 +3,14 @@ */ interface EnvConfig { - /** API 基础路径:开发环境由 vite 代理转发到 NestJS API */ - apiBaseUrl: string; - appName: string; - debug: boolean; + /** API 基础路径:开发环境由 vite 代理转发到 NestJS API */ + apiBaseUrl: string; + appName: string; + debug: boolean; } export const envConfig: EnvConfig = { - apiBaseUrl: import.meta.env.VITE_API_BASE_URL ?? '/api', - appName: import.meta.env.VITE_APP_NAME ?? 'Atlas Seller Kit', - debug: import.meta.env.VITE_DEBUG === 'true', + apiBaseUrl: import.meta.env.VITE_API_BASE_URL ?? '/api', + appName: import.meta.env.VITE_APP_NAME ?? 'Atlas Seller Kit', + debug: import.meta.env.VITE_DEBUG === 'true', }; diff --git a/apps/web/src/index.css b/apps/web/src/index.css index 0e339df..5ec4752 100644 --- a/apps/web/src/index.css +++ b/apps/web/src/index.css @@ -1,37 +1,37 @@ :root { - --primary-color: #8b5cf6; - --primary-light: #a78bfa; - --primary-dark: #7c3aed; - /* 侧边菜单背景(纯色,中间调;想再调直接改这里) */ - --sider-bg: #6d28d9; - --text-primary: #1f2937; - --text-secondary: #6b7280; - --bg-color: #f9fafb; - --card-bg: #ffffff; - --border-color: #e5e7eb; + --primary-color: #8b5cf6; + --primary-light: #a78bfa; + --primary-dark: #7c3aed; + /* 侧边菜单背景(纯色,中间调;想再调直接改这里) */ + --sider-bg: #6d28d9; + --text-primary: #1f2937; + --text-secondary: #6b7280; + --bg-color: #f9fafb; + --card-bg: #ffffff; + --border-color: #e5e7eb; } * { - margin: 0; - padding: 0; - box-sizing: border-box; + margin: 0; + padding: 0; + box-sizing: border-box; } body { - margin: 0; - font-family: - -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', - 'Microsoft YaHei', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', - 'Helvetica Neue', sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - background-color: var(--bg-color); - color: var(--text-primary); - /* 全局默认字号 14px,与 antd 主题 token 的 fontSize 保持一致 */ - font-size: 14px; - line-height: 1.6; + margin: 0; + font-family: + -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', + 'Hiragino Sans GB', 'Microsoft YaHei', 'Roboto', 'Oxygen', 'Ubuntu', + 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + background-color: var(--bg-color); + color: var(--text-primary); + /* 全局默认字号 14px,与 antd 主题 token 的 fontSize 保持一致 */ + font-size: 14px; + line-height: 1.6; } #root { - min-height: 100vh; + min-height: 100vh; } diff --git a/apps/web/src/layouts/AuthLayout.css b/apps/web/src/layouts/AuthLayout.css index 210e239..efd8fc1 100644 --- a/apps/web/src/layouts/AuthLayout.css +++ b/apps/web/src/layouts/AuthLayout.css @@ -1,71 +1,79 @@ .auth-page { - min-height: 100vh; - display: flex; - align-items: center; - justify-content: center; - padding: 24px; - background: - radial-gradient(1000px 500px at 15% -10%, rgba(139, 92, 246, 0.14), transparent 60%), - radial-gradient(900px 480px at 95% 110%, rgba(109, 40, 217, 0.1), transparent 55%), - var(--bg-color); + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + padding: 24px; + background: + radial-gradient( + 1000px 500px at 15% -10%, + rgba(139, 92, 246, 0.14), + transparent 60% + ), + radial-gradient( + 900px 480px at 95% 110%, + rgba(109, 40, 217, 0.1), + transparent 55% + ), + var(--bg-color); } .auth-panel { - width: 100%; - max-width: 400px; + width: 100%; + max-width: 400px; } .auth-brand { - text-align: center; - margin-bottom: 24px; + text-align: center; + margin-bottom: 24px; } .auth-logo { - font-size: 26px; - font-weight: 700; - color: var(--primary-dark); + font-size: 26px; + font-weight: 700; + color: var(--primary-dark); } .auth-logo-subtitle { - font-size: 13px; - color: var(--text-secondary); - margin-top: 2px; + font-size: 13px; + color: var(--text-secondary); + margin-top: 2px; } .auth-card { - background: var(--card-bg); - border: 1px solid var(--border-color); - border-radius: 12px; - box-shadow: 0 10px 30px rgba(17, 24, 39, 0.06); - padding: 32px 28px; + background: var(--card-bg); + border: 1px solid var(--border-color); + border-radius: 12px; + box-shadow: 0 10px 30px rgba(17, 24, 39, 0.06); + padding: 32px 28px; } .auth-title { - font-size: 20px; - font-weight: 600; - color: var(--text-primary); + font-size: 20px; + font-weight: 600; + color: var(--text-primary); } .auth-subtitle { - font-size: 14px; - color: var(--text-secondary); - margin: 4px 0 20px; + font-size: 14px; + color: var(--text-secondary); + margin: 4px 0 20px; } .auth-footer { - margin-top: 16px; - text-align: center; - font-size: 14px; - color: var(--text-secondary); + margin-top: 16px; + text-align: center; + font-size: 14px; + color: var(--text-secondary); } .auth-footer a { - color: var(--primary-color); - font-weight: 500; + color: var(--primary-color); + font-weight: 500; } @media (max-width: 768px) { - .auth-card { - padding: 24px 20px; - } + .auth-card { + padding: 24px 20px; + } } diff --git a/apps/web/src/layouts/AuthLayout.tsx b/apps/web/src/layouts/AuthLayout.tsx index 55c9103..4ece55d 100644 --- a/apps/web/src/layouts/AuthLayout.tsx +++ b/apps/web/src/layouts/AuthLayout.tsx @@ -3,37 +3,37 @@ import type { ReactNode } from 'react'; import './AuthLayout.css'; interface AuthLayoutProps { - /** 页面标题,如「登录」 */ - title: string; - /** 标题下的一行说明 */ - subtitle: string; - /** 卡片底部的切换入口 */ - footer: ReactNode; - children: ReactNode; + /** 页面标题,如「登录」 */ + title: string; + /** 标题下的一行说明 */ + subtitle: string; + /** 卡片底部的切换入口 */ + footer: ReactNode; + children: ReactNode; } /** 注册/登录共用的居中卡片布局,品牌视觉与 MainLayout 一致 */ const AuthLayout = ({ title, subtitle, footer, children }: AuthLayoutProps) => { - useEffect(() => { - document.title = `${title} - Atlas Seller Kit`; - }, [title]); + useEffect(() => { + document.title = `${title} - Atlas Seller Kit`; + }, [title]); - return ( -
-
-
-
Atlas Kit
-
商品工作台
+ return ( +
+
+
+
Atlas Kit
+
商品工作台
+
+
+
{title}
+
{subtitle}
+ {children} +
{footer}
+
+
-
-
{title}
-
{subtitle}
- {children} -
{footer}
-
-
-
- ); + ); }; export default AuthLayout; diff --git a/apps/web/src/layouts/MainLayout.css b/apps/web/src/layouts/MainLayout.css index 0878bea..c07c96a 100644 --- a/apps/web/src/layouts/MainLayout.css +++ b/apps/web/src/layouts/MainLayout.css @@ -1,115 +1,115 @@ .main-layout { - min-height: 100vh; + min-height: 100vh; } .main-sider { - background: var(--sider-bg) !important; - display: flex; - flex-direction: column; + background: var(--sider-bg) !important; + display: flex; + flex-direction: column; } .sidebar-header { - padding: 24px 20px; - border-bottom: 1px solid rgba(255, 255, 255, 0.1); - text-align: center; + padding: 24px 20px; + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + text-align: center; } .logo { - font-size: 22px; - font-weight: 700; - color: white; - margin-bottom: 4px; + font-size: 22px; + font-weight: 700; + color: white; + margin-bottom: 4px; } .logo-subtitle { - font-size: 12px; - color: rgba(255, 255, 255, 0.8); + font-size: 12px; + color: rgba(255, 255, 255, 0.8); } .main-header { - background: white !important; - padding: 0 24px !important; - display: flex; - align-items: center; - justify-content: space-between; - box-shadow: - 0 1px 3px 0 rgba(0, 0, 0, 0.1), - 0 1px 2px 0 rgba(0, 0, 0, 0.06); - position: sticky; - top: 0; - z-index: 100; - height: 64px; - line-height: 1; + background: white !important; + padding: 0 24px !important; + display: flex; + align-items: center; + justify-content: space-between; + box-shadow: + 0 1px 3px 0 rgba(0, 0, 0, 0.1), + 0 1px 2px 0 rgba(0, 0, 0, 0.06); + position: sticky; + top: 0; + z-index: 100; + height: 64px; + line-height: 1; } .header-left { - display: flex; - align-items: center; - gap: 16px; + display: flex; + align-items: center; + gap: 16px; } .collapse-trigger, .mobile-menu-trigger { - font-size: 18px; - cursor: pointer; - color: #1f2937; - border-radius: 4px; - transition: background 0.2s; - display: flex; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - flex-shrink: 0; + font-size: 18px; + cursor: pointer; + color: #1f2937; + border-radius: 4px; + transition: background 0.2s; + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + flex-shrink: 0; } .collapse-trigger:hover, .mobile-menu-trigger:hover { - background: #f9fafb; + background: #f9fafb; } .page-title-group { - display: flex; - flex-direction: column; - justify-content: center; - line-height: 1.4; + display: flex; + flex-direction: column; + justify-content: center; + line-height: 1.4; } .page-title { - font-size: 20px; - font-weight: 600; - color: #1f2937; - line-height: 1.2; - margin-bottom: 4px; + font-size: 20px; + font-weight: 600; + color: #1f2937; + line-height: 1.2; + margin-bottom: 4px; } .page-subtitle { - font-size: 14px; - color: #6b7280; - font-style: italic; - line-height: 1.2; + font-size: 14px; + color: #6b7280; + font-style: italic; + line-height: 1.2; } .main-content { - padding: 24px; - background: #f3f4f6; - min-height: calc(100vh - 64px); + padding: 24px; + background: #f3f4f6; + min-height: calc(100vh - 64px); } @media (max-width: 768px) { - .main-content { - padding: 16px; - } + .main-content { + padding: 16px; + } - .main-header { - padding: 0 16px !important; - } + .main-header { + padding: 0 16px !important; + } - .page-title { - font-size: 18px; - } + .page-title { + font-size: 18px; + } - .page-subtitle { - font-size: 12px; - } + .page-subtitle { + font-size: 12px; + } } diff --git a/apps/web/src/layouts/MainLayout.tsx b/apps/web/src/layouts/MainLayout.tsx index 589f1e3..e8f5480 100644 --- a/apps/web/src/layouts/MainLayout.tsx +++ b/apps/web/src/layouts/MainLayout.tsx @@ -9,95 +9,116 @@ import './MainLayout.css'; const { Header, Sider, Content } = Layout; const MainLayout = () => { - const [collapsed, setCollapsed] = useState(false); - const [mobileMenuOpen, setMobileMenuOpen] = useState(false); - const [isMobile, setIsMobile] = useState(false); - const location = useLocation(); + const [collapsed, setCollapsed] = useState(false); + const [mobileMenuOpen, setMobileMenuOpen] = useState(false); + const [isMobile, setIsMobile] = useState(false); + const location = useLocation(); - const pageInfo = useMemo(() => getPageInfo(location.pathname), [location.pathname]); + const pageInfo = useMemo( + () => getPageInfo(location.pathname), + [location.pathname], + ); - useEffect(() => { - const checkMobile = () => { - setIsMobile(window.innerWidth < 768); - if (window.innerWidth >= 768) setMobileMenuOpen(false); - }; - checkMobile(); - window.addEventListener('resize', checkMobile); - return () => window.removeEventListener('resize', checkMobile); - }, []); + useEffect(() => { + const checkMobile = () => { + setIsMobile(window.innerWidth < 768); + if (window.innerWidth >= 768) setMobileMenuOpen(false); + }; + checkMobile(); + window.addEventListener('resize', checkMobile); + return () => window.removeEventListener('resize', checkMobile); + }, []); - return ( - - {!isMobile && ( - -
-
{collapsed ? 'A' : 'Atlas Kit'}
- {!collapsed &&
商品工作台
} -
- -
- )} - - {isMobile && ( - setMobileMenuOpen(false)} - open={mobileMenuOpen} - styles={{ body: { padding: 0, background: 'var(--sider-bg)' } }} - width={200} - > - setMobileMenuOpen(false)} /> - - )} - - -
-
- {isMobile && ( - setMobileMenuOpen(true)} - /> - )} + return ( + {!isMobile && ( -
setCollapsed(!collapsed)}> - {collapsed ? : } -
+ +
+
+ {collapsed ? 'A' : 'Atlas Kit'} +
+ {!collapsed && ( +
商品工作台
+ )} +
+ +
)} -
-
{pageInfo.title}
-
{pageInfo.subtitle}
-
-
-
- - - -
-
- ); + {isMobile && ( + setMobileMenuOpen(false)} + open={mobileMenuOpen} + styles={{ + body: { padding: 0, background: 'var(--sider-bg)' }, + }} + width={200} + > + setMobileMenuOpen(false)} + /> + + )} + + +
+
+ {isMobile && ( + setMobileMenuOpen(true)} + /> + )} + {!isMobile && ( +
setCollapsed(!collapsed)} + > + {collapsed ? ( + + ) : ( + + )} +
+ )} +
+
{pageInfo.title}
+
+ {pageInfo.subtitle} +
+
+
+
+ + + + +
+ + ); }; export default MainLayout; diff --git a/apps/web/src/layouts/SidebarMenu.css b/apps/web/src/layouts/SidebarMenu.css index fbfd0b6..4b09df6 100644 --- a/apps/web/src/layouts/SidebarMenu.css +++ b/apps/web/src/layouts/SidebarMenu.css @@ -1,134 +1,140 @@ .sidebar-menu-container { - flex: 1; - overflow: hidden; - display: flex; - flex-direction: column; + flex: 1; + overflow: hidden; + display: flex; + flex-direction: column; } .sidebar-menu { - background: transparent !important; - border: none; - height: 100%; - overflow-y: auto; - overflow-x: hidden; + background: transparent !important; + border: none; + height: 100%; + overflow-y: auto; + overflow-x: hidden; } .sidebar-menu .ant-menu-item { - margin: 0 !important; - padding: 12px 20px !important; - height: auto !important; - line-height: 1.5 !important; - transition: all 0.3s !important; - font-size: 15px !important; - font-weight: 600 !important; + margin: 0 !important; + padding: 12px 20px !important; + height: auto !important; + line-height: 1.5 !important; + transition: all 0.3s !important; + font-size: 15px !important; + font-weight: 600 !important; } .sidebar-menu .ant-menu-item .ant-menu-title-content { - font-size: 15px !important; - font-weight: 600 !important; - transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); - display: inline-block; + font-size: 15px !important; + font-weight: 600 !important; + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); + display: inline-block; } .sidebar-menu .ant-menu-item:hover { - background: rgba(255, 255, 255, 0.1) !important; + background: rgba(255, 255, 255, 0.1) !important; } .sidebar-menu .ant-menu-item-selected { - background: rgba(255, 255, 255, 0.2) !important; - border-left: 3px solid white; + background: rgba(255, 255, 255, 0.2) !important; + border-left: 3px solid white; } .sidebar-menu .ant-menu-item-selected .ant-menu-title-content { - transform: translateX(8px); + transform: translateX(8px); } .sidebar-menu .ant-menu-item-selected:hover { - background: rgba(255, 255, 255, 0.25) !important; + background: rgba(255, 255, 255, 0.25) !important; } .sidebar-menu .ant-menu-item-selected:hover .ant-menu-title-content { - transform: translateX(8px); + transform: translateX(8px); } .sidebar-menu .ant-menu-item-group-title { - padding: 12px 20px 8px !important; - font-size: 12px !important; - color: rgba(255, 255, 255, 0.7) !important; - text-transform: uppercase; - letter-spacing: 1px; - font-weight: 500; + padding: 12px 20px 8px !important; + font-size: 12px !important; + color: rgba(255, 255, 255, 0.7) !important; + text-transform: uppercase; + letter-spacing: 1px; + font-weight: 500; } .sidebar-menu .ant-menu-item-icon { - transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); - font-size: 18px !important; - display: inline-flex; - align-items: center; + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); + font-size: 18px !important; + display: inline-flex; + align-items: center; } .sidebar-menu .ant-menu-item:hover .ant-menu-item-icon { - transform: scale(1.05); + transform: scale(1.05); } .sidebar-menu .ant-menu-item-selected .ant-menu-item-icon { - transform: translateX(8px); + transform: translateX(8px); } @media (max-width: 768px) { - .sidebar-menu .ant-menu-item { - padding: 14px 20px !important; - } + .sidebar-menu .ant-menu-item { + padding: 14px 20px !important; + } } /* ── 折叠态(60px):图标居中,覆盖展开态的左对齐 padding/位移 ── */ .sidebar-menu.ant-menu-inline-collapsed .ant-menu-item, .sidebar-menu.ant-menu-inline-collapsed .ant-menu-item-group-title { - padding: 12px 0 !important; - text-align: center; + padding: 12px 0 !important; + text-align: center; } .sidebar-menu.ant-menu-inline-collapsed .ant-menu-item { - display: flex; - align-items: center; - justify-content: center; - width: 100%; + display: flex; + align-items: center; + justify-content: center; + width: 100%; } .sidebar-menu.ant-menu-inline-collapsed .ant-menu-item .ant-menu-title-content, -.sidebar-menu.ant-menu-inline-collapsed .ant-menu-item-selected .ant-menu-title-content { - transform: none !important; +.sidebar-menu.ant-menu-inline-collapsed + .ant-menu-item-selected + .ant-menu-title-content { + transform: none !important; } .sidebar-menu.ant-menu-inline-collapsed .ant-menu-item .ant-menu-item-icon, -.sidebar-menu.ant-menu-inline-collapsed .ant-menu-item:hover .ant-menu-item-icon, -.sidebar-menu.ant-menu-inline-collapsed .ant-menu-item-selected .ant-menu-item-icon { - transform: none !important; - margin: 0; +.sidebar-menu.ant-menu-inline-collapsed + .ant-menu-item:hover + .ant-menu-item-icon, +.sidebar-menu.ant-menu-inline-collapsed + .ant-menu-item-selected + .ant-menu-item-icon { + transform: none !important; + margin: 0; } /* 折叠时去掉左侧 3px 选中边框(会挤偏图标),选中态用高亮背景区分 */ .sidebar-menu.ant-menu-inline-collapsed .ant-menu-item-selected { - border-left: none !important; + border-left: none !important; } /* 折叠时隐藏 label 占位(antd 折叠动画保留 opacity 占位,会把图标挤离中心) */ .sidebar-menu.ant-menu-inline-collapsed .ant-menu-item .ant-menu-title-content { - display: none !important; + display: none !important; } /* 兼容:部分版本折叠态用 vertical 类渲染,同样居中 */ .sidebar-menu.ant-menu-vertical .ant-menu-item, .sidebar-menu.ant-menu-inline-collapsed .ant-menu-item { - padding-left: 0 !important; - padding-right: 0 !important; + padding-left: 0 !important; + padding-right: 0 !important; } .sidebar-menu.ant-menu-vertical .ant-menu-item .ant-menu-title-content { - display: none !important; + display: none !important; } /* 折叠态 flex 子元素居中(display:flex 已生效,缺 justify-content) */ .sidebar-menu.ant-menu-inline-collapsed .ant-menu-item { - justify-content: center !important; + justify-content: center !important; } diff --git a/apps/web/src/layouts/SidebarMenu.tsx b/apps/web/src/layouts/SidebarMenu.tsx index 4f69933..c2c51b6 100644 --- a/apps/web/src/layouts/SidebarMenu.tsx +++ b/apps/web/src/layouts/SidebarMenu.tsx @@ -6,57 +6,59 @@ import { routeMenuConfig } from './menuConfig'; import './SidebarMenu.css'; interface SidebarMenuProps { - collapsed: boolean; - onMenuClick?: () => void; + collapsed: boolean; + onMenuClick?: () => void; } const SidebarMenu = ({ collapsed, onMenuClick }: SidebarMenuProps) => { - const location = useLocation(); - const navigate = useNavigate(); + const location = useLocation(); + const navigate = useNavigate(); - const menuItems: MenuProps['items'] = useMemo(() => { - const children = routeMenuConfig.map((config) => ({ - key: config.key, - icon: config.icon, - label: config.label, - })); - return [ - { - type: 'group' as const, - label: collapsed ? '' : '主要功能', - className: 'menu-section-title', - children, - }, - ]; - }, [collapsed]); + const menuItems: MenuProps['items'] = useMemo(() => { + const children = routeMenuConfig.map((config) => ({ + key: config.key, + icon: config.icon, + label: config.label, + })); + return [ + { + type: 'group' as const, + label: collapsed ? '' : '主要功能', + className: 'menu-section-title', + children, + }, + ]; + }, [collapsed]); - const selectedKeys = useMemo(() => { - const path = location.pathname; - if (path === '/' || path === '') { - return [routeMenuConfig[0].key]; - } - const config = routeMenuConfig.find((item) => path.startsWith(item.path)); - return [config ? config.key : path]; - }, [location.pathname]); + const selectedKeys = useMemo(() => { + const path = location.pathname; + if (path === '/' || path === '') { + return [routeMenuConfig[0].key]; + } + const config = routeMenuConfig.find((item) => + path.startsWith(item.path), + ); + return [config ? config.key : path]; + }, [location.pathname]); - const handleMenuClick: MenuProps['onClick'] = ({ key }) => { - navigate(key); - if (onMenuClick) onMenuClick(); - }; + const handleMenuClick: MenuProps['onClick'] = ({ key }) => { + navigate(key); + if (onMenuClick) onMenuClick(); + }; - return ( -
- -
- ); + return ( +
+ +
+ ); }; export default SidebarMenu; diff --git a/apps/web/src/layouts/menuConfig.tsx b/apps/web/src/layouts/menuConfig.tsx index 79dd7de..9fefdb0 100644 --- a/apps/web/src/layouts/menuConfig.tsx +++ b/apps/web/src/layouts/menuConfig.tsx @@ -1,80 +1,87 @@ import { - CalculatorOutlined, - GlobalOutlined, - InboxOutlined, - PictureOutlined, - ShopOutlined, + CalculatorOutlined, + GlobalOutlined, + InboxOutlined, + PictureOutlined, + ShopOutlined, } from '@ant-design/icons'; import type { ReactNode } from 'react'; export interface RouteMenuConfig { - /** 路由路径 */ - path: string; - /** 菜单键值(与 path 相同) */ - key: string; - /** 菜单图标 */ - icon: ReactNode; - /** 菜单标签 */ - label: string; - /** 页面标题 */ - title: string; - /** 页面副标题 */ - subtitle: string; + /** 路由路径 */ + path: string; + /** 菜单键值(与 path 相同) */ + key: string; + /** 菜单图标 */ + icon: ReactNode; + /** 菜单标签 */ + label: string; + /** 页面标题 */ + title: string; + /** 页面副标题 */ + subtitle: string; } /** 左侧一级菜单,顺序与 docs/requirements/account-store-watermark.md 的导航约定一致 */ export const routeMenuConfig: RouteMenuConfig[] = [ - { - path: '/online-products', - key: '/online-products', - icon: , - label: '在线商品', - title: '在线商品', - subtitle: '按 SKU 查看平台已上架商品与同步状态', - }, - { - path: '/collection', - key: '/collection', - icon: , - label: '采集箱', - title: '采集箱', - subtitle: '查看已采集的商品,进入编辑上架', - }, - { - path: '/shops', - key: '/shops', - icon: , - label: '店铺管理', - title: '店铺管理', - subtitle: '绑定平台店铺授权与水印', - }, - { - path: '/watermarks', - key: '/watermarks', - icon: , - label: '水印管理', - title: '水印管理', - subtitle: '维护水印模板并绑定到店铺', - }, - { - path: '/pricing', - key: '/pricing', - icon: , - label: '定价工具', - title: '定价工具', - subtitle: '独立试算与物流计价规则', - }, + { + path: '/online-products', + key: '/online-products', + icon: , + label: '在线商品', + title: '在线商品', + subtitle: '按 SKU 查看平台已上架商品与同步状态', + }, + { + path: '/collection', + key: '/collection', + icon: , + label: '采集箱', + title: '采集箱', + subtitle: '查看已采集的商品,进入编辑上架', + }, + { + path: '/shops', + key: '/shops', + icon: , + label: '店铺管理', + title: '店铺管理', + subtitle: '绑定平台店铺授权与水印', + }, + { + path: '/watermarks', + key: '/watermarks', + icon: , + label: '水印管理', + title: '水印管理', + subtitle: '维护水印模板并绑定到店铺', + }, + { + path: '/pricing', + key: '/pricing', + icon: , + label: '定价工具', + title: '定价工具', + subtitle: '独立试算与物流计价规则', + }, ]; /** 根据路径获取页面标题信息 */ -export const getPageInfo = (path: string): { title: string; subtitle: string } => { - if (path === '/' || path === '') { - const first = routeMenuConfig[0]; - return { title: first.title, subtitle: first.subtitle }; - } - if (path.startsWith('/products/')) { - return { title: '商品编辑', subtitle: '商品 AI 编辑页:SPU/SKU、媒体、定价与发布' }; - } - const config = routeMenuConfig.find((item) => path.startsWith(item.path)); - return config ? { title: config.title, subtitle: config.subtitle } : getPageInfo('/'); +export const getPageInfo = ( + path: string, +): { title: string; subtitle: string } => { + if (path === '/' || path === '') { + const first = routeMenuConfig[0]; + return { title: first.title, subtitle: first.subtitle }; + } + if (path.startsWith('/products/')) { + return { + title: '商品编辑', + subtitle: '商品 AI 编辑页:SPU/SKU、媒体、定价与发布', + }; + } + const config = routeMenuConfig.find((item) => path.startsWith(item.path)); + return config + ? { title: config.title, subtitle: config.subtitle } + : getPageInfo('/'); }; diff --git a/apps/web/src/main.tsx b/apps/web/src/main.tsx index cc14d83..00f5203 100644 --- a/apps/web/src/main.tsx +++ b/apps/web/src/main.tsx @@ -4,7 +4,7 @@ import './index.css'; import App from './App'; createRoot(document.getElementById('root')!).render( - - - , + + + , ); diff --git a/apps/web/src/pages/auth/LoginPage.tsx b/apps/web/src/pages/auth/LoginPage.tsx index 1415800..6c0112f 100644 --- a/apps/web/src/pages/auth/LoginPage.tsx +++ b/apps/web/src/pages/auth/LoginPage.tsx @@ -10,76 +10,100 @@ import { authToken } from '@/services/authToken'; import { emailFormatRule } from '@/utils/validators'; interface LoginFormValues { - email: string; - password: string; + email: string; + password: string; } /** 登录页,契约见 docs/api/auth.md §3 */ const LoginPage = () => { - const navigate = useNavigate(); - const { message } = AntdApp.useApp(); - const [submitting, setSubmitting] = useState(false); + const navigate = useNavigate(); + const { message } = AntdApp.useApp(); + const [submitting, setSubmitting] = useState(false); - const handleFinish = async (values: LoginFormValues) => { - setSubmitting(true); - try { - const session = await authApi.login({ - email: values.email.trim(), - password: values.password, - }); - authToken.set(session.access_token); - message.success('登录成功'); - navigate('/online-products', { replace: true }); - } catch (error) { - // 契约约定登录失败统一返回 401 INVALID_CREDENTIALS,不区分邮箱不存在或密码错误 - if (axios.isAxiosError(error) && error.response?.status === 401) { - message.error('邮箱或密码不正确'); - } else { - message.error(apiErrorMessage(error)); - } - } finally { - setSubmitting(false); - } - }; + const handleFinish = async (values: LoginFormValues) => { + setSubmitting(true); + try { + const session = await authApi.login({ + email: values.email.trim(), + password: values.password, + }); + authToken.set(session.access_token); + message.success('登录成功'); + navigate('/online-products', { replace: true }); + } catch (error) { + // 契约约定登录失败统一返回 401 INVALID_CREDENTIALS,不区分邮箱不存在或密码错误 + if (axios.isAxiosError(error) && error.response?.status === 401) { + message.error('邮箱或密码不正确'); + } else { + message.error(apiErrorMessage(error)); + } + } finally { + setSubmitting(false); + } + }; - return ( - - 还没有账户?立即注册 - - } - > - layout="vertical" requiredMark={false} onFinish={handleFinish}> - + 还没有账户?立即注册 + + } > - } - placeholder="请输入邮箱" - autoComplete="email" - autoFocus - /> - - - } - placeholder="请输入密码" - autoComplete="current-password" - /> - - - - - - - ); + + layout="vertical" + requiredMark={false} + onFinish={handleFinish} + > + + + } + placeholder="请输入邮箱" + autoComplete="email" + autoFocus + /> + + + + } + placeholder="请输入密码" + autoComplete="current-password" + /> + + + + + + + ); }; export default LoginPage; diff --git a/apps/web/src/pages/auth/RegisterPage.tsx b/apps/web/src/pages/auth/RegisterPage.tsx index df7644f..dc92442 100644 --- a/apps/web/src/pages/auth/RegisterPage.tsx +++ b/apps/web/src/pages/auth/RegisterPage.tsx @@ -10,126 +10,157 @@ import { authToken } from '@/services/authToken'; import { emailFormatRule } from '@/utils/validators'; interface RegisterFormValues { - display_name?: string; - email: string; - password: string; - password_confirmation: string; + display_name?: string; + email: string; + password: string; + password_confirmation: string; } /** 注册页,契约见 docs/api/auth.md §2;密码长度与复杂度由服务端唯一校验,前端不自行放宽或收窄 */ const RegisterPage = () => { - const navigate = useNavigate(); - const { message } = AntdApp.useApp(); - const [form] = Form.useForm(); - const [submitting, setSubmitting] = useState(false); + const navigate = useNavigate(); + const { message } = AntdApp.useApp(); + const [form] = Form.useForm(); + const [submitting, setSubmitting] = useState(false); - const handleFinish = async (values: RegisterFormValues) => { - setSubmitting(true); - try { - const session = await authApi.register({ - email: values.email.trim(), - password: values.password, - password_confirmation: values.password_confirmation, - display_name: values.display_name?.trim() || undefined, - }); - // 注册成功即在同一事务创建用户、个人工作空间和登录会话 - authToken.set(session.access_token); - message.success('注册成功,已进入你的工作空间'); - navigate('/online-products', { replace: true }); - } catch (error) { - // 重复邮箱返回 409 EMAIL_ALREADY_REGISTERED,落到邮箱字段上提示 - if (axios.isAxiosError(error) && error.response?.status === 409) { - form.setFields([{ name: 'email', errors: ['该邮箱已注册,请直接登录'] }]); - } else { - message.error(apiErrorMessage(error)); - } - } finally { - setSubmitting(false); - } - }; + const handleFinish = async (values: RegisterFormValues) => { + setSubmitting(true); + try { + const session = await authApi.register({ + email: values.email.trim(), + password: values.password, + password_confirmation: values.password_confirmation, + display_name: values.display_name?.trim() || undefined, + }); + // 注册成功即在同一事务创建用户、个人工作空间和登录会话 + authToken.set(session.access_token); + message.success('注册成功,已进入你的工作空间'); + navigate('/online-products', { replace: true }); + } catch (error) { + // 重复邮箱返回 409 EMAIL_ALREADY_REGISTERED,落到邮箱字段上提示 + if (axios.isAxiosError(error) && error.response?.status === 409) { + form.setFields([ + { name: 'email', errors: ['该邮箱已注册,请直接登录'] }, + ]); + } else { + message.error(apiErrorMessage(error)); + } + } finally { + setSubmitting(false); + } + }; - return ( - - 已有账户?直接登录 - - } - > - - form={form} - layout="vertical" - requiredMark={false} - onFinish={handleFinish} - > - + 已有账户?直接登录 + + } > - } - placeholder="选填" - maxLength={80} - autoComplete="nickname" - /> - - - } - placeholder="请输入邮箱" - autoComplete="email" - /> - - - } - placeholder="请输入密码" - autoComplete="new-password" - /> - - ({ - validator(_, value) { - if (!value || getFieldValue('password') === value) { - return Promise.resolve(); - } - return Promise.reject(new Error('两次输入的密码不一致')); - }, - }), - ]} - > - } - placeholder="请再次输入密码" - autoComplete="new-password" - /> - - - - - - - ); + + form={form} + layout="vertical" + requiredMark={false} + onFinish={handleFinish} + > + + + } + placeholder="选填" + maxLength={80} + autoComplete="nickname" + /> + + + + } + placeholder="请输入邮箱" + autoComplete="email" + /> + + + + } + placeholder="请输入密码" + autoComplete="new-password" + /> + + ({ + validator(_, value) { + if ( + !value || + getFieldValue('password') === value + ) { + return Promise.resolve(); + } + return Promise.reject( + new Error('两次输入的密码不一致'), + ); + }, + }), + ]} + > + + } + placeholder="请再次输入密码" + autoComplete="new-password" + /> + + + + + + + ); }; export default RegisterPage; diff --git a/apps/web/src/pages/collection/CollectionPage.tsx b/apps/web/src/pages/collection/CollectionPage.tsx index 55cdd3b..e86fdaf 100644 --- a/apps/web/src/pages/collection/CollectionPage.tsx +++ b/apps/web/src/pages/collection/CollectionPage.tsx @@ -2,7 +2,7 @@ import PagePlaceholder from '@/components/PagePlaceholder'; /** 采集箱:查看已采集的商品,进入编辑上架(业务模块尚未实现) */ const CollectionPage = () => ( - + ); export default CollectionPage; diff --git a/apps/web/src/pages/online-products/OnlineProductsPage.tsx b/apps/web/src/pages/online-products/OnlineProductsPage.tsx index b017d53..77dc6de 100644 --- a/apps/web/src/pages/online-products/OnlineProductsPage.tsx +++ b/apps/web/src/pages/online-products/OnlineProductsPage.tsx @@ -2,10 +2,10 @@ import PagePlaceholder from '@/components/PagePlaceholder'; /** 在线商品:按 SKU 查看平台已上架商品与同步状态(业务模块尚未实现) */ const OnlineProductsPage = () => ( - + ); export default OnlineProductsPage; diff --git a/apps/web/src/pages/pricing/PricingPage.tsx b/apps/web/src/pages/pricing/PricingPage.tsx index c2ce77d..cb432b8 100644 --- a/apps/web/src/pages/pricing/PricingPage.tsx +++ b/apps/web/src/pages/pricing/PricingPage.tsx @@ -2,7 +2,10 @@ import PagePlaceholder from '@/components/PagePlaceholder'; /** 定价工具:独立试算与物流计价规则(业务模块尚未实现) */ const PricingPage = () => ( - + ); export default PricingPage; diff --git a/apps/web/src/pages/products/ProductEditPage.tsx b/apps/web/src/pages/products/ProductEditPage.tsx index 1898016..a053335 100644 --- a/apps/web/src/pages/products/ProductEditPage.tsx +++ b/apps/web/src/pages/products/ProductEditPage.tsx @@ -3,14 +3,14 @@ import PagePlaceholder from '@/components/PagePlaceholder'; /** 商品 AI 编辑页:编辑 SPU/SKU、媒体、定价与首次发布(业务模块尚未实现) */ const ProductEditPage = () => { - const { id } = useParams<{ id: string }>(); + const { id } = useParams<{ id: string }>(); - return ( - - ); + return ( + + ); }; export default ProductEditPage; diff --git a/apps/web/src/pages/shops/ShopsPage.tsx b/apps/web/src/pages/shops/ShopsPage.tsx index ad11521..d93e67b 100644 --- a/apps/web/src/pages/shops/ShopsPage.tsx +++ b/apps/web/src/pages/shops/ShopsPage.tsx @@ -2,7 +2,10 @@ import PagePlaceholder from '@/components/PagePlaceholder'; /** 店铺管理:绑定平台店铺授权与水印(业务模块尚未实现) */ const ShopsPage = () => ( - + ); export default ShopsPage; diff --git a/apps/web/src/pages/watermarks/WatermarksPage.tsx b/apps/web/src/pages/watermarks/WatermarksPage.tsx index 81f01f1..dfd6922 100644 --- a/apps/web/src/pages/watermarks/WatermarksPage.tsx +++ b/apps/web/src/pages/watermarks/WatermarksPage.tsx @@ -2,7 +2,10 @@ import PagePlaceholder from '@/components/PagePlaceholder'; /** 水印管理:维护水印模板并绑定到店铺(业务模块尚未实现) */ const WatermarksPage = () => ( - + ); export default WatermarksPage; diff --git a/apps/web/src/router/index.tsx b/apps/web/src/router/index.tsx index 8b65f67..bad0f67 100644 --- a/apps/web/src/router/index.tsx +++ b/apps/web/src/router/index.tsx @@ -10,22 +10,25 @@ import ShopsPage from '@/pages/shops/ShopsPage'; import WatermarksPage from '@/pages/watermarks/WatermarksPage'; export const router = createBrowserRouter([ - { - path: '/', - element: , - children: [ - { index: true, element: }, - { path: 'online-products', element: }, - { path: 'collection', element: }, - { path: 'shops', element: }, - { path: 'watermarks', element: }, - { path: 'pricing', element: }, - // 商品 AI 编辑页:从采集箱/在线商品进入,不在左侧菜单中出现 - { path: 'products/:id', element: }, - ], - }, - // 认证页在主布局之外;API 侧会话体系实现后再加路由守卫 - { path: 'login', element: }, - { path: 'register', element: }, - { path: '*', element: }, + { + path: '/', + element: , + children: [ + { + index: true, + element: , + }, + { path: 'online-products', element: }, + { path: 'collection', element: }, + { path: 'shops', element: }, + { path: 'watermarks', element: }, + { path: 'pricing', element: }, + // 商品 AI 编辑页:从采集箱/在线商品进入,不在左侧菜单中出现 + { path: 'products/:id', element: }, + ], + }, + // 认证页在主布局之外;API 侧会话体系实现后再加路由守卫 + { path: 'login', element: }, + { path: 'register', element: }, + { path: '*', element: }, ]); diff --git a/apps/web/src/services/api.ts b/apps/web/src/services/api.ts index afa628d..8934434 100644 --- a/apps/web/src/services/api.ts +++ b/apps/web/src/services/api.ts @@ -1,102 +1,122 @@ import axios from 'axios'; -import type { AxiosInstance, AxiosRequestConfig, InternalAxiosRequestConfig } from 'axios'; +import type { + AxiosInstance, + AxiosRequestConfig, + InternalAxiosRequestConfig, +} from 'axios'; import { envConfig } from '@/config/env'; import { authToken } from '@/services/authToken'; declare module 'axios' { - export interface AxiosRequestConfig { - /** 401 刷新重放标记,防止无限重试 */ - _retried?: boolean; - } + export interface AxiosRequestConfig { + /** 401 刷新重放标记,防止无限重试 */ + _retried?: boolean; + } } const apiClient: AxiosInstance = axios.create({ - baseURL: envConfig.apiBaseUrl, - timeout: 30000, - // 不设全局 Content-Type:axios 1.x 遇到「默认 JSON 头 + FormData」会把表单转成 JSON 发送, - // 导致素材上传等表单接口解析失败。对象请求体 axios 会自动补 JSON 头。 + baseURL: envConfig.apiBaseUrl, + timeout: 30000, + // 不设全局 Content-Type:axios 1.x 遇到「默认 JSON 头 + FormData」会把表单转成 JSON 发送, + // 导致素材上传等表单接口解析失败。对象请求体 axios 会自动补 JSON 头。 }); // access token 仅在内存中短暂持有(docs/api/conventions.md §1),每次请求动态附加 Bearer 头 apiClient.interceptors.request.use((config: InternalAxiosRequestConfig) => { - const token = authToken.get(); - if (token) { - config.headers.Authorization = `Bearer ${token}`; - } - return config; + const token = authToken.get(); + if (token) { + config.headers.Authorization = `Bearer ${token}`; + } + return config; }); // 认证接口自身的失败不进入刷新流程 -const AUTH_PATHS = ['/auth/login', '/auth/register', '/auth/refresh', '/auth/logout']; +const AUTH_PATHS = [ + '/auth/login', + '/auth/register', + '/auth/refresh', + '/auth/logout', +]; let refreshTask: Promise | null = null; /** 并发 401 只触发一次刷新请求;刷新依赖 HttpOnly refresh cookie */ function refreshAccessToken(): Promise { - refreshTask ??= apiClient - .post<{ access_token: string }>('/auth/refresh') - .then((res) => { - authToken.set(res.data.access_token); - return res.data.access_token; - }) - .catch(() => { - authToken.clear(); - return null; - }) - .finally(() => { - refreshTask = null; - }); - return refreshTask; + refreshTask ??= apiClient + .post<{ access_token: string }>('/auth/refresh') + .then((res) => { + authToken.set(res.data.access_token); + return res.data.access_token; + }) + .catch(() => { + authToken.clear(); + return null; + }) + .finally(() => { + refreshTask = null; + }); + return refreshTask; } apiClient.interceptors.response.use( - (response) => response, - async (error) => { - if (envConfig.debug) { - console.error('请求失败:', error.response?.data || error.message); - } - const config = error.config as AxiosRequestConfig | undefined; - const url = config?.url ?? ''; - const isAuthPath = AUTH_PATHS.some((path) => url.includes(path)); - // access token 过期时用 refresh cookie 换新 token 并重放一次; - // 刷新失败说明会话已失效,整页跳转登录页(后续可换成路由内跳转并保留来源) - if (error.response?.status === 401 && config && !config._retried && !isAuthPath) { - config._retried = true; - const token = await refreshAccessToken(); - if (token) { - return apiClient.request(config); - } - window.location.assign('/login'); - } - return Promise.reject(error); - }, + (response) => response, + async (error) => { + if (envConfig.debug) { + console.error('请求失败:', error.response?.data || error.message); + } + const config = error.config as AxiosRequestConfig | undefined; + const url = config?.url ?? ''; + const isAuthPath = AUTH_PATHS.some((path) => url.includes(path)); + // access token 过期时用 refresh cookie 换新 token 并重放一次; + // 刷新失败说明会话已失效,整页跳转登录页(后续可换成路由内跳转并保留来源) + if ( + error.response?.status === 401 && + config && + !config._retried && + !isAuthPath + ) { + config._retried = true; + const token = await refreshAccessToken(); + if (token) { + return apiClient.request(config); + } + window.location.assign('/login'); + } + return Promise.reject(error); + }, ); export const api = { - get: (url: string, config?: AxiosRequestConfig) => - apiClient.get(url, config).then((res) => res.data), + get: (url: string, config?: AxiosRequestConfig) => + apiClient.get(url, config).then((res) => res.data), - post: (url: string, data?: unknown, config?: AxiosRequestConfig) => - apiClient.post(url, data, config).then((res) => res.data), + post: ( + url: string, + data?: unknown, + config?: AxiosRequestConfig, + ) => apiClient.post(url, data, config).then((res) => res.data), - patch: (url: string, data?: unknown, config?: AxiosRequestConfig) => - apiClient.patch(url, data, config).then((res) => res.data), + patch: ( + url: string, + data?: unknown, + config?: AxiosRequestConfig, + ) => apiClient.patch(url, data, config).then((res) => res.data), - delete: (url: string, config?: AxiosRequestConfig) => - apiClient.delete(url, config).then((res) => res.data), + delete: (url: string, config?: AxiosRequestConfig) => + apiClient.delete(url, config).then((res) => res.data), }; /** 统一错误格式为 { error: { code, message, request_id } }(docs/api/conventions.md),提取可展示信息 */ export function apiErrorMessage(error: unknown): string { - if (axios.isAxiosError(error)) { - const data = error.response?.data as - { error?: { message?: unknown }; message?: unknown } | undefined; - if (data?.error?.message) return String(data.error.message); - if (data?.message) return String(data.message); - if (error.response) return `请求失败(HTTP ${error.response.status})`; - return '网络连接失败,请稍后重试'; - } - return error instanceof Error ? error.message : String(error); + if (axios.isAxiosError(error)) { + const data = error.response?.data as + { error?: { message?: unknown }; message?: unknown } | undefined; + if (data?.error?.message) return String(data.error.message); + if (data?.message) return String(data.message); + if (error.response) return `请求失败(HTTP ${error.response.status})`; + return '网络连接失败,请稍后重试'; + } + return error instanceof Error ? error.message : String(error); } export default apiClient; diff --git a/apps/web/src/services/auth.ts b/apps/web/src/services/auth.ts index d0679d0..ff53825 100644 --- a/apps/web/src/services/auth.ts +++ b/apps/web/src/services/auth.ts @@ -1,13 +1,20 @@ import { api } from '@/services/api'; -import type { AuthSession, LoginPayload, MeResult, RegisterPayload } from '@/types/auth'; +import type { + AuthSession, + LoginPayload, + MeResult, + RegisterPayload, +} from '@/types/auth'; /** 账户与会话接口,契约见 docs/api/auth.md */ export const authApi = { - register: (payload: RegisterPayload) => api.post('/auth/register', payload), + register: (payload: RegisterPayload) => + api.post('/auth/register', payload), - login: (payload: LoginPayload) => api.post('/auth/login', payload), + login: (payload: LoginPayload) => + api.post('/auth/login', payload), - logout: () => api.post('/auth/logout'), + logout: () => api.post('/auth/logout'), - me: () => api.get('/auth/me'), + me: () => api.get('/auth/me'), }; diff --git a/apps/web/src/services/authToken.ts b/apps/web/src/services/authToken.ts index d0b8241..c8afc8b 100644 --- a/apps/web/src/services/authToken.ts +++ b/apps/web/src/services/authToken.ts @@ -6,11 +6,11 @@ let accessToken: string | null = null; export const authToken = { - get: () => accessToken, - set: (token: string) => { - accessToken = token; - }, - clear: () => { - accessToken = null; - }, + get: () => accessToken, + set: (token: string) => { + accessToken = token; + }, + clear: () => { + accessToken = null; + }, }; diff --git a/apps/web/src/types/auth.ts b/apps/web/src/types/auth.ts index f68f230..6b9c4eb 100644 --- a/apps/web/src/types/auth.ts +++ b/apps/web/src/types/auth.ts @@ -4,52 +4,52 @@ */ export interface AuthUser { - id: string; - email: string; - display_name: string | null; - email_verified_at: string | null; - created_at?: string; + id: string; + email: string; + display_name: string | null; + email_verified_at: string | null; + created_at?: string; } export interface AuthWorkspace { - id: string; - name: string; - role: string; + id: string; + name: string; + role: string; } /** 注册 / 登录成功返回的会话(access token 短期有效,refresh token 在 HttpOnly cookie 中) */ export interface AuthSession { - access_token: string; - access_token_expires_in: number; - user: AuthUser; - workspace: AuthWorkspace; + access_token: string; + access_token_expires_in: number; + user: AuthUser; + workspace: AuthWorkspace; } export interface RegisterPayload { - email: string; - password: string; - password_confirmation: string; - display_name?: string; + email: string; + password: string; + password_confirmation: string; + display_name?: string; } export interface LoginPayload { - email: string; - password: string; + email: string; + password: string; } export interface PlatformSummary { - id: string; - code: string; - name: string; + id: string; + code: string; + name: string; } /** GET /api/auth/me 的返回;default_store 摘要字段以后续门店接口文档为准 */ export interface MeResult { - user: AuthUser; - workspace: AuthWorkspace; - platforms: PlatformSummary[]; - suggested_context: { - platform_id: string; - default_store: { id: string; name: string } | null; - }; + user: AuthUser; + workspace: AuthWorkspace; + platforms: PlatformSummary[]; + suggested_context: { + platform_id: string; + default_store: { id: string; name: string } | null; + }; } diff --git a/apps/web/src/utils/validators.ts b/apps/web/src/utils/validators.ts index bebd5e9..804fa4d 100644 --- a/apps/web/src/utils/validators.ts +++ b/apps/web/src/utils/validators.ts @@ -2,8 +2,8 @@ import type { Rule } from 'antd/es/form'; /** 邮箱格式校验:仅在非空时校验,避免与 required 规则在空值时同时报错(antd v6 行为) */ export const emailFormatRule: Rule = { - validator: (_, value: string) => - !value || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) - ? Promise.resolve() - : Promise.reject(new Error('邮箱格式不正确')), + validator: (_, value: string) => + !value || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) + ? Promise.resolve() + : Promise.reject(new Error('邮箱格式不正确')), }; diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 71623a9..5e9dc56 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -1,21 +1,21 @@ { - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "composite": true, - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo", - // Web 走 Vite 打包,使用 bundler 解析;覆盖 base 中面向 NestJS 的 Node16 模块设置 - "module": "ESNext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "isolatedModules": true, - "useDefineForClassFields": true, - "lib": ["ES2023", "DOM", "DOM.Iterable"], - "jsx": "react-jsx", - "noEmit": true, - "allowImportingTsExtensions": false, - "paths": { - "@/*": ["./src/*"] - } - }, - "include": ["src", "vite.config.ts"] + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.tsbuildinfo", + // Web 走 Vite 打包,使用 bundler 解析;覆盖 base 中面向 NestJS 的 Node16 模块设置 + "module": "ESNext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "isolatedModules": true, + "useDefineForClassFields": true, + "lib": ["ES2023", "DOM", "DOM.Iterable"], + "jsx": "react-jsx", + "noEmit": true, + "allowImportingTsExtensions": false, + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src", "vite.config.ts"] } diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 131dc4a..d7e84db 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -4,20 +4,20 @@ import react from '@vitejs/plugin-react'; // 前端开发服务器:/api 代理到本地 NestJS API(apps/api,默认 8200) export default defineConfig({ - plugins: [react()], - resolve: { - alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)), + plugins: [react()], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)), + }, }, - }, - server: { - port: Number(process.env.WEB_PORT ?? 8100), - strictPort: true, - proxy: { - '/api': { - target: process.env.API_ORIGIN ?? 'http://localhost:8200', - changeOrigin: true, - }, + server: { + port: Number(process.env.WEB_PORT ?? 8100), + strictPort: true, + proxy: { + '/api': { + target: process.env.API_ORIGIN ?? 'http://localhost:8200', + changeOrigin: true, + }, + }, }, - }, }); diff --git a/apps/worker/package.json b/apps/worker/package.json index 50a09cd..00ac42b 100644 --- a/apps/worker/package.json +++ b/apps/worker/package.json @@ -1,21 +1,21 @@ { - "name": "@atlas/worker", - "version": "0.1.0", - "private": true, - "scripts": { - "build": "tsc -p tsconfig.json", - "dev": "tsx watch src/main.ts", - "start": "node dist/main.js", - "typecheck": "tsc -p tsconfig.json --noEmit" - }, - "dependencies": { - "@atlas/contracts": "workspace:*", - "bullmq": "6.3.4", - "ioredis": "6.0.0" - }, - "devDependencies": { - "@types/node": "26.3.0", - "tsx": "4.23.13", - "typescript": "7.0.2" - } + "name": "@atlas/worker", + "version": "0.1.0", + "private": true, + "scripts": { + "build": "tsc -p tsconfig.json", + "dev": "tsx watch src/main.ts", + "start": "node dist/main.js", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "@atlas/contracts": "workspace:*", + "bullmq": "6.3.4", + "ioredis": "6.0.0" + }, + "devDependencies": { + "@types/node": "26.3.0", + "tsx": "4.23.13", + "typescript": "7.0.2" + } } diff --git a/apps/worker/src/main.ts b/apps/worker/src/main.ts index 58b0c06..bf938d1 100644 --- a/apps/worker/src/main.ts +++ b/apps/worker/src/main.ts @@ -3,22 +3,25 @@ import IORedis from 'ioredis'; // 显式构造客户端实例传给 BullMQ:原生 ESM(pnpm start)下 BullMQ 无法按 connection // 选项自动加载 ioredis;maxRetriesPerRequest: null 是 BullMQ Worker 的要求 -const connection = new IORedis(process.env.REDIS_URL ?? 'redis://localhost:6379', { - maxRetriesPerRequest: null, -}); +const connection = new IORedis( + process.env.REDIS_URL ?? 'redis://localhost:6379', + { + maxRetriesPerRequest: null, + }, +); const dispatchQueue = new Queue('atlas-dispatch', { connection }); async function bootstrap() { - await dispatchQueue.waitUntilReady(); - console.info( - 'Atlas Worker is ready; it will consume transactional-outbox events after that module exists.', - ); + await dispatchQueue.waitUntilReady(); + console.info( + 'Atlas Worker is ready; it will consume transactional-outbox events after that module exists.', + ); } void bootstrap(); async function shutdown() { - await dispatchQueue.close(); + await dispatchQueue.close(); } process.once('SIGINT', () => void shutdown()); diff --git a/apps/worker/tsconfig.json b/apps/worker/tsconfig.json index 762e711..f802d0a 100644 --- a/apps/worker/tsconfig.json +++ b/apps/worker/tsconfig.json @@ -1,9 +1,9 @@ { - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "types": ["node"] - }, - "include": ["src/**/*.ts"] + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "types": ["node"] + }, + "include": ["src/**/*.ts"] } diff --git a/docs/api/README.md b/docs/api/README.md index 080a218..0ffeac1 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -2,6 +2,10 @@ > 状态:第一批可评审契约。本文档描述预期的 NestJS HTTP API,不代表接口已经实现。接口统一以前缀 `/api` 提供,JSON 字段使用 `snake_case`,时间使用 ISO 8601 UTC 字符串,ID 使用 UUID。 +API 启动后会在 `/api-docs` 提供 Swagger UI,并在其 OpenAPI 文档中标记已实现的接口。Swagger 是运行时参考,不替代本目录的冻结契约。 + +运行状态端点不使用 `/api` 前缀:`GET /health` 只表明进程存活,`GET /ready` 会校验应用数据库连接,失败时返回 `503`。生产环境由环境变量控制 API 端口、CORS 来源、日志级别、请求体上限、认证限流及可信反向代理列表;缺少或格式错误的必需安全配置会阻止 API 启动。 + ## 1. 文档路线 | 文档 | 状态 | 范围 | diff --git a/docs/api/conventions.md b/docs/api/conventions.md index 8744122..295d4c5 100644 --- a/docs/api/conventions.md +++ b/docs/api/conventions.md @@ -29,6 +29,25 @@ X-Atlas-Platform-Id: 57ad…-uuid ## 3. 响应、分页和字段格式 +### 3.1 强制响应信封 + +本项目不采用完整 JSON:API 规范,但所有业务 HTTP 接口必须使用以下响应信封;这是 +前端、服务端、Worker 和扩展共同遵守的强制契约: + +| 场景 | HTTP 响应体 | +|---|---| +| 成功的单资源或同步动作 | `{ "data": T }` | +| 成功的列表 | `{ "data": T[], "meta": PaginationMeta }` | +| 失败 | `{ "error": ApiError }` | +| `204 No Content` | 无响应体 | + +`data` 只能位于顶层且只能出现一次;不得返回 `{ "data": { "data": ... } }`,也不得以 +`{ "data": null }` 表示失败。HTTP 状态码仍表达请求结果,错误必须使用本文件第 4 节的 +`error` 信封,不能混入成功响应。`meta` 只承载分页、游标或与整个响应相关的元信息,不能 +替代资源字段。 + +### 3.2 成功与列表响应 + 成功响应统一为: ```json diff --git a/docs/architecture/database-security.md b/docs/architecture/database-security.md index f66c887..bb44136 100644 --- a/docs/architecture/database-security.md +++ b/docs/architecture/database-security.md @@ -12,6 +12,22 @@ `atlas_app_login` 和 `atlas_app` 都必须是 `NOBYPASSRLS`,也不能是 PostgreSQL 超级用户。生产环境不得把 `atlas_migrator` 的连接串写入 API 或 Worker 的环境变量。 +### 角色链与请求上下文 + +三层角色链是固定的,不能简化为“应用直接使用迁移账号”: + +```text +atlas_migrator ──拥有──> atlas schema 与业务表 + +atlas_app_login ──登录身份,NOINHERIT──> SET LOCAL ROLE atlas_app +atlas_app ──无登录权限组──────────> 最小 DML 与序列权限 +``` + +API 和 Worker 只以 `atlas_app_login` 建立连接。每笔业务事务必须先执行 +`SET LOCAL ROLE atlas_app`,再设置 `SET LOCAL app.workspace_id`。前者收窄为 +应用所需的最小数据库权限,后者为 RLS 策略提供当前工作空间上下文;任何一步缺失, +都不应使跨工作空间数据变得可见。 + ## 2. 一次性数据库初始化 以下由云数据库管理员或基础设施脚本执行;它不属于 NestJS 的业务 migration,因为托管 PostgreSQL 常不允许应用账户创建角色。密码应从密钥管理服务注入,示例中不填写真实密码。 @@ -22,6 +38,7 @@ CREATE ROLE atlas_app NOLOGIN NOINHERIT NOBYPASSRLS; CREATE ROLE atlas_app_login LOGIN NOINHERIT NOBYPASSRLS PASSWORD ''; GRANT atlas_app TO atlas_app_login; +GRANT CREATE ON DATABASE atlas TO atlas_migrator; CREATE SCHEMA IF NOT EXISTS atlas AUTHORIZATION atlas_migrator; GRANT USAGE ON SCHEMA atlas TO atlas_app; @@ -34,7 +51,7 @@ ALTER DEFAULT PRIVILEGES FOR ROLE atlas_migrator IN SCHEMA atlas GRANT USAGE, SELECT ON SEQUENCES TO atlas_app; ``` -首次 DDL 与后续 migration 都以 `atlas_migrator` 执行,确保新表的所有者一致。若云服务统一由管理员创建 schema,可将 `atlas_migrator` 设为 schema/表所有者或由管理员代为执行 migration;无论哪种方式,应用登录角色都不得成为表所有者。 +首次 DDL 与后续 migration 都以 `atlas_migrator` 执行,确保新表的所有者一致。迁移角色拥有数据库级 `CREATE` 的唯一目的,是创建其拥有的 `atlas` schema;它不授予 API 或 Worker 任何额外权限。若云服务统一由管理员创建 schema,可将 `atlas_migrator` 设为 schema/表所有者或由管理员代为执行 migration;无论哪种方式,应用登录角色都不得成为表所有者。 ## 3. RLS 的运行方式 diff --git a/docs/project/HANDOFF.md b/docs/project/HANDOFF.md index cb169f8..0dc8974 100644 --- a/docs/project/HANDOFF.md +++ b/docs/project/HANDOFF.md @@ -86,6 +86,7 @@ User → Workspace → Membership / Role - 覆盖账户认证、平台/门店、水印与素材、定价、浏览器采集/采集箱、商品编辑/首次发布、在线商品读取与同步。 - 所有接口遵循统一鉴权、工作空间隔离、页头平台上下文、金额字符串、错误格式、`Idempotency-Key`、`If-Match` 和异步 `operation` 约定。 +- **响应信封是强制契约:** 成功单资源或同步动作返回 `{ "data": T }`,列表返回 `{ "data": T[], "meta": PaginationMeta }`,失败返回 `{ "error": ApiError }`,`204 No Content` 不返回响应体。项目不采用完整 JSON:API;任何调用方不得自行增加嵌套 `data` 或以 `data: null` 表示错误。完整规则见 [`api/conventions.md`](../api/conventions.md)。 - 关键异步动作必须在同一事务写入业务记录、`operations`(如需用户可见进度)和 `outbox_events`;Dispatcher 至少一次投递 BullMQ,Worker 必须幂等。 - DDL 已通过临时隔离 PostgreSQL 实例执行验证;API 契约已完成文档评审。这不表示 NestJS 模块、迁移执行器或 Worker 已实现。 diff --git a/infra/README.md b/infra/README.md index e3d50f2..52bd7f9 100644 --- a/infra/README.md +++ b/infra/README.md @@ -1,5 +1,10 @@ # 本地基础设施 -复制根目录 `.env.example` 为 `.env` 后,执行 `pnpm infra:up` 启动 PostgreSQL、Redis 和 MinIO。镜像使用已验证的明确版本标签;升级前应先在本地或 staging 验证,再显式更新标签。 +复制根目录 `.env.example` 为 `.env` 后,执行 `pnpm infra:up` 启动 PostgreSQL、Redis 和 MinIO。该命令会显式加载根目录 `.env`,避免因 Compose 文件位于 `infra/` 而回退到默认端口或密码。镜像使用已验证的明确版本标签;升级前应先在本地或 staging 验证,再显式更新标签。 应用进程由 `pnpm dev` 在宿主机启动:Web 使用 Vite 热更新,API 与 Worker 使用各自的 watch 模式。生产环境的 API、Worker 和反向代理容器编排将在部署运行手册中补充;PostgreSQL 和对象存储继续遵守现有架构文档的托管服务边界。 +首次执行 `pnpm infra:up` 时,PostgreSQL 会以本地管理员初始化,并创建三个独立角色:`atlas_migrator`(仅迁移)、`atlas_app`(无登录权限组)与 `atlas_app_login`(API/Worker 登录)。 + +执行迁移只能使用 `MIGRATOR_DATABASE_URL`:`pnpm --filter @atlas/database migrate`。API 和 Worker 只能使用 `DATABASE_URL`,应用事务会切换到 `atlas_app` 并按请求设置工作空间上下文。 + +如已有旧的本地 PostgreSQL volume,初始化脚本不会再次运行;请不要让 API 使用管理员或 migrator 连接串。需要重建本地开发数据时,先确认没有需要保留的数据,再移除该项目的 PostgreSQL volume 后重新执行 `pnpm infra:up`。 diff --git a/infra/compose.yaml b/infra/compose.yaml index 0af6765..739f0be 100644 --- a/infra/compose.yaml +++ b/infra/compose.yaml @@ -1,44 +1,49 @@ name: atlas-seller-kit services: - postgres: - image: postgres:18.6-alpine - environment: - POSTGRES_USER: ${POSTGRES_USER:-atlas_app_login} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change-me-local-only} - POSTGRES_DB: ${POSTGRES_DB:-atlas} - ports: - - '${POSTGRES_PORT:-5432}:5432' - volumes: - - postgres-data:/var/lib/postgresql/data - healthcheck: - test: ['CMD-SHELL', 'pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB'] - interval: 5s - timeout: 5s - retries: 20 + postgres: + image: postgres:18.6-alpine + environment: + POSTGRES_USER: ${POSTGRES_ADMIN_USER:-atlas_admin} + POSTGRES_PASSWORD: ${POSTGRES_ADMIN_PASSWORD:-change-me-local-only} + POSTGRES_DB: ${POSTGRES_DB:-atlas} + ATLAS_MIGRATOR_PASSWORD: ${ATLAS_MIGRATOR_PASSWORD:-change-me-local-only} + ATLAS_APP_PASSWORD: ${ATLAS_APP_PASSWORD:-change-me-local-only} + ports: + - '${POSTGRES_PORT:-5432}:5432' + volumes: + # PostgreSQL 18 将集群数据放在版本化子目录,volume 必须挂到父目录。 + - postgres-data:/var/lib/postgresql + - ./postgres/init:/docker-entrypoint-initdb.d:ro + healthcheck: + test: + ['CMD-SHELL', 'pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB'] + interval: 5s + timeout: 5s + retries: 20 - redis: - image: redis:7.4.11-alpine3.21 - ports: - - '6379:6379' - healthcheck: - test: ['CMD', 'redis-cli', 'ping'] - interval: 5s - timeout: 5s - retries: 20 + redis: + image: redis:7.4.11-alpine3.21 + ports: + - '6379:6379' + healthcheck: + test: ['CMD', 'redis-cli', 'ping'] + interval: 5s + timeout: 5s + retries: 20 - minio: - image: minio/minio:RELEASE.2025-09-07T16-13-09Z - command: server /data --console-address ':9001' - environment: - MINIO_ROOT_USER: ${MINIO_ROOT_USER:-atlas_minio_local} - MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-change-me-local-only} - ports: - - '${MINIO_PORT:-9000}:9000' - - '${MINIO_CONSOLE_PORT:-9001}:9001' - volumes: - - minio-data:/data + minio: + image: minio/minio:RELEASE.2025-09-07T16-13-09Z + command: server /data --console-address ':9001' + environment: + MINIO_ROOT_USER: ${MINIO_ROOT_USER:-atlas_minio_local} + MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-change-me-local-only} + ports: + - '${MINIO_PORT:-9000}:9000' + - '${MINIO_CONSOLE_PORT:-9001}:9001' + volumes: + - minio-data:/data volumes: - postgres-data: - minio-data: + postgres-data: + minio-data: diff --git a/infra/postgres/init/001-roles.sh b/infra/postgres/init/001-roles.sh new file mode 100755 index 0000000..77e1cf1 --- /dev/null +++ b/infra/postgres/init/001-roles.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -eu + +: "${ATLAS_MIGRATOR_PASSWORD:?ATLAS_MIGRATOR_PASSWORD is required}" +: "${ATLAS_APP_PASSWORD:?ATLAS_APP_PASSWORD is required}" + +psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" --set ON_ERROR_STOP=1 \ + --set database_name="$POSTGRES_DB" --set migrator_password="$ATLAS_MIGRATOR_PASSWORD" --set app_password="$ATLAS_APP_PASSWORD" <<-'SQL' + CREATE ROLE atlas_migrator LOGIN NOINHERIT NOBYPASSRLS PASSWORD :'migrator_password'; + CREATE ROLE atlas_app NOLOGIN NOINHERIT NOBYPASSRLS; + CREATE ROLE atlas_app_login LOGIN NOINHERIT NOBYPASSRLS PASSWORD :'app_password'; + GRANT atlas_app TO atlas_app_login; + -- 仅允许迁移角色创建 atlas schema;应用登录角色不拥有数据库级建库权限。 + GRANT CREATE ON DATABASE :"database_name" TO atlas_migrator; + CREATE SCHEMA atlas AUTHORIZATION atlas_migrator; + GRANT USAGE ON SCHEMA atlas TO atlas_app; + ALTER DEFAULT PRIVILEGES FOR ROLE atlas_migrator IN SCHEMA atlas GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO atlas_app; + ALTER DEFAULT PRIVILEGES FOR ROLE atlas_migrator IN SCHEMA atlas GRANT USAGE, SELECT ON SEQUENCES TO atlas_app; +SQL diff --git a/package.json b/package.json index 3e5a1c1..ea20912 100644 --- a/package.json +++ b/package.json @@ -9,14 +9,16 @@ }, "scripts": { "build": "turbo run build", - "dev": "turbo run dev --parallel", + "dev": "turbo run dev", + "dev:backend": "turbo run dev --filter=@atlas/api --filter=@atlas/worker", + "dev:frontend": "turbo run dev --filter=@atlas/web", "lint": "turbo run lint", "typecheck": "turbo run typecheck", "test": "turbo run test", - "format": "prettier --write .", - "format:check": "prettier --check .", - "infra:up": "docker compose -f infra/compose.yaml up -d postgres redis minio", - "infra:down": "docker compose -f infra/compose.yaml down" + "format": "prettier --config ./prettier.config.mjs --write .", + "format:check": "prettier --config ./prettier.config.mjs --check .", + "infra:up": "docker compose --env-file .env -f infra/compose.yaml up -d postgres redis minio", + "infra:down": "docker compose --env-file .env -f infra/compose.yaml down" }, "devDependencies": { "prettier": "3.9.6", diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 8cad5d0..52742c5 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -1,20 +1,20 @@ { - "name": "@atlas/contracts", - "version": "0.1.0", - "private": true, - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "files": [ - "dist" - ], - "scripts": { - "build": "tsc -p tsconfig.json", - "typecheck": "tsc -p tsconfig.json --noEmit" - }, - "dependencies": { - "zod": "4.5.4" - }, - "devDependencies": { - "typescript": "7.0.2" - } + "name": "@atlas/contracts", + "version": "0.1.0", + "private": true, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "zod": "4.5.4" + }, + "devDependencies": { + "typescript": "7.0.2" + } } diff --git a/packages/contracts/src/auth.ts b/packages/contracts/src/auth.ts new file mode 100644 index 0000000..c24e26e --- /dev/null +++ b/packages/contracts/src/auth.ts @@ -0,0 +1,36 @@ +import { z } from 'zod'; + +export const registerRequestSchema = z.object({ + email: z.string().trim().email().max(254), + password: z.string().min(1), + password_confirmation: z.string().min(1), + display_name: z.string().trim().max(80).nullable().optional(), +}); +export const loginRequestSchema = z.object({ + email: z.string().trim().email().max(254), + password: z.string().min(1), +}); + +export const authUserSchema = z.object({ + id: z.uuid(), + email: z.string().email(), + display_name: z.string().nullable(), + email_verified_at: z.iso.datetime().nullable(), + created_at: z.iso.datetime(), +}); +export const workspaceSchema = z.object({ + id: z.uuid(), + name: z.string(), + role: z.enum(['owner', 'admin', 'editor', 'viewer']), +}); +export const authSessionResponseSchema = z.object({ + access_token: z.string(), + access_token_expires_in: z.number().int().positive(), + user: authUserSchema, + workspace: workspaceSchema, +}); +export type RegisterRequest = z.infer; +export type LoginRequest = z.infer; +export type AuthUser = z.infer; +export type Workspace = z.infer; +export type AuthSessionResponse = z.infer; diff --git a/packages/contracts/src/collection.ts b/packages/contracts/src/collection.ts index d417e5d..68c028a 100644 --- a/packages/contracts/src/collection.ts +++ b/packages/contracts/src/collection.ts @@ -5,20 +5,22 @@ import { z } from 'zod'; * 领域字段会随采集模块实现逐步补全,不能在扩展侧绕过此契约直接构造 API 请求。 */ export const collectedProductPayloadSchema = z.object({ - source: z.object({ - platform: z.enum(['ozon', '1688', 'taobao', 'tmall']), - itemKey: z.string().min(1), - canonicalUrl: z.url(), - collectedAt: z.iso.datetime(), - parserVersion: z.string().min(1), - }), - common: z.object({ - title: z.string().min(1).optional(), - }), - variantAxes: z.array(z.unknown()), - variants: z.array(z.unknown()), - assets: z.array(z.unknown()), - evidence: z.array(z.unknown()), + source: z.object({ + platform: z.enum(['ozon', '1688', 'taobao', 'tmall']), + itemKey: z.string().min(1), + canonicalUrl: z.url(), + collectedAt: z.iso.datetime(), + parserVersion: z.string().min(1), + }), + common: z.object({ + title: z.string().min(1).optional(), + }), + variantAxes: z.array(z.unknown()), + variants: z.array(z.unknown()), + assets: z.array(z.unknown()), + evidence: z.array(z.unknown()), }); -export type CollectedProductPayload = z.infer; +export type CollectedProductPayload = z.infer< + typeof collectedProductPayloadSchema +>; diff --git a/packages/contracts/src/index.ts b/packages/contracts/src/index.ts index 989b92d..470e292 100644 --- a/packages/contracts/src/index.ts +++ b/packages/contracts/src/index.ts @@ -1 +1,2 @@ export * from './collection'; +export * from './auth'; diff --git a/packages/contracts/tsconfig.json b/packages/contracts/tsconfig.json index df59da5..00ed99b 100644 --- a/packages/contracts/tsconfig.json +++ b/packages/contracts/tsconfig.json @@ -1,8 +1,8 @@ { - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist" - }, - "include": ["src/**/*.ts"] + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": ["src/**/*.ts"] } diff --git a/packages/database/migrations/001_foundation.sql b/packages/database/migrations/001_foundation.sql new file mode 100644 index 0000000..ae08412 --- /dev/null +++ b/packages/database/migrations/001_foundation.sql @@ -0,0 +1,678 @@ +-- Atlas Seller Kit: cloud foundation schema +-- PostgreSQL 15+ recommended. Run through a migration tool, not from the browser. + +CREATE EXTENSION IF NOT EXISTS citext; +CREATE EXTENSION IF NOT EXISTS pgcrypto; +CREATE SCHEMA IF NOT EXISTS atlas; +SET search_path TO atlas, public; + +CREATE TYPE membership_role AS ENUM ('owner', 'admin', 'editor', 'viewer'); +CREATE TYPE account_status AS ENUM ('active', 'disabled', 'pending_review'); +CREATE TYPE platform_status AS ENUM ('active', 'disabled'); +CREATE TYPE store_status AS ENUM ('verifying', 'active', 'credential_invalid', 'sync_error', 'disabled', 'deleted'); +CREATE TYPE credential_status AS ENUM ('unknown', 'valid', 'invalid', 'expired', 'rotation_required'); +CREATE TYPE secret_kind AS ENUM ('seller_api_key', 'browser_cookie'); +CREATE TYPE watermark_kind AS ENUM ('text', 'image'); +CREATE TYPE watermark_position AS ENUM ('top_left', 'top_center', 'top_right', 'middle_left', 'center', 'middle_right', 'bottom_left', 'bottom_center', 'bottom_right'); +CREATE TYPE record_status AS ENUM ('draft', 'active', 'archived', 'superseded'); +CREATE TYPE rule_source AS ENUM ('manual_rule', 'competitor_capture', 'platform_sync', 'product_observed'); +CREATE TYPE fulfillment_mode AS ENUM ('rfbs', 'fbs', 'fbo', 'fbp', 'unknown'); +CREATE TYPE billing_weight_basis AS ENUM ('actual_only', 'max_actual_volume', 'conditional_volume'); +CREATE TYPE quote_status AS ENUM ('draft', 'calculated', 'confirmed', 'invalid', 'superseded'); +CREATE TYPE exchange_rate_source AS ENUM ('cbr', 'exchange_rate_api_open', 'frankfurter', 'manual'); +CREATE TYPE exchange_rate_kind AS ENUM ('official_reference', 'market_reference', 'manual'); +CREATE TYPE fx_rate_origin AS ENUM ('system_rate', 'policy_fixed', 'quote_override'); +CREATE TYPE operation_status AS ENUM ('queued', 'running', 'succeeded', 'failed', 'cancelled'); +CREATE TYPE media_upload_status AS ENUM ('pending', 'uploaded', 'validating', 'ready', 'failed', 'expired'); +CREATE TYPE idempotency_request_status AS ENUM ('in_progress', 'completed'); +CREATE TYPE outbox_event_status AS ENUM ('pending', 'dispatching', 'dispatched', 'dead_letter'); + +CREATE TABLE users ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + email CITEXT NOT NULL UNIQUE CHECK (length(email) <= 254 AND position('@' IN email) > 1), + password_hash TEXT NOT NULL, + display_name TEXT, + status account_status NOT NULL DEFAULT 'active', + email_verified_at TIMESTAMPTZ, + last_login_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE TABLE workspaces ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + name TEXT NOT NULL, + slug CITEXT NOT NULL UNIQUE, + status record_status NOT NULL DEFAULT 'active', + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE TABLE workspace_memberships ( + workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT, + user_id UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT, + role membership_role NOT NULL DEFAULT 'editor', + joined_at TIMESTAMPTZ NOT NULL DEFAULT now(), + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + PRIMARY KEY (workspace_id, user_id) +); + +CREATE TABLE user_sessions ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + refresh_token_hash TEXT NOT NULL UNIQUE, + expires_at TIMESTAMPTZ NOT NULL, + revoked_at TIMESTAMPTZ, + ip_hash TEXT, + user_agent TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + CHECK (expires_at > created_at) +); + +CREATE TABLE platforms ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + code CITEXT NOT NULL UNIQUE, + name TEXT NOT NULL, + status platform_status NOT NULL DEFAULT 'active', + capabilities JSONB NOT NULL DEFAULT '{}'::jsonb, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE TABLE currencies ( + code CHAR(3) PRIMARY KEY, + name TEXT NOT NULL, + symbol TEXT NOT NULL, + decimal_places SMALLINT NOT NULL DEFAULT 2 CHECK (decimal_places BETWEEN 0 AND 6), + is_enabled BOOLEAN NOT NULL DEFAULT true +); + +CREATE TABLE platform_currency_support ( + platform_id UUID NOT NULL REFERENCES platforms(id) ON DELETE CASCADE, + currency_code CHAR(3) NOT NULL REFERENCES currencies(code), + is_enabled BOOLEAN NOT NULL DEFAULT true, + PRIMARY KEY (platform_id, currency_code) +); + +-- Global immutable rate history. rate always means one unit of base_currency_code equals rate units of quote_currency_code. +CREATE TABLE exchange_rates ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + base_currency_code CHAR(3) NOT NULL REFERENCES currencies(code), + quote_currency_code CHAR(3) NOT NULL REFERENCES currencies(code), + rate NUMERIC(24,10) NOT NULL CHECK (rate > 0), + kind exchange_rate_kind NOT NULL, + source exchange_rate_source NOT NULL, + source_reference TEXT, + effective_on DATE NOT NULL, + observed_at TIMESTAMPTZ, + fetched_at TIMESTAMPTZ NOT NULL DEFAULT now(), + raw_payload JSONB NOT NULL DEFAULT '{}'::jsonb, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + CHECK (base_currency_code <> quote_currency_code), + UNIQUE (base_currency_code, quote_currency_code, kind, source, effective_on) +); +CREATE INDEX ix_exchange_rates_current_lookup + ON exchange_rates (base_currency_code, quote_currency_code, kind, effective_on DESC, fetched_at DESC); + +CREATE TABLE stores ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT, + platform_id UUID NOT NULL REFERENCES platforms(id) ON DELETE RESTRICT, + name TEXT NOT NULL, + platform_client_id TEXT NOT NULL, + currency_code CHAR(3) NOT NULL REFERENCES currencies(code), + is_default BOOLEAN NOT NULL DEFAULT false, + note TEXT, + status store_status NOT NULL DEFAULT 'verifying', + credential_status credential_status NOT NULL DEFAULT 'unknown', + credential_checked_at TIMESTAMPTZ, + last_error_code TEXT, + last_error_message TEXT, + last_error_at TIMESTAMPTZ, + api_key_expires_at TIMESTAMPTZ, + product_limit INTEGER CHECK (product_limit IS NULL OR product_limit >= 0), + product_limit_checked_at TIMESTAMPTZ, + deleted_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + revision INTEGER NOT NULL DEFAULT 1 CHECK (revision > 0), + UNIQUE (workspace_id, id), + UNIQUE (workspace_id, id, platform_id), + UNIQUE (workspace_id, platform_id, platform_client_id) +); +CREATE UNIQUE INDEX ux_stores_one_default_per_platform + ON stores (workspace_id, platform_id) + WHERE is_default AND deleted_at IS NULL; +CREATE INDEX ix_stores_workspace_platform ON stores (workspace_id, platform_id, created_at DESC); + +CREATE TABLE store_secrets ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL, + store_id UUID NOT NULL, + kind secret_kind NOT NULL, + secret_ciphertext BYTEA NOT NULL, + secret_nonce BYTEA NOT NULL, + encryption_key_version TEXT NOT NULL, + fingerprint TEXT NOT NULL, + status credential_status NOT NULL DEFAULT 'unknown', + expires_at TIMESTAMPTZ, + last_verified_at TIMESTAMPTZ, + revoked_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + FOREIGN KEY (workspace_id, store_id) REFERENCES stores(workspace_id, id) ON DELETE CASCADE, + UNIQUE (workspace_id, store_id, kind, fingerprint) +); +CREATE UNIQUE INDEX ux_store_secrets_one_current_kind + ON store_secrets (workspace_id, store_id, kind) + WHERE revoked_at IS NULL; + +CREATE TABLE store_warehouses ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL, + store_id UUID NOT NULL, + platform_warehouse_id TEXT NOT NULL, + name TEXT NOT NULL, + fulfillment fulfillment_mode NOT NULL DEFAULT 'unknown', + is_rfbs BOOLEAN, + status TEXT NOT NULL, + payload JSONB NOT NULL DEFAULT '{}'::jsonb, + synced_at TIMESTAMPTZ NOT NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + FOREIGN KEY (workspace_id, store_id) REFERENCES stores(workspace_id, id) ON DELETE CASCADE, + UNIQUE (workspace_id, store_id, platform_warehouse_id) +); + +-- Durable API-visible operation state. Queue job ids are auxiliary and never the only record. +CREATE TABLE operations ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT, + kind TEXT NOT NULL, + status operation_status NOT NULL DEFAULT 'queued', + resource_type TEXT, + resource_id UUID, + result JSONB NOT NULL DEFAULT '{}'::jsonb, + error_code TEXT, + error_message TEXT, + attempt_count INTEGER NOT NULL DEFAULT 0 CHECK (attempt_count >= 0), + created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + started_at TIMESTAMPTZ, + completed_at TIMESTAMPTZ, + CHECK (completed_at IS NULL OR completed_at >= created_at), + UNIQUE (workspace_id, id) +); +CREATE INDEX ix_operations_workspace_status ON operations (workspace_id, status, created_at DESC); + +-- Durable replay record for authenticated, retryable business writes. +-- request_fingerprint is an HMAC of canonical request content, never a raw request body. +CREATE TABLE idempotency_requests ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT, + user_id UUID NOT NULL REFERENCES users(id) ON DELETE RESTRICT, + http_method TEXT NOT NULL CHECK (http_method IN ('POST', 'PUT', 'PATCH', 'DELETE')), + request_path TEXT NOT NULL CHECK (request_path ~ '^/api/'), + idempotency_key UUID NOT NULL, + request_fingerprint TEXT NOT NULL, + status idempotency_request_status NOT NULL DEFAULT 'in_progress', + response_status SMALLINT, + response_body JSONB, + resource_type TEXT, + resource_id UUID, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + completed_at TIMESTAMPTZ, + expires_at TIMESTAMPTZ NOT NULL DEFAULT now() + INTERVAL '48 hours', + CHECK (expires_at > created_at), + CHECK ( + (status = 'in_progress' AND completed_at IS NULL AND response_status IS NULL) + OR (status = 'completed' AND completed_at IS NOT NULL AND response_status BETWEEN 200 AND 599) + ), + UNIQUE (workspace_id, user_id, http_method, request_path, idempotency_key), + UNIQUE (workspace_id, id) +); +CREATE INDEX ix_idempotency_requests_expiry + ON idempotency_requests (expires_at); + +-- Transactional Outbox. A dispatcher makes these events available to BullMQ only after their business transaction commits. +-- event_payload contains identifiers and immutable snapshots only; it must not contain credentials or access URLs. +CREATE TABLE outbox_events ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT, + aggregate_type TEXT NOT NULL, + aggregate_id UUID NOT NULL, + event_type TEXT NOT NULL, + event_payload JSONB NOT NULL DEFAULT '{}'::jsonb, + deduplication_key TEXT, + status outbox_event_status NOT NULL DEFAULT 'pending', + attempt_count INTEGER NOT NULL DEFAULT 0 CHECK (attempt_count >= 0), + next_attempt_at TIMESTAMPTZ NOT NULL DEFAULT now(), + locked_by TEXT, + locked_until TIMESTAMPTZ, + dispatched_at TIMESTAMPTZ, + last_error_code TEXT, + last_error_message TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + CHECK ( + (status = 'dispatching' AND locked_by IS NOT NULL AND locked_until IS NOT NULL) + OR (status <> 'dispatching' AND locked_by IS NULL AND locked_until IS NULL) + ), + CHECK (dispatched_at IS NULL OR status = 'dispatched'), + UNIQUE (workspace_id, id) +); +CREATE INDEX ix_outbox_events_dispatch + ON outbox_events (workspace_id, status, next_attempt_at, created_at) + WHERE status IN ('pending', 'dispatching'); +CREATE INDEX ix_outbox_events_aggregate + ON outbox_events (workspace_id, aggregate_type, aggregate_id, created_at DESC); + +CREATE TABLE media_assets ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT, + storage_provider TEXT NOT NULL, -- local_minio / qiniu_kodo; provider configuration is server-side only. + bucket TEXT NOT NULL, + object_key TEXT NOT NULL, + content_type TEXT NOT NULL, + byte_size BIGINT NOT NULL CHECK (byte_size > 0), + checksum_sha256 TEXT NOT NULL, + width_px INTEGER CHECK (width_px IS NULL OR width_px > 0), + height_px INTEGER CHECK (height_px IS NULL OR height_px > 0), + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE (workspace_id, id), + UNIQUE (workspace_id, storage_provider, bucket, object_key), + UNIQUE (workspace_id, checksum_sha256) +); + +-- A short-lived, durable record for browser direct uploads. object_key is never returned as public file identity. +CREATE TABLE media_upload_intents ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT, + purpose TEXT NOT NULL, + storage_provider TEXT NOT NULL, + bucket TEXT NOT NULL, + object_key TEXT NOT NULL, + expected_content_type TEXT NOT NULL, + expected_byte_size BIGINT NOT NULL CHECK (expected_byte_size > 0), + expected_checksum_sha256 TEXT NOT NULL, + status media_upload_status NOT NULL DEFAULT 'pending', + asset_id UUID, + error_code TEXT, + error_message TEXT, + expires_at TIMESTAMPTZ NOT NULL, + created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + completed_at TIMESTAMPTZ, + FOREIGN KEY (workspace_id, asset_id) REFERENCES media_assets(workspace_id, id) ON DELETE RESTRICT, + CHECK (expires_at > created_at), + CHECK (completed_at IS NULL OR completed_at >= created_at), + CHECK ((status = 'ready') = (asset_id IS NOT NULL)), + UNIQUE (workspace_id, id), + UNIQUE (storage_provider, bucket, object_key) +); +CREATE INDEX ix_media_upload_intents_expiry ON media_upload_intents (status, expires_at); + +CREATE TABLE watermark_fonts ( + code CITEXT PRIMARY KEY, + display_name TEXT NOT NULL, + status record_status NOT NULL DEFAULT 'active', + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE TABLE watermark_templates ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT, + name TEXT NOT NULL, + kind watermark_kind NOT NULL, + current_version INTEGER NOT NULL DEFAULT 1 CHECK (current_version > 0), + status record_status NOT NULL DEFAULT 'active', + deleted_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + revision INTEGER NOT NULL DEFAULT 1 CHECK (revision > 0), + UNIQUE (workspace_id, id), + UNIQUE (workspace_id, name) +); + +CREATE TABLE watermark_template_versions ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL, + template_id UUID NOT NULL, + version INTEGER NOT NULL CHECK (version > 0), + kind watermark_kind NOT NULL, + text_content TEXT, + image_asset_id UUID, + font_code CITEXT REFERENCES watermark_fonts(code), + font_size_px SMALLINT CHECK (font_size_px BETWEEN 12 AND 60), + opacity NUMERIC(5,4) NOT NULL CHECK (opacity BETWEEN 0 AND 1), + scale_ratio NUMERIC(7,4) CHECK (scale_ratio > 0), + position watermark_position NOT NULL, + created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + FOREIGN KEY (workspace_id, template_id) REFERENCES watermark_templates(workspace_id, id) ON DELETE CASCADE, + FOREIGN KEY (workspace_id, image_asset_id) REFERENCES media_assets(workspace_id, id) ON DELETE RESTRICT, + UNIQUE (workspace_id, id), + UNIQUE (workspace_id, template_id, version), + CHECK ( + (kind = 'text' AND text_content IS NOT NULL AND font_code IS NOT NULL AND font_size_px IS NOT NULL AND image_asset_id IS NULL) + OR (kind = 'image' AND image_asset_id IS NOT NULL AND scale_ratio IS NOT NULL AND text_content IS NULL) + ) +); + +CREATE TABLE store_watermark_bindings ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL, + store_id UUID NOT NULL, + template_id UUID NOT NULL, + bound_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL, + bound_at TIMESTAMPTZ NOT NULL DEFAULT now(), + unbound_at TIMESTAMPTZ, + FOREIGN KEY (workspace_id, store_id) REFERENCES stores(workspace_id, id) ON DELETE CASCADE, + FOREIGN KEY (workspace_id, template_id) REFERENCES watermark_templates(workspace_id, id) ON DELETE RESTRICT, + CHECK (unbound_at IS NULL OR unbound_at >= bound_at) +); +CREATE UNIQUE INDEX ux_store_watermark_one_active + ON store_watermark_bindings (workspace_id, store_id) + WHERE unbound_at IS NULL; + +CREATE TABLE platform_product_categories ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + platform_id UUID NOT NULL REFERENCES platforms(id) ON DELETE CASCADE, + parent_id UUID REFERENCES platform_product_categories(id) ON DELETE RESTRICT, + external_category_id TEXT NOT NULL, + external_type_id TEXT, + name TEXT NOT NULL, + path TEXT NOT NULL, + is_active BOOLEAN NOT NULL DEFAULT true, + source_payload JSONB NOT NULL DEFAULT '{}'::jsonb, + synced_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE (platform_id, id), + UNIQUE (platform_id, external_category_id, external_type_id) +); + +CREATE TABLE commission_categories ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + platform_id UUID NOT NULL REFERENCES platforms(id) ON DELETE CASCADE, + parent_id UUID REFERENCES commission_categories(id) ON DELETE RESTRICT, + source_category_key TEXT, + name TEXT NOT NULL, + path TEXT NOT NULL, + source rule_source NOT NULL, + status record_status NOT NULL DEFAULT 'draft', + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE (platform_id, id), + UNIQUE (platform_id, path) +); + +CREATE TABLE commission_category_rules ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + commission_category_id UUID NOT NULL REFERENCES commission_categories(id) ON DELETE CASCADE, + fulfillment fulfillment_mode NOT NULL DEFAULT 'unknown', + market_code TEXT NOT NULL DEFAULT 'RU', + currency_code CHAR(3) NOT NULL REFERENCES currencies(code), + min_price NUMERIC(18,4), + max_price NUMERIC(18,4), + min_inclusive BOOLEAN NOT NULL DEFAULT false, + max_inclusive BOOLEAN NOT NULL DEFAULT true, + commission_rate NUMERIC(7,6) NOT NULL CHECK (commission_rate >= 0 AND commission_rate < 1), + source rule_source NOT NULL, + version TEXT NOT NULL, + status record_status NOT NULL DEFAULT 'draft', + effective_from TIMESTAMPTZ NOT NULL, + effective_to TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + CHECK (min_price IS NULL OR min_price >= 0), + CHECK (max_price IS NULL OR max_price >= 0), + CHECK (min_price IS NULL OR max_price IS NULL OR min_price <= max_price), + CHECK (effective_to IS NULL OR effective_to > effective_from) +); + +CREATE TABLE platform_product_category_commission_mappings ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + platform_id UUID NOT NULL REFERENCES platforms(id) ON DELETE CASCADE, + platform_product_category_id UUID NOT NULL, + commission_category_id UUID NOT NULL, + fulfillment fulfillment_mode NOT NULL DEFAULT 'unknown', + market_code TEXT NOT NULL DEFAULT 'RU', + priority SMALLINT NOT NULL DEFAULT 100 CHECK (priority >= 0), + source rule_source NOT NULL DEFAULT 'manual_rule', + status record_status NOT NULL DEFAULT 'draft', + effective_from TIMESTAMPTZ NOT NULL, + effective_to TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + FOREIGN KEY (platform_id, platform_product_category_id) + REFERENCES platform_product_categories(platform_id, id) ON DELETE CASCADE, + FOREIGN KEY (platform_id, commission_category_id) + REFERENCES commission_categories(platform_id, id) ON DELETE RESTRICT, + CHECK (effective_to IS NULL OR effective_to > effective_from) +); +CREATE INDEX ix_category_commission_mapping_lookup + ON platform_product_category_commission_mappings (platform_product_category_id, fulfillment, market_code, status, effective_from DESC, priority); + +CREATE TABLE logistics_providers ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + code CITEXT NOT NULL UNIQUE, + name TEXT NOT NULL, + status record_status NOT NULL DEFAULT 'active', + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE TABLE logistics_rate_cards ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + provider_id UUID NOT NULL REFERENCES logistics_providers(id) ON DELETE RESTRICT, + platform_id UUID NOT NULL REFERENCES platforms(id) ON DELETE RESTRICT, + fulfillment fulfillment_mode NOT NULL, + market_code TEXT NOT NULL DEFAULT 'RU', + version TEXT NOT NULL, + source_name TEXT NOT NULL, + source_uri TEXT, + status record_status NOT NULL DEFAULT 'draft', + effective_from TIMESTAMPTZ NOT NULL, + effective_to TIMESTAMPTZ, + reviewed_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL, + reviewed_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE (platform_id, id), + UNIQUE (provider_id, platform_id, fulfillment, market_code, version), + CHECK (effective_to IS NULL OR effective_to > effective_from) +); + +CREATE TABLE logistics_product_types ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + rate_card_id UUID NOT NULL REFERENCES logistics_rate_cards(id) ON DELETE CASCADE, + code CITEXT NOT NULL, + name TEXT NOT NULL, + merchandise_currency_code CHAR(3) NOT NULL REFERENCES currencies(code), + min_merchandise_value NUMERIC(18,4), + max_merchandise_value NUMERIC(18,4), + min_value_inclusive BOOLEAN NOT NULL DEFAULT false, + max_value_inclusive BOOLEAN NOT NULL DEFAULT true, + min_actual_weight_kg NUMERIC(12,3) NOT NULL DEFAULT 0.001 CHECK (min_actual_weight_kg >= 0.001), + max_actual_weight_kg NUMERIC(12,3), + max_sum_dimensions_cm NUMERIC(12,3), + max_longest_side_cm NUMERIC(12,3), + max_second_longest_side_cm NUMERIC(12,3), + billing_basis billing_weight_basis NOT NULL, + volume_divisor NUMERIC(12,3), + volume_condition_sum_gt_cm NUMERIC(12,3), + volume_round_scale SMALLINT CHECK (volume_round_scale BETWEEN 0 AND 6), + billing_round_scale SMALLINT CHECK (billing_round_scale BETWEEN 0 AND 6), + max_volume_weight_kg NUMERIC(12,3), + volume_limit_round_scale SMALLINT CHECK (volume_limit_round_scale BETWEEN 0 AND 6), + return_policy JSONB NOT NULL DEFAULT '{}'::jsonb, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE (rate_card_id, code), + CHECK (max_merchandise_value IS NULL OR max_merchandise_value >= 0), + CHECK (min_merchandise_value IS NULL OR min_merchandise_value >= 0), + CHECK (min_merchandise_value IS NULL OR max_merchandise_value IS NULL OR min_merchandise_value <= max_merchandise_value), + CHECK (max_actual_weight_kg IS NULL OR max_actual_weight_kg >= min_actual_weight_kg), + CHECK ((billing_basis = 'actual_only' AND volume_divisor IS NULL) OR (billing_basis <> 'actual_only' AND volume_divisor IS NOT NULL)) +); + +CREATE TABLE logistics_transport_methods ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + rate_card_id UUID NOT NULL REFERENCES logistics_rate_cards(id) ON DELETE CASCADE, + code CITEXT NOT NULL, + name TEXT NOT NULL, + speed_label TEXT, + min_transit_days SMALLINT CHECK (min_transit_days >= 0), + max_transit_days SMALLINT CHECK (max_transit_days >= min_transit_days), + status record_status NOT NULL DEFAULT 'active', + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE (rate_card_id, code) +); + +CREATE TABLE logistics_rate_rules ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + product_type_id UUID NOT NULL REFERENCES logistics_product_types(id) ON DELETE CASCADE, + transport_method_id UUID NOT NULL REFERENCES logistics_transport_methods(id) ON DELETE CASCADE, + fixed_fee_cny NUMERIC(18,4) NOT NULL DEFAULT 0 CHECK (fixed_fee_cny >= 0), + per_billable_kg_fee_cny NUMERIC(18,4) NOT NULL CHECK (per_billable_kg_fee_cny >= 0), + min_charge_cny NUMERIC(18,4) CHECK (min_charge_cny IS NULL OR min_charge_cny >= 0), + surcharge_rules JSONB NOT NULL DEFAULT '[]'::jsonb, + status record_status NOT NULL DEFAULT 'active', + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE (product_type_id, transport_method_id) +); + +CREATE TABLE pricing_policies ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL, + store_id UUID NOT NULL, + platform_id UUID NOT NULL, + name TEXT NOT NULL, + note TEXT, + status record_status NOT NULL DEFAULT 'active', + is_default BOOLEAN NOT NULL DEFAULT false, + rate_card_id UUID NOT NULL, + default_transport_method_id UUID REFERENCES logistics_transport_methods(id) ON DELETE RESTRICT, + domestic_shipping_and_label_fee_cny NUMERIC(18,4) NOT NULL DEFAULT 0 CHECK (domestic_shipping_and_label_fee_cny >= 0), + ad_rate NUMERIC(7,6) NOT NULL DEFAULT 0 CHECK (ad_rate >= 0 AND ad_rate < 1), + last_mile_rate NUMERIC(7,6) NOT NULL DEFAULT 0 CHECK (last_mile_rate >= 0 AND last_mile_rate < 1), + withdrawal_rate NUMERIC(7,6) NOT NULL DEFAULT 0 CHECK (withdrawal_rate >= 0 AND withdrawal_rate < 1), + other_rate NUMERIC(7,6) NOT NULL DEFAULT 0 CHECK (other_rate >= 0 AND other_rate < 1), + desired_markup_rate NUMERIC(7,6) NOT NULL DEFAULT 0 CHECK (desired_markup_rate >= 0), + list_price_discount_rate NUMERIC(7,6) NOT NULL DEFAULT 0 CHECK (list_price_discount_rate >= 0 AND list_price_discount_rate < 1), + allow_commission_override BOOLEAN NOT NULL DEFAULT false, + fx_strategy TEXT NOT NULL DEFAULT 'system' CHECK (fx_strategy IN ('system', 'fixed', 'override_allowed')), + fixed_cny_to_rub_rate NUMERIC(18,8), + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + revision INTEGER NOT NULL DEFAULT 1 CHECK (revision > 0), + FOREIGN KEY (workspace_id, store_id, platform_id) REFERENCES stores(workspace_id, id, platform_id) ON DELETE CASCADE, + FOREIGN KEY (platform_id, rate_card_id) REFERENCES logistics_rate_cards(platform_id, id) ON DELETE RESTRICT, + UNIQUE (workspace_id, id), + UNIQUE (workspace_id, id, store_id, platform_id), + UNIQUE (workspace_id, store_id, name), + CHECK ((fx_strategy = 'fixed' AND fixed_cny_to_rub_rate > 0) OR (fx_strategy <> 'fixed' AND fixed_cny_to_rub_rate IS NULL)) +); +CREATE UNIQUE INDEX ux_pricing_policies_one_default + ON pricing_policies (workspace_id, store_id) + WHERE is_default AND status = 'active'; + +CREATE TABLE pricing_policy_transport_methods ( + workspace_id UUID NOT NULL, + pricing_policy_id UUID NOT NULL, + transport_method_id UUID NOT NULL REFERENCES logistics_transport_methods(id) ON DELETE RESTRICT, + is_enabled BOOLEAN NOT NULL DEFAULT true, + sort_order SMALLINT NOT NULL DEFAULT 0, + PRIMARY KEY (workspace_id, pricing_policy_id, transport_method_id), + FOREIGN KEY (workspace_id, pricing_policy_id) REFERENCES pricing_policies(workspace_id, id) ON DELETE CASCADE +); + +CREATE TABLE pricing_quotes ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE RESTRICT, + store_id UUID NOT NULL, + platform_id UUID NOT NULL, + pricing_policy_id UUID, + product_variant_id UUID, -- Logical FK; add real FK in the product/SKU migration. + platform_product_category_id UUID, + fulfillment fulfillment_mode NOT NULL, + purchase_cost_cny NUMERIC(18,4) NOT NULL CHECK (purchase_cost_cny >= 0), + package_weight_kg NUMERIC(12,3) NOT NULL CHECK (package_weight_kg >= 0.001), + package_length_cm NUMERIC(12,3) NOT NULL CHECK (package_length_cm > 0), + package_width_cm NUMERIC(12,3) NOT NULL CHECK (package_width_cm > 0), + package_height_cm NUMERIC(12,3) NOT NULL CHECK (package_height_cm > 0), + fx_cny_to_rub NUMERIC(18,8) NOT NULL CHECK (fx_cny_to_rub > 0), + fx_rate_origin fx_rate_origin NOT NULL DEFAULT 'system_rate', + exchange_rate_id UUID REFERENCES exchange_rates(id) ON DELETE SET NULL, + input_snapshot JSONB NOT NULL, + status quote_status NOT NULL DEFAULT 'draft', + selected_option_id UUID, + calculated_at TIMESTAMPTZ, + confirmed_at TIMESTAMPTZ, + created_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + FOREIGN KEY (workspace_id, store_id, platform_id) REFERENCES stores(workspace_id, id, platform_id) ON DELETE CASCADE, + FOREIGN KEY (workspace_id, pricing_policy_id, store_id, platform_id) + REFERENCES pricing_policies(workspace_id, id, store_id, platform_id) ON DELETE RESTRICT, + FOREIGN KEY (platform_id, platform_product_category_id) + REFERENCES platform_product_categories(platform_id, id) ON DELETE RESTRICT, + UNIQUE (workspace_id, id) +); + +CREATE TABLE pricing_quote_options ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + workspace_id UUID NOT NULL, + quote_id UUID NOT NULL, + logistics_rate_rule_id UUID REFERENCES logistics_rate_rules(id) ON DELETE SET NULL, + commission_rule_id UUID REFERENCES commission_category_rules(id) ON DELETE SET NULL, + logistics_product_type_id UUID REFERENCES logistics_product_types(id) ON DELETE SET NULL, + transport_method_id UUID REFERENCES logistics_transport_methods(id) ON DELETE SET NULL, + merchandise_value_cny NUMERIC(18,4) NOT NULL CHECK (merchandise_value_cny >= 0), + selling_price_rub NUMERIC(18,4) NOT NULL CHECK (selling_price_rub >= 0), + list_price_rub NUMERIC(18,4) NOT NULL CHECK (list_price_rub >= selling_price_rub), + billable_weight_kg NUMERIC(12,3) NOT NULL CHECK (billable_weight_kg >= 0.001), + logistics_fee_cny NUMERIC(18,4) NOT NULL CHECK (logistics_fee_cny >= 0), + commission_fee_rub NUMERIC(18,4) NOT NULL CHECK (commission_fee_rub >= 0), + domestic_fee_cny NUMERIC(18,4) NOT NULL CHECK (domestic_fee_cny >= 0), + ad_fee_rub NUMERIC(18,4) NOT NULL CHECK (ad_fee_rub >= 0), + last_mile_fee_rub NUMERIC(18,4) NOT NULL CHECK (last_mile_fee_rub >= 0), + withdrawal_fee_rub NUMERIC(18,4) NOT NULL CHECK (withdrawal_fee_rub >= 0), + other_fee_rub NUMERIC(18,4) NOT NULL CHECK (other_fee_rub >= 0), + profit_rub NUMERIC(18,4) NOT NULL, + calculation_snapshot JSONB NOT NULL, + is_valid BOOLEAN NOT NULL DEFAULT true, + validation_errors JSONB NOT NULL DEFAULT '[]'::jsonb, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + FOREIGN KEY (workspace_id, quote_id) REFERENCES pricing_quotes(workspace_id, id) ON DELETE CASCADE, + UNIQUE (workspace_id, quote_id, transport_method_id, logistics_product_type_id, commission_rule_id) +); +ALTER TABLE pricing_quotes + ADD CONSTRAINT fk_pricing_quotes_selected_option + FOREIGN KEY (selected_option_id) REFERENCES pricing_quote_options(id) ON DELETE SET NULL; + +-- Tenant isolation. The API must set app.workspace_id with SET LOCAL after authorization. +CREATE OR REPLACE FUNCTION app_current_workspace_id() RETURNS UUID +LANGUAGE SQL STABLE AS $$ + SELECT NULLIF(current_setting('app.workspace_id', true), '')::UUID +$$; + +DO $$ +DECLARE table_name TEXT; +BEGIN + FOREACH table_name IN ARRAY ARRAY[ + 'stores', 'store_secrets', 'store_warehouses', 'operations', 'idempotency_requests', 'outbox_events', + 'media_assets', 'media_upload_intents', + 'watermark_templates', 'watermark_template_versions', 'store_watermark_bindings', + 'pricing_policies', 'pricing_policy_transport_methods', 'pricing_quotes', 'pricing_quote_options' + ] + LOOP + EXECUTE format('ALTER TABLE %I ENABLE ROW LEVEL SECURITY', table_name); + EXECUTE format('ALTER TABLE %I FORCE ROW LEVEL SECURITY', table_name); + EXECUTE format( + 'CREATE POLICY workspace_isolation ON %I USING (workspace_id = app_current_workspace_id()) WITH CHECK (workspace_id = app_current_workspace_id())', + table_name + ); + END LOOP; +END $$; diff --git a/packages/database/migrations/002_seed_global.sql b/packages/database/migrations/002_seed_global.sql new file mode 100644 index 0000000..67d4a63 --- /dev/null +++ b/packages/database/migrations/002_seed_global.sql @@ -0,0 +1,17 @@ +-- Global reference data required by the initial authenticated application shell. +SET search_path TO atlas, public; + +INSERT INTO currencies (code, name, symbol, decimal_places) +VALUES ('CNY', 'Chinese Yuan', '¥', 2), ('RUB', 'Russian Ruble', '₽', 2) +ON CONFLICT (code) DO NOTHING; + +INSERT INTO platforms (code, name) +VALUES ('OZON', 'Ozon') +ON CONFLICT (code) DO NOTHING; + +INSERT INTO platform_currency_support (platform_id, currency_code) +SELECT id, currency_code +FROM platforms +CROSS JOIN (VALUES ('RUB'::CHAR(3))) AS supported(currency_code) +WHERE code = 'OZON' +ON CONFLICT (platform_id, currency_code) DO NOTHING; diff --git a/packages/database/package.json b/packages/database/package.json index ae47c07..4fc679b 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -1,16 +1,22 @@ { - "name": "@atlas/database", - "version": "0.1.0", - "private": true, - "scripts": { - "typecheck": "tsc -p tsconfig.json --noEmit" - }, - "dependencies": { - "pg": "8.23.0" - }, - "devDependencies": { - "@types/node": "26.3.0", - "@types/pg": "8.23.1", - "typescript": "7.0.2" - } + "name": "@atlas/database", + "version": "0.1.0", + "private": true, + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "migrate": "tsx src/migrate.ts", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "dependencies": { + "pg": "8.23.0" + }, + "devDependencies": { + "@types/node": "26.3.0", + "@types/pg": "8.23.1", + "tsx": "4.23.13", + "typescript": "7.0.2" + } } diff --git a/packages/database/src/index.ts b/packages/database/src/index.ts index 6fe8fed..c6de24b 100644 --- a/packages/database/src/index.ts +++ b/packages/database/src/index.ts @@ -1,5 +1,2 @@ -/** - * 数据库访问层的唯一入口。 - * 后续在此封装迁移连接与应用连接,应用事务必须先设置 app.workspace_id。 - */ -export const databasePackageName = '@atlas/database'; +export { Database, createApplicationDatabase } from './pool.js'; +export type { DatabaseTransaction } from './pool.js'; diff --git a/packages/database/src/migrate.ts b/packages/database/src/migrate.ts new file mode 100644 index 0000000..5a40c09 --- /dev/null +++ b/packages/database/src/migrate.ts @@ -0,0 +1,70 @@ +import { createHash } from 'node:crypto'; +import { readdir, readFile } from 'node:fs/promises'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { Pool } from 'pg'; + +const migrationsDirectory = join( + dirname(fileURLToPath(import.meta.url)), + '../migrations', +); +const connectionString = process.env.MIGRATOR_DATABASE_URL; + +if (!connectionString) { + throw new Error( + 'MIGRATOR_DATABASE_URL is required; never run migrations with the application connection.', + ); +} + +const pool = new Pool({ connectionString, max: 1 }); + +async function migrate() { + const files = (await readdir(migrationsDirectory)) + .filter((file) => /^\d+_.+\.sql$/.test(file)) + .sort(); + const client = await pool.connect(); + try { + await client.query('CREATE SCHEMA IF NOT EXISTS atlas'); + await client.query(`CREATE TABLE IF NOT EXISTS atlas.schema_migrations ( + filename TEXT PRIMARY KEY, + checksum TEXT NOT NULL, + applied_at TIMESTAMPTZ NOT NULL DEFAULT now() + )`); + for (const filename of files) { + const sql = await readFile( + join(migrationsDirectory, filename), + 'utf8', + ); + const checksum = createHash('sha256').update(sql).digest('hex'); + const applied = await client.query<{ checksum: string }>( + 'SELECT checksum FROM atlas.schema_migrations WHERE filename = $1', + [filename], + ); + if (applied.rowCount) { + if (applied.rows[0].checksum !== checksum) + throw new Error( + `Applied migration was modified: ${filename}`, + ); + continue; + } + await client.query('BEGIN'); + try { + await client.query(sql); + await client.query( + 'INSERT INTO atlas.schema_migrations (filename, checksum) VALUES ($1, $2)', + [filename, checksum], + ); + await client.query('COMMIT'); + console.info(`Applied migration ${filename}`); + } catch (error) { + await client.query('ROLLBACK'); + throw error; + } + } + } finally { + client.release(); + await pool.end(); + } +} + +void migrate(); diff --git a/packages/database/src/pool.ts b/packages/database/src/pool.ts new file mode 100644 index 0000000..d7685a1 --- /dev/null +++ b/packages/database/src/pool.ts @@ -0,0 +1,59 @@ +import { Pool, type PoolClient, type QueryResultRow } from 'pg'; + +export type DatabaseTransaction = Pick; + +export class Database { + public constructor(private readonly pool: Pool) {} + + public async transaction( + work: (transaction: DatabaseTransaction) => Promise, + ): Promise { + const client = await this.pool.connect(); + try { + await client.query('BEGIN'); + // atlas_app_login is NOINHERIT by design; application DML always uses the least-privileged group role. + await client.query('SET LOCAL ROLE atlas_app'); + const result = await work(client); + await client.query('COMMIT'); + return result; + } catch (error) { + await client.query('ROLLBACK'); + throw error; + } finally { + client.release(); + } + } + + /** Every tenant-scoped query must run through this method. */ + public async workspaceTransaction( + workspaceId: string, + work: (transaction: DatabaseTransaction) => Promise, + ): Promise { + return this.transaction(async (transaction) => { + // SET LOCAL is scoped to this transaction and cannot leak a tenant id through the pool. + await transaction.query( + "SELECT set_config('app.workspace_id', $1, true)", + [workspaceId], + ); + return work(transaction); + }); + } + + public async query( + text: string, + values?: unknown[], + ) { + // Even non-tenant reads use the restricted role; callers cannot accidentally use the login role's privileges. + return this.transaction((transaction) => + transaction.query(text, values), + ); + } + + public async close() { + await this.pool.end(); + } +} + +export function createApplicationDatabase(connectionString: string): Database { + return new Database(new Pool({ connectionString, max: 10 })); +} diff --git a/packages/database/tsconfig.json b/packages/database/tsconfig.json index df59da5..00ed99b 100644 --- a/packages/database/tsconfig.json +++ b/packages/database/tsconfig.json @@ -1,8 +1,8 @@ { - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "dist" - }, - "include": ["src/**/*.ts"] + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": ["src/**/*.ts"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index baac250..c6c1225 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4356 +1,5924 @@ lockfileVersion: '9.0' settings: - autoInstallPeers: true - excludeLinksFromLockfile: false + autoInstallPeers: true + excludeLinksFromLockfile: false importers: + .: + devDependencies: + prettier: + specifier: 3.9.6 + version: 3.9.6 + turbo: + specifier: 2.10.12 + version: 2.10.12 + typescript: + specifier: 7.0.2 + version: 7.0.2 - .: - devDependencies: - prettier: - specifier: 3.9.6 - version: 3.9.6 - turbo: - specifier: 2.10.12 - version: 2.10.12 - typescript: - specifier: 7.0.2 - version: 7.0.2 + apps/api: + dependencies: + '@atlas/contracts': + specifier: workspace:* + version: link:../../packages/contracts + '@atlas/database': + specifier: workspace:* + version: link:../../packages/database + '@nestjs/common': + specifier: 12.0.1 + version: 12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/config': + specifier: 12.0.0 + version: 12.0.0(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) + '@nestjs/core': + specifier: 12.0.1 + version: 12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@12.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/platform-express': + specifier: 12.0.1 + version: 12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@12.0.1) + '@nestjs/swagger': + specifier: 12.0.1 + version: 12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@12.0.1)(reflect-metadata@0.2.2) + helmet: + specifier: 8.3.0 + version: 8.3.0 + ioredis: + specifier: 6.0.0 + version: 6.0.0 + reflect-metadata: + specifier: 0.2.2 + version: 0.2.2 + rxjs: + specifier: 7.8.2 + version: 7.8.2 + zod: + specifier: 4.5.4 + version: 4.5.4 + devDependencies: + '@types/express': + specifier: 5.0.6 + version: 5.0.6 + '@types/node': + specifier: 26.3.0 + version: 26.3.0 + tsx: + specifier: 4.23.13 + version: 4.23.13 + typescript: + specifier: 7.0.2 + version: 7.0.2 - apps/api: - dependencies: - '@atlas/contracts': - specifier: workspace:* - version: link:../../packages/contracts - '@nestjs/common': - specifier: 12.0.1 - version: 12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': - specifier: 12.0.1 - version: 12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@12.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/platform-express': - specifier: 12.0.1 - version: 12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@12.0.1) - reflect-metadata: - specifier: 0.2.2 - version: 0.2.2 - rxjs: - specifier: 7.8.2 - version: 7.8.2 - devDependencies: - '@types/node': - specifier: 26.3.0 - version: 26.3.0 - tsx: - specifier: 4.23.13 - version: 4.23.13 - typescript: - specifier: 7.0.2 - version: 7.0.2 + apps/extension: + dependencies: + '@atlas/contracts': + specifier: workspace:* + version: link:../../packages/contracts + '@wxt-dev/module-react': + specifier: 1.2.2 + version: 1.2.2(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13))(wxt@0.21.4(esbuild@0.28.2)(rolldown@1.2.6)(typescript@7.0.2)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13))) + react: + specifier: 19.2.8 + version: 19.2.8 + react-dom: + specifier: 19.2.8 + version: 19.2.8(react@19.2.8) + devDependencies: + '@types/react': + specifier: 19.2.18 + version: 19.2.18 + '@types/react-dom': + specifier: 19.2.5 + version: 19.2.5(@types/react@19.2.18) + typescript: + specifier: 7.0.2 + version: 7.0.2 + wxt: + specifier: 0.21.4 + version: 0.21.4(esbuild@0.28.2)(rolldown@1.2.6)(typescript@7.0.2)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) - apps/extension: - dependencies: - '@atlas/contracts': - specifier: workspace:* - version: link:../../packages/contracts - '@wxt-dev/module-react': - specifier: 1.2.2 - version: 1.2.2(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13))(wxt@0.21.4(esbuild@0.28.2)(rolldown@1.2.6)(typescript@7.0.2)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13))) - react: - specifier: 19.2.8 - version: 19.2.8 - react-dom: - specifier: 19.2.8 - version: 19.2.8(react@19.2.8) - devDependencies: - '@types/react': - specifier: 19.2.18 - version: 19.2.18 - '@types/react-dom': - specifier: 19.2.5 - version: 19.2.5(@types/react@19.2.18) - typescript: - specifier: 7.0.2 - version: 7.0.2 - wxt: - specifier: 0.21.4 - version: 0.21.4(esbuild@0.28.2)(rolldown@1.2.6)(typescript@7.0.2)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) + apps/web: + dependencies: + '@ant-design/icons': + specifier: 6.3.4 + version: 6.3.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + antd: + specifier: 6.6.2 + version: 6.6.2(luxon@3.7.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + axios: + specifier: 1.20.0 + version: 1.20.0(debug@4.4.3) + react: + specifier: 19.2.8 + version: 19.2.8 + react-dom: + specifier: 19.2.8 + version: 19.2.8(react@19.2.8) + react-router-dom: + specifier: 7.18.3 + version: 7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + devDependencies: + '@types/node': + specifier: 26.3.0 + version: 26.3.0 + '@types/react': + specifier: 19.2.18 + version: 19.2.18 + '@types/react-dom': + specifier: 19.2.5 + version: 19.2.5(@types/react@19.2.18) + '@vitejs/plugin-react': + specifier: 6.1.1 + version: 6.1.1(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) + typescript: + specifier: 7.0.2 + version: 7.0.2 + vite: + specifier: 8.2.2 + version: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13) - apps/web: - dependencies: - '@ant-design/icons': - specifier: 6.3.4 - version: 6.3.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - antd: - specifier: 6.6.2 - version: 6.6.2(luxon@3.7.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - axios: - specifier: 1.20.0 - version: 1.20.0(debug@4.4.3) - react: - specifier: 19.2.8 - version: 19.2.8 - react-dom: - specifier: 19.2.8 - version: 19.2.8(react@19.2.8) - react-router-dom: - specifier: 7.18.3 - version: 7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - devDependencies: - '@types/node': - specifier: 26.3.0 - version: 26.3.0 - '@types/react': - specifier: 19.2.18 - version: 19.2.18 - '@types/react-dom': - specifier: 19.2.5 - version: 19.2.5(@types/react@19.2.18) - '@vitejs/plugin-react': - specifier: 6.1.1 - version: 6.1.1(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) - typescript: - specifier: 7.0.2 - version: 7.0.2 - vite: - specifier: 8.2.2 - version: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13) + apps/worker: + dependencies: + '@atlas/contracts': + specifier: workspace:* + version: link:../../packages/contracts + bullmq: + specifier: 6.3.4 + version: 6.3.4(ioredis@6.0.0)(pg@8.23.0) + ioredis: + specifier: 6.0.0 + version: 6.0.0 + devDependencies: + '@types/node': + specifier: 26.3.0 + version: 26.3.0 + tsx: + specifier: 4.23.13 + version: 4.23.13 + typescript: + specifier: 7.0.2 + version: 7.0.2 - apps/worker: - dependencies: - '@atlas/contracts': - specifier: workspace:* - version: link:../../packages/contracts - bullmq: - specifier: 6.3.4 - version: 6.3.4(ioredis@6.0.0)(pg@8.23.0) - ioredis: - specifier: 6.0.0 - version: 6.0.0 - devDependencies: - '@types/node': - specifier: 26.3.0 - version: 26.3.0 - tsx: - specifier: 4.23.13 - version: 4.23.13 - typescript: - specifier: 7.0.2 - version: 7.0.2 + packages/contracts: + dependencies: + zod: + specifier: 4.5.4 + version: 4.5.4 + devDependencies: + typescript: + specifier: 7.0.2 + version: 7.0.2 - packages/contracts: - dependencies: - zod: - specifier: 4.5.4 - version: 4.5.4 - devDependencies: - typescript: - specifier: 7.0.2 - version: 7.0.2 - - packages/database: - dependencies: - pg: - specifier: 8.23.0 - version: 8.23.0 - devDependencies: - '@types/node': - specifier: 26.3.0 - version: 26.3.0 - '@types/pg': - specifier: 8.23.1 - version: 8.23.1 - typescript: - specifier: 7.0.2 - version: 7.0.2 + packages/database: + dependencies: + pg: + specifier: 8.23.0 + version: 8.23.0 + devDependencies: + '@types/node': + specifier: 26.3.0 + version: 26.3.0 + '@types/pg': + specifier: 8.23.1 + version: 8.23.1 + tsx: + specifier: 4.23.13 + version: 4.23.13 + typescript: + specifier: 7.0.2 + version: 7.0.2 packages: - - '@1natsu/wait-element@4.2.0': - resolution: {integrity: sha512-Om0Q+WE9mNrpY4AwMTvkFiYHv8VM7TML3PvOqXy+w6kAjLjKhGYHYX+305+a6J8RVpds9s7IF2Z5aOPYwULFNw==} - - '@aklinker1/rollup-plugin-visualizer@5.12.0': - resolution: {integrity: sha512-X24LvEGw6UFmy0lpGJDmXsMyBD58XmX1bbwsaMLhNoM+UMQfQ3b2RtC+nz4b/NoRK5r6QJSKJHBNVeUdwqybaQ==} - engines: {node: '>=14'} - hasBin: true - peerDependencies: - rollup: 2.x || 3.x || 4.x - peerDependenciesMeta: - rollup: - optional: true - - '@aklinker1/zero-zip@1.0.1': - resolution: {integrity: sha512-07a596Bd1QO0bi3tIyt2xruq6vKk7hCUt9enHBwggvipB0iiycoJ9/CqzN6UFawaKbOi6NBfMlUxUXzIOZ7Dsg==} - - '@ant-design/colors@8.0.1': - resolution: {integrity: sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ==} - - '@ant-design/cssinjs-utils@2.1.2': - resolution: {integrity: sha512-5fTHQ158jJJ5dC/ECeyIdZUzKxE/mpEMRZxthyG1sw/AKRHKgJBg00Yi6ACVXgycdje7KahRNvNET/uBccwCnA==} - peerDependencies: - react: '>=18' - react-dom: '>=18' - - '@ant-design/cssinjs@2.1.2': - resolution: {integrity: sha512-2Hy8BnCEH31xPeSLbhhB2ctCPXE2ZnASdi+KbSeS79BNbUhL9hAEe20SkUk+BR8aKTmqb6+FKFruk7w8z0VoRQ==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - '@ant-design/fast-color@3.0.1': - resolution: {integrity: sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw==} - engines: {node: '>=8.x'} - - '@ant-design/icons-svg@4.6.0': - resolution: {integrity: sha512-PRomU725ABMf/lnQp5HiB7my1kjEbFY0D10N4lXYxK6TIB1gKjIVD5MRThpDaezLgw1D774J8eOeeDB0M6wHrQ==} - - '@ant-design/icons@6.3.4': - resolution: {integrity: sha512-kDoUlppczVyCUTFthF6cHmPzMBYqNZQhu9j6EyIX/YIdM9j9CZNZoJUjzVw7/1v1VO8WwVMmPp15r/uwIAS0AQ==} - engines: {node: '>=8'} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - '@ant-design/react-slick@2.0.0': - resolution: {integrity: sha512-HMS9sRoEmZey8LsE/Yo6+klhlzU12PisjrVcydW3So7RdklyEd2qehyU6a7Yp+OYN72mgsYs3NFCyP2lCPFVqg==} - peerDependencies: - react: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - - '@babel/helper-string-parser@7.29.7': - resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.29.7': - resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.8': - resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/runtime@7.29.7': - resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} - engines: {node: '>=6.9.0'} - - '@babel/runtime@8.0.0': - resolution: {integrity: sha512-sL6cvO2IfkSu/iU+zs2S/w01B7A8V7suXSIKEN4hPFFdZoiPGxrj5pAG0lCaqLWiEIrjKzdznIWuaLcxPR53qw==} - - '@babel/types@7.29.8': - resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} - engines: {node: '>=6.9.0'} - - '@borewit/text-codec@0.2.2': - resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} - - '@emotion/hash@0.8.0': - resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} - - '@emotion/unitless@0.7.5': - resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} - - '@esbuild/aix-ppc64@0.28.2': - resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.28.2': - resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.28.2': - resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.28.2': - resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.28.2': - resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.28.2': - resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.28.2': - resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.28.2': - resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.28.2': - resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.28.2': - resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.28.2': - resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.28.2': - resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.28.2': - resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.28.2': - resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.28.2': - resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.28.2': - resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.28.2': - resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-arm64@0.28.2': - resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.28.2': - resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-arm64@0.28.2': - resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.28.2': - resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openharmony-arm64@0.28.2': - resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - - '@esbuild/sunos-x64@0.28.2': - resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.28.2': - resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.28.2': - resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.28.2': - resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - - '@ioredis/commands@2.0.0': - resolution: {integrity: sha512-vrx0AE/T0h7cRZwfo1M39Cr+ZhZrkf0V8mQN75wucKCxCLD9l/VX6no3gFvrLqD1IlG/1LtzWovqEw3t0Vr9zg==} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.6.0': - resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@lukeed/csprng@1.1.0': - resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} - engines: {node: '>=8'} - - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': - resolution: {integrity: sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==} - cpu: [arm64] - os: [darwin] - - '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': - resolution: {integrity: sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==} - cpu: [x64] - os: [darwin] - - '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': - resolution: {integrity: sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==} - cpu: [arm64] - os: [linux] - - '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': - resolution: {integrity: sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==} - cpu: [arm] - os: [linux] - - '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': - resolution: {integrity: sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==} - cpu: [x64] - os: [linux] - - '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': - resolution: {integrity: sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==} - cpu: [x64] - os: [win32] - - '@nestjs/common@12.0.1': - resolution: {integrity: sha512-v0zTaRCTV2K2xSnb3GnJoQKtaR6VxouJtm+P2gpr5w61dlXeWpXl1WVknCSzUqx2QwTV10tBkHETxvQvkf2Exg==} - peerDependencies: - class-transformer: '>=0.4.1' - class-validator: '>=0.13.2' - reflect-metadata: ^0.1.12 || ^0.2.0 - rxjs: ^7.1.0 - peerDependenciesMeta: - class-transformer: - optional: true - class-validator: - optional: true - - '@nestjs/core@12.0.1': - resolution: {integrity: sha512-rU6tAi8vDdyzHgN0iW0J4UJvziroOqzHqzlqL7phOSPizaXVEePfv+OUOsdJEOh0Qd14mslc3udOheLrAEcZow==} - engines: {node: '>= 20'} - peerDependencies: - '@nestjs/common': ^12.0.0 - '@nestjs/microservices': ^12.0.0 - '@nestjs/platform-express': ^12.0.0 - '@nestjs/websockets': ^12.0.0 - reflect-metadata: ^0.1.12 || ^0.2.0 - rxjs: ^7.1.0 - peerDependenciesMeta: - '@nestjs/microservices': - optional: true - '@nestjs/platform-express': - optional: true - '@nestjs/websockets': - optional: true - - '@nestjs/platform-express@12.0.1': - resolution: {integrity: sha512-nF8bRgROptMyixYBfiJUAsjj2o9k13zxAjUKYaqHTPk8mTSd+gk7hXz6NykXNrfHWmMEYC9RttQlMUdMHNTbuA==} - peerDependencies: - '@nestjs/common': ^12.0.0 - '@nestjs/core': ^12.0.0 - - '@oxc-project/types@0.147.0': - resolution: {integrity: sha512-IJ3s6ltHLp45S0bh7phkX+gJO7A1Wuz2EaqpAhb8WjqDwbzMiWKHhyyT42tskaWjEYXtHtVCPpnBJVT9+dcRLg==} - - '@rc-component/async-validator@6.0.0': - resolution: {integrity: sha512-D3AGQwdyE58gmvx6waVSXJ80JGO+IY5L2O8HDnSOex7JNlzB3GuN/4hyHNTdhy2qtOhkpbIjmeAN3tL993wKbA==} - engines: {node: '>=14.x'} - - '@rc-component/cascader@1.22.0': - resolution: {integrity: sha512-SffrA57aS9oub3VuI7ajPhJTPtaNxngSvtRhD40Rd8dwJ5vfWPSrVanWgeepdWFGBt7EHftIK5RUU0u3rCTwWw==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/checkbox@2.0.0': - resolution: {integrity: sha512-3CXGPpAR9gsPKeO2N78HAPOzU30UdemD6HGJoWVJOpa6WleaGB5kzZj3v6bdTZab31YuWgY/RxV3VKPctn0DwQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/collapse@1.2.0': - resolution: {integrity: sha512-ZRYSKSS39qsFx93p26bde7JUZJshsUBEQRlRXPuJYlAiNX0vyYlF5TsAm8JZN3LcF8XvKikdzPbgAtXSbkLUkw==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/color-picker@3.1.1': - resolution: {integrity: sha512-OHaCHLHszCegdXmIq2ZRIZBN/EtpT6Wm8SG/gpzLATHbVKc/avvuKi+zlOuk05FTWvgaMmpxAko44uRJ3M+2pg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/context@2.0.2': - resolution: {integrity: sha512-uiGpAlblCNlziHPwj4S4Iy/oemeuz/hR03mbiEjTCXwsqOIN3BOzsRMyDwpyO5Fm0vIEEJRUf9ZtbRLbhksuTA==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/dialog@1.10.0': - resolution: {integrity: sha512-eDukNlz9vNszAGv7i3zKXdxEd3wgVmNxuJijYt8zvTh17QwTu8KK/bdURRd/lU4qaMzhO1HKKmMrwOnkaw0BvQ==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/drawer@1.4.2': - resolution: {integrity: sha512-1ib+fZEp6FBu+YvcIktm+nCQ+Q+qIpwpoaJH6opGr4ofh2QMq+qdr5DLC4oCf5qf3pcWX9lUWPYX652k4ini8Q==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/dropdown@1.0.3': - resolution: {integrity: sha512-YTST/N6kpqpDz3IMuM/PSSZnrDpSOA6dgHv12gPA90ZTSLv2CoqkZ0+9NtwTY6BeO7dstPblSic2QJg7dSFy/g==} - peerDependencies: - react: '>=16.11.0' - react-dom: '>=16.11.0' - - '@rc-component/form@1.8.6': - resolution: {integrity: sha512-1EXVsSKPZC6kGrIqxVck7kAWM6T65b6et/n5wIcyiaIa41VrDshD0nVLHoBDEIZr2ATQsOP6icb4XQkNFMLBAw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/image@1.10.0': - resolution: {integrity: sha512-BjeZCRQ+hw+4WAhvrw8rJvy5fckA2xpf/X2XQEOABUHvLTNB9inB98X3Mp54jYQ7g10DfWERQWHXeC4ylxp1Uw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/input-number@1.6.2': - resolution: {integrity: sha512-Gjcq7meZlCOiWN1t1xCC+7/s85humHVokTBI7PJgTfoyw5OWF74y3e6P8PHX104g9+b54jsodFIzyaj6p8LI9w==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/input@1.3.1': - resolution: {integrity: sha512-iFvTUT9W+JC/MSin2aGAk8NqsVlTzcExNC9DZariON1IWirju9NoNeEk47an4Q8iHazkoVI/y1LnDi88+CPcig==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - '@rc-component/listy@1.2.3': - resolution: {integrity: sha512-IXiMjV5s0rczLBlfh7G5nB4M3365mrEeedjwKtf5I+Ns3PqRUsebR2h5u8CeFarsVfLUPC2I5p0h09TNoOWyvQ==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/mentions@1.12.0': - resolution: {integrity: sha512-v5MBx8zDcqCT+uybJgKpcx3Fgrvj0m3u+A/15RlSBaMx12lLoJZTTYggC3pbYYfohcKujWWUyBz6O6Gp2vGiNA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/menu@1.5.0': - resolution: {integrity: sha512-RjvzPsZkwVEg3xu+/jDDqDeUCBJAnWylONFlGeQgg5enlNAnlpybqhaMGE/UPEIvr6hL90PGhjFBguJqj0Qb2Q==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/mini-decimal@1.1.4': - resolution: {integrity: sha512-xiuXcaCwyOWpD8a8scdExFl+bntNphAW8XeenL1ig2en0AAZY0Pcp4pC0dI22qJ+NvxKn9RoNIoRdqYU3BLH4w==} - engines: {node: '>=8.x'} - - '@rc-component/motion@1.3.3': - resolution: {integrity: sha512-Xh3IszxvlSv3/PLYFyC2UZi9LNB83yOnkB/LNmRzaypZLvkhqUIPS7MQpGZcCMWrNsXV2p6YTSWbSGvFpEle9A==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/mutate-observer@2.0.1': - resolution: {integrity: sha512-AyarjoLU5YlxuValRi+w8JRH2Z84TBbFO2RoGWz9d8bSu0FqT8DtugH3xC3BV7mUwlmROFauyWuXFuq4IFbH+w==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/notification@2.0.8': - resolution: {integrity: sha512-MTRA3b8eHE14gh5R9nlXzbWZEDEBFVkEHj/FI1VOXw2zrSnSxqbuuU3drsq+k53e6MHwtegoFay1tnNYhtl61Q==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/overflow@1.0.1': - resolution: {integrity: sha512-syfmgAABaHCnCDzPwHZ/2tuvIcpOO3jefYZMmfkN+pmo8HKTzsfhS57vxo4ksPdN0By+uWVJhJWNFozNBxi2eA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/pagination@1.4.0': - resolution: {integrity: sha512-CW1g7P9V8u+e8JQdUsl2RWg+GCsoee0mtJjZUCCxn/vb3jzOwDKm6hAdwddHCVBfWJ58eGUBZz3IvnU8rRktjw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/picker@1.12.0': - resolution: {integrity: sha512-0FZGgDiDZFMm2hcfGv4jyjm7yWIj2MiwfeTzLL0vWkO+8cCSKdiM9XhWpkn1aAsoI2EwUy48Oz2cGfvL8ZKrfw==} - engines: {node: '>=12.x'} - peerDependencies: - date-fns: '>= 2.x' - dayjs: '>= 1.x' - luxon: '>= 3.x' - moment: '>= 2.x' - react: '>=16.9.0' - react-dom: '>=16.9.0' - peerDependenciesMeta: - date-fns: - optional: true - dayjs: - optional: true - luxon: - optional: true - moment: - optional: true - - '@rc-component/portal@2.2.1': - resolution: {integrity: sha512-ck+r1kW/JSv0wxPji3KN2ss9K6Z0qqwusw/mf/0JobXhZ8hC2ejZwCJObW/SvDi0uhA0VzmCnx0CaCci95tcmA==} - engines: {node: '>=12.x'} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/progress@1.0.3': - resolution: {integrity: sha512-Q1nPLIvKr95el/q76yaBh5nv1hqCsWaHQb8U7vXEDMefEhHgM7n3CPoN+o4LHnTyANQHmMFgoS/naAT4Bhxuaw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/qrcode@2.0.0': - resolution: {integrity: sha512-aAv3QhPP1xyafuTZOxub6a54pCeBnN3IwQkpETrBtthq4BL5IgxnCbuoBWPDpdLw1y1j6BgBUCAKV92+yX06Dw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/rate@1.0.1': - resolution: {integrity: sha512-bkXxeBqDpl5IOC7yL7GcSYjQx9G8H+6kLYQnNZWeBYq2OYIv1MONd6mqKTjnnJYpV0cQIU2z3atdW0j1kttpTw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/resize-observer@1.1.2': - resolution: {integrity: sha512-t/Bb0W8uvL4PYKAB3YcChC+DlHh0Wt5kM7q/J+0qpVEUMLe7Hk5zuvc9km0hMnTFPSx5Z7Wu/fzCLN6erVLE8Q==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/segmented@1.3.0': - resolution: {integrity: sha512-5J/bJ01mbDnoA6P/FW8SxUvKn+OgUSTZJPzCNnTBntG50tzoP7DydGhqxp7ggZXZls7me3mc2EQDXakU3iTVFg==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - '@rc-component/select@1.10.1': - resolution: {integrity: sha512-H+yQsl+qED9NilQ3g6zdpsMwUgwVjrcMTkNHAWRVU/MoNCYgTbDgU+MIMgZDK+rVdd2JUfI/MkysMcZZ0cyQKw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '*' - react-dom: '*' - - '@rc-component/slider@1.1.1': - resolution: {integrity: sha512-LSzgWGYDgeCDgR4r1XlU29gbYws6HpLnvJd/uMhLeW/vQgxldeR+Wb4uzHDCHiYEbr1bnEHWdjkPxjJRHxuiig==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/steps@1.2.3': - resolution: {integrity: sha512-/b9gHcvDGjTDWJZW7+1kKFvzs0jrEeQ8mFvvIgX+h7xNT0FsOYODJYKjyJR4fPbvMBCfCOEqaBK66HBxov5BQA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/switch@1.0.3': - resolution: {integrity: sha512-Jgi+EbOBquje/XNdofr7xbJQZPYJP+BlPfR0h+WN4zFkdtB2EWqEfvkXJWeipflwjWip0/17rNbxEAqs8hVHfw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/table@1.11.1': - resolution: {integrity: sha512-OWdS6DMmeWb7bJBGqPxYZpQbzBlBiXZUu2sqo6Ii7Sjs9GeK1IsrXrWk26SL2c6KEseabswdxrRj7WUm9LdECw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/tabs@1.13.0': - resolution: {integrity: sha512-3FXr+9ZII8tFLWuDWrgjRaxZd2mazkKJAGRFEfVmp4r1qnBglOlxQ78l54Td1aj6/iFaaEReKSAF2HToztU5uw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/tooltip@1.5.2': - resolution: {integrity: sha512-VLq4BclU3LgRe46g2hTr2bdsM8tFYs7dVwpuD88rPNNg4lCGe8mBSS4FiRzYzS+ffnZ46y4SI8KYKo9K7qBnhw==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/tour@2.4.0': - resolution: {integrity: sha512-aui4r4TqmTzwaBgcQxHYep8kM8PTjZFufjokObpy35KfFeZ0k9ArquWFZqegQlH24P14t+F0qO0mGTgzlav1yg==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/tree-select@1.16.1': - resolution: {integrity: sha512-a1Oi6EJhqAhdOxxupdJi6fP0RPHMKn5TcfkX2+llaQ4lF4nwfH7b6SCHcnsybaa2s+pk1yZYwVyeOYkDnEBRdg==} - peerDependencies: - react: '*' - react-dom: '*' - - '@rc-component/tree@1.4.0': - resolution: {integrity: sha512-dGsJGDJQedA0BqqVgj3F8BvHXTSZijyhTXdbAdkcx8lynzZkty/CV3Z3LOm/fxz+BCfl3dfGiAQpb7Q5XNvl0Q==} - engines: {node: '>=10.x'} - peerDependencies: - react: '*' - react-dom: '*' - - '@rc-component/trigger@3.10.1': - resolution: {integrity: sha512-mXlDN0IXdtV8Yqqm8195ECCyrbmfvvfKvwVvSlH0+qvKD6BUF8gRhEjSy0FOcD1+CcDRHgTiX99LoxfQrmh3Cw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/upload@1.1.1': - resolution: {integrity: sha512-GvYWSKeaJTOxxC5p6+nOSadzfvXA1h8C/iHFPFZX+szH3JUXrvs+DLiW8YUTBgvMh8m63mJeHrlYlJzAlg+pDA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/util@1.13.0': - resolution: {integrity: sha512-IXf2zBfZrbQGT+G8LxnoICDBGnMHIPIiq5HCRn3EDfKUx28x1rnbZBj46ULJf4sM8ImTG1SepqfNBdxZziqQ4w==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rc-component/virtual-list@1.5.1': - resolution: {integrity: sha512-boqHxdtyWC88u8quYgEO49bcBy5fzRiOcnBge+N4nLzs2k8hUQ/yw7JE9dM6yCBE4jSm5YSHVCVMS+suBuJGKA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - '@rolldown/binding-android-arm-eabi@1.2.6': - resolution: {integrity: sha512-b+jTcARdTiFLI6jB4a5XjTm0RWd6KcRfQj/I2356fxUZemiho9zQLxo0RtCuMDAyKcLo6cEltkgbQp6d1+sjjQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@rolldown/binding-android-arm64@1.2.6': - resolution: {integrity: sha512-lkWU8ZJaRk9q3CIEY1Tc7vIFALp3Xw5NfGJo2hQg5oIqNgxWi1zI+IiDEK3r70BF5Dzol1tcXsnzsRc8NLhG+Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.2.6': - resolution: {integrity: sha512-dgR56NYnvAszm7Ob1B2/Vn0e8bUQYZH2UjVaMMtMVOCKFSfjhfLmuA/9+O+F+ajUdG6B/bSssrKW6JJYASa8jA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.2.6': - resolution: {integrity: sha512-vpVxFvUCFioJqug7OTvqptkc4yb8UX0AwfDmJpaR/0sWz+BUmqSVAf7c8JkUgnN8YLspb4a/N6NhTyMAmdyQ7Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.2.6': - resolution: {integrity: sha512-h1wG6Y6K3JlRswxsI64qQJqBAy4vrLuHgRbc8CZMGSWTOFRY6ghMApM1NKzB2I0n5xV1fjkE18SuVl2QpLeNpA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.2.6': - resolution: {integrity: sha512-tbCiqub0q2MVWJKgF5PoAlNWCtQydiOYSLIkd8sByqK/6MMYLJRcSXSYodqYtd0O+Fw7QaVmKKlS4oL94YRZ0w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.2.6': - resolution: {integrity: sha512-oxK9+baEBPhZG5HB4URY+uU04zJWeZlH6Tb9rB5DK4DF9XR1uXNLXt5Q5ZsugTKayNCNLhkcwz/ye74hRI98dg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-arm64-musl@1.2.6': - resolution: {integrity: sha512-muWCk27FVBEZtv0MsK8gnfSmgczA8KQ0uRVJbTABKhkRfQc38aUrcb7fhi3BNiyseFmgcRsoMfQsSNJ+DbZdSw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rolldown/binding-linux-ppc64-gnu@1.2.6': - resolution: {integrity: sha512-eWDoSfU7Co2qj3vgB3Dt4lj1mG6CoWbcJQkRMP3XJplyCMtuaq3LHvPFjS9QIPvMGWVadJC04Xiy0IdcVPtnwQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-s390x-gnu@1.2.6': - resolution: {integrity: sha512-2bWNjRSIayvupRKxXUY2tWG9fYdoUlTqWywHRvE8Eq3GvuQ+f2HeIkve697fIt+IQs/PV8yFsdWuhp1aJ1PdnA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-gnu@1.2.6': - resolution: {integrity: sha512-KekI0gS0wLxe1UBSQSjenBVwou/JkcQPDzBPICGZjxUv9k3RteHDPBQaiOicZUFKRIH2wKEimGwVpnJsbPzu7w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-musl@1.2.6': - resolution: {integrity: sha512-TvtPnfVr+HtyGiDmPK4VWmlNm7QhNNAcK5Q9A7aOXsI8545yCyaoMaicXrFZ72JzeYjaUVk7yT243zT0jzjFKQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rolldown/binding-openharmony-arm64@1.2.6': - resolution: {integrity: sha512-iOo0VEay2XFhaCcH0sps5XIimkSuOnNaZrf6+ZkoSOQBJPKNU48RkmJv0/lSpipexu5P+ouFgafe5IGr/DiQfg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-win32-arm64-msvc@1.2.6': - resolution: {integrity: sha512-y5NTmmasMS455JlOCO4ZM9krIchv3Mvm1crL1iUPGOPgEzSkves9n0SdC5Sjz6+qWDFhd8/JpfWMH8NSWNHe+A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.2.6': - resolution: {integrity: sha512-np8iZSLfXlAD4kWhiyq/u0Yt8oZDtRQ8lGhQaCXo2rl37KNjeU0GjJuwr4P3oeZ++ROfofsKNBqR5LTO8aXyWQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@tokenizer/inflate@0.4.1': - resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} - engines: {node: '>=18'} - - '@tokenizer/token@0.3.0': - resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - - '@topcli/prompts@4.0.0': - resolution: {integrity: sha512-kkKYPb4k/6kRdnESt77B5vJrrYnYHIYczwv0P1c+tfN/IWEx3KZeKEHoUq7sImIyBEXWdA2uakIroD9pmRJziQ==} - engines: {node: '>=22.0.0'} - - '@turbo/darwin-64@2.10.12': - resolution: {integrity: sha512-9nKgKoF6ZOUsM+or0OtNf+TTJSfGvDNP7ZFv/ZGWVwOSCkumyctQiTeHwB4UNljHTnC41AqylgbunLDHoccNrA==} - cpu: [x64] - os: [darwin] - - '@turbo/darwin-arm64@2.10.12': - resolution: {integrity: sha512-H4Elb1jqTZVeIC9bbcNwjSzemZ6RegoTOVHeuV5Osirt2Z8UguTyisMEkvZjPVZgMeN9J4ERZBFad40tFnkb7w==} - cpu: [arm64] - os: [darwin] - - '@turbo/linux-64@2.10.12': - resolution: {integrity: sha512-lr7KIotukvjZwEXiFSYAeOH3BWzjFVBbSzTbv0fuGFsNukYyH0+g1hB5ecqnJkgkYU+KHEMG1edOhnjiKON1wQ==} - cpu: [x64] - os: [android, linux] - - '@turbo/linux-arm64@2.10.12': - resolution: {integrity: sha512-f0pZDTtvzB5SuNwuXBaKbZHUCMCukgc8nMlHEuvLmj91Fzec+MEbr3cAvGNor5htEDqZnO6Lxt9N/GPI/77oGA==} - cpu: [arm64] - os: [android, linux] - - '@turbo/windows-64@2.10.12': - resolution: {integrity: sha512-SDOueJRjS/QcykWf2KCRtTLmIl5YMKsLbXkXQGhDwcTXvKXZiS5ih5lBl/gkwZIpYFjqA/rAlfMzlAFcVHNe0g==} - cpu: [x64] - os: [win32] - - '@turbo/windows-arm64@2.10.12': - resolution: {integrity: sha512-0i0mVUa4kKk+/B3RwEwPMf9CB+T7ul56hn5FFHNA4VUNTOoLBEd6aNf3FaKfCatDNZ6cicCEf6if9QUTVyzzcA==} - cpu: [arm64] - os: [win32] - - '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - - '@types/filesystem@0.0.36': - resolution: {integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==} - - '@types/filewriter@0.0.33': - resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} - - '@types/har-format@1.2.16': - resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==} - - '@types/node@26.3.0': - resolution: {integrity: sha512-L3fgrnchriRC2ExBflb8j4uZZURHZfQsmQeyVzhjcHW4kkwVyo8/0h1B2MVzMTrYUJYu6G7EWs14hW/L9putqw==} - - '@types/pg@8.23.1': - resolution: {integrity: sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A==} - - '@types/react-dom@19.2.5': - resolution: {integrity: sha512-fMPwH9v7r/pp43yUd2/Mbiex5KouJwwR3dzHkhLREUC6764VyDsqxhAxv6OFEYR1RhjOyD1naqba8ECDBe7ZQg==} - peerDependencies: - '@types/react': ^19.2.0 - - '@types/react@19.2.18': - resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==} - - '@typescript/typescript-aix-ppc64@7.0.2': - resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} - engines: {node: '>=16.20.0'} - cpu: [ppc64] - os: [aix] - - '@typescript/typescript-darwin-arm64@7.0.2': - resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} - engines: {node: '>=16.20.0'} - cpu: [arm64] - os: [darwin] - - '@typescript/typescript-darwin-x64@7.0.2': - resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} - engines: {node: '>=16.20.0'} - cpu: [x64] - os: [darwin] - - '@typescript/typescript-freebsd-arm64@7.0.2': - resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} - engines: {node: '>=16.20.0'} - cpu: [arm64] - os: [freebsd] - - '@typescript/typescript-freebsd-x64@7.0.2': - resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} - engines: {node: '>=16.20.0'} - cpu: [x64] - os: [freebsd] - - '@typescript/typescript-linux-arm64@7.0.2': - resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} - engines: {node: '>=16.20.0'} - cpu: [arm64] - os: [linux] - - '@typescript/typescript-linux-arm@7.0.2': - resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} - engines: {node: '>=16.20.0'} - cpu: [arm] - os: [linux] - - '@typescript/typescript-linux-loong64@7.0.2': - resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} - engines: {node: '>=16.20.0'} - cpu: [loong64] - os: [linux] - - '@typescript/typescript-linux-mips64el@7.0.2': - resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} - engines: {node: '>=16.20.0'} - cpu: [mips64el] - os: [linux] - - '@typescript/typescript-linux-ppc64@7.0.2': - resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} - engines: {node: '>=16.20.0'} - cpu: [ppc64] - os: [linux] - - '@typescript/typescript-linux-riscv64@7.0.2': - resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} - engines: {node: '>=16.20.0'} - cpu: [riscv64] - os: [linux] - - '@typescript/typescript-linux-s390x@7.0.2': - resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} - engines: {node: '>=16.20.0'} - cpu: [s390x] - os: [linux] - - '@typescript/typescript-linux-x64@7.0.2': - resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} - engines: {node: '>=16.20.0'} - cpu: [x64] - os: [linux] - - '@typescript/typescript-netbsd-arm64@7.0.2': - resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} - engines: {node: '>=16.20.0'} - cpu: [arm64] - os: [netbsd] - - '@typescript/typescript-netbsd-x64@7.0.2': - resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} - engines: {node: '>=16.20.0'} - cpu: [x64] - os: [netbsd] - - '@typescript/typescript-openbsd-arm64@7.0.2': - resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} - engines: {node: '>=16.20.0'} - cpu: [arm64] - os: [openbsd] - - '@typescript/typescript-openbsd-x64@7.0.2': - resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} - engines: {node: '>=16.20.0'} - cpu: [x64] - os: [openbsd] - - '@typescript/typescript-sunos-x64@7.0.2': - resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} - engines: {node: '>=16.20.0'} - cpu: [x64] - os: [sunos] - - '@typescript/typescript-win32-arm64@7.0.2': - resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} - engines: {node: '>=16.20.0'} - cpu: [arm64] - os: [win32] - - '@typescript/typescript-win32-x64@7.0.2': - resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} - engines: {node: '>=16.20.0'} - cpu: [x64] - os: [win32] - - '@vitejs/plugin-react@6.1.1': - resolution: {integrity: sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 - babel-plugin-react-compiler: ^1.0.0 - oxc-transform-react: ^0.145.0 - vite: ^8.0.0 - peerDependenciesMeta: - '@rolldown/plugin-babel': - optional: true - babel-plugin-react-compiler: - optional: true - oxc-transform-react: - optional: true - - '@webext-core/fake-browser@2.0.1': - resolution: {integrity: sha512-4x5z1z8F0KU8ShF4ForXJ8qnA8oZTy7HYjI91Mbpdzp3H3hU9HR6TNPUxfWtSpFz2FwgEircuJKQg0qFIn6RLg==} - - '@webext-core/isolated-element@3.0.0': - resolution: {integrity: sha512-PmSIBMSe+rFw6eXzpJoV+glc1HPO40clcT9FJ7rSfCQzNewK8/nQZoBYWen2cMqdXdBNM9to/IbNNu5mdQLaPg==} - - '@webext-core/match-patterns@2.0.0': - resolution: {integrity: sha512-EsyMMKfQuSE4rWCjP/TifwvUWlhC/OhiGn5OK3p9F0d57UmtLib0nzguzPKyxM1/kZV7SkE+jYXkE8gsdPRLmw==} - - '@wxt-dev/browser@0.2.7': - resolution: {integrity: sha512-Dr3h3qS25Wah4LjoCSw5uazD+547Q0dLnxaRjkkLauus008daHAulgNKTU4HkojaS9QBdo3xUlwUYPTBCQb+XQ==} - - '@wxt-dev/module-react@1.2.2': - resolution: {integrity: sha512-+lRLi1r9dAXpLySWSIWHLJ1h/nFzR20iQnx3RNrKyA6oJg4+ClOluVXozHjfPg9Okfy/umtffiOopGayASrg6w==} - peerDependencies: - vite: ^5.4.19 || ^6.3.4 || ^7.0.0 || ^8.0.0-0 - wxt: '>=0.19.16' - - '@wxt-dev/storage@1.2.9': - resolution: {integrity: sha512-dh9TJwvLBM2x4wyy9nE7eYE3wA8pgz1TXSyz7RbdjkJxLfFfWkbeIqiU7VkGy7Vx8sJBmQjoSpk9zSUb3Bjy0Q==} - - accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} - - acorn@8.18.0: - resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} - engines: {node: '>=0.4.0'} - hasBin: true - - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - antd@6.6.2: - resolution: {integrity: sha512-aTOPWXsqfWrlSiI0a1qR9UWR4jBCTJ8FNZfZmYQP9/aGGLJSrw9/c5uE+4vSVSt3riQlIPAwR3BcAgEHmE7GMg==} - peerDependencies: - react: '>=18.0.0' - react-dom: '>=18.0.0' - - append-field@1.0.0: - resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - axios@1.20.0: - resolution: {integrity: sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==} - - body-parser@2.3.0: - resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} - engines: {node: '>=18'} - - boolbase@2.0.0: - resolution: {integrity: sha512-DkVaaQHymRhpYEYo9x1oo7Q7B0Y6KJUsjm3c9eTyFDby4MHLBTwZ6ZDWBel5zrYxj1WsZgC5oLpiz+93MluXeA==} - engines: {node: '>=20.19.0'} - - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - - bullmq@6.3.4: - resolution: {integrity: sha512-DpilB5sayCB8huCp4YuzVhJjxB4ieHidzu+GPgbcjPi3kQv0gdLoLnk+I+mMACDQ88rTbSiT+B4crmhWFGL9GA==} - engines: {node: '>=14.17.0'} - peerDependencies: - bullmq-otel: '>=2.0.0' - ioredis: '>=5.0.0' - pg: '>=8.0.0' - redis: '>=5.0.0' - peerDependenciesMeta: - bullmq-otel: - optional: true - ioredis: - optional: true - pg: - optional: true - redis: - optional: true - - busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} - - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - c12@3.3.4: - resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==} - peerDependencies: - magicast: '*' - peerDependenciesMeta: - magicast: - optional: true - - cac@7.0.0: - resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} - engines: {node: '>=20.19.0'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} - - chokidar@5.0.0: - resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} - engines: {node: '>= 20.19.0'} - - citty@0.2.2: - resolution: {integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==} - - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - - cluster-key-slot@1.1.1: - resolution: {integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==} - engines: {node: '>=0.10.0'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - compute-scroll-into-view@3.1.1: - resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} - - concat-stream@2.0.0: - resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} - engines: {'0': node >= 6.0} - - confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - - confbox@0.2.4: - resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} - - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - - content-disposition@1.1.0: - resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} - engines: {node: '>=18'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - content-type@2.1.0: - resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} - engines: {node: '>=18'} - - cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} - - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - - cookie@1.1.1: - resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} - engines: {node: '>=18'} - - cors@2.8.6: - resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} - engines: {node: '>= 0.10'} - - cron-parser@5.10.0: - resolution: {integrity: sha512-izNAxJyRWUP8ljBoDSub5WyrVOUlT4SLGShswE7eoRBpp6QUsSycYxLBMJlbshgPBMcPT/nrfgjNY2918ayv2A==} - engines: {node: '>=18'} - - css-select@7.0.0: - resolution: {integrity: sha512-snmjEVXy+1LnwXdxhYvTMj1d9tOh4HxkA1YmoayVBeeyR2C14Pum7fcxJIm4SswYspVy866eYNwlH6xC3/VH5g==} - engines: {node: '>=20.19.0'} - - css-what@8.0.0: - resolution: {integrity: sha512-DH0Bqq3DNp5tdOReuNyAA+Ev4Y2GS5FMbZpeTLP6C4CDi0h5nL0BmUPChXw3o/qbHLDWHl49sbNqQVY7bMSDdw==} - engines: {node: '>=20.19.0'} - - cssom@0.5.0: - resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - dayjs@1.11.23: - resolution: {integrity: sha512-QDTCU0M0MxR3hQfnlDJfwekQiaanm1ubOD231u73WBckQ/fsamwRLiE2GBz6D3a/xF1NgfiDLJjXBa1hYOYTtQ==} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - define-lazy-prop@2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} - - defu@6.1.7: - resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - denque@2.1.0: - resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} - engines: {node: '>=0.10'} - - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - destr@2.0.5: - resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - - dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - - dom-serializer@3.1.1: - resolution: {integrity: sha512-4MEa38/QexBob6gFNwu+EGdWvhJ1OKuNwdYY3Y3NyeWDQfnGeDYQUDfIRzWu5B5gsv03so2Uxd28YC6zrsx3Lw==} - engines: {node: '>=20.19.0'} - - domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - - domelementtype@3.0.0: - resolution: {integrity: sha512-umCQid3jKbDmVjx8jGaW7uUykm4DEUeyV21hPxNMo2nV955DhUThwqyOIDtreepP31hl84X7G5U9ZfsWvIB3Pg==} - engines: {node: '>=20.19.0'} - - domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - - domhandler@6.0.1: - resolution: {integrity: sha512-gYzvtM72ZtxQO0T048kd6HWSbbGCNOUwcnfQ01cqIJ4X2IYKFFHZ5mKvrQETcFXxsRObZulDaKmy//R7TPtsBg==} - engines: {node: '>=20.19.0'} - - domutils@3.2.2: - resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - - domutils@4.0.2: - resolution: {integrity: sha512-qI4JLRKnSzqFqr7hAlS5xQDusBCjKSEG4t4+7aNrIQMHBcsC2TGEhuyABJdYkgSewL57PNLYEiibY2iPKhKpaA==} - engines: {node: '>=20.19.0'} - - dotenv-expand@13.0.0: - resolution: {integrity: sha512-aBfBS8eYIeXmpHI9ThIlA7/WLq+SLt18iXUZhb52rW89QLKQFoIpPG1bPeewoPZsTyjSSO3T7234FBVUM1V2rA==} - engines: {node: '>=12'} - - dotenv@17.4.2: - resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} - engines: {node: '>=12'} - - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - entities@7.0.1: - resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} - engines: {node: '>=0.12'} - - entities@8.0.0: - resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} - engines: {node: '>=20.19.0'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-object-atoms@1.1.2: - resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - esbuild@0.28.2: - resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} - engines: {node: '>=18'} - hasBin: true - - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - express@5.2.1: - resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} - engines: {node: '>= 18'} - - exsolve@1.1.1: - resolution: {integrity: sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==} - - fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - file-type@22.0.2: - resolution: {integrity: sha512-0H8TsCUGBLx+V5adH3EY52hTAcyLKbV1D4gq5cIOJ6DnQAHeV9Z2Hhuc5CoBX4YmvB2oL+JIC84z0qO7JsCoNw==} - engines: {node: '>=22'} - - filesize@11.0.22: - resolution: {integrity: sha512-RlCVs9CY+oSsRnNZn95J9vDXjNjOwddKyTFjOYtA4yxYVIxBnwiVVGJX+TFhsmu3uUf81JDGyijtYL9xgawlTw==} - engines: {node: '>= 10.8.0'} - - finalhandler@2.1.1: - resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} - engines: {node: '>= 18.0.0'} - - follow-redirects@1.16.0: - resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - form-data@4.0.6: - resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} - engines: {node: '>= 6'} - - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - giget@3.3.1: - resolution: {integrity: sha512-r+mvuDjrjMpsdw46Kmeydb8bdHm7wOKw8wNBtTndkjbPjgAp5oUJUxRE76wZFknxIPokfWvep2qSXK37aXE6zg==} - hasBin: true - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.4: - resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} - engines: {node: '>= 0.4'} - - hookable@6.1.1: - resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} - - html-escaper@3.0.3: - resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} - - htmlparser2@10.1.0: - resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} - - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} - - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - - iconv-lite@0.7.3: - resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} - engines: {node: '>=0.10.0'} - - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ioredis@6.0.0: - resolution: {integrity: sha512-f+Dtubxfpf6KYFq7WVXJoOLn0bk4TJrMrN9SzeE+jrWrCWj7XX3fA6vkryafhADX+GMymRxgDJDOI33COkJc0w==} - engines: {node: '>=20.0.0'} - - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-mobile@5.0.0: - resolution: {integrity: sha512-Tz/yndySvLAEXh+Uk8liFCxOwVH6YutuR74utvOcu7I9Di+DwM0mtdPVZNaVvvBUM2OXxne/NhOs1zAO7riusQ==} - - is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - - is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - - iterare@1.2.1: - resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} - engines: {node: '>=6'} - - jiti@2.7.0: - resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} - hasBin: true - - js-tokens@10.0.0: - resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} - - json2mq@0.2.0: - resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==} - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - lightningcss-android-arm64@1.33.0: - resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-darwin-arm64@1.33.0: - resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.33.0: - resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.33.0: - resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.33.0: - resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.33.0: - resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - lightningcss-linux-arm64-musl@1.33.0: - resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - lightningcss-linux-x64-gnu@1.33.0: - resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - lightningcss-linux-x64-musl@1.33.0: - resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - lightningcss-win32-arm64-msvc@1.33.0: - resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.33.0: - resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.33.0: - resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} - engines: {node: '>= 12.0.0'} - - linkedom@0.18.13: - resolution: {integrity: sha512-ES/o9qotMpzpN2MHs+Iq/JcVoOj8Fa5wiQYrTdFpvAnwXL0g66XHHUc9WUMk6nAlBtGsFQ24ne+SYnvnaQ2FSw==} - engines: {node: '>=16'} - peerDependencies: - canvas: '>= 2' - peerDependenciesMeta: - canvas: - optional: true - - load-esm@1.0.3: - resolution: {integrity: sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==} - engines: {node: '>=13.2.0'} - - local-pkg@1.2.1: - resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} - engines: {node: '>=14'} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - luxon@3.7.2: - resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} - engines: {node: '>=12'} - - magic-string@1.2.3: - resolution: {integrity: sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==} - - magicast@0.5.4: - resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} - - many-keys-map@3.0.3: - resolution: {integrity: sha512-1DiZmDHPXMBgMRjeUtHy1q1VYmeJscHxhIAexX9z/zjRMP80+0ETuPfssi8z+kMY4DwUgsKuHqpjxgmeA9gBNA==} - engines: {node: '>=18'} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - media-typer@1.1.1: - resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} - engines: {node: '>= 0.8'} - - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} - - mlly@1.8.2: - resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - msgpackr-extract@3.0.4: - resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==} - hasBin: true - - msgpackr@2.1.0: - resolution: {integrity: sha512-p/pBCVO63CsvvpkomUnNNag6+n38rULuDA6HHe70o2gtC8ODI52foF/4ko2qQcp6OiErJXTmrZeXmsGGHsIQNQ==} - - multer@2.2.0: - resolution: {integrity: sha512-6rdyFg2kLrMh9Jee7/BMPuV9lEAd7lLW2YUpF9/YxR7njyoUwwQ0ZPh3TaIY50Sw6vlyD2HW3wGOkTS4P79xrQ==} - engines: {node: '>= 10.16.0'} - - nanoid@3.3.18: - resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - negotiator@1.1.0: - resolution: {integrity: sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==} - engines: {node: '>=18'} - - node-abort-controller@3.1.1: - resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} - - node-gyp-build-optional-packages@5.2.2: - resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} - hasBin: true - - nth-check@3.0.1: - resolution: {integrity: sha512-GX0gsdbGVCgnRgbeGaubfjpBXyYRWOOCVeYh08bSQvDZqxz5ndXs1OTfAt/h36G1xvI94YIspsI0sVFqAV9+RQ==} - engines: {node: '>=20.19.0'} - - nypm@0.6.9: - resolution: {integrity: sha512-zxlE2yvSWZWmHcNdT3+5zV2lrCogeE9YOklHrR3dFjqutq5wO7GFDYLFDRXLsYnJzwvy/im9fYoxePvS0VTW0w==} - engines: {node: '>=18'} - hasBin: true - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - ohash@2.0.12: - resolution: {integrity: sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - open@8.4.2: - resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} - engines: {node: '>=12'} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - path-to-regexp@8.4.2: - resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - perfect-debounce@2.1.0: - resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} - - pg-cloudflare@1.4.0: - resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==} - - pg-connection-string@2.14.0: - resolution: {integrity: sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==} - - pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} - - pg-pool@3.14.0: - resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==} - peerDependencies: - pg: '>=8.0' - - pg-protocol@1.16.0: - resolution: {integrity: sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==} - - pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} - - pg@8.23.0: - resolution: {integrity: sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==} - engines: {node: '>= 16.0.0'} - peerDependencies: - pg-native: '>=3.0.1' - peerDependenciesMeta: - pg-native: - optional: true - - pgpass@1.0.5: - resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} - engines: {node: '>=8.6'} - - picomatch@4.0.7: - resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} - engines: {node: '>=12'} - - pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - - pkg-types@2.3.1: - resolution: {integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==} - - postcss@8.5.26: - resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} - engines: {node: ^10 || ^12 || >=14} - - postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} - - postgres-bytea@1.0.1: - resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} - engines: {node: '>=0.10.0'} - - postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} - - postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} - - prettier@3.9.6: - resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==} - engines: {node: '>=14'} - hasBin: true - - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - - proxy-from-env@2.1.0: - resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} - engines: {node: '>=10'} - - publish-browser-extension@6.1.1: - resolution: {integrity: sha512-ovfBOz+cZIOBHZ+oxTfpv1kSGU7ruzy8CXoFGvhXsUbJuty45srGzf1ufEePs69virOWXfFbhZRoNQUdgPvwXA==} - engines: {node: '>=22.0.0'} - hasBin: true - - qs@6.16.0: - resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==} - engines: {node: '>=0.6'} - - quansync@0.2.11: - resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} - - range-parser@1.3.0: - resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} - engines: {node: '>= 0.6'} - - raw-body@3.0.2: - resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} - engines: {node: '>= 0.10'} - - rc9@3.0.1: - resolution: {integrity: sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==} - - react-dom@19.2.8: - resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==} - peerDependencies: - react: ^19.2.8 - - react-is@19.2.8: - resolution: {integrity: sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==} - - react-router-dom@7.18.3: - resolution: {integrity: sha512-ytVbyBBM7vMfRCam25r0WMhSVSom909A8p+8m0/f1w853dz/xfFu6etAT2SEbVoSnI+ZoPRDqIsQXVT89gp7kg==} - engines: {node: '>=20.0.0'} - peerDependencies: - react: '>=18' - react-dom: '>=18' - - react-router@7.18.3: - resolution: {integrity: sha512-gyXgtdr5uACJ5b1Q4udzjVV+tb/rlHIMJKuJ0e89R4Kzgz47z/rgP0dIKxktqIEUhDHluGTPJJH/wRha7CyqsA==} - engines: {node: '>=20.0.0'} - peerDependencies: - react: '>=18' - react-dom: '>=18' - peerDependenciesMeta: - react-dom: - optional: true - - react@19.2.8: - resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==} - engines: {node: '>=0.10.0'} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - readdirp@5.1.1: - resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} - engines: {node: '>= 20.19.0'} - - redis-errors@1.2.0: - resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} - engines: {node: '>=4'} - - reflect-metadata@0.2.2: - resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - rolldown@1.2.6: - resolution: {integrity: sha512-vMM4q3aixf46GiF1Kok8jDPFsEpXgFWGjUHXNkNHNm+Y2adXAG2dbX91jkti3i0ZRsOlcmbuzAz1poObSHCmUA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} - - rxjs@7.8.2: - resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - - scroll-into-view-if-needed@3.1.0: - resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} - - scule@1.3.0: - resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - - semver@7.8.5: - resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} - engines: {node: '>=10'} - hasBin: true - - send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} - - serve-static@2.2.1: - resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} - engines: {node: '>= 18'} - - set-cookie-parser@2.7.2: - resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.1: - resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} - engines: {node: '>= 0.4'} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} - - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - - standard-as-callback@2.1.0: - resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} - - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - - string-convert@0.2.1: - resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-literal@4.0.0: - resolution: {integrity: sha512-PaqAvfUZKBwc/SLmNZtHmzK+v19Z4O4eS3cKPeGvbIv/U3pnyEq4Tuw3/4v/FwfM8VQaEawsyCcOQ0P+kpwWWw==} - - strtok3@10.3.5: - resolution: {integrity: sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==} - engines: {node: '>=18'} - - stylis@4.4.0: - resolution: {integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==} - - superlock@1.3.5: - resolution: {integrity: sha512-XpWNthvezZnWp0u7/UL8rBbBOnq2Qx39fw+0RNMC/+eotOd81glzsmIWVH0ejarhTeDQihxOKSbjm2XXFo5a8w==} - engines: {node: '>= 14'} - - tasuku@2.3.0: - resolution: {integrity: sha512-9Jtk+XAnttslCw4i9RceSZGr2PT5TLn0vUyWnoP2SdlSYzkiYRY6kB5qnPi5IQ/Em8e4oBow1rpaA39iijTIrA==} - - throttle-debounce@5.0.2: - resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} - engines: {node: '>=12.22'} - - tiny-open@1.3.0: - resolution: {integrity: sha512-GUFS8yjJZq0oWqCKCJVHcBgMpmi2WEGXY1le3E5ncR0DsgTII5uUyxtfk8/vGyDDGBE42UYHR6Ocvlk8mkXSRg==} - - tinyexec@1.3.0: - resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==} - engines: {node: '>=18'} - - tinyglobby@0.2.17: - resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} - engines: {node: '>=12.0.0'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - token-types@6.1.2: - resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} - engines: {node: '>=14.16'} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - tsx@4.23.13: - resolution: {integrity: sha512-BL5MGkRln6aDYhb0xbQlEAGw743BaZYWdbWtdJOBriYJboKgUUYCadFp2/FpBBZquBC/ezNBn7wMMPx7FDZUDw==} - engines: {node: '>=18.0.0'} - hasBin: true - - turbo@2.10.12: - resolution: {integrity: sha512-AswgMPnpOoaVZHrrSBejETzEbuIA69OVGwfkHwfrY0A23VjWXBANzgq9+OymWOHAIArB7D1+1z498WY8fGg1Jw==} - hasBin: true - - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - - type-is@2.1.0: - resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} - engines: {node: '>= 18'} - - typedarray@0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - - typescript@7.0.2: - resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} - engines: {node: '>=16.20.0'} - hasBin: true - - ufo@1.6.4: - resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} - - uhyphen@0.2.0: - resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==} - - uid@2.0.2: - resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} - engines: {node: '>=8'} - - uint8array-extras@1.5.0: - resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} - engines: {node: '>=18'} - - undici-types@8.3.0: - resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} - - unimport@6.4.0: - resolution: {integrity: sha512-JJOOuNMFq8b4ZPBKwQUxEcba4MplskDzYI1Lvrf8rJfWphZTWvPNXWa493qsPngHUmub89w6C7j+SeLWTE/UIQ==} - engines: {node: '>=18.12.0'} - peerDependencies: - oxc-parser: '*' - rolldown: ^1.0.0 - peerDependenciesMeta: - oxc-parser: - optional: true - rolldown: - optional: true - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - unplugin-utils@0.3.2: - resolution: {integrity: sha512-xVToRh2CTmLk2HnEG7ac4rl1MJTT3RFkpS8B++/SnB0kXvuaavD+n3m/vrzyWQOdJNSZQACnbz01pnppbwV5BA==} - engines: {node: '>=20.19.0'} - - unplugin@3.3.0: - resolution: {integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==} - engines: {node: ^20.19.0 || >=22.12.0} - peerDependencies: - '@farmfe/core': '*' - '@rspack/core': '*' - bun-types-no-globals: '*' - esbuild: '*' - rolldown: '*' - rollup: '*' - unloader: '*' - vite: '*' - webpack: '*' - peerDependenciesMeta: - '@farmfe/core': - optional: true - '@rspack/core': - optional: true - bun-types-no-globals: - optional: true - esbuild: - optional: true - rolldown: - optional: true - rollup: - optional: true - unloader: - optional: true - vite: - optional: true - webpack: - optional: true - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - vite@8.2.2: - resolution: {integrity: sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.4.0 || ^0.5.0 - esbuild: ^0.27.0 || ^0.28.0 - jiti: '>=1.21.0' - less: ^4.0.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - '@vitejs/devtools': - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - webpack-virtual-modules@0.6.2: - resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - wxt@0.21.4: - resolution: {integrity: sha512-iyVMTXb37BQAbsPHCuPzrK3ZxnO9pZmvbKl7VJWIHe3RG40On2NyP2FOjArtOITO96plEYnh3o+iUlRp9qE90w==} - engines: {bun: '>=1.2.0', node: '>=22'} - hasBin: true - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=5.4' - vite: ^6.3.4 || ^7.0.0 || ^8.0.0-0 - web-ext: '>=9.2.0' - peerDependenciesMeta: - eslint: - optional: true - typescript: - optional: true - web-ext: - optional: true - - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs@17.7.3: - resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} - engines: {node: '>=12'} - - zod@4.5.4: - resolution: {integrity: sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==} + '@1natsu/wait-element@4.2.0': + resolution: + { + integrity: sha512-Om0Q+WE9mNrpY4AwMTvkFiYHv8VM7TML3PvOqXy+w6kAjLjKhGYHYX+305+a6J8RVpds9s7IF2Z5aOPYwULFNw==, + } + + '@aklinker1/rollup-plugin-visualizer@5.12.0': + resolution: + { + integrity: sha512-X24LvEGw6UFmy0lpGJDmXsMyBD58XmX1bbwsaMLhNoM+UMQfQ3b2RtC+nz4b/NoRK5r6QJSKJHBNVeUdwqybaQ==, + } + engines: { node: '>=14' } + hasBin: true + peerDependencies: + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rollup: + optional: true + + '@aklinker1/zero-zip@1.0.1': + resolution: + { + integrity: sha512-07a596Bd1QO0bi3tIyt2xruq6vKk7hCUt9enHBwggvipB0iiycoJ9/CqzN6UFawaKbOi6NBfMlUxUXzIOZ7Dsg==, + } + + '@ant-design/colors@8.0.1': + resolution: + { + integrity: sha512-foPVl0+SWIslGUtD/xBr1p9U4AKzPhNYEseXYRRo5QSzGACYZrQbe11AYJbYfAWnWSpGBx6JjBmSeugUsD9vqQ==, + } + + '@ant-design/cssinjs-utils@2.1.2': + resolution: + { + integrity: sha512-5fTHQ158jJJ5dC/ECeyIdZUzKxE/mpEMRZxthyG1sw/AKRHKgJBg00Yi6ACVXgycdje7KahRNvNET/uBccwCnA==, + } + peerDependencies: + react: '>=18' + react-dom: '>=18' + + '@ant-design/cssinjs@2.1.2': + resolution: + { + integrity: sha512-2Hy8BnCEH31xPeSLbhhB2ctCPXE2ZnASdi+KbSeS79BNbUhL9hAEe20SkUk+BR8aKTmqb6+FKFruk7w8z0VoRQ==, + } + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@ant-design/fast-color@3.0.1': + resolution: + { + integrity: sha512-esKJegpW4nckh0o6kV3Tkb7NPIZYbPnnFxmQDUmL08ukXZAvV85TZBr70eGuke/CIArLaP6aw8lt9KILjnWuOw==, + } + engines: { node: '>=8.x' } + + '@ant-design/icons-svg@4.6.0': + resolution: + { + integrity: sha512-PRomU725ABMf/lnQp5HiB7my1kjEbFY0D10N4lXYxK6TIB1gKjIVD5MRThpDaezLgw1D774J8eOeeDB0M6wHrQ==, + } + + '@ant-design/icons@6.3.4': + resolution: + { + integrity: sha512-kDoUlppczVyCUTFthF6cHmPzMBYqNZQhu9j6EyIX/YIdM9j9CZNZoJUjzVw7/1v1VO8WwVMmPp15r/uwIAS0AQ==, + } + engines: { node: '>=8' } + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@ant-design/react-slick@2.0.0': + resolution: + { + integrity: sha512-HMS9sRoEmZey8LsE/Yo6+klhlzU12PisjrVcydW3So7RdklyEd2qehyU6a7Yp+OYN72mgsYs3NFCyP2lCPFVqg==, + } + peerDependencies: + react: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@babel/helper-string-parser@7.29.7': + resolution: + { + integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==, + } + engines: { node: '>=6.9.0' } + + '@babel/helper-validator-identifier@7.29.7': + resolution: + { + integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==, + } + engines: { node: '>=6.9.0' } + + '@babel/parser@7.29.8': + resolution: + { + integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==, + } + engines: { node: '>=6.0.0' } + hasBin: true + + '@babel/runtime@7.29.7': + resolution: + { + integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==, + } + engines: { node: '>=6.9.0' } + + '@babel/runtime@8.0.0': + resolution: + { + integrity: sha512-sL6cvO2IfkSu/iU+zs2S/w01B7A8V7suXSIKEN4hPFFdZoiPGxrj5pAG0lCaqLWiEIrjKzdznIWuaLcxPR53qw==, + } + + '@babel/types@7.29.8': + resolution: + { + integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==, + } + engines: { node: '>=6.9.0' } + + '@borewit/text-codec@0.2.2': + resolution: + { + integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==, + } + + '@emotion/hash@0.8.0': + resolution: + { + integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==, + } + + '@emotion/unitless@0.7.5': + resolution: + { + integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==, + } + + '@esbuild/aix-ppc64@0.28.2': + resolution: + { + integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==, + } + engines: { node: '>=18' } + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.2': + resolution: + { + integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==, + } + engines: { node: '>=18' } + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.2': + resolution: + { + integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==, + } + engines: { node: '>=18' } + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: + { + integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==, + } + engines: { node: '>=18' } + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.2': + resolution: + { + integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==, + } + engines: { node: '>=18' } + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.2': + resolution: + { + integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==, + } + engines: { node: '>=18' } + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.2': + resolution: + { + integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==, + } + engines: { node: '>=18' } + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: + { + integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==, + } + engines: { node: '>=18' } + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.2': + resolution: + { + integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==, + } + engines: { node: '>=18' } + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: + { + integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==, + } + engines: { node: '>=18' } + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.2': + resolution: + { + integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==, + } + engines: { node: '>=18' } + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.2': + resolution: + { + integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==, + } + engines: { node: '>=18' } + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.2': + resolution: + { + integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==, + } + engines: { node: '>=18' } + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.2': + resolution: + { + integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==, + } + engines: { node: '>=18' } + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: + { + integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==, + } + engines: { node: '>=18' } + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: + { + integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==, + } + engines: { node: '>=18' } + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: + { + integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==, + } + engines: { node: '>=18' } + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.2': + resolution: + { + integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==, + } + engines: { node: '>=18' } + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.2': + resolution: + { + integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==, + } + engines: { node: '>=18' } + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.2': + resolution: + { + integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==, + } + engines: { node: '>=18' } + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.2': + resolution: + { + integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==, + } + engines: { node: '>=18' } + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.2': + resolution: + { + integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==, + } + engines: { node: '>=18' } + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.2': + resolution: + { + integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==, + } + engines: { node: '>=18' } + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.2': + resolution: + { + integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==, + } + engines: { node: '>=18' } + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.2': + resolution: + { + integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==, + } + engines: { node: '>=18' } + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: + { + integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==, + } + engines: { node: '>=18' } + cpu: [x64] + os: [win32] + + '@ioredis/commands@2.0.0': + resolution: + { + integrity: sha512-vrx0AE/T0h7cRZwfo1M39Cr+ZhZrkf0V8mQN75wucKCxCLD9l/VX6no3gFvrLqD1IlG/1LtzWovqEw3t0Vr9zg==, + } + + '@jridgewell/gen-mapping@0.3.13': + resolution: + { + integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==, + } + + '@jridgewell/remapping@2.3.5': + resolution: + { + integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==, + } + + '@jridgewell/resolve-uri@3.1.2': + resolution: + { + integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, + } + engines: { node: '>=6.0.0' } + + '@jridgewell/sourcemap-codec@1.6.0': + resolution: + { + integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==, + } + + '@jridgewell/trace-mapping@0.3.31': + resolution: + { + integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==, + } + + '@lukeed/csprng@1.1.0': + resolution: + { + integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==, + } + engines: { node: '>=8' } + + '@microsoft/tsdoc@0.16.0': + resolution: + { + integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==, + } + + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': + resolution: + { + integrity: sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==, + } + cpu: [arm64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': + resolution: + { + integrity: sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==, + } + cpu: [x64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': + resolution: + { + integrity: sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==, + } + cpu: [arm64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': + resolution: + { + integrity: sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==, + } + cpu: [arm] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': + resolution: + { + integrity: sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==, + } + cpu: [x64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': + resolution: + { + integrity: sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==, + } + cpu: [x64] + os: [win32] + + '@nestjs/common@12.0.1': + resolution: + { + integrity: sha512-v0zTaRCTV2K2xSnb3GnJoQKtaR6VxouJtm+P2gpr5w61dlXeWpXl1WVknCSzUqx2QwTV10tBkHETxvQvkf2Exg==, + } + peerDependencies: + class-transformer: '>=0.4.1' + class-validator: '>=0.13.2' + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + + '@nestjs/config@12.0.0': + resolution: + { + integrity: sha512-pG5+fFfCo3cdgVkLJLvvhUGfxEjwzv9hIAQ1aJVHvHlHVniDWfwX5pR/utgoAkJzSikv2oTR1BmIF03FXdi42Q==, + } + peerDependencies: + '@nestjs/common': ^11.0.0 || ^12.0.0 + rxjs: ^7.1.0 + + '@nestjs/core@12.0.1': + resolution: + { + integrity: sha512-rU6tAi8vDdyzHgN0iW0J4UJvziroOqzHqzlqL7phOSPizaXVEePfv+OUOsdJEOh0Qd14mslc3udOheLrAEcZow==, + } + engines: { node: '>= 20' } + peerDependencies: + '@nestjs/common': ^12.0.0 + '@nestjs/microservices': ^12.0.0 + '@nestjs/platform-express': ^12.0.0 + '@nestjs/websockets': ^12.0.0 + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + '@nestjs/microservices': + optional: true + '@nestjs/platform-express': + optional: true + '@nestjs/websockets': + optional: true + + '@nestjs/mapped-types@12.0.0': + resolution: + { + integrity: sha512-aX7lxZcqXldtnSr0bgT2ZPQvpTpIwBMW1GMX29o4s3q02vmq6JoTYuPW0GwYXa8BiFMRX7WbGZVDA703pNqOMQ==, + } + engines: { node: '>=20.19.0' } + peerDependencies: + '@nestjs/common': ^10.0.0 || ^11.0.0 || ^12.0.0 + class-transformer: ^0.4.0 || ^0.5.0 + class-validator: ^0.13.0 || ^0.14.0 || ^0.15.0 + reflect-metadata: ^0.1.12 || ^0.2.0 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + + '@nestjs/platform-express@12.0.1': + resolution: + { + integrity: sha512-nF8bRgROptMyixYBfiJUAsjj2o9k13zxAjUKYaqHTPk8mTSd+gk7hXz6NykXNrfHWmMEYC9RttQlMUdMHNTbuA==, + } + peerDependencies: + '@nestjs/common': ^12.0.0 + '@nestjs/core': ^12.0.0 + + '@nestjs/swagger@12.0.1': + resolution: + { + integrity: sha512-fQ0WyutSSHedO9HzSkOFKFaRygYNGBno5EggcZljs+KL8tHzPPTO5oyJpaf3BoOKFGGsN/0B13EbIpH2pkPx8g==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + peerDependencies: + '@fastify/static': ^8.0.0 || ^9.0.0 || ^10.0.0 + '@nestjs/common': ^12.0.0 + '@nestjs/core': ^12.0.0 + class-transformer: '*' + class-validator: '*' + reflect-metadata: ^0.1.12 || ^0.2.0 + peerDependenciesMeta: + '@fastify/static': + optional: true + class-transformer: + optional: true + class-validator: + optional: true + + '@oxc-project/types@0.147.0': + resolution: + { + integrity: sha512-IJ3s6ltHLp45S0bh7phkX+gJO7A1Wuz2EaqpAhb8WjqDwbzMiWKHhyyT42tskaWjEYXtHtVCPpnBJVT9+dcRLg==, + } + + '@rc-component/async-validator@6.0.0': + resolution: + { + integrity: sha512-D3AGQwdyE58gmvx6waVSXJ80JGO+IY5L2O8HDnSOex7JNlzB3GuN/4hyHNTdhy2qtOhkpbIjmeAN3tL993wKbA==, + } + engines: { node: '>=14.x' } + + '@rc-component/cascader@1.22.0': + resolution: + { + integrity: sha512-SffrA57aS9oub3VuI7ajPhJTPtaNxngSvtRhD40Rd8dwJ5vfWPSrVanWgeepdWFGBt7EHftIK5RUU0u3rCTwWw==, + } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/checkbox@2.0.0': + resolution: + { + integrity: sha512-3CXGPpAR9gsPKeO2N78HAPOzU30UdemD6HGJoWVJOpa6WleaGB5kzZj3v6bdTZab31YuWgY/RxV3VKPctn0DwQ==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/collapse@1.2.0': + resolution: + { + integrity: sha512-ZRYSKSS39qsFx93p26bde7JUZJshsUBEQRlRXPuJYlAiNX0vyYlF5TsAm8JZN3LcF8XvKikdzPbgAtXSbkLUkw==, + } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/color-picker@3.1.1': + resolution: + { + integrity: sha512-OHaCHLHszCegdXmIq2ZRIZBN/EtpT6Wm8SG/gpzLATHbVKc/avvuKi+zlOuk05FTWvgaMmpxAko44uRJ3M+2pg==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/context@2.0.2': + resolution: + { + integrity: sha512-uiGpAlblCNlziHPwj4S4Iy/oemeuz/hR03mbiEjTCXwsqOIN3BOzsRMyDwpyO5Fm0vIEEJRUf9ZtbRLbhksuTA==, + } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/dialog@1.10.0': + resolution: + { + integrity: sha512-eDukNlz9vNszAGv7i3zKXdxEd3wgVmNxuJijYt8zvTh17QwTu8KK/bdURRd/lU4qaMzhO1HKKmMrwOnkaw0BvQ==, + } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/drawer@1.4.2': + resolution: + { + integrity: sha512-1ib+fZEp6FBu+YvcIktm+nCQ+Q+qIpwpoaJH6opGr4ofh2QMq+qdr5DLC4oCf5qf3pcWX9lUWPYX652k4ini8Q==, + } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/dropdown@1.0.3': + resolution: + { + integrity: sha512-YTST/N6kpqpDz3IMuM/PSSZnrDpSOA6dgHv12gPA90ZTSLv2CoqkZ0+9NtwTY6BeO7dstPblSic2QJg7dSFy/g==, + } + peerDependencies: + react: '>=16.11.0' + react-dom: '>=16.11.0' + + '@rc-component/form@1.8.6': + resolution: + { + integrity: sha512-1EXVsSKPZC6kGrIqxVck7kAWM6T65b6et/n5wIcyiaIa41VrDshD0nVLHoBDEIZr2ATQsOP6icb4XQkNFMLBAw==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/image@1.10.0': + resolution: + { + integrity: sha512-BjeZCRQ+hw+4WAhvrw8rJvy5fckA2xpf/X2XQEOABUHvLTNB9inB98X3Mp54jYQ7g10DfWERQWHXeC4ylxp1Uw==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/input-number@1.6.2': + resolution: + { + integrity: sha512-Gjcq7meZlCOiWN1t1xCC+7/s85humHVokTBI7PJgTfoyw5OWF74y3e6P8PHX104g9+b54jsodFIzyaj6p8LI9w==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/input@1.3.1': + resolution: + { + integrity: sha512-iFvTUT9W+JC/MSin2aGAk8NqsVlTzcExNC9DZariON1IWirju9NoNeEk47an4Q8iHazkoVI/y1LnDi88+CPcig==, + } + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@rc-component/listy@1.2.3': + resolution: + { + integrity: sha512-IXiMjV5s0rczLBlfh7G5nB4M3365mrEeedjwKtf5I+Ns3PqRUsebR2h5u8CeFarsVfLUPC2I5p0h09TNoOWyvQ==, + } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/mentions@1.12.0': + resolution: + { + integrity: sha512-v5MBx8zDcqCT+uybJgKpcx3Fgrvj0m3u+A/15RlSBaMx12lLoJZTTYggC3pbYYfohcKujWWUyBz6O6Gp2vGiNA==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/menu@1.5.0': + resolution: + { + integrity: sha512-RjvzPsZkwVEg3xu+/jDDqDeUCBJAnWylONFlGeQgg5enlNAnlpybqhaMGE/UPEIvr6hL90PGhjFBguJqj0Qb2Q==, + } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/mini-decimal@1.1.4': + resolution: + { + integrity: sha512-xiuXcaCwyOWpD8a8scdExFl+bntNphAW8XeenL1ig2en0AAZY0Pcp4pC0dI22qJ+NvxKn9RoNIoRdqYU3BLH4w==, + } + engines: { node: '>=8.x' } + + '@rc-component/motion@1.3.3': + resolution: + { + integrity: sha512-Xh3IszxvlSv3/PLYFyC2UZi9LNB83yOnkB/LNmRzaypZLvkhqUIPS7MQpGZcCMWrNsXV2p6YTSWbSGvFpEle9A==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/mutate-observer@2.0.1': + resolution: + { + integrity: sha512-AyarjoLU5YlxuValRi+w8JRH2Z84TBbFO2RoGWz9d8bSu0FqT8DtugH3xC3BV7mUwlmROFauyWuXFuq4IFbH+w==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/notification@2.0.8': + resolution: + { + integrity: sha512-MTRA3b8eHE14gh5R9nlXzbWZEDEBFVkEHj/FI1VOXw2zrSnSxqbuuU3drsq+k53e6MHwtegoFay1tnNYhtl61Q==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/overflow@1.0.1': + resolution: + { + integrity: sha512-syfmgAABaHCnCDzPwHZ/2tuvIcpOO3jefYZMmfkN+pmo8HKTzsfhS57vxo4ksPdN0By+uWVJhJWNFozNBxi2eA==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/pagination@1.4.0': + resolution: + { + integrity: sha512-CW1g7P9V8u+e8JQdUsl2RWg+GCsoee0mtJjZUCCxn/vb3jzOwDKm6hAdwddHCVBfWJ58eGUBZz3IvnU8rRktjw==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/picker@1.12.0': + resolution: + { + integrity: sha512-0FZGgDiDZFMm2hcfGv4jyjm7yWIj2MiwfeTzLL0vWkO+8cCSKdiM9XhWpkn1aAsoI2EwUy48Oz2cGfvL8ZKrfw==, + } + engines: { node: '>=12.x' } + peerDependencies: + date-fns: '>= 2.x' + dayjs: '>= 1.x' + luxon: '>= 3.x' + moment: '>= 2.x' + react: '>=16.9.0' + react-dom: '>=16.9.0' + peerDependenciesMeta: + date-fns: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + + '@rc-component/portal@2.2.1': + resolution: + { + integrity: sha512-ck+r1kW/JSv0wxPji3KN2ss9K6Z0qqwusw/mf/0JobXhZ8hC2ejZwCJObW/SvDi0uhA0VzmCnx0CaCci95tcmA==, + } + engines: { node: '>=12.x' } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/progress@1.0.3': + resolution: + { + integrity: sha512-Q1nPLIvKr95el/q76yaBh5nv1hqCsWaHQb8U7vXEDMefEhHgM7n3CPoN+o4LHnTyANQHmMFgoS/naAT4Bhxuaw==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/qrcode@2.0.0': + resolution: + { + integrity: sha512-aAv3QhPP1xyafuTZOxub6a54pCeBnN3IwQkpETrBtthq4BL5IgxnCbuoBWPDpdLw1y1j6BgBUCAKV92+yX06Dw==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/rate@1.0.1': + resolution: + { + integrity: sha512-bkXxeBqDpl5IOC7yL7GcSYjQx9G8H+6kLYQnNZWeBYq2OYIv1MONd6mqKTjnnJYpV0cQIU2z3atdW0j1kttpTw==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/resize-observer@1.1.2': + resolution: + { + integrity: sha512-t/Bb0W8uvL4PYKAB3YcChC+DlHh0Wt5kM7q/J+0qpVEUMLe7Hk5zuvc9km0hMnTFPSx5Z7Wu/fzCLN6erVLE8Q==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/segmented@1.3.0': + resolution: + { + integrity: sha512-5J/bJ01mbDnoA6P/FW8SxUvKn+OgUSTZJPzCNnTBntG50tzoP7DydGhqxp7ggZXZls7me3mc2EQDXakU3iTVFg==, + } + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@rc-component/select@1.10.1': + resolution: + { + integrity: sha512-H+yQsl+qED9NilQ3g6zdpsMwUgwVjrcMTkNHAWRVU/MoNCYgTbDgU+MIMgZDK+rVdd2JUfI/MkysMcZZ0cyQKw==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '*' + react-dom: '*' + + '@rc-component/slider@1.1.1': + resolution: + { + integrity: sha512-LSzgWGYDgeCDgR4r1XlU29gbYws6HpLnvJd/uMhLeW/vQgxldeR+Wb4uzHDCHiYEbr1bnEHWdjkPxjJRHxuiig==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/steps@1.2.3': + resolution: + { + integrity: sha512-/b9gHcvDGjTDWJZW7+1kKFvzs0jrEeQ8mFvvIgX+h7xNT0FsOYODJYKjyJR4fPbvMBCfCOEqaBK66HBxov5BQA==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/switch@1.0.3': + resolution: + { + integrity: sha512-Jgi+EbOBquje/XNdofr7xbJQZPYJP+BlPfR0h+WN4zFkdtB2EWqEfvkXJWeipflwjWip0/17rNbxEAqs8hVHfw==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/table@1.11.1': + resolution: + { + integrity: sha512-OWdS6DMmeWb7bJBGqPxYZpQbzBlBiXZUu2sqo6Ii7Sjs9GeK1IsrXrWk26SL2c6KEseabswdxrRj7WUm9LdECw==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/tabs@1.13.0': + resolution: + { + integrity: sha512-3FXr+9ZII8tFLWuDWrgjRaxZd2mazkKJAGRFEfVmp4r1qnBglOlxQ78l54Td1aj6/iFaaEReKSAF2HToztU5uw==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/tooltip@1.5.2': + resolution: + { + integrity: sha512-VLq4BclU3LgRe46g2hTr2bdsM8tFYs7dVwpuD88rPNNg4lCGe8mBSS4FiRzYzS+ffnZ46y4SI8KYKo9K7qBnhw==, + } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/tour@2.4.0': + resolution: + { + integrity: sha512-aui4r4TqmTzwaBgcQxHYep8kM8PTjZFufjokObpy35KfFeZ0k9ArquWFZqegQlH24P14t+F0qO0mGTgzlav1yg==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/tree-select@1.16.1': + resolution: + { + integrity: sha512-a1Oi6EJhqAhdOxxupdJi6fP0RPHMKn5TcfkX2+llaQ4lF4nwfH7b6SCHcnsybaa2s+pk1yZYwVyeOYkDnEBRdg==, + } + peerDependencies: + react: '*' + react-dom: '*' + + '@rc-component/tree@1.4.0': + resolution: + { + integrity: sha512-dGsJGDJQedA0BqqVgj3F8BvHXTSZijyhTXdbAdkcx8lynzZkty/CV3Z3LOm/fxz+BCfl3dfGiAQpb7Q5XNvl0Q==, + } + engines: { node: '>=10.x' } + peerDependencies: + react: '*' + react-dom: '*' + + '@rc-component/trigger@3.10.1': + resolution: + { + integrity: sha512-mXlDN0IXdtV8Yqqm8195ECCyrbmfvvfKvwVvSlH0+qvKD6BUF8gRhEjSy0FOcD1+CcDRHgTiX99LoxfQrmh3Cw==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/upload@1.1.1': + resolution: + { + integrity: sha512-GvYWSKeaJTOxxC5p6+nOSadzfvXA1h8C/iHFPFZX+szH3JUXrvs+DLiW8YUTBgvMh8m63mJeHrlYlJzAlg+pDA==, + } + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/util@1.13.0': + resolution: + { + integrity: sha512-IXf2zBfZrbQGT+G8LxnoICDBGnMHIPIiq5HCRn3EDfKUx28x1rnbZBj46ULJf4sM8ImTG1SepqfNBdxZziqQ4w==, + } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rc-component/virtual-list@1.5.1': + resolution: + { + integrity: sha512-boqHxdtyWC88u8quYgEO49bcBy5fzRiOcnBge+N4nLzs2k8hUQ/yw7JE9dM6yCBE4jSm5YSHVCVMS+suBuJGKA==, + } + engines: { node: '>=8.x' } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@rolldown/binding-android-arm-eabi@1.2.6': + resolution: + { + integrity: sha512-b+jTcARdTiFLI6jB4a5XjTm0RWd6KcRfQj/I2356fxUZemiho9zQLxo0RtCuMDAyKcLo6cEltkgbQp6d1+sjjQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm] + os: [android] + + '@rolldown/binding-android-arm64@1.2.6': + resolution: + { + integrity: sha512-lkWU8ZJaRk9q3CIEY1Tc7vIFALp3Xw5NfGJo2hQg5oIqNgxWi1zI+IiDEK3r70BF5Dzol1tcXsnzsRc8NLhG+Q==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.6': + resolution: + { + integrity: sha512-dgR56NYnvAszm7Ob1B2/Vn0e8bUQYZH2UjVaMMtMVOCKFSfjhfLmuA/9+O+F+ajUdG6B/bSssrKW6JJYASa8jA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.6': + resolution: + { + integrity: sha512-vpVxFvUCFioJqug7OTvqptkc4yb8UX0AwfDmJpaR/0sWz+BUmqSVAf7c8JkUgnN8YLspb4a/N6NhTyMAmdyQ7Q==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.6': + resolution: + { + integrity: sha512-h1wG6Y6K3JlRswxsI64qQJqBAy4vrLuHgRbc8CZMGSWTOFRY6ghMApM1NKzB2I0n5xV1fjkE18SuVl2QpLeNpA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.6': + resolution: + { + integrity: sha512-tbCiqub0q2MVWJKgF5PoAlNWCtQydiOYSLIkd8sByqK/6MMYLJRcSXSYodqYtd0O+Fw7QaVmKKlS4oL94YRZ0w==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.6': + resolution: + { + integrity: sha512-oxK9+baEBPhZG5HB4URY+uU04zJWeZlH6Tb9rB5DK4DF9XR1uXNLXt5Q5ZsugTKayNCNLhkcwz/ye74hRI98dg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.2.6': + resolution: + { + integrity: sha512-muWCk27FVBEZtv0MsK8gnfSmgczA8KQ0uRVJbTABKhkRfQc38aUrcb7fhi3BNiyseFmgcRsoMfQsSNJ+DbZdSw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.2.6': + resolution: + { + integrity: sha512-eWDoSfU7Co2qj3vgB3Dt4lj1mG6CoWbcJQkRMP3XJplyCMtuaq3LHvPFjS9QIPvMGWVadJC04Xiy0IdcVPtnwQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.6': + resolution: + { + integrity: sha512-2bWNjRSIayvupRKxXUY2tWG9fYdoUlTqWywHRvE8Eq3GvuQ+f2HeIkve697fIt+IQs/PV8yFsdWuhp1aJ1PdnA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.6': + resolution: + { + integrity: sha512-KekI0gS0wLxe1UBSQSjenBVwou/JkcQPDzBPICGZjxUv9k3RteHDPBQaiOicZUFKRIH2wKEimGwVpnJsbPzu7w==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.2.6': + resolution: + { + integrity: sha512-TvtPnfVr+HtyGiDmPK4VWmlNm7QhNNAcK5Q9A7aOXsI8545yCyaoMaicXrFZ72JzeYjaUVk7yT243zT0jzjFKQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.2.6': + resolution: + { + integrity: sha512-iOo0VEay2XFhaCcH0sps5XIimkSuOnNaZrf6+ZkoSOQBJPKNU48RkmJv0/lSpipexu5P+ouFgafe5IGr/DiQfg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.6': + resolution: + { + integrity: sha512-y5NTmmasMS455JlOCO4ZM9krIchv3Mvm1crL1iUPGOPgEzSkves9n0SdC5Sjz6+qWDFhd8/JpfWMH8NSWNHe+A==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.6': + resolution: + { + integrity: sha512-np8iZSLfXlAD4kWhiyq/u0Yt8oZDtRQ8lGhQaCXo2rl37KNjeU0GjJuwr4P3oeZ++ROfofsKNBqR5LTO8aXyWQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: + { + integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==, + } + + '@scarf/scarf@1.4.0': + resolution: + { + integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==, + } + + '@standard-schema/spec@1.1.0': + resolution: + { + integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==, + } + + '@tokenizer/inflate@0.4.1': + resolution: + { + integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==, + } + engines: { node: '>=18' } + + '@tokenizer/token@0.3.0': + resolution: + { + integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==, + } + + '@topcli/prompts@4.0.0': + resolution: + { + integrity: sha512-kkKYPb4k/6kRdnESt77B5vJrrYnYHIYczwv0P1c+tfN/IWEx3KZeKEHoUq7sImIyBEXWdA2uakIroD9pmRJziQ==, + } + engines: { node: '>=22.0.0' } + + '@turbo/darwin-64@2.10.12': + resolution: + { + integrity: sha512-9nKgKoF6ZOUsM+or0OtNf+TTJSfGvDNP7ZFv/ZGWVwOSCkumyctQiTeHwB4UNljHTnC41AqylgbunLDHoccNrA==, + } + cpu: [x64] + os: [darwin] + + '@turbo/darwin-arm64@2.10.12': + resolution: + { + integrity: sha512-H4Elb1jqTZVeIC9bbcNwjSzemZ6RegoTOVHeuV5Osirt2Z8UguTyisMEkvZjPVZgMeN9J4ERZBFad40tFnkb7w==, + } + cpu: [arm64] + os: [darwin] + + '@turbo/linux-64@2.10.12': + resolution: + { + integrity: sha512-lr7KIotukvjZwEXiFSYAeOH3BWzjFVBbSzTbv0fuGFsNukYyH0+g1hB5ecqnJkgkYU+KHEMG1edOhnjiKON1wQ==, + } + cpu: [x64] + os: [android, linux] + + '@turbo/linux-arm64@2.10.12': + resolution: + { + integrity: sha512-f0pZDTtvzB5SuNwuXBaKbZHUCMCukgc8nMlHEuvLmj91Fzec+MEbr3cAvGNor5htEDqZnO6Lxt9N/GPI/77oGA==, + } + cpu: [arm64] + os: [android, linux] + + '@turbo/windows-64@2.10.12': + resolution: + { + integrity: sha512-SDOueJRjS/QcykWf2KCRtTLmIl5YMKsLbXkXQGhDwcTXvKXZiS5ih5lBl/gkwZIpYFjqA/rAlfMzlAFcVHNe0g==, + } + cpu: [x64] + os: [win32] + + '@turbo/windows-arm64@2.10.12': + resolution: + { + integrity: sha512-0i0mVUa4kKk+/B3RwEwPMf9CB+T7ul56hn5FFHNA4VUNTOoLBEd6aNf3FaKfCatDNZ6cicCEf6if9QUTVyzzcA==, + } + cpu: [arm64] + os: [win32] + + '@types/body-parser@1.19.6': + resolution: + { + integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==, + } + + '@types/connect@3.4.38': + resolution: + { + integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==, + } + + '@types/estree@1.0.9': + resolution: + { + integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==, + } + + '@types/express-serve-static-core@5.1.3': + resolution: + { + integrity: sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw==, + } + + '@types/express@5.0.6': + resolution: + { + integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==, + } + + '@types/filesystem@0.0.36': + resolution: + { + integrity: sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==, + } + + '@types/filewriter@0.0.33': + resolution: + { + integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==, + } + + '@types/har-format@1.2.16': + resolution: + { + integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==, + } + + '@types/http-errors@2.0.5': + resolution: + { + integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==, + } + + '@types/node@26.3.0': + resolution: + { + integrity: sha512-L3fgrnchriRC2ExBflb8j4uZZURHZfQsmQeyVzhjcHW4kkwVyo8/0h1B2MVzMTrYUJYu6G7EWs14hW/L9putqw==, + } + + '@types/pg@8.23.1': + resolution: + { + integrity: sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A==, + } + + '@types/qs@6.15.1': + resolution: + { + integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==, + } + + '@types/range-parser@1.2.7': + resolution: + { + integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==, + } + + '@types/react-dom@19.2.5': + resolution: + { + integrity: sha512-fMPwH9v7r/pp43yUd2/Mbiex5KouJwwR3dzHkhLREUC6764VyDsqxhAxv6OFEYR1RhjOyD1naqba8ECDBe7ZQg==, + } + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.18': + resolution: + { + integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==, + } + + '@types/send@1.2.1': + resolution: + { + integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==, + } + + '@types/serve-static@2.2.0': + resolution: + { + integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==, + } + + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: + { + integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==, + } + engines: { node: '>=16.20.0' } + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: + { + integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==, + } + engines: { node: '>=16.20.0' } + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: + { + integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==, + } + engines: { node: '>=16.20.0' } + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: + { + integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==, + } + engines: { node: '>=16.20.0' } + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: + { + integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==, + } + engines: { node: '>=16.20.0' } + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: + { + integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==, + } + engines: { node: '>=16.20.0' } + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: + { + integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==, + } + engines: { node: '>=16.20.0' } + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: + { + integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==, + } + engines: { node: '>=16.20.0' } + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: + { + integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==, + } + engines: { node: '>=16.20.0' } + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: + { + integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==, + } + engines: { node: '>=16.20.0' } + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: + { + integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==, + } + engines: { node: '>=16.20.0' } + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: + { + integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==, + } + engines: { node: '>=16.20.0' } + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: + { + integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==, + } + engines: { node: '>=16.20.0' } + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: + { + integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==, + } + engines: { node: '>=16.20.0' } + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: + { + integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==, + } + engines: { node: '>=16.20.0' } + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: + { + integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==, + } + engines: { node: '>=16.20.0' } + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: + { + integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==, + } + engines: { node: '>=16.20.0' } + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: + { + integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==, + } + engines: { node: '>=16.20.0' } + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: + { + integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==, + } + engines: { node: '>=16.20.0' } + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: + { + integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==, + } + engines: { node: '>=16.20.0' } + cpu: [x64] + os: [win32] + + '@vitejs/plugin-react@6.1.1': + resolution: + { + integrity: sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + peerDependencies: + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + oxc-transform-react: ^0.145.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + oxc-transform-react: + optional: true + + '@webext-core/fake-browser@2.0.1': + resolution: + { + integrity: sha512-4x5z1z8F0KU8ShF4ForXJ8qnA8oZTy7HYjI91Mbpdzp3H3hU9HR6TNPUxfWtSpFz2FwgEircuJKQg0qFIn6RLg==, + } + + '@webext-core/isolated-element@3.0.0': + resolution: + { + integrity: sha512-PmSIBMSe+rFw6eXzpJoV+glc1HPO40clcT9FJ7rSfCQzNewK8/nQZoBYWen2cMqdXdBNM9to/IbNNu5mdQLaPg==, + } + + '@webext-core/match-patterns@2.0.0': + resolution: + { + integrity: sha512-EsyMMKfQuSE4rWCjP/TifwvUWlhC/OhiGn5OK3p9F0d57UmtLib0nzguzPKyxM1/kZV7SkE+jYXkE8gsdPRLmw==, + } + + '@wxt-dev/browser@0.2.7': + resolution: + { + integrity: sha512-Dr3h3qS25Wah4LjoCSw5uazD+547Q0dLnxaRjkkLauus008daHAulgNKTU4HkojaS9QBdo3xUlwUYPTBCQb+XQ==, + } + + '@wxt-dev/module-react@1.2.2': + resolution: + { + integrity: sha512-+lRLi1r9dAXpLySWSIWHLJ1h/nFzR20iQnx3RNrKyA6oJg4+ClOluVXozHjfPg9Okfy/umtffiOopGayASrg6w==, + } + peerDependencies: + vite: ^5.4.19 || ^6.3.4 || ^7.0.0 || ^8.0.0-0 + wxt: '>=0.19.16' + + '@wxt-dev/storage@1.2.9': + resolution: + { + integrity: sha512-dh9TJwvLBM2x4wyy9nE7eYE3wA8pgz1TXSyz7RbdjkJxLfFfWkbeIqiU7VkGy7Vx8sJBmQjoSpk9zSUb3Bjy0Q==, + } + + accepts@2.0.0: + resolution: + { + integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==, + } + engines: { node: '>= 0.6' } + + acorn@8.18.0: + resolution: + { + integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==, + } + engines: { node: '>=0.4.0' } + hasBin: true + + agent-base@6.0.2: + resolution: + { + integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==, + } + engines: { node: '>= 6.0.0' } + + ansi-regex@5.0.1: + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: '>=8' } + + ansi-styles@4.3.0: + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: '>=8' } + + antd@6.6.2: + resolution: + { + integrity: sha512-aTOPWXsqfWrlSiI0a1qR9UWR4jBCTJ8FNZfZmYQP9/aGGLJSrw9/c5uE+4vSVSt3riQlIPAwR3BcAgEHmE7GMg==, + } + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + append-field@1.0.0: + resolution: + { + integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==, + } + + argparse@2.0.1: + resolution: + { + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, + } + + asynckit@0.4.0: + resolution: + { + integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, + } + + axios@1.20.0: + resolution: + { + integrity: sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==, + } + + body-parser@2.3.0: + resolution: + { + integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==, + } + engines: { node: '>=18' } + + boolbase@2.0.0: + resolution: + { + integrity: sha512-DkVaaQHymRhpYEYo9x1oo7Q7B0Y6KJUsjm3c9eTyFDby4MHLBTwZ6ZDWBel5zrYxj1WsZgC5oLpiz+93MluXeA==, + } + engines: { node: '>=20.19.0' } + + buffer-from@1.1.2: + resolution: + { + integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, + } + + bullmq@6.3.4: + resolution: + { + integrity: sha512-DpilB5sayCB8huCp4YuzVhJjxB4ieHidzu+GPgbcjPi3kQv0gdLoLnk+I+mMACDQ88rTbSiT+B4crmhWFGL9GA==, + } + engines: { node: '>=14.17.0' } + peerDependencies: + bullmq-otel: '>=2.0.0' + ioredis: '>=5.0.0' + pg: '>=8.0.0' + redis: '>=5.0.0' + peerDependenciesMeta: + bullmq-otel: + optional: true + ioredis: + optional: true + pg: + optional: true + redis: + optional: true + + busboy@1.6.0: + resolution: + { + integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==, + } + engines: { node: '>=10.16.0' } + + bytes@3.1.2: + resolution: + { + integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==, + } + engines: { node: '>= 0.8' } + + c12@3.3.4: + resolution: + { + integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==, + } + peerDependencies: + magicast: '*' + peerDependenciesMeta: + magicast: + optional: true + + cac@7.0.0: + resolution: + { + integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==, + } + engines: { node: '>=20.19.0' } + + call-bind-apply-helpers@1.0.2: + resolution: + { + integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==, + } + engines: { node: '>= 0.4' } + + call-bound@1.0.4: + resolution: + { + integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==, + } + engines: { node: '>= 0.4' } + + chokidar@5.0.0: + resolution: + { + integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==, + } + engines: { node: '>= 20.19.0' } + + citty@0.2.2: + resolution: + { + integrity: sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==, + } + + cliui@8.0.1: + resolution: + { + integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, + } + engines: { node: '>=12' } + + clsx@2.1.1: + resolution: + { + integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==, + } + engines: { node: '>=6' } + + cluster-key-slot@1.1.1: + resolution: + { + integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==, + } + engines: { node: '>=0.10.0' } + + color-convert@2.0.1: + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: '>=7.0.0' } + + color-name@1.1.4: + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } + + combined-stream@1.0.8: + resolution: + { + integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, + } + engines: { node: '>= 0.8' } + + compute-scroll-into-view@3.1.1: + resolution: + { + integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==, + } + + concat-stream@2.0.0: + resolution: + { + integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==, + } + engines: { '0': node >= 6.0 } + + confbox@0.1.8: + resolution: + { + integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==, + } + + confbox@0.2.4: + resolution: + { + integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==, + } + + consola@3.4.2: + resolution: + { + integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==, + } + engines: { node: ^14.18.0 || >=16.10.0 } + + content-disposition@1.1.0: + resolution: + { + integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==, + } + engines: { node: '>=18' } + + content-type@1.0.5: + resolution: + { + integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==, + } + engines: { node: '>= 0.6' } + + content-type@2.1.0: + resolution: + { + integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==, + } + engines: { node: '>=18' } + + cookie-signature@1.2.2: + resolution: + { + integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==, + } + engines: { node: '>=6.6.0' } + + cookie@0.7.2: + resolution: + { + integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==, + } + engines: { node: '>= 0.6' } + + cookie@1.1.1: + resolution: + { + integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==, + } + engines: { node: '>=18' } + + cors@2.8.6: + resolution: + { + integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==, + } + engines: { node: '>= 0.10' } + + cron-parser@5.10.0: + resolution: + { + integrity: sha512-izNAxJyRWUP8ljBoDSub5WyrVOUlT4SLGShswE7eoRBpp6QUsSycYxLBMJlbshgPBMcPT/nrfgjNY2918ayv2A==, + } + engines: { node: '>=18' } + + css-select@7.0.0: + resolution: + { + integrity: sha512-snmjEVXy+1LnwXdxhYvTMj1d9tOh4HxkA1YmoayVBeeyR2C14Pum7fcxJIm4SswYspVy866eYNwlH6xC3/VH5g==, + } + engines: { node: '>=20.19.0' } + + css-what@8.0.0: + resolution: + { + integrity: sha512-DH0Bqq3DNp5tdOReuNyAA+Ev4Y2GS5FMbZpeTLP6C4CDi0h5nL0BmUPChXw3o/qbHLDWHl49sbNqQVY7bMSDdw==, + } + engines: { node: '>=20.19.0' } + + cssom@0.5.0: + resolution: + { + integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==, + } + + csstype@3.2.3: + resolution: + { + integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, + } + + dayjs@1.11.23: + resolution: + { + integrity: sha512-QDTCU0M0MxR3hQfnlDJfwekQiaanm1ubOD231u73WBckQ/fsamwRLiE2GBz6D3a/xF1NgfiDLJjXBa1hYOYTtQ==, + } + + debug@4.4.3: + resolution: + { + integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, + } + engines: { node: '>=6.0' } + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + define-lazy-prop@2.0.0: + resolution: + { + integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==, + } + engines: { node: '>=8' } + + defu@6.1.7: + resolution: + { + integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==, + } + + delayed-stream@1.0.0: + resolution: + { + integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, + } + engines: { node: '>=0.4.0' } + + denque@2.1.0: + resolution: + { + integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==, + } + engines: { node: '>=0.10' } + + depd@2.0.0: + resolution: + { + integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==, + } + engines: { node: '>= 0.8' } + + destr@2.0.5: + resolution: + { + integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==, + } + + detect-libc@2.1.2: + resolution: + { + integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==, + } + engines: { node: '>=8' } + + dom-serializer@2.0.0: + resolution: + { + integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==, + } + + dom-serializer@3.1.1: + resolution: + { + integrity: sha512-4MEa38/QexBob6gFNwu+EGdWvhJ1OKuNwdYY3Y3NyeWDQfnGeDYQUDfIRzWu5B5gsv03so2Uxd28YC6zrsx3Lw==, + } + engines: { node: '>=20.19.0' } + + domelementtype@2.3.0: + resolution: + { + integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==, + } + + domelementtype@3.0.0: + resolution: + { + integrity: sha512-umCQid3jKbDmVjx8jGaW7uUykm4DEUeyV21hPxNMo2nV955DhUThwqyOIDtreepP31hl84X7G5U9ZfsWvIB3Pg==, + } + engines: { node: '>=20.19.0' } + + domhandler@5.0.3: + resolution: + { + integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==, + } + engines: { node: '>= 4' } + + domhandler@6.0.1: + resolution: + { + integrity: sha512-gYzvtM72ZtxQO0T048kd6HWSbbGCNOUwcnfQ01cqIJ4X2IYKFFHZ5mKvrQETcFXxsRObZulDaKmy//R7TPtsBg==, + } + engines: { node: '>=20.19.0' } + + domutils@3.2.2: + resolution: + { + integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==, + } + + domutils@4.0.2: + resolution: + { + integrity: sha512-qI4JLRKnSzqFqr7hAlS5xQDusBCjKSEG4t4+7aNrIQMHBcsC2TGEhuyABJdYkgSewL57PNLYEiibY2iPKhKpaA==, + } + engines: { node: '>=20.19.0' } + + dotenv-expand@13.0.0: + resolution: + { + integrity: sha512-aBfBS8eYIeXmpHI9ThIlA7/WLq+SLt18iXUZhb52rW89QLKQFoIpPG1bPeewoPZsTyjSSO3T7234FBVUM1V2rA==, + } + engines: { node: '>=12' } + + dotenv@17.4.2: + resolution: + { + integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==, + } + engines: { node: '>=12' } + + dunder-proto@1.0.1: + resolution: + { + integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==, + } + engines: { node: '>= 0.4' } + + ee-first@1.1.1: + resolution: + { + integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, + } + + emoji-regex@8.0.0: + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } + + encodeurl@2.0.0: + resolution: + { + integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==, + } + engines: { node: '>= 0.8' } + + entities@4.5.0: + resolution: + { + integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==, + } + engines: { node: '>=0.12' } + + entities@7.0.1: + resolution: + { + integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==, + } + engines: { node: '>=0.12' } + + entities@8.0.0: + resolution: + { + integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==, + } + engines: { node: '>=20.19.0' } + + es-define-property@1.0.1: + resolution: + { + integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==, + } + engines: { node: '>= 0.4' } + + es-errors@1.3.0: + resolution: + { + integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, + } + engines: { node: '>= 0.4' } + + es-object-atoms@1.1.2: + resolution: + { + integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==, + } + engines: { node: '>= 0.4' } + + es-set-tostringtag@2.1.0: + resolution: + { + integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==, + } + engines: { node: '>= 0.4' } + + es-toolkit@1.51.0: + resolution: + { + integrity: sha512-zC2lQGkM7QX+Gm6iM3+WIdZJzthsEd14LvRNJneSO2hzyz/zNBENR8+YXWo1cKxgPBtV6ksPYHELbcwBRzmdCw==, + } + + esbuild@0.28.2: + resolution: + { + integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==, + } + engines: { node: '>=18' } + hasBin: true + + escalade@3.2.0: + resolution: + { + integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, + } + engines: { node: '>=6' } + + escape-html@1.0.3: + resolution: + { + integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, + } + + escape-string-regexp@5.0.0: + resolution: + { + integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==, + } + engines: { node: '>=12' } + + estree-walker@3.0.3: + resolution: + { + integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, + } + + etag@1.8.1: + resolution: + { + integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==, + } + engines: { node: '>= 0.6' } + + express@5.2.1: + resolution: + { + integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==, + } + engines: { node: '>= 18' } + + exsolve@1.1.1: + resolution: + { + integrity: sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==, + } + + fast-safe-stringify@2.1.1: + resolution: + { + integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==, + } + + fdir@6.5.0: + resolution: + { + integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, + } + engines: { node: '>=12.0.0' } + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-type@22.0.2: + resolution: + { + integrity: sha512-0H8TsCUGBLx+V5adH3EY52hTAcyLKbV1D4gq5cIOJ6DnQAHeV9Z2Hhuc5CoBX4YmvB2oL+JIC84z0qO7JsCoNw==, + } + engines: { node: '>=22' } + + filesize@11.0.22: + resolution: + { + integrity: sha512-RlCVs9CY+oSsRnNZn95J9vDXjNjOwddKyTFjOYtA4yxYVIxBnwiVVGJX+TFhsmu3uUf81JDGyijtYL9xgawlTw==, + } + engines: { node: '>= 10.8.0' } + + finalhandler@2.1.1: + resolution: + { + integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==, + } + engines: { node: '>= 18.0.0' } + + follow-redirects@1.16.0: + resolution: + { + integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==, + } + engines: { node: '>=4.0' } + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.6: + resolution: + { + integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==, + } + engines: { node: '>= 6' } + + forwarded@0.2.0: + resolution: + { + integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==, + } + engines: { node: '>= 0.6' } + + fresh@2.0.0: + resolution: + { + integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==, + } + engines: { node: '>= 0.8' } + + fsevents@2.3.3: + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] + + function-bind@1.1.2: + resolution: + { + integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, + } + + get-caller-file@2.0.5: + resolution: + { + integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, + } + engines: { node: 6.* || 8.* || >= 10.* } + + get-intrinsic@1.3.0: + resolution: + { + integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==, + } + engines: { node: '>= 0.4' } + + get-proto@1.0.1: + resolution: + { + integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==, + } + engines: { node: '>= 0.4' } + + giget@3.3.1: + resolution: + { + integrity: sha512-r+mvuDjrjMpsdw46Kmeydb8bdHm7wOKw8wNBtTndkjbPjgAp5oUJUxRE76wZFknxIPokfWvep2qSXK37aXE6zg==, + } + hasBin: true + + gopd@1.2.0: + resolution: + { + integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==, + } + engines: { node: '>= 0.4' } + + has-symbols@1.1.0: + resolution: + { + integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==, + } + engines: { node: '>= 0.4' } + + has-tostringtag@1.0.2: + resolution: + { + integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==, + } + engines: { node: '>= 0.4' } + + hasown@2.0.4: + resolution: + { + integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==, + } + engines: { node: '>= 0.4' } + + helmet@8.3.0: + resolution: + { + integrity: sha512-Qgpiaws3Sm30Av8Eah6sjMCZZwjlBu+E68rhpCWBshY1lb09HtLwj5GviX0OyQIn+ulUS0iX0AxN5n3tLZzz1w==, + } + engines: { node: '>=18.0.0' } + + hookable@6.1.1: + resolution: + { + integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==, + } + + html-escaper@3.0.3: + resolution: + { + integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==, + } + + htmlparser2@10.1.0: + resolution: + { + integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==, + } + + http-errors@2.0.1: + resolution: + { + integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==, + } + engines: { node: '>= 0.8' } + + https-proxy-agent@5.0.1: + resolution: + { + integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==, + } + engines: { node: '>= 6' } + + iconv-lite@0.7.3: + resolution: + { + integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==, + } + engines: { node: '>=0.10.0' } + + ieee754@1.2.1: + resolution: + { + integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, + } + + inherits@2.0.4: + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } + + ioredis@6.0.0: + resolution: + { + integrity: sha512-f+Dtubxfpf6KYFq7WVXJoOLn0bk4TJrMrN9SzeE+jrWrCWj7XX3fA6vkryafhADX+GMymRxgDJDOI33COkJc0w==, + } + engines: { node: '>=20.0.0' } + + ipaddr.js@1.9.1: + resolution: + { + integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==, + } + engines: { node: '>= 0.10' } + + is-docker@2.2.1: + resolution: + { + integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==, + } + engines: { node: '>=8' } + hasBin: true + + is-fullwidth-code-point@3.0.0: + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: '>=8' } + + is-mobile@5.0.0: + resolution: + { + integrity: sha512-Tz/yndySvLAEXh+Uk8liFCxOwVH6YutuR74utvOcu7I9Di+DwM0mtdPVZNaVvvBUM2OXxne/NhOs1zAO7riusQ==, + } + + is-potential-custom-element-name@1.0.1: + resolution: + { + integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==, + } + + is-promise@4.0.0: + resolution: + { + integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==, + } + + is-wsl@2.2.0: + resolution: + { + integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==, + } + engines: { node: '>=8' } + + iterare@1.2.1: + resolution: + { + integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==, + } + engines: { node: '>=6' } + + jiti@2.7.0: + resolution: + { + integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==, + } + hasBin: true + + js-tokens@10.0.0: + resolution: + { + integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==, + } + + js-yaml@5.4.1: + resolution: + { + integrity: sha512-28R/k+NAjeuf7+CKlTxWZVExJGwVVLwY06DgEnOMz2gEpfNkDcD7QvyiVPT0xy0XXhU8vHsd4Ot42OOPdJG7dQ==, + } + hasBin: true + + json2mq@0.2.0: + resolution: + { + integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==, + } + + json5@2.2.3: + resolution: + { + integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, + } + engines: { node: '>=6' } + hasBin: true + + lightningcss-android-arm64@1.33.0: + resolution: + { + integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==, + } + engines: { node: '>= 12.0.0' } + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.33.0: + resolution: + { + integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==, + } + engines: { node: '>= 12.0.0' } + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: + { + integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==, + } + engines: { node: '>= 12.0.0' } + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.33.0: + resolution: + { + integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==, + } + engines: { node: '>= 12.0.0' } + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: + { + integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==, + } + engines: { node: '>= 12.0.0' } + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: + { + integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==, + } + engines: { node: '>= 12.0.0' } + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: + { + integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==, + } + engines: { node: '>= 12.0.0' } + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: + { + integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==, + } + engines: { node: '>= 12.0.0' } + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.33.0: + resolution: + { + integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==, + } + engines: { node: '>= 12.0.0' } + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: + { + integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==, + } + engines: { node: '>= 12.0.0' } + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: + { + integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==, + } + engines: { node: '>= 12.0.0' } + cpu: [x64] + os: [win32] + + lightningcss@1.33.0: + resolution: + { + integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==, + } + engines: { node: '>= 12.0.0' } + + linkedom@0.18.13: + resolution: + { + integrity: sha512-ES/o9qotMpzpN2MHs+Iq/JcVoOj8Fa5wiQYrTdFpvAnwXL0g66XHHUc9WUMk6nAlBtGsFQ24ne+SYnvnaQ2FSw==, + } + engines: { node: '>=16' } + peerDependencies: + canvas: '>= 2' + peerDependenciesMeta: + canvas: + optional: true + + load-esm@1.0.3: + resolution: + { + integrity: sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==, + } + engines: { node: '>=13.2.0' } + + local-pkg@1.2.1: + resolution: + { + integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==, + } + engines: { node: '>=14' } + + lodash.merge@4.6.2: + resolution: + { + integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, + } + + luxon@3.7.2: + resolution: + { + integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==, + } + engines: { node: '>=12' } + + magic-string@1.2.3: + resolution: + { + integrity: sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==, + } + + magicast@0.5.4: + resolution: + { + integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==, + } + + many-keys-map@3.0.3: + resolution: + { + integrity: sha512-1DiZmDHPXMBgMRjeUtHy1q1VYmeJscHxhIAexX9z/zjRMP80+0ETuPfssi8z+kMY4DwUgsKuHqpjxgmeA9gBNA==, + } + engines: { node: '>=18' } + + math-intrinsics@1.1.0: + resolution: + { + integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==, + } + engines: { node: '>= 0.4' } + + media-typer@0.3.0: + resolution: + { + integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==, + } + engines: { node: '>= 0.6' } + + media-typer@1.1.1: + resolution: + { + integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==, + } + engines: { node: '>= 0.8' } + + merge-descriptors@2.0.0: + resolution: + { + integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==, + } + engines: { node: '>=18' } + + mime-db@1.52.0: + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: '>= 0.6' } + + mime-db@1.54.0: + resolution: + { + integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==, + } + engines: { node: '>= 0.6' } + + mime-types@2.1.35: + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: '>= 0.6' } + + mime-types@3.0.2: + resolution: + { + integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==, + } + engines: { node: '>=18' } + + mlly@1.8.2: + resolution: + { + integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==, + } + + ms@2.1.3: + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } + + msgpackr-extract@3.0.4: + resolution: + { + integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==, + } + hasBin: true + + msgpackr@2.1.0: + resolution: + { + integrity: sha512-p/pBCVO63CsvvpkomUnNNag6+n38rULuDA6HHe70o2gtC8ODI52foF/4ko2qQcp6OiErJXTmrZeXmsGGHsIQNQ==, + } + + multer@2.2.0: + resolution: + { + integrity: sha512-6rdyFg2kLrMh9Jee7/BMPuV9lEAd7lLW2YUpF9/YxR7njyoUwwQ0ZPh3TaIY50Sw6vlyD2HW3wGOkTS4P79xrQ==, + } + engines: { node: '>= 10.16.0' } + + nanoid@3.3.18: + resolution: + { + integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + + negotiator@1.1.0: + resolution: + { + integrity: sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==, + } + engines: { node: '>=18' } + + node-abort-controller@3.1.1: + resolution: + { + integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==, + } + + node-gyp-build-optional-packages@5.2.2: + resolution: + { + integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==, + } + hasBin: true + + nth-check@3.0.1: + resolution: + { + integrity: sha512-GX0gsdbGVCgnRgbeGaubfjpBXyYRWOOCVeYh08bSQvDZqxz5ndXs1OTfAt/h36G1xvI94YIspsI0sVFqAV9+RQ==, + } + engines: { node: '>=20.19.0' } + + nypm@0.6.9: + resolution: + { + integrity: sha512-zxlE2yvSWZWmHcNdT3+5zV2lrCogeE9YOklHrR3dFjqutq5wO7GFDYLFDRXLsYnJzwvy/im9fYoxePvS0VTW0w==, + } + engines: { node: '>=18' } + hasBin: true + + object-assign@4.1.1: + resolution: + { + integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==, + } + engines: { node: '>=0.10.0' } + + object-inspect@1.13.4: + resolution: + { + integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==, + } + engines: { node: '>= 0.4' } + + ohash@2.0.12: + resolution: + { + integrity: sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==, + } + + on-finished@2.4.1: + resolution: + { + integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==, + } + engines: { node: '>= 0.8' } + + once@1.4.0: + resolution: + { + integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, + } + + open@8.4.2: + resolution: + { + integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==, + } + engines: { node: '>=12' } + + parseurl@1.3.3: + resolution: + { + integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==, + } + engines: { node: '>= 0.8' } + + path-to-regexp@8.4.2: + resolution: + { + integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==, + } + + pathe@2.0.3: + resolution: + { + integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, + } + + perfect-debounce@2.1.0: + resolution: + { + integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==, + } + + pg-cloudflare@1.4.0: + resolution: + { + integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==, + } + + pg-connection-string@2.14.0: + resolution: + { + integrity: sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==, + } + + pg-int8@1.0.1: + resolution: + { + integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==, + } + engines: { node: '>=4.0.0' } + + pg-pool@3.14.0: + resolution: + { + integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==, + } + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.16.0: + resolution: + { + integrity: sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==, + } + + pg-types@2.2.0: + resolution: + { + integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==, + } + engines: { node: '>=4' } + + pg@8.23.0: + resolution: + { + integrity: sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==, + } + engines: { node: '>= 16.0.0' } + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: + { + integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==, + } + + picocolors@1.1.1: + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } + + picomatch@2.3.2: + resolution: + { + integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==, + } + engines: { node: '>=8.6' } + + picomatch@4.0.7: + resolution: + { + integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==, + } + engines: { node: '>=12' } + + pkg-types@1.3.1: + resolution: + { + integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==, + } + + pkg-types@2.3.1: + resolution: + { + integrity: sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==, + } + + postcss@8.5.26: + resolution: + { + integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==, + } + engines: { node: ^10 || ^12 || >=14 } + + postgres-array@2.0.0: + resolution: + { + integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==, + } + engines: { node: '>=4' } + + postgres-bytea@1.0.1: + resolution: + { + integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==, + } + engines: { node: '>=0.10.0' } + + postgres-date@1.0.7: + resolution: + { + integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==, + } + engines: { node: '>=0.10.0' } + + postgres-interval@1.2.0: + resolution: + { + integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==, + } + engines: { node: '>=0.10.0' } + + prettier@3.9.6: + resolution: + { + integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==, + } + engines: { node: '>=14' } + hasBin: true + + proxy-addr@2.0.7: + resolution: + { + integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==, + } + engines: { node: '>= 0.10' } + + proxy-from-env@2.1.0: + resolution: + { + integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==, + } + engines: { node: '>=10' } + + publish-browser-extension@6.1.1: + resolution: + { + integrity: sha512-ovfBOz+cZIOBHZ+oxTfpv1kSGU7ruzy8CXoFGvhXsUbJuty45srGzf1ufEePs69virOWXfFbhZRoNQUdgPvwXA==, + } + engines: { node: '>=22.0.0' } + hasBin: true + + qs@6.16.0: + resolution: + { + integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==, + } + engines: { node: '>=0.6' } + + quansync@0.2.11: + resolution: + { + integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==, + } + + range-parser@1.3.0: + resolution: + { + integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==, + } + engines: { node: '>= 0.6' } + + raw-body@3.0.2: + resolution: + { + integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==, + } + engines: { node: '>= 0.10' } + + rc9@3.0.1: + resolution: + { + integrity: sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==, + } + + react-dom@19.2.8: + resolution: + { + integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==, + } + peerDependencies: + react: ^19.2.8 + + react-is@19.2.8: + resolution: + { + integrity: sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==, + } + + react-router-dom@7.18.3: + resolution: + { + integrity: sha512-ytVbyBBM7vMfRCam25r0WMhSVSom909A8p+8m0/f1w853dz/xfFu6etAT2SEbVoSnI+ZoPRDqIsQXVT89gp7kg==, + } + engines: { node: '>=20.0.0' } + peerDependencies: + react: '>=18' + react-dom: '>=18' + + react-router@7.18.3: + resolution: + { + integrity: sha512-gyXgtdr5uACJ5b1Q4udzjVV+tb/rlHIMJKuJ0e89R4Kzgz47z/rgP0dIKxktqIEUhDHluGTPJJH/wRha7CyqsA==, + } + engines: { node: '>=20.0.0' } + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + + react@19.2.8: + resolution: + { + integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==, + } + engines: { node: '>=0.10.0' } + + readable-stream@3.6.2: + resolution: + { + integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==, + } + engines: { node: '>= 6' } + + readdirp@5.1.1: + resolution: + { + integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==, + } + engines: { node: '>= 20.19.0' } + + redis-errors@1.2.0: + resolution: + { + integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==, + } + engines: { node: '>=4' } + + reflect-metadata@0.2.2: + resolution: + { + integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==, + } + + require-directory@2.1.1: + resolution: + { + integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, + } + engines: { node: '>=0.10.0' } + + rolldown@1.2.6: + resolution: + { + integrity: sha512-vMM4q3aixf46GiF1Kok8jDPFsEpXgFWGjUHXNkNHNm+Y2adXAG2dbX91jkti3i0ZRsOlcmbuzAz1poObSHCmUA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + hasBin: true + + router@2.2.0: + resolution: + { + integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==, + } + engines: { node: '>= 18' } + + rxjs@7.8.2: + resolution: + { + integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==, + } + + safe-buffer@5.2.1: + resolution: + { + integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, + } + + safer-buffer@2.1.2: + resolution: + { + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, + } + + scheduler@0.27.0: + resolution: + { + integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==, + } + + scroll-into-view-if-needed@3.1.0: + resolution: + { + integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==, + } + + scule@1.3.0: + resolution: + { + integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==, + } + + semver@7.8.5: + resolution: + { + integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==, + } + engines: { node: '>=10' } + hasBin: true + + send@1.2.1: + resolution: + { + integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==, + } + engines: { node: '>= 18' } + + serve-static@2.2.1: + resolution: + { + integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==, + } + engines: { node: '>= 18' } + + set-cookie-parser@2.7.2: + resolution: + { + integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==, + } + + setprototypeof@1.2.0: + resolution: + { + integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==, + } + + side-channel-list@1.0.1: + resolution: + { + integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==, + } + engines: { node: '>= 0.4' } + + side-channel-map@1.0.1: + resolution: + { + integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==, + } + engines: { node: '>= 0.4' } + + side-channel-weakmap@1.0.2: + resolution: + { + integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==, + } + engines: { node: '>= 0.4' } + + side-channel@1.1.1: + resolution: + { + integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==, + } + engines: { node: '>= 0.4' } + + source-map-js@1.2.1: + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, + } + engines: { node: '>=0.10.0' } + + source-map@0.7.6: + resolution: + { + integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==, + } + engines: { node: '>= 12' } + + split2@4.2.0: + resolution: + { + integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==, + } + engines: { node: '>= 10.x' } + + standard-as-callback@2.1.0: + resolution: + { + integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==, + } + + statuses@2.0.2: + resolution: + { + integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==, + } + engines: { node: '>= 0.8' } + + streamsearch@1.1.0: + resolution: + { + integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==, + } + engines: { node: '>=10.0.0' } + + string-convert@0.2.1: + resolution: + { + integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==, + } + + string-width@4.2.3: + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: '>=8' } + + string_decoder@1.3.0: + resolution: + { + integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, + } + + strip-ansi@6.0.1: + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: '>=8' } + + strip-literal@4.0.0: + resolution: + { + integrity: sha512-PaqAvfUZKBwc/SLmNZtHmzK+v19Z4O4eS3cKPeGvbIv/U3pnyEq4Tuw3/4v/FwfM8VQaEawsyCcOQ0P+kpwWWw==, + } + + strtok3@10.3.5: + resolution: + { + integrity: sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==, + } + engines: { node: '>=18' } + + stylis@4.4.0: + resolution: + { + integrity: sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==, + } + + superlock@1.3.5: + resolution: + { + integrity: sha512-XpWNthvezZnWp0u7/UL8rBbBOnq2Qx39fw+0RNMC/+eotOd81glzsmIWVH0ejarhTeDQihxOKSbjm2XXFo5a8w==, + } + engines: { node: '>= 14' } + + swagger-ui-dist@5.32.14: + resolution: + { + integrity: sha512-nOA2pSQhcmODMUQZpJHYKNuwniDUqcOWGNaSCOoZv12FdOSJ9JxV95HtyRGNMqEBj6h6lCNTy20TgZDYTSuUIg==, + } + + tasuku@2.3.0: + resolution: + { + integrity: sha512-9Jtk+XAnttslCw4i9RceSZGr2PT5TLn0vUyWnoP2SdlSYzkiYRY6kB5qnPi5IQ/Em8e4oBow1rpaA39iijTIrA==, + } + + throttle-debounce@5.0.2: + resolution: + { + integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==, + } + engines: { node: '>=12.22' } + + tiny-open@1.3.0: + resolution: + { + integrity: sha512-GUFS8yjJZq0oWqCKCJVHcBgMpmi2WEGXY1le3E5ncR0DsgTII5uUyxtfk8/vGyDDGBE42UYHR6Ocvlk8mkXSRg==, + } + + tinyexec@1.3.0: + resolution: + { + integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==, + } + engines: { node: '>=18' } + + tinyglobby@0.2.17: + resolution: + { + integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==, + } + engines: { node: '>=12.0.0' } + + toidentifier@1.0.1: + resolution: + { + integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==, + } + engines: { node: '>=0.6' } + + token-types@6.1.2: + resolution: + { + integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==, + } + engines: { node: '>=14.16' } + + tslib@2.8.1: + resolution: + { + integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, + } + + tsx@4.23.13: + resolution: + { + integrity: sha512-BL5MGkRln6aDYhb0xbQlEAGw743BaZYWdbWtdJOBriYJboKgUUYCadFp2/FpBBZquBC/ezNBn7wMMPx7FDZUDw==, + } + engines: { node: '>=18.0.0' } + hasBin: true + + turbo@2.10.12: + resolution: + { + integrity: sha512-AswgMPnpOoaVZHrrSBejETzEbuIA69OVGwfkHwfrY0A23VjWXBANzgq9+OymWOHAIArB7D1+1z498WY8fGg1Jw==, + } + hasBin: true + + type-is@1.6.18: + resolution: + { + integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==, + } + engines: { node: '>= 0.6' } + + type-is@2.1.0: + resolution: + { + integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==, + } + engines: { node: '>= 18' } + + typedarray@0.0.6: + resolution: + { + integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==, + } + + typescript@7.0.2: + resolution: + { + integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==, + } + engines: { node: '>=16.20.0' } + hasBin: true + + ufo@1.6.4: + resolution: + { + integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==, + } + + uhyphen@0.2.0: + resolution: + { + integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==, + } + + uid@2.0.2: + resolution: + { + integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==, + } + engines: { node: '>=8' } + + uint8array-extras@1.5.0: + resolution: + { + integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==, + } + engines: { node: '>=18' } + + undici-types@8.3.0: + resolution: + { + integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==, + } + + unimport@6.4.0: + resolution: + { + integrity: sha512-JJOOuNMFq8b4ZPBKwQUxEcba4MplskDzYI1Lvrf8rJfWphZTWvPNXWa493qsPngHUmub89w6C7j+SeLWTE/UIQ==, + } + engines: { node: '>=18.12.0' } + peerDependencies: + oxc-parser: '*' + rolldown: ^1.0.0 + peerDependenciesMeta: + oxc-parser: + optional: true + rolldown: + optional: true + + unpipe@1.0.0: + resolution: + { + integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, + } + engines: { node: '>= 0.8' } + + unplugin-utils@0.3.2: + resolution: + { + integrity: sha512-xVToRh2CTmLk2HnEG7ac4rl1MJTT3RFkpS8B++/SnB0kXvuaavD+n3m/vrzyWQOdJNSZQACnbz01pnppbwV5BA==, + } + engines: { node: '>=20.19.0' } + + unplugin@3.3.0: + resolution: + { + integrity: sha512-qa66K+crbfyE6JK10GjvbJeRrOsuC/JpbnHctfyp/i4oBTxWOzJfRZyDiOk1PtErMFRu8JhsU/wPvOdBNWe5Rg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + peerDependencies: + '@farmfe/core': '*' + '@rspack/core': '*' + bun-types-no-globals: '*' + esbuild: '*' + rolldown: '*' + rollup: '*' + unloader: '*' + vite: '*' + webpack: '*' + peerDependenciesMeta: + '@farmfe/core': + optional: true + '@rspack/core': + optional: true + bun-types-no-globals: + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + unloader: + optional: true + vite: + optional: true + webpack: + optional: true + + util-deprecate@1.0.2: + resolution: + { + integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, + } + + vary@1.1.2: + resolution: + { + integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, + } + engines: { node: '>= 0.8' } + + vite@8.2.2: + resolution: + { + integrity: sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==, + } + engines: { node: ^20.19.0 || >=22.12.0 } + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.4.0 || ^0.5.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + webpack-virtual-modules@0.6.2: + resolution: + { + integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==, + } + + wrap-ansi@7.0.0: + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: '>=10' } + + wrappy@1.0.2: + resolution: + { + integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, + } + + wxt@0.21.4: + resolution: + { + integrity: sha512-iyVMTXb37BQAbsPHCuPzrK3ZxnO9pZmvbKl7VJWIHe3RG40On2NyP2FOjArtOITO96plEYnh3o+iUlRp9qE90w==, + } + engines: { bun: '>=1.2.0', node: '>=22' } + hasBin: true + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=5.4' + vite: ^6.3.4 || ^7.0.0 || ^8.0.0-0 + web-ext: '>=9.2.0' + peerDependenciesMeta: + eslint: + optional: true + typescript: + optional: true + web-ext: + optional: true + + xtend@4.0.2: + resolution: + { + integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==, + } + engines: { node: '>=0.4' } + + y18n@5.0.8: + resolution: + { + integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, + } + engines: { node: '>=10' } + + yargs-parser@21.1.1: + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: '>=12' } + + yargs@17.7.3: + resolution: + { + integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==, + } + engines: { node: '>=12' } + + zod@4.5.4: + resolution: + { + integrity: sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==, + } snapshots: + '@1natsu/wait-element@4.2.0': + dependencies: + defu: 6.1.7 + many-keys-map: 3.0.3 - '@1natsu/wait-element@4.2.0': - dependencies: - defu: 6.1.7 - many-keys-map: 3.0.3 + '@aklinker1/rollup-plugin-visualizer@5.12.0': + dependencies: + open: 8.4.2 + picomatch: 2.3.2 + source-map: 0.7.6 + yargs: 17.7.3 - '@aklinker1/rollup-plugin-visualizer@5.12.0': - dependencies: - open: 8.4.2 - picomatch: 2.3.2 - source-map: 0.7.6 - yargs: 17.7.3 + '@aklinker1/zero-zip@1.0.1': {} - '@aklinker1/zero-zip@1.0.1': {} + '@ant-design/colors@8.0.1': + dependencies: + '@ant-design/fast-color': 3.0.1 - '@ant-design/colors@8.0.1': - dependencies: - '@ant-design/fast-color': 3.0.1 + '@ant-design/cssinjs-utils@2.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@ant-design/cssinjs': 2.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@babel/runtime': 7.29.7 + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) - '@ant-design/cssinjs-utils@2.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@ant-design/cssinjs': 2.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@babel/runtime': 7.29.7 - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) + '@ant-design/cssinjs@2.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@babel/runtime': 7.29.7 + '@emotion/hash': 0.8.0 + '@emotion/unitless': 0.7.5 + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + csstype: 3.2.3 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + stylis: 4.4.0 - '@ant-design/cssinjs@2.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@babel/runtime': 7.29.7 - '@emotion/hash': 0.8.0 - '@emotion/unitless': 0.7.5 - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - csstype: 3.2.3 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - stylis: 4.4.0 + '@ant-design/fast-color@3.0.1': {} - '@ant-design/fast-color@3.0.1': {} + '@ant-design/icons-svg@4.6.0': {} - '@ant-design/icons-svg@4.6.0': {} + '@ant-design/icons@6.3.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@ant-design/colors': 8.0.1 + '@ant-design/icons-svg': 4.6.0 + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) - '@ant-design/icons@6.3.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@ant-design/colors': 8.0.1 - '@ant-design/icons-svg': 4.6.0 - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) + '@ant-design/react-slick@2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@babel/runtime': 7.29.7 + clsx: 2.1.1 + json2mq: 0.2.0 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + throttle-debounce: 5.0.2 - '@ant-design/react-slick@2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@babel/runtime': 7.29.7 - clsx: 2.1.1 - json2mq: 0.2.0 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - throttle-debounce: 5.0.2 + '@babel/helper-string-parser@7.29.7': {} - '@babel/helper-string-parser@7.29.7': {} + '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helper-validator-identifier@7.29.7': {} + '@babel/parser@7.29.8': + dependencies: + '@babel/types': 7.29.8 - '@babel/parser@7.29.8': - dependencies: - '@babel/types': 7.29.8 + '@babel/runtime@7.29.7': {} - '@babel/runtime@7.29.7': {} + '@babel/runtime@8.0.0': {} - '@babel/runtime@8.0.0': {} + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 - '@babel/types@7.29.8': - dependencies: - '@babel/helper-string-parser': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 + '@borewit/text-codec@0.2.2': {} - '@borewit/text-codec@0.2.2': {} + '@emotion/hash@0.8.0': {} - '@emotion/hash@0.8.0': {} + '@emotion/unitless@0.7.5': {} - '@emotion/unitless@0.7.5': {} + '@esbuild/aix-ppc64@0.28.2': + optional: true - '@esbuild/aix-ppc64@0.28.2': - optional: true + '@esbuild/android-arm64@0.28.2': + optional: true - '@esbuild/android-arm64@0.28.2': - optional: true + '@esbuild/android-arm@0.28.2': + optional: true - '@esbuild/android-arm@0.28.2': - optional: true + '@esbuild/android-x64@0.28.2': + optional: true - '@esbuild/android-x64@0.28.2': - optional: true + '@esbuild/darwin-arm64@0.28.2': + optional: true - '@esbuild/darwin-arm64@0.28.2': - optional: true + '@esbuild/darwin-x64@0.28.2': + optional: true - '@esbuild/darwin-x64@0.28.2': - optional: true + '@esbuild/freebsd-arm64@0.28.2': + optional: true - '@esbuild/freebsd-arm64@0.28.2': - optional: true + '@esbuild/freebsd-x64@0.28.2': + optional: true - '@esbuild/freebsd-x64@0.28.2': - optional: true + '@esbuild/linux-arm64@0.28.2': + optional: true - '@esbuild/linux-arm64@0.28.2': - optional: true + '@esbuild/linux-arm@0.28.2': + optional: true - '@esbuild/linux-arm@0.28.2': - optional: true + '@esbuild/linux-ia32@0.28.2': + optional: true - '@esbuild/linux-ia32@0.28.2': - optional: true + '@esbuild/linux-loong64@0.28.2': + optional: true - '@esbuild/linux-loong64@0.28.2': - optional: true + '@esbuild/linux-mips64el@0.28.2': + optional: true - '@esbuild/linux-mips64el@0.28.2': - optional: true + '@esbuild/linux-ppc64@0.28.2': + optional: true - '@esbuild/linux-ppc64@0.28.2': - optional: true + '@esbuild/linux-riscv64@0.28.2': + optional: true - '@esbuild/linux-riscv64@0.28.2': - optional: true + '@esbuild/linux-s390x@0.28.2': + optional: true - '@esbuild/linux-s390x@0.28.2': - optional: true + '@esbuild/linux-x64@0.28.2': + optional: true - '@esbuild/linux-x64@0.28.2': - optional: true + '@esbuild/netbsd-arm64@0.28.2': + optional: true - '@esbuild/netbsd-arm64@0.28.2': - optional: true + '@esbuild/netbsd-x64@0.28.2': + optional: true - '@esbuild/netbsd-x64@0.28.2': - optional: true + '@esbuild/openbsd-arm64@0.28.2': + optional: true - '@esbuild/openbsd-arm64@0.28.2': - optional: true + '@esbuild/openbsd-x64@0.28.2': + optional: true - '@esbuild/openbsd-x64@0.28.2': - optional: true + '@esbuild/openharmony-arm64@0.28.2': + optional: true - '@esbuild/openharmony-arm64@0.28.2': - optional: true + '@esbuild/sunos-x64@0.28.2': + optional: true - '@esbuild/sunos-x64@0.28.2': - optional: true + '@esbuild/win32-arm64@0.28.2': + optional: true - '@esbuild/win32-arm64@0.28.2': - optional: true + '@esbuild/win32-ia32@0.28.2': + optional: true - '@esbuild/win32-ia32@0.28.2': - optional: true + '@esbuild/win32-x64@0.28.2': + optional: true - '@esbuild/win32-x64@0.28.2': - optional: true + '@ioredis/commands@2.0.0': {} - '@ioredis/commands@2.0.0': {} + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.6.0 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/resolve-uri@3.1.2': {} + '@jridgewell/sourcemap-codec@1.6.0': {} - '@jridgewell/sourcemap-codec@1.6.0': {} + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@lukeed/csprng@1.1.0': {} + + '@microsoft/tsdoc@0.16.0': {} + + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': + optional: true + + '@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + '@standard-schema/spec': 1.1.0 + file-type: 22.0.2 + iterare: 1.2.1 + load-esm: 1.0.3 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + transitivePeerDependencies: + - supports-color + + '@nestjs/config@12.0.0(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@standard-schema/spec': 1.1.0 + dotenv: 17.4.2 + dotenv-expand: 13.0.0 + es-toolkit: 1.51.0 + rxjs: 7.8.2 + + '@nestjs/core@12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@12.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + fast-safe-stringify: 2.1.1 + iterare: 1.2.1 + path-to-regexp: 8.4.2 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + optionalDependencies: + '@nestjs/platform-express': 12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@12.0.1) + + '@nestjs/mapped-types@12.0.0(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(reflect-metadata@0.2.2)': + dependencies: + '@nestjs/common': 12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + reflect-metadata: 0.2.2 + + '@nestjs/platform-express@12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@12.0.1)': + dependencies: + '@nestjs/common': 12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@12.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + cors: 2.8.6 + express: 5.2.1 + multer: 2.2.0 + path-to-regexp: 8.4.2 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@nestjs/swagger@12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@12.0.1)(reflect-metadata@0.2.2)': + dependencies: + '@microsoft/tsdoc': 0.16.0 + '@nestjs/common': 12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@12.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/mapped-types': 12.0.0(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(reflect-metadata@0.2.2) + '@standard-schema/spec': 1.1.0 + es-toolkit: 1.51.0 + js-yaml: 5.4.1 + path-to-regexp: 8.4.2 + reflect-metadata: 0.2.2 + swagger-ui-dist: 5.32.14 + + '@oxc-project/types@0.147.0': {} + + '@rc-component/async-validator@6.0.0': + dependencies: + '@babel/runtime': 7.29.7 + + '@rc-component/cascader@1.22.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/select': 1.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/tree': 1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/checkbox@2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/collapse@1.2.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@babel/runtime': 7.29.7 + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/color-picker@3.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@ant-design/fast-color': 3.0.1 + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/context@2.0.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/dialog@1.10.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/drawer@1.4.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/dropdown@1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/form@1.8.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/async-validator': 6.0.0 + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/image@1.10.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/input-number@1.6.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/mini-decimal': 1.1.4 + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/input@1.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/listy@1.2.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/virtual-list': 1.5.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/mentions@1.12.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/input': 1.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/menu': 1.5.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/menu@1.5.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/overflow': 1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/mini-decimal@1.1.4': + dependencies: + '@babel/runtime': 7.29.7 + + '@rc-component/motion@1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/mutate-observer@2.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/notification@2.0.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/overflow@1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@babel/runtime': 7.29.7 + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/pagination@1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/picker@1.12.0(dayjs@1.11.23)(luxon@3.7.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/overflow': 1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + optionalDependencies: + dayjs: 1.11.23 + luxon: 3.7.2 + + '@rc-component/portal@2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/progress@1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/qrcode@2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@babel/runtime': 7.29.7 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/rate@1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/resize-observer@1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/segmented@1.3.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@babel/runtime': 7.29.7 + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/select@1.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/overflow': 1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/virtual-list': 1.5.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/slider@1.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/steps@1.2.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/switch@1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/table@1.11.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/context': 2.0.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/virtual-list': 1.5.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/tabs@1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/dropdown': 1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/menu': 1.5.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/tooltip@1.5.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/tour@2.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/tree-select@1.16.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/select': 1.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/tree': 1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/tree@1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/virtual-list': 1.5.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/trigger@3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/upload@1.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rc-component/util@1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + is-mobile: 5.0.0 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + react-is: 19.2.8 + + '@rc-component/virtual-list@1.5.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': + dependencies: + '@babel/runtime': 8.0.0 + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + + '@rolldown/binding-android-arm-eabi@1.2.6': + optional: true + + '@rolldown/binding-android-arm64@1.2.6': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.6': + optional: true + + '@rolldown/binding-darwin-x64@1.2.6': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.6': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.6': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.6': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.6': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.6': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.6': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.6': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.6': + optional: true - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.6.0 - - '@lukeed/csprng@1.1.0': {} - - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': - optional: true - - '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': - optional: true - - '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': - optional: true - - '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': - optional: true - - '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': - optional: true - - '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': - optional: true - - '@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2)': - dependencies: - '@standard-schema/spec': 1.1.0 - file-type: 22.0.2 - iterare: 1.2.1 - load-esm: 1.0.3 - reflect-metadata: 0.2.2 - rxjs: 7.8.2 - tslib: 2.8.1 - uid: 2.0.2 - transitivePeerDependencies: - - supports-color - - '@nestjs/core@12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@12.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': - dependencies: - '@nestjs/common': 12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2) - fast-safe-stringify: 2.1.1 - iterare: 1.2.1 - path-to-regexp: 8.4.2 - reflect-metadata: 0.2.2 - rxjs: 7.8.2 - tslib: 2.8.1 - uid: 2.0.2 - optionalDependencies: - '@nestjs/platform-express': 12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@12.0.1) - - '@nestjs/platform-express@12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@12.0.1)': - dependencies: - '@nestjs/common': 12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 12.0.1(@nestjs/common@12.0.1(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@12.0.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) - cors: 2.8.6 - express: 5.2.1 - multer: 2.2.0 - path-to-regexp: 8.4.2 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - '@oxc-project/types@0.147.0': {} - - '@rc-component/async-validator@6.0.0': - dependencies: - '@babel/runtime': 7.29.7 - - '@rc-component/cascader@1.22.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/select': 1.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/tree': 1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/checkbox@2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/collapse@1.2.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@babel/runtime': 7.29.7 - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/color-picker@3.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@ant-design/fast-color': 3.0.1 - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/context@2.0.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/dialog@1.10.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/drawer@1.4.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/dropdown@1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/form@1.8.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/async-validator': 6.0.0 - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/image@1.10.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/input-number@1.6.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/mini-decimal': 1.1.4 - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/input@1.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/listy@1.2.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/virtual-list': 1.5.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/mentions@1.12.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/input': 1.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/menu': 1.5.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/menu@1.5.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/overflow': 1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/mini-decimal@1.1.4': - dependencies: - '@babel/runtime': 7.29.7 - - '@rc-component/motion@1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/mutate-observer@2.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/notification@2.0.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/overflow@1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@babel/runtime': 7.29.7 - '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/pagination@1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/picker@1.12.0(dayjs@1.11.23)(luxon@3.7.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/overflow': 1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - optionalDependencies: - dayjs: 1.11.23 - luxon: 3.7.2 - - '@rc-component/portal@2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/progress@1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/qrcode@2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@babel/runtime': 7.29.7 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/rate@1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/resize-observer@1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/segmented@1.3.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@babel/runtime': 7.29.7 - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/select@1.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/overflow': 1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/virtual-list': 1.5.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/slider@1.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/steps@1.2.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/switch@1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/table@1.11.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/context': 2.0.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/virtual-list': 1.5.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/tabs@1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/dropdown': 1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/menu': 1.5.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/tooltip@1.5.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/tour@2.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/tree-select@1.16.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/select': 1.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/tree': 1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/tree@1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/virtual-list': 1.5.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/trigger@3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/portal': 2.2.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/upload@1.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rc-component/util@1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - is-mobile: 5.0.0 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - react-is: 19.2.8 - - '@rc-component/virtual-list@1.5.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': - dependencies: - '@babel/runtime': 8.0.0 - '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - - '@rolldown/binding-android-arm-eabi@1.2.6': - optional: true - - '@rolldown/binding-android-arm64@1.2.6': - optional: true - - '@rolldown/binding-darwin-arm64@1.2.6': - optional: true - - '@rolldown/binding-darwin-x64@1.2.6': - optional: true - - '@rolldown/binding-freebsd-x64@1.2.6': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.2.6': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.2.6': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.2.6': - optional: true - - '@rolldown/binding-linux-ppc64-gnu@1.2.6': - optional: true + '@rolldown/binding-openharmony-arm64@1.2.6': + optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.6': - optional: true + '@rolldown/binding-win32-arm64-msvc@1.2.6': + optional: true - '@rolldown/binding-linux-x64-gnu@1.2.6': - optional: true + '@rolldown/binding-win32-x64-msvc@1.2.6': + optional: true - '@rolldown/binding-linux-x64-musl@1.2.6': - optional: true + '@rolldown/pluginutils@1.0.1': {} - '@rolldown/binding-openharmony-arm64@1.2.6': - optional: true + '@scarf/scarf@1.4.0': {} - '@rolldown/binding-win32-arm64-msvc@1.2.6': - optional: true + '@standard-schema/spec@1.1.0': {} - '@rolldown/binding-win32-x64-msvc@1.2.6': - optional: true + '@tokenizer/inflate@0.4.1': + dependencies: + debug: 4.4.3 + token-types: 6.1.2 + transitivePeerDependencies: + - supports-color - '@rolldown/pluginutils@1.0.1': {} + '@tokenizer/token@0.3.0': {} - '@standard-schema/spec@1.1.0': {} + '@topcli/prompts@4.0.0': {} - '@tokenizer/inflate@0.4.1': - dependencies: - debug: 4.4.3 - token-types: 6.1.2 - transitivePeerDependencies: - - supports-color + '@turbo/darwin-64@2.10.12': + optional: true - '@tokenizer/token@0.3.0': {} + '@turbo/darwin-arm64@2.10.12': + optional: true - '@topcli/prompts@4.0.0': {} + '@turbo/linux-64@2.10.12': + optional: true - '@turbo/darwin-64@2.10.12': - optional: true + '@turbo/linux-arm64@2.10.12': + optional: true - '@turbo/darwin-arm64@2.10.12': - optional: true + '@turbo/windows-64@2.10.12': + optional: true - '@turbo/linux-64@2.10.12': - optional: true + '@turbo/windows-arm64@2.10.12': + optional: true - '@turbo/linux-arm64@2.10.12': - optional: true + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 26.3.0 - '@turbo/windows-64@2.10.12': - optional: true + '@types/connect@3.4.38': + dependencies: + '@types/node': 26.3.0 - '@turbo/windows-arm64@2.10.12': - optional: true + '@types/estree@1.0.9': {} - '@types/estree@1.0.9': {} + '@types/express-serve-static-core@5.1.3': + dependencies: + '@types/node': 26.3.0 + '@types/qs': 6.15.1 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 - '@types/filesystem@0.0.36': - dependencies: - '@types/filewriter': 0.0.33 + '@types/express@5.0.6': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 5.1.3 + '@types/serve-static': 2.2.0 - '@types/filewriter@0.0.33': {} + '@types/filesystem@0.0.36': + dependencies: + '@types/filewriter': 0.0.33 - '@types/har-format@1.2.16': {} + '@types/filewriter@0.0.33': {} - '@types/node@26.3.0': - dependencies: - undici-types: 8.3.0 + '@types/har-format@1.2.16': {} - '@types/pg@8.23.1': - dependencies: - '@types/node': 26.3.0 - pg-protocol: 1.16.0 - pg-types: 2.2.0 + '@types/http-errors@2.0.5': {} - '@types/react-dom@19.2.5(@types/react@19.2.18)': - dependencies: - '@types/react': 19.2.18 + '@types/node@26.3.0': + dependencies: + undici-types: 8.3.0 - '@types/react@19.2.18': - dependencies: - csstype: 3.2.3 + '@types/pg@8.23.1': + dependencies: + '@types/node': 26.3.0 + pg-protocol: 1.16.0 + pg-types: 2.2.0 - '@typescript/typescript-aix-ppc64@7.0.2': - optional: true + '@types/qs@6.15.1': {} - '@typescript/typescript-darwin-arm64@7.0.2': - optional: true + '@types/range-parser@1.2.7': {} - '@typescript/typescript-darwin-x64@7.0.2': - optional: true + '@types/react-dom@19.2.5(@types/react@19.2.18)': + dependencies: + '@types/react': 19.2.18 - '@typescript/typescript-freebsd-arm64@7.0.2': - optional: true + '@types/react@19.2.18': + dependencies: + csstype: 3.2.3 - '@typescript/typescript-freebsd-x64@7.0.2': - optional: true + '@types/send@1.2.1': + dependencies: + '@types/node': 26.3.0 - '@typescript/typescript-linux-arm64@7.0.2': - optional: true + '@types/serve-static@2.2.0': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 26.3.0 - '@typescript/typescript-linux-arm@7.0.2': - optional: true + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true - '@typescript/typescript-linux-loong64@7.0.2': - optional: true + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true - '@typescript/typescript-linux-mips64el@7.0.2': - optional: true + '@typescript/typescript-darwin-x64@7.0.2': + optional: true - '@typescript/typescript-linux-ppc64@7.0.2': - optional: true + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true - '@typescript/typescript-linux-riscv64@7.0.2': - optional: true + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true - '@typescript/typescript-linux-s390x@7.0.2': - optional: true + '@typescript/typescript-linux-arm64@7.0.2': + optional: true - '@typescript/typescript-linux-x64@7.0.2': - optional: true + '@typescript/typescript-linux-arm@7.0.2': + optional: true - '@typescript/typescript-netbsd-arm64@7.0.2': - optional: true + '@typescript/typescript-linux-loong64@7.0.2': + optional: true - '@typescript/typescript-netbsd-x64@7.0.2': - optional: true - - '@typescript/typescript-openbsd-arm64@7.0.2': - optional: true - - '@typescript/typescript-openbsd-x64@7.0.2': - optional: true - - '@typescript/typescript-sunos-x64@7.0.2': - optional: true - - '@typescript/typescript-win32-arm64@7.0.2': - optional: true - - '@typescript/typescript-win32-x64@7.0.2': - optional: true - - '@vitejs/plugin-react@6.1.1(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13))': - dependencies: - '@rolldown/pluginutils': 1.0.1 - vite: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13) - - '@webext-core/fake-browser@2.0.1': - dependencies: - '@wxt-dev/browser': 0.2.7 - lodash.merge: 4.6.2 - - '@webext-core/isolated-element@3.0.0': - dependencies: - is-potential-custom-element-name: 1.0.1 - - '@webext-core/match-patterns@2.0.0': {} - - '@wxt-dev/browser@0.2.7': - dependencies: - '@types/filesystem': 0.0.36 - '@types/har-format': 1.2.16 - - '@wxt-dev/module-react@1.2.2(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13))(wxt@0.21.4(esbuild@0.28.2)(rolldown@1.2.6)(typescript@7.0.2)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)))': - dependencies: - '@vitejs/plugin-react': 6.1.1(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) - vite: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13) - wxt: 0.21.4(esbuild@0.28.2)(rolldown@1.2.6)(typescript@7.0.2)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) - transitivePeerDependencies: - - '@rolldown/plugin-babel' - - babel-plugin-react-compiler - - oxc-transform-react - - '@wxt-dev/storage@1.2.9': - dependencies: - '@wxt-dev/browser': 0.2.7 - superlock: 1.3.5 - - accepts@2.0.0: - dependencies: - mime-types: 3.0.2 - negotiator: 1.1.0 - - acorn@8.18.0: {} - - agent-base@6.0.2: - dependencies: - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - ansi-regex@5.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - antd@6.6.2(luxon@3.7.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): - dependencies: - '@ant-design/colors': 8.0.1 - '@ant-design/cssinjs': 2.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@ant-design/cssinjs-utils': 2.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@ant-design/fast-color': 3.0.1 - '@ant-design/icons': 6.3.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@ant-design/react-slick': 2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@babel/runtime': 7.29.7 - '@rc-component/cascader': 1.22.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/checkbox': 2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/collapse': 1.2.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/color-picker': 3.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/dialog': 1.10.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/drawer': 1.4.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/dropdown': 1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/form': 1.8.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/image': 1.10.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/input': 1.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/input-number': 1.6.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/listy': 1.2.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/mentions': 1.12.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/menu': 1.5.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/mutate-observer': 2.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/notification': 2.0.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/pagination': 1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/picker': 1.12.0(dayjs@1.11.23)(luxon@3.7.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/progress': 1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/qrcode': 2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/rate': 1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/segmented': 1.3.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/select': 1.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/slider': 1.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/steps': 1.2.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/switch': 1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/table': 1.11.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/tabs': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/tooltip': 1.5.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/tour': 2.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/tree': 1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/tree-select': 1.16.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/upload': 1.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - clsx: 2.1.1 - dayjs: 1.11.23 - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - scroll-into-view-if-needed: 3.1.0 - throttle-debounce: 5.0.2 - transitivePeerDependencies: - - date-fns - - luxon - - moment - - append-field@1.0.0: {} - - asynckit@0.4.0: {} - - axios@1.20.0(debug@4.4.3): - dependencies: - follow-redirects: 1.16.0(debug@4.4.3) - form-data: 4.0.6 - https-proxy-agent: 5.0.1 - proxy-from-env: 2.1.0 - transitivePeerDependencies: - - debug - - supports-color - - body-parser@2.3.0: - dependencies: - bytes: 3.1.2 - content-type: 2.1.0 - debug: 4.4.3 - http-errors: 2.0.1 - iconv-lite: 0.7.3 - on-finished: 2.4.1 - qs: 6.16.0 - raw-body: 3.0.2 - type-is: 2.1.0 - transitivePeerDependencies: - - supports-color - - boolbase@2.0.0: {} - - buffer-from@1.1.2: {} - - bullmq@6.3.4(ioredis@6.0.0)(pg@8.23.0): - dependencies: - cron-parser: 5.10.0 - msgpackr: 2.1.0 - node-abort-controller: 3.1.1 - semver: 7.8.5 - tslib: 2.8.1 - optionalDependencies: - ioredis: 6.0.0 - pg: 8.23.0 - - busboy@1.6.0: - dependencies: - streamsearch: 1.1.0 - - bytes@3.1.2: {} - - c12@3.3.4(magicast@0.5.4): - dependencies: - chokidar: 5.0.0 - confbox: 0.2.4 - defu: 6.1.7 - dotenv: 17.4.2 - exsolve: 1.1.1 - giget: 3.3.1 - jiti: 2.7.0 - ohash: 2.0.12 - pathe: 2.0.3 - perfect-debounce: 2.1.0 - pkg-types: 2.3.1 - rc9: 3.0.1 - optionalDependencies: - magicast: 0.5.4 - - cac@7.0.0: {} - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - chokidar@5.0.0: - dependencies: - readdirp: 5.1.1 - - citty@0.2.2: {} - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true - clsx@2.1.1: {} + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true - cluster-key-slot@1.1.1: {} + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + '@vitejs/plugin-react@6.1.1(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13))': + dependencies: + '@rolldown/pluginutils': 1.0.1 + vite: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13) + + '@webext-core/fake-browser@2.0.1': + dependencies: + '@wxt-dev/browser': 0.2.7 + lodash.merge: 4.6.2 + + '@webext-core/isolated-element@3.0.0': + dependencies: + is-potential-custom-element-name: 1.0.1 + + '@webext-core/match-patterns@2.0.0': {} + + '@wxt-dev/browser@0.2.7': + dependencies: + '@types/filesystem': 0.0.36 + '@types/har-format': 1.2.16 + + '@wxt-dev/module-react@1.2.2(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13))(wxt@0.21.4(esbuild@0.28.2)(rolldown@1.2.6)(typescript@7.0.2)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)))': + dependencies: + '@vitejs/plugin-react': 6.1.1(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) + vite: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13) + wxt: 0.21.4(esbuild@0.28.2)(rolldown@1.2.6)(typescript@7.0.2)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) + transitivePeerDependencies: + - '@rolldown/plugin-babel' + - babel-plugin-react-compiler + - oxc-transform-react + + '@wxt-dev/storage@1.2.9': + dependencies: + '@wxt-dev/browser': 0.2.7 + superlock: 1.3.5 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.1.0 + + acorn@8.18.0: {} + + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + antd@6.6.2(luxon@3.7.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + dependencies: + '@ant-design/colors': 8.0.1 + '@ant-design/cssinjs': 2.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@ant-design/cssinjs-utils': 2.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@ant-design/fast-color': 3.0.1 + '@ant-design/icons': 6.3.4(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@ant-design/react-slick': 2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@babel/runtime': 7.29.7 + '@rc-component/cascader': 1.22.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/checkbox': 2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/collapse': 1.2.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/color-picker': 3.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/dialog': 1.10.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/drawer': 1.4.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/dropdown': 1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/form': 1.8.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/image': 1.10.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/input': 1.3.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/input-number': 1.6.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/listy': 1.2.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/mentions': 1.12.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/menu': 1.5.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/motion': 1.3.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/mutate-observer': 2.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/notification': 2.0.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/pagination': 1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/picker': 1.12.0(dayjs@1.11.23)(luxon@3.7.2)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/progress': 1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/qrcode': 2.0.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/rate': 1.0.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/resize-observer': 1.1.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/segmented': 1.3.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/select': 1.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/slider': 1.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/steps': 1.2.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/switch': 1.0.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/table': 1.11.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/tabs': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/tooltip': 1.5.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/tour': 2.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/tree': 1.4.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/tree-select': 1.16.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/trigger': 3.10.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/upload': 1.1.1(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + '@rc-component/util': 1.13.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + clsx: 2.1.1 + dayjs: 1.11.23 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + scroll-into-view-if-needed: 3.1.0 + throttle-debounce: 5.0.2 + transitivePeerDependencies: + - date-fns + - luxon + - moment + + append-field@1.0.0: {} + + argparse@2.0.1: {} + + asynckit@0.4.0: {} + + axios@1.20.0(debug@4.4.3): + dependencies: + follow-redirects: 1.16.0(debug@4.4.3) + form-data: 4.0.6 + https-proxy-agent: 5.0.1 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + - supports-color + + body-parser@2.3.0: + dependencies: + bytes: 3.1.2 + content-type: 2.1.0 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + on-finished: 2.4.1 + qs: 6.16.0 + raw-body: 3.0.2 + type-is: 2.1.0 + transitivePeerDependencies: + - supports-color + + boolbase@2.0.0: {} + + buffer-from@1.1.2: {} + + bullmq@6.3.4(ioredis@6.0.0)(pg@8.23.0): + dependencies: + cron-parser: 5.10.0 + msgpackr: 2.1.0 + node-abort-controller: 3.1.1 + semver: 7.8.5 + tslib: 2.8.1 + optionalDependencies: + ioredis: 6.0.0 + pg: 8.23.0 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + bytes@3.1.2: {} + + c12@3.3.4(magicast@0.5.4): + dependencies: + chokidar: 5.0.0 + confbox: 0.2.4 + defu: 6.1.7 + dotenv: 17.4.2 + exsolve: 1.1.1 + giget: 3.3.1 + jiti: 2.7.0 + ohash: 2.0.12 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.1 + rc9: 3.0.1 + optionalDependencies: + magicast: 0.5.4 + + cac@7.0.0: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 - color-name@1.1.4: {} + citty@0.2.2: {} - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 - compute-scroll-into-view@3.1.1: {} + clsx@2.1.1: {} - concat-stream@2.0.0: - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 3.6.2 - typedarray: 0.0.6 + cluster-key-slot@1.1.1: {} - confbox@0.1.8: {} + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 - confbox@0.2.4: {} + color-name@1.1.4: {} - consola@3.4.2: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 - content-disposition@1.1.0: {} + compute-scroll-into-view@3.1.1: {} - content-type@1.0.5: {} + concat-stream@2.0.0: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + typedarray: 0.0.6 - content-type@2.1.0: {} + confbox@0.1.8: {} - cookie-signature@1.2.2: {} + confbox@0.2.4: {} - cookie@0.7.2: {} + consola@3.4.2: {} - cookie@1.1.1: {} + content-disposition@1.1.0: {} - cors@2.8.6: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 + content-type@1.0.5: {} - cron-parser@5.10.0: - dependencies: - luxon: 3.7.2 + content-type@2.1.0: {} - css-select@7.0.0: - dependencies: - boolbase: 2.0.0 - css-what: 8.0.0 - domhandler: 6.0.1 - domutils: 4.0.2 - nth-check: 3.0.1 + cookie-signature@1.2.2: {} - css-what@8.0.0: {} + cookie@0.7.2: {} - cssom@0.5.0: {} + cookie@1.1.1: {} - csstype@3.2.3: {} + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 - dayjs@1.11.23: {} + cron-parser@5.10.0: + dependencies: + luxon: 3.7.2 - debug@4.4.3: - dependencies: - ms: 2.1.3 + css-select@7.0.0: + dependencies: + boolbase: 2.0.0 + css-what: 8.0.0 + domhandler: 6.0.1 + domutils: 4.0.2 + nth-check: 3.0.1 - define-lazy-prop@2.0.0: {} + css-what@8.0.0: {} - defu@6.1.7: {} + cssom@0.5.0: {} - delayed-stream@1.0.0: {} + csstype@3.2.3: {} - denque@2.1.0: {} + dayjs@1.11.23: {} - depd@2.0.0: {} + debug@4.4.3: + dependencies: + ms: 2.1.3 - destr@2.0.5: {} + define-lazy-prop@2.0.0: {} - detect-libc@2.1.2: {} + defu@6.1.7: {} - dom-serializer@2.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 + delayed-stream@1.0.0: {} - dom-serializer@3.1.1: - dependencies: - domelementtype: 3.0.0 - domhandler: 6.0.1 - entities: 8.0.0 + denque@2.1.0: {} - domelementtype@2.3.0: {} + depd@2.0.0: {} - domelementtype@3.0.0: {} + destr@2.0.5: {} - domhandler@5.0.3: - dependencies: - domelementtype: 2.3.0 + detect-libc@2.1.2: {} - domhandler@6.0.1: - dependencies: - domelementtype: 3.0.0 + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 - domutils@3.2.2: - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 + dom-serializer@3.1.1: + dependencies: + domelementtype: 3.0.0 + domhandler: 6.0.1 + entities: 8.0.0 - domutils@4.0.2: - dependencies: - dom-serializer: 3.1.1 - domelementtype: 3.0.0 - domhandler: 6.0.1 + domelementtype@2.3.0: {} - dotenv-expand@13.0.0: - dependencies: - dotenv: 17.4.2 + domelementtype@3.0.0: {} - dotenv@17.4.2: {} + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - ee-first@1.1.1: {} - - emoji-regex@8.0.0: {} - - encodeurl@2.0.0: {} - - entities@4.5.0: {} - - entities@7.0.1: {} - - entities@8.0.0: {} - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-object-atoms@1.1.2: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.4 - - esbuild@0.28.2: - 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 - - escalade@3.2.0: {} - - escape-html@1.0.3: {} - - escape-string-regexp@5.0.0: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.9 - - etag@1.8.1: {} - - express@5.2.1: - dependencies: - accepts: 2.0.0 - body-parser: 2.3.0 - content-disposition: 1.1.0 - content-type: 1.0.5 - cookie: 0.7.2 - cookie-signature: 1.2.2 - debug: 4.4.3 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 2.1.1 - fresh: 2.0.0 - http-errors: 2.0.1 - merge-descriptors: 2.0.0 - mime-types: 3.0.2 - on-finished: 2.4.1 - once: 1.4.0 - parseurl: 1.3.3 - proxy-addr: 2.0.7 - qs: 6.16.0 - range-parser: 1.3.0 - router: 2.2.0 - send: 1.2.1 - serve-static: 2.2.1 - statuses: 2.0.2 - type-is: 2.1.0 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - exsolve@1.1.1: {} - - fast-safe-stringify@2.1.1: {} - - fdir@6.5.0(picomatch@4.0.7): - optionalDependencies: - picomatch: 4.0.7 - - file-type@22.0.2: - dependencies: - '@tokenizer/inflate': 0.4.1 - strtok3: 10.3.5 - token-types: 6.1.2 - uint8array-extras: 1.5.0 - transitivePeerDependencies: - - supports-color - - filesize@11.0.22: {} - - finalhandler@2.1.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - follow-redirects@1.16.0(debug@4.4.3): - optionalDependencies: - debug: 4.4.3 - - form-data@4.0.6: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.4 - mime-types: 2.1.35 - - forwarded@0.2.0: {} - - fresh@2.0.0: {} - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - get-caller-file@2.0.5: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.2 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.4 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.2 - - giget@3.3.1: {} - - gopd@1.2.0: {} - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.4: - dependencies: - function-bind: 1.1.2 + domhandler@6.0.1: + dependencies: + domelementtype: 3.0.0 - hookable@6.1.1: {} + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 - html-escaper@3.0.3: {} + domutils@4.0.2: + dependencies: + dom-serializer: 3.1.1 + domelementtype: 3.0.0 + domhandler: 6.0.1 - htmlparser2@10.1.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.2.2 - entities: 7.0.1 + dotenv-expand@13.0.0: + dependencies: + dotenv: 17.4.2 - http-errors@2.0.1: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.2 - toidentifier: 1.0.1 + dotenv@17.4.2: {} - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + + emoji-regex@8.0.0: {} + + encodeurl@2.0.0: {} + + entities@4.5.0: {} + + entities@7.0.1: {} + + entities@8.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + es-toolkit@1.51.0: {} + + esbuild@0.28.2: + 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 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@5.0.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + + etag@1.8.1: {} + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.3.0 + content-disposition: 1.1.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.16.0 + range-parser: 1.3.0 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.1.0 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + exsolve@1.1.1: {} + + fast-safe-stringify@2.1.1: {} + + fdir@6.5.0(picomatch@4.0.7): + optionalDependencies: + picomatch: 4.0.7 + + file-type@22.0.2: + dependencies: + '@tokenizer/inflate': 0.4.1 + strtok3: 10.3.5 + token-types: 6.1.2 + uint8array-extras: 1.5.0 + transitivePeerDependencies: + - supports-color + + filesize@11.0.22: {} + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + follow-redirects@1.16.0(debug@4.4.3): + optionalDependencies: + debug: 4.4.3 + + form-data@4.0.6: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.4 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + giget@3.3.1: {} + + gopd@1.2.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 - iconv-lite@0.7.3: - dependencies: - safer-buffer: 2.1.2 + helmet@8.3.0: {} - ieee754@1.2.1: {} + hookable@6.1.1: {} - inherits@2.0.4: {} + html-escaper@3.0.3: {} - ioredis@6.0.0: - dependencies: - '@ioredis/commands': 2.0.0 - cluster-key-slot: 1.1.1 - debug: 4.4.3 - denque: 2.1.0 - redis-errors: 1.2.0 - standard-as-callback: 2.1.0 - transitivePeerDependencies: - - supports-color + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 - ipaddr.js@1.9.1: {} + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 - is-docker@2.2.1: {} + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color - is-fullwidth-code-point@3.0.0: {} + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 - is-mobile@5.0.0: {} + ieee754@1.2.1: {} - is-potential-custom-element-name@1.0.1: {} + inherits@2.0.4: {} - is-promise@4.0.0: {} + ioredis@6.0.0: + dependencies: + '@ioredis/commands': 2.0.0 + cluster-key-slot: 1.1.1 + debug: 4.4.3 + denque: 2.1.0 + redis-errors: 1.2.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color - is-wsl@2.2.0: - dependencies: - is-docker: 2.2.1 + ipaddr.js@1.9.1: {} - iterare@1.2.1: {} + is-docker@2.2.1: {} - jiti@2.7.0: {} + is-fullwidth-code-point@3.0.0: {} - js-tokens@10.0.0: {} + is-mobile@5.0.0: {} - json2mq@0.2.0: - dependencies: - string-convert: 0.2.1 + is-potential-custom-element-name@1.0.1: {} - json5@2.2.3: {} + is-promise@4.0.0: {} - lightningcss-android-arm64@1.33.0: - optional: true + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 - lightningcss-darwin-arm64@1.33.0: - optional: true + iterare@1.2.1: {} - lightningcss-darwin-x64@1.33.0: - optional: true + jiti@2.7.0: {} - lightningcss-freebsd-x64@1.33.0: - optional: true + js-tokens@10.0.0: {} - lightningcss-linux-arm-gnueabihf@1.33.0: - optional: true + js-yaml@5.4.1: + dependencies: + argparse: 2.0.1 - lightningcss-linux-arm64-gnu@1.33.0: - optional: true + json2mq@0.2.0: + dependencies: + string-convert: 0.2.1 - lightningcss-linux-arm64-musl@1.33.0: - optional: true + json5@2.2.3: {} - lightningcss-linux-x64-gnu@1.33.0: - optional: true + lightningcss-android-arm64@1.33.0: + optional: true - lightningcss-linux-x64-musl@1.33.0: - optional: true + lightningcss-darwin-arm64@1.33.0: + optional: true - lightningcss-win32-arm64-msvc@1.33.0: - optional: true + lightningcss-darwin-x64@1.33.0: + optional: true - lightningcss-win32-x64-msvc@1.33.0: - optional: true + lightningcss-freebsd-x64@1.33.0: + optional: true - lightningcss@1.33.0: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.33.0 - lightningcss-darwin-arm64: 1.33.0 - lightningcss-darwin-x64: 1.33.0 - lightningcss-freebsd-x64: 1.33.0 - lightningcss-linux-arm-gnueabihf: 1.33.0 - lightningcss-linux-arm64-gnu: 1.33.0 - lightningcss-linux-arm64-musl: 1.33.0 - lightningcss-linux-x64-gnu: 1.33.0 - lightningcss-linux-x64-musl: 1.33.0 - lightningcss-win32-arm64-msvc: 1.33.0 - lightningcss-win32-x64-msvc: 1.33.0 + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true - linkedom@0.18.13: - dependencies: - css-select: 7.0.0 - cssom: 0.5.0 - html-escaper: 3.0.3 - htmlparser2: 10.1.0 - uhyphen: 0.2.0 + lightningcss-linux-arm64-gnu@1.33.0: + optional: true - load-esm@1.0.3: {} + lightningcss-linux-arm64-musl@1.33.0: + optional: true - local-pkg@1.2.1: - dependencies: - mlly: 1.8.2 - pkg-types: 2.3.1 - quansync: 0.2.11 + lightningcss-linux-x64-gnu@1.33.0: + optional: true - lodash.merge@4.6.2: {} + lightningcss-linux-x64-musl@1.33.0: + optional: true - luxon@3.7.2: {} + lightningcss-win32-arm64-msvc@1.33.0: + optional: true - magic-string@1.2.3: - dependencies: - '@jridgewell/sourcemap-codec': 1.6.0 + lightningcss-win32-x64-msvc@1.33.0: + optional: true - magicast@0.5.4: - dependencies: - '@babel/parser': 7.29.8 - '@babel/types': 7.29.8 - source-map-js: 1.2.1 + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 - many-keys-map@3.0.3: {} + linkedom@0.18.13: + dependencies: + css-select: 7.0.0 + cssom: 0.5.0 + html-escaper: 3.0.3 + htmlparser2: 10.1.0 + uhyphen: 0.2.0 - math-intrinsics@1.1.0: {} + load-esm@1.0.3: {} - media-typer@0.3.0: {} + local-pkg@1.2.1: + dependencies: + mlly: 1.8.2 + pkg-types: 2.3.1 + quansync: 0.2.11 - media-typer@1.1.1: {} + lodash.merge@4.6.2: {} - merge-descriptors@2.0.0: {} + luxon@3.7.2: {} - mime-db@1.52.0: {} + magic-string@1.2.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 - mime-db@1.54.0: {} + magicast@0.5.4: + dependencies: + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + source-map-js: 1.2.1 - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 + many-keys-map@3.0.3: {} - mime-types@3.0.2: - dependencies: - mime-db: 1.54.0 + math-intrinsics@1.1.0: {} - mlly@1.8.2: - dependencies: - acorn: 8.18.0 - pathe: 2.0.3 - pkg-types: 1.3.1 - ufo: 1.6.4 + media-typer@0.3.0: {} - ms@2.1.3: {} + media-typer@1.1.1: {} - msgpackr-extract@3.0.4: - dependencies: - node-gyp-build-optional-packages: 5.2.2 - optionalDependencies: - '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.4 - '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.4 - '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.4 - '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.4 - '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.4 - '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4 - optional: true + merge-descriptors@2.0.0: {} - msgpackr@2.1.0: - optionalDependencies: - msgpackr-extract: 3.0.4 + mime-db@1.52.0: {} - multer@2.2.0: - dependencies: - append-field: 1.0.0 - busboy: 1.6.0 - concat-stream: 2.0.0 - type-is: 1.6.18 + mime-db@1.54.0: {} - nanoid@3.3.18: {} + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 - negotiator@1.1.0: - dependencies: - content-type: 2.1.0 + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 - node-abort-controller@3.1.1: {} + mlly@1.8.2: + dependencies: + acorn: 8.18.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.4 - node-gyp-build-optional-packages@5.2.2: - dependencies: - detect-libc: 2.1.2 - optional: true + ms@2.1.3: {} - nth-check@3.0.1: - dependencies: - boolbase: 2.0.0 + msgpackr-extract@3.0.4: + dependencies: + node-gyp-build-optional-packages: 5.2.2 + optionalDependencies: + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.4 + '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4 + optional: true - nypm@0.6.9: - dependencies: - citty: 0.2.2 - pathe: 2.0.3 - tinyexec: 1.3.0 + msgpackr@2.1.0: + optionalDependencies: + msgpackr-extract: 3.0.4 - object-assign@4.1.1: {} + multer@2.2.0: + dependencies: + append-field: 1.0.0 + busboy: 1.6.0 + concat-stream: 2.0.0 + type-is: 1.6.18 - object-inspect@1.13.4: {} + nanoid@3.3.18: {} - ohash@2.0.12: {} + negotiator@1.1.0: + dependencies: + content-type: 2.1.0 - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 + node-abort-controller@3.1.1: {} - once@1.4.0: - dependencies: - wrappy: 1.0.2 + node-gyp-build-optional-packages@5.2.2: + dependencies: + detect-libc: 2.1.2 + optional: true - open@8.4.2: - dependencies: - define-lazy-prop: 2.0.0 - is-docker: 2.2.1 - is-wsl: 2.2.0 + nth-check@3.0.1: + dependencies: + boolbase: 2.0.0 - parseurl@1.3.3: {} + nypm@0.6.9: + dependencies: + citty: 0.2.2 + pathe: 2.0.3 + tinyexec: 1.3.0 - path-to-regexp@8.4.2: {} + object-assign@4.1.1: {} - pathe@2.0.3: {} + object-inspect@1.13.4: {} - perfect-debounce@2.1.0: {} + ohash@2.0.12: {} - pg-cloudflare@1.4.0: - optional: true + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 - pg-connection-string@2.14.0: {} + once@1.4.0: + dependencies: + wrappy: 1.0.2 - pg-int8@1.0.1: {} + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 - pg-pool@3.14.0(pg@8.23.0): - dependencies: - pg: 8.23.0 + parseurl@1.3.3: {} - pg-protocol@1.16.0: {} + path-to-regexp@8.4.2: {} - pg-types@2.2.0: - dependencies: - pg-int8: 1.0.1 - postgres-array: 2.0.0 - postgres-bytea: 1.0.1 - postgres-date: 1.0.7 - postgres-interval: 1.2.0 + pathe@2.0.3: {} - pg@8.23.0: - dependencies: - pg-connection-string: 2.14.0 - pg-pool: 3.14.0(pg@8.23.0) - pg-protocol: 1.16.0 - pg-types: 2.2.0 - pgpass: 1.0.5 - optionalDependencies: - pg-cloudflare: 1.4.0 + perfect-debounce@2.1.0: {} - pgpass@1.0.5: - dependencies: - split2: 4.2.0 + pg-cloudflare@1.4.0: + optional: true - picocolors@1.1.1: {} + pg-connection-string@2.14.0: {} - picomatch@2.3.2: {} + pg-int8@1.0.1: {} - picomatch@4.0.7: {} + pg-pool@3.14.0(pg@8.23.0): + dependencies: + pg: 8.23.0 - pkg-types@1.3.1: - dependencies: - confbox: 0.1.8 - mlly: 1.8.2 - pathe: 2.0.3 + pg-protocol@1.16.0: {} - pkg-types@2.3.1: - dependencies: - confbox: 0.2.4 - exsolve: 1.1.1 - pathe: 2.0.3 + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.1 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 - postcss@8.5.26: - dependencies: - nanoid: 3.3.18 - picocolors: 1.1.1 - source-map-js: 1.2.1 + pg@8.23.0: + dependencies: + pg-connection-string: 2.14.0 + pg-pool: 3.14.0(pg@8.23.0) + pg-protocol: 1.16.0 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.4.0 - postgres-array@2.0.0: {} + pgpass@1.0.5: + dependencies: + split2: 4.2.0 - postgres-bytea@1.0.1: {} + picocolors@1.1.1: {} - postgres-date@1.0.7: {} + picomatch@2.3.2: {} - postgres-interval@1.2.0: - dependencies: - xtend: 4.0.2 - - prettier@3.9.6: {} - - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - proxy-from-env@2.1.0: {} - - publish-browser-extension@6.1.1: - dependencies: - '@topcli/prompts': 4.0.0 - cac: 7.0.0 - tasuku: 2.3.0 - - qs@6.16.0: - dependencies: - es-define-property: 1.0.1 - side-channel: 1.1.1 + picomatch@4.0.7: {} - quansync@0.2.11: {} + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 - range-parser@1.3.0: {} + pkg-types@2.3.1: + dependencies: + confbox: 0.2.4 + exsolve: 1.1.1 + pathe: 2.0.3 - raw-body@3.0.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.1 - iconv-lite: 0.7.3 - unpipe: 1.0.0 - - rc9@3.0.1: - dependencies: - defu: 6.1.7 - destr: 2.0.5 - - react-dom@19.2.8(react@19.2.8): - dependencies: - react: 19.2.8 - scheduler: 0.27.0 - - react-is@19.2.8: {} - - react-router-dom@7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8): - dependencies: - react: 19.2.8 - react-dom: 19.2.8(react@19.2.8) - react-router: 7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - - react-router@7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8): - dependencies: - cookie: 1.1.1 - react: 19.2.8 - set-cookie-parser: 2.7.2 - optionalDependencies: - react-dom: 19.2.8(react@19.2.8) - - react@19.2.8: {} - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - readdirp@5.1.1: {} - - redis-errors@1.2.0: {} - - reflect-metadata@0.2.2: {} - - require-directory@2.1.1: {} - - rolldown@1.2.6: - dependencies: - '@oxc-project/types': 0.147.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm-eabi': 1.2.6 - '@rolldown/binding-android-arm64': 1.2.6 - '@rolldown/binding-darwin-arm64': 1.2.6 - '@rolldown/binding-darwin-x64': 1.2.6 - '@rolldown/binding-freebsd-x64': 1.2.6 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.6 - '@rolldown/binding-linux-arm64-gnu': 1.2.6 - '@rolldown/binding-linux-arm64-musl': 1.2.6 - '@rolldown/binding-linux-ppc64-gnu': 1.2.6 - '@rolldown/binding-linux-s390x-gnu': 1.2.6 - '@rolldown/binding-linux-x64-gnu': 1.2.6 - '@rolldown/binding-linux-x64-musl': 1.2.6 - '@rolldown/binding-openharmony-arm64': 1.2.6 - '@rolldown/binding-win32-arm64-msvc': 1.2.6 - '@rolldown/binding-win32-x64-msvc': 1.2.6 - - router@2.2.0: - dependencies: - debug: 4.4.3 - depd: 2.0.0 - is-promise: 4.0.0 - parseurl: 1.3.3 - path-to-regexp: 8.4.2 - transitivePeerDependencies: - - supports-color - - rxjs@7.8.2: - dependencies: - tslib: 2.8.1 - - safe-buffer@5.2.1: {} - - safer-buffer@2.1.2: {} - - scheduler@0.27.0: {} - - scroll-into-view-if-needed@3.1.0: - dependencies: - compute-scroll-into-view: 3.1.1 - - scule@1.3.0: {} - - semver@7.8.5: {} - - send@1.2.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.1 - mime-types: 3.0.2 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.3.0 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - serve-static@2.2.1: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.1 - transitivePeerDependencies: - - supports-color - - set-cookie-parser@2.7.2: {} - - setprototypeof@1.2.0: {} - - side-channel-list@1.0.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.1 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - source-map-js@1.2.1: {} - - source-map@0.7.6: {} - - split2@4.2.0: {} - - standard-as-callback@2.1.0: {} - - statuses@2.0.2: {} - - streamsearch@1.1.0: {} - - string-convert@0.2.1: {} - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-literal@4.0.0: - dependencies: - js-tokens: 10.0.0 - - strtok3@10.3.5: - dependencies: - '@tokenizer/token': 0.3.0 - - stylis@4.4.0: {} - - superlock@1.3.5: {} - - tasuku@2.3.0: {} - - throttle-debounce@5.0.2: {} - - tiny-open@1.3.0: {} - - tinyexec@1.3.0: {} - - tinyglobby@0.2.17: - dependencies: - fdir: 6.5.0(picomatch@4.0.7) - picomatch: 4.0.7 - - toidentifier@1.0.1: {} - - token-types@6.1.2: - dependencies: - '@borewit/text-codec': 0.2.2 - '@tokenizer/token': 0.3.0 - ieee754: 1.2.1 - - tslib@2.8.1: {} - - tsx@4.23.13: - dependencies: - esbuild: 0.28.2 - optionalDependencies: - fsevents: 2.3.3 - - turbo@2.10.12: - optionalDependencies: - '@turbo/darwin-64': 2.10.12 - '@turbo/darwin-arm64': 2.10.12 - '@turbo/linux-64': 2.10.12 - '@turbo/linux-arm64': 2.10.12 - '@turbo/windows-64': 2.10.12 - '@turbo/windows-arm64': 2.10.12 - - type-is@1.6.18: - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - - type-is@2.1.0: - dependencies: - content-type: 2.1.0 - media-typer: 1.1.1 - mime-types: 3.0.2 - - typedarray@0.0.6: {} - - typescript@7.0.2: - optionalDependencies: - '@typescript/typescript-aix-ppc64': 7.0.2 - '@typescript/typescript-darwin-arm64': 7.0.2 - '@typescript/typescript-darwin-x64': 7.0.2 - '@typescript/typescript-freebsd-arm64': 7.0.2 - '@typescript/typescript-freebsd-x64': 7.0.2 - '@typescript/typescript-linux-arm': 7.0.2 - '@typescript/typescript-linux-arm64': 7.0.2 - '@typescript/typescript-linux-loong64': 7.0.2 - '@typescript/typescript-linux-mips64el': 7.0.2 - '@typescript/typescript-linux-ppc64': 7.0.2 - '@typescript/typescript-linux-riscv64': 7.0.2 - '@typescript/typescript-linux-s390x': 7.0.2 - '@typescript/typescript-linux-x64': 7.0.2 - '@typescript/typescript-netbsd-arm64': 7.0.2 - '@typescript/typescript-netbsd-x64': 7.0.2 - '@typescript/typescript-openbsd-arm64': 7.0.2 - '@typescript/typescript-openbsd-x64': 7.0.2 - '@typescript/typescript-sunos-x64': 7.0.2 - '@typescript/typescript-win32-arm64': 7.0.2 - '@typescript/typescript-win32-x64': 7.0.2 - - ufo@1.6.4: {} - - uhyphen@0.2.0: {} - - uid@2.0.2: - dependencies: - '@lukeed/csprng': 1.1.0 - - uint8array-extras@1.5.0: {} - - undici-types@8.3.0: {} - - unimport@6.4.0(esbuild@0.28.2)(rolldown@1.2.6)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)): - dependencies: - acorn: 8.18.0 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - local-pkg: 1.2.1 - magic-string: 1.2.3 - mlly: 1.8.2 - pathe: 2.0.3 - picomatch: 4.0.7 - pkg-types: 2.3.1 - scule: 1.3.0 - strip-literal: 4.0.0 - tinyglobby: 0.2.17 - unplugin: 3.3.0(esbuild@0.28.2)(rolldown@1.2.6)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) - unplugin-utils: 0.3.2 - optionalDependencies: - rolldown: 1.2.6 - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - esbuild - - rollup - - unloader - - vite - - webpack - - unpipe@1.0.0: {} - - unplugin-utils@0.3.2: - dependencies: - pathe: 2.0.3 - picomatch: 4.0.7 - - unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.6)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)): - dependencies: - '@jridgewell/remapping': 2.3.5 - picomatch: 4.0.7 - webpack-virtual-modules: 0.6.2 - optionalDependencies: - esbuild: 0.28.2 - rolldown: 1.2.6 - vite: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13) - - util-deprecate@1.0.2: {} - - vary@1.1.2: {} - - vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13): - dependencies: - lightningcss: 1.33.0 - picomatch: 4.0.7 - postcss: 8.5.26 - rolldown: 1.2.6 - tinyglobby: 0.2.17 - optionalDependencies: - '@types/node': 26.3.0 - esbuild: 0.28.2 - fsevents: 2.3.3 - jiti: 2.7.0 - tsx: 4.23.13 - - webpack-virtual-modules@0.6.2: {} - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrappy@1.0.2: {} - - wxt@0.21.4(esbuild@0.28.2)(rolldown@1.2.6)(typescript@7.0.2)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)): - dependencies: - '@1natsu/wait-element': 4.2.0 - '@aklinker1/rollup-plugin-visualizer': 5.12.0 - '@aklinker1/zero-zip': 1.0.1 - '@topcli/prompts': 4.0.0 - '@webext-core/fake-browser': 2.0.1 - '@webext-core/isolated-element': 3.0.0 - '@webext-core/match-patterns': 2.0.0 - '@wxt-dev/browser': 0.2.7 - '@wxt-dev/storage': 1.2.9 - c12: 3.3.4(magicast@0.5.4) - cac: 7.0.0 - chokidar: 5.0.0 - consola: 3.4.2 - defu: 6.1.7 - dotenv-expand: 13.0.0 - filesize: 11.0.22 - giget: 3.3.1 - hookable: 6.1.1 - json5: 2.2.3 - linkedom: 0.18.13 - magicast: 0.5.4 - nypm: 0.6.9 - picomatch: 4.0.7 - publish-browser-extension: 6.1.1 - superlock: 1.3.5 - tiny-open: 1.3.0 - tinyexec: 1.3.0 - tinyglobby: 0.2.17 - unimport: 6.4.0(esbuild@0.28.2)(rolldown@1.2.6)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) - vite: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13) - optionalDependencies: - typescript: 7.0.2 - transitivePeerDependencies: - - '@farmfe/core' - - '@rspack/core' - - bun-types-no-globals - - canvas - - esbuild - - oxc-parser - - rolldown - - rollup - - unloader - - webpack - - xtend@4.0.2: {} - - y18n@5.0.8: {} - - yargs-parser@21.1.1: {} - - yargs@17.7.3: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - zod@4.5.4: {} + postcss@8.5.26: + dependencies: + nanoid: 3.3.18 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postgres-array@2.0.0: {} + + postgres-bytea@1.0.1: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + + prettier@3.9.6: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@2.1.0: {} + + publish-browser-extension@6.1.1: + dependencies: + '@topcli/prompts': 4.0.0 + cac: 7.0.0 + tasuku: 2.3.0 + + qs@6.16.0: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + + quansync@0.2.11: {} + + range-parser@1.3.0: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + unpipe: 1.0.0 + + rc9@3.0.1: + dependencies: + defu: 6.1.7 + destr: 2.0.5 + + react-dom@19.2.8(react@19.2.8): + dependencies: + react: 19.2.8 + scheduler: 0.27.0 + + react-is@19.2.8: {} + + react-router-dom@7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + dependencies: + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + react-router: 7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8) + + react-router@7.18.3(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + dependencies: + cookie: 1.1.1 + react: 19.2.8 + set-cookie-parser: 2.7.2 + optionalDependencies: + react-dom: 19.2.8(react@19.2.8) + + react@19.2.8: {} + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@5.1.1: {} + + redis-errors@1.2.0: {} + + reflect-metadata@0.2.2: {} + + require-directory@2.1.1: {} + + rolldown@1.2.6: + dependencies: + '@oxc-project/types': 0.147.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.6 + '@rolldown/binding-android-arm64': 1.2.6 + '@rolldown/binding-darwin-arm64': 1.2.6 + '@rolldown/binding-darwin-x64': 1.2.6 + '@rolldown/binding-freebsd-x64': 1.2.6 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.6 + '@rolldown/binding-linux-arm64-gnu': 1.2.6 + '@rolldown/binding-linux-arm64-musl': 1.2.6 + '@rolldown/binding-linux-ppc64-gnu': 1.2.6 + '@rolldown/binding-linux-s390x-gnu': 1.2.6 + '@rolldown/binding-linux-x64-gnu': 1.2.6 + '@rolldown/binding-linux-x64-musl': 1.2.6 + '@rolldown/binding-openharmony-arm64': 1.2.6 + '@rolldown/binding-win32-arm64-msvc': 1.2.6 + '@rolldown/binding-win32-x64-msvc': 1.2.6 + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + scheduler@0.27.0: {} + + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + + scule@1.3.0: {} + + semver@7.8.5: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.3.0 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + set-cookie-parser@2.7.2: {} + + setprototypeof@1.2.0: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + source-map-js@1.2.1: {} + + source-map@0.7.6: {} + + split2@4.2.0: {} + + standard-as-callback@2.1.0: {} + + statuses@2.0.2: {} + + streamsearch@1.1.0: {} + + string-convert@0.2.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-literal@4.0.0: + dependencies: + js-tokens: 10.0.0 + + strtok3@10.3.5: + dependencies: + '@tokenizer/token': 0.3.0 + + stylis@4.4.0: {} + + superlock@1.3.5: {} + + swagger-ui-dist@5.32.14: + dependencies: + '@scarf/scarf': 1.4.0 + + tasuku@2.3.0: {} + + throttle-debounce@5.0.2: {} + + tiny-open@1.3.0: {} + + tinyexec@1.3.0: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + + toidentifier@1.0.1: {} + + token-types@6.1.2: + dependencies: + '@borewit/text-codec': 0.2.2 + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + + tslib@2.8.1: {} + + tsx@4.23.13: + dependencies: + esbuild: 0.28.2 + optionalDependencies: + fsevents: 2.3.3 + + turbo@2.10.12: + optionalDependencies: + '@turbo/darwin-64': 2.10.12 + '@turbo/darwin-arm64': 2.10.12 + '@turbo/linux-64': 2.10.12 + '@turbo/linux-arm64': 2.10.12 + '@turbo/windows-64': 2.10.12 + '@turbo/windows-arm64': 2.10.12 + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + type-is@2.1.0: + dependencies: + content-type: 2.1.0 + media-typer: 1.1.1 + mime-types: 3.0.2 + + typedarray@0.0.6: {} + + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + + ufo@1.6.4: {} + + uhyphen@0.2.0: {} + + uid@2.0.2: + dependencies: + '@lukeed/csprng': 1.1.0 + + uint8array-extras@1.5.0: {} + + undici-types@8.3.0: {} + + unimport@6.4.0(esbuild@0.28.2)(rolldown@1.2.6)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)): + dependencies: + acorn: 8.18.0 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + local-pkg: 1.2.1 + magic-string: 1.2.3 + mlly: 1.8.2 + pathe: 2.0.3 + picomatch: 4.0.7 + pkg-types: 2.3.1 + scule: 1.3.0 + strip-literal: 4.0.0 + tinyglobby: 0.2.17 + unplugin: 3.3.0(esbuild@0.28.2)(rolldown@1.2.6)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) + unplugin-utils: 0.3.2 + optionalDependencies: + rolldown: 1.2.6 + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rollup + - unloader + - vite + - webpack + + unpipe@1.0.0: {} + + unplugin-utils@0.3.2: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.7 + + unplugin@3.3.0(esbuild@0.28.2)(rolldown@1.2.6)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)): + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.7 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + esbuild: 0.28.2 + rolldown: 1.2.6 + vite: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13) + + util-deprecate@1.0.2: {} + + vary@1.1.2: {} + + vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13): + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.7 + postcss: 8.5.26 + rolldown: 1.2.6 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 26.3.0 + esbuild: 0.28.2 + fsevents: 2.3.3 + jiti: 2.7.0 + tsx: 4.23.13 + + webpack-virtual-modules@0.6.2: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + wxt@0.21.4(esbuild@0.28.2)(rolldown@1.2.6)(typescript@7.0.2)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)): + dependencies: + '@1natsu/wait-element': 4.2.0 + '@aklinker1/rollup-plugin-visualizer': 5.12.0 + '@aklinker1/zero-zip': 1.0.1 + '@topcli/prompts': 4.0.0 + '@webext-core/fake-browser': 2.0.1 + '@webext-core/isolated-element': 3.0.0 + '@webext-core/match-patterns': 2.0.0 + '@wxt-dev/browser': 0.2.7 + '@wxt-dev/storage': 1.2.9 + c12: 3.3.4(magicast@0.5.4) + cac: 7.0.0 + chokidar: 5.0.0 + consola: 3.4.2 + defu: 6.1.7 + dotenv-expand: 13.0.0 + filesize: 11.0.22 + giget: 3.3.1 + hookable: 6.1.1 + json5: 2.2.3 + linkedom: 0.18.13 + magicast: 0.5.4 + nypm: 0.6.9 + picomatch: 4.0.7 + publish-browser-extension: 6.1.1 + superlock: 1.3.5 + tiny-open: 1.3.0 + tinyexec: 1.3.0 + tinyglobby: 0.2.17 + unimport: 6.4.0(esbuild@0.28.2)(rolldown@1.2.6)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13)) + vite: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.13) + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - canvas + - esbuild + - oxc-parser + - rolldown + - rollup + - unloader + - webpack + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.3: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + zod@4.5.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 108c6d8..9628a10 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,5 +3,6 @@ packages: - packages/* allowBuilds: + '@scarf/scarf': false esbuild: true msgpackr-extract: false diff --git a/prettier.config.mjs b/prettier.config.mjs deleted file mode 100644 index 392f3b1..0000000 --- a/prettier.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -export default { - singleQuote: true, - trailingComma: 'all', - printWidth: 100, -}; diff --git a/tsconfig.base.json b/tsconfig.base.json index ad8d800..48f2b10 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,14 +1,14 @@ { - "compilerOptions": { - "target": "ES2023", - "module": "Node16", - "moduleResolution": "Node16", - "strict": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "skipLibCheck": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true - } + "compilerOptions": { + "target": "ES2023", + "module": "Node16", + "moduleResolution": "Node16", + "strict": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true + } } diff --git a/turbo.json b/turbo.json index e987225..9f0fa36 100644 --- a/turbo.json +++ b/turbo.json @@ -1,24 +1,24 @@ { - "$schema": "https://turbo.build/schema.json", - "tasks": { - "build": { - "dependsOn": ["^build"], - "outputs": ["dist/**", ".output/**"] - }, - "dev": { - "cache": false, - "persistent": true - }, - "lint": { - "dependsOn": ["^lint"] - }, - "typecheck": { - "dependsOn": ["^typecheck"], - "outputs": [] - }, - "test": { - "dependsOn": ["^build"], - "outputs": ["coverage/**"] + "$schema": "https://turbo.build/schema.json", + "tasks": { + "build": { + "dependsOn": ["^build"], + "outputs": ["dist/**", ".output/**"] + }, + "dev": { + "cache": false, + "persistent": true + }, + "lint": { + "dependsOn": ["^lint"] + }, + "typecheck": { + "dependsOn": ["^typecheck"], + "outputs": [] + }, + "test": { + "dependsOn": ["^build"], + "outputs": ["coverage/**"] + } } - } }