From 7db59c9290312741ff1067ca8d22b49a10871388 Mon Sep 17 00:00:00 2001 From: richarjiang Date: Sun, 15 Mar 2026 13:59:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20claw-market=20CLI?= =?UTF-8?q?=20=E5=B7=A5=E5=85=B7=E5=B9=B6=E6=9B=B4=E6=96=B0=20skill=20?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=20CLI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建 pnpm monorepo 结构 (pnpm-workspace.yaml) - 添加 @ricardweii/claw-market CLI 包 - register/heartbeat/task/config 命令 - 中英文国际化支持 - JSON 输出格式支持 - 更新 openclaw-reporter skill 使用 CLI 替代 curl - 修复注册 API 返回缺少 name 字段的问题 - 更新 CLAUDE.md 文档说明 monorepo 结构 --- CLAUDE.md | 69 +- app/api/v1/register/route.ts | 1 + package.json | 3 + packages/claw-market/.gitignore | 4 + packages/claw-market/README.md | 163 ++ packages/claw-market/README.zh.md | 163 ++ packages/claw-market/package.json | 62 + packages/claw-market/src/commands/config.ts | 117 ++ .../claw-market/src/commands/heartbeat.ts | 74 + packages/claw-market/src/commands/register.ts | 87 + packages/claw-market/src/commands/task.ts | 95 ++ packages/claw-market/src/i18n/en.json | 61 + packages/claw-market/src/i18n/index.ts | 70 + packages/claw-market/src/i18n/zh.json | 61 + packages/claw-market/src/index.ts | 69 + packages/claw-market/src/lib/api.ts | 176 +++ packages/claw-market/src/lib/config.ts | 118 ++ packages/claw-market/src/lib/platform.ts | 23 + packages/claw-market/src/lib/validate.ts | 66 + packages/claw-market/tsconfig.json | 21 + packages/claw-market/tsup.config.ts | 15 + pnpm-lock.yaml | 1402 +++++++++++++++++ pnpm-workspace.yaml | 2 + skill/openclaw-reporter/SKILL.md | 109 +- 24 files changed, 2968 insertions(+), 63 deletions(-) create mode 100644 packages/claw-market/.gitignore create mode 100644 packages/claw-market/README.md create mode 100644 packages/claw-market/README.zh.md create mode 100644 packages/claw-market/package.json create mode 100644 packages/claw-market/src/commands/config.ts create mode 100644 packages/claw-market/src/commands/heartbeat.ts create mode 100644 packages/claw-market/src/commands/register.ts create mode 100644 packages/claw-market/src/commands/task.ts create mode 100644 packages/claw-market/src/i18n/en.json create mode 100644 packages/claw-market/src/i18n/index.ts create mode 100644 packages/claw-market/src/i18n/zh.json create mode 100644 packages/claw-market/src/index.ts create mode 100644 packages/claw-market/src/lib/api.ts create mode 100644 packages/claw-market/src/lib/config.ts create mode 100644 packages/claw-market/src/lib/platform.ts create mode 100644 packages/claw-market/src/lib/validate.ts create mode 100644 packages/claw-market/tsconfig.json create mode 100644 packages/claw-market/tsup.config.ts create mode 100644 pnpm-workspace.yaml diff --git a/CLAUDE.md b/CLAUDE.md index 6d04094..21b3417 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,10 +4,33 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -OpenClaw Market is a real-time global heatmap dashboard that visualizes AI agent ("claw") activity worldwide. Agents install the `openclaw-reporter` skill, which sends anonymous heartbeats and task summaries to this server. The frontend renders a 3D globe and dashboard panels showing live activity via SSE. +OpenClaw Market is a real-time global heatmap dashboard that visualizes AI agent ("claw") activity worldwide. Agents install the `openclaw-reporter` skill or `@ricardweii/claw-market` CLI, which sends anonymous heartbeats and task summaries to this server. The frontend renders a 3D globe and dashboard panels showing live activity via SSE. + +## Monorepo Structure + +This is a pnpm monorepo with two packages: + +``` +openclaw-market/ +├── app/ # Next.js application (main web app) +├── lib/ # Shared libraries for web app +├── packages/ +│ └── claw-market/ # CLI tool (published to npm) +│ ├── src/ +│ │ ├── index.ts # CLI entry point +│ │ ├── commands/ # register, heartbeat, task, config +│ │ ├── lib/ # api, config, validate, platform +│ │ └── i18n/ # en.json, zh.json +│ └── package.json +├── skill/ +│ └── openclaw-reporter/ # Claude Code skill (uses CLI) +└── pnpm-workspace.yaml +``` ## Commands +### Main App + ```bash pnpm dev # Start dev server with Turbopack (localhost:3000) pnpm build # Production build @@ -19,11 +42,26 @@ pnpm db:studio # Open Drizzle Studio GUI bash scripts/deploy.sh # Build locally, rsync to server, restart PM2 ``` +### CLI Package + +```bash +pnpm --filter claw-market build # Build CLI +pnpm --filter claw-market lint # Type check CLI +pnpm --filter claw-market dev # Build with watch mode + +# Or from packages/claw-market: +cd packages/claw-market +pnpm build +node dist/index.js --help +``` + ## Architecture ### Data Flow -1. **Reporter skill** (`skill/openclaw-reporter/SKILL.md`) runs inside Claude Code sessions on user machines. It calls `/api/v1/register` once, then sends periodic heartbeats and task reports via Bearer token auth. +1. **Reporter sources**: + - **CLI** (`packages/claw-market/`) — Standalone npm package `@ricardweii/claw-market` + - **Skill** (`skill/openclaw-reporter/SKILL.md`) — Claude Code skill that wraps the CLI 2. **API routes** (`app/api/v1/`) validate requests, update MySQL via Drizzle, cache state in Redis, and publish events to a Redis Pub/Sub channel (`channel:realtime`). 3. **SSE endpoint** (`/api/v1/stream`) subscribes to Redis Pub/Sub and streams events to the browser. 4. **Frontend** is a single-page "use client" app. The homepage renders a 3D globe (`react-globe.gl`), dashboard panels, and a continent drill-down page. Data arrives via polling (`use-heatmap-data`) and SSE (`use-sse`). @@ -33,7 +71,7 @@ bash scripts/deploy.sh # Build locally, rsync to server, restart PM2 - **Auth**: Bearer token via `lib/auth/api-key.ts`. API keys are generated at registration, cached in Redis for 1 hour. - **Geo**: IP geolocation via `ip-api.com`, results cached in `geo_cache` MySQL table. Country-to-continent mapping in `lib/geo/ip-location.ts`. - **Real-time**: Redis Pub/Sub (`lib/redis/index.ts`) for event broadcasting. SSE stream route creates a per-connection Redis subscriber. -- **Validation**: Zod schemas in `lib/validators/schemas.ts`. +- **Validation**: Zod schemas in `lib/validators/schemas.ts`. Shared with CLI via copy (same structure). - **Database**: Drizzle ORM with MySQL (`mysql2` driver). Schema in `lib/db/schema.ts`. Tables: `claws`, `heartbeats`, `tasks`, `geo_cache`. - **Redis**: ioredis with two singleton clients (main + subscriber). Stores online status, active claw sorted sets, global/region stats, hourly activity, heatmap cache. - **i18n**: `next-intl` with locale-prefixed routing (`/en/...`, `/zh/...`). Config in `i18n/routing.ts`, middleware in `middleware.ts`, translations in `messages/en.json` and `messages/zh.json`. @@ -48,6 +86,16 @@ bash scripts/deploy.sh # Build locally, rsync to server, restart PM2 - `components/layout/` — Navbar, particle background, view switcher, install banner, language switcher - `messages/` — i18n translation files (en, zh) +### CLI Structure (`packages/claw-market/`) + +- `src/index.ts` — CLI entry point (commander) +- `src/commands/` — Command implementations (register, heartbeat, task, config) +- `src/lib/api.ts` — HTTP client for API calls +- `src/lib/config.ts` — Config file management (~/.openclaw/config.json) +- `src/lib/validate.ts` — Zod validation schemas +- `src/lib/platform.ts` — Platform/model detection +- `src/i18n/` — Translation files (en, zh) + ## Environment Variables See `.env.example`: `DATABASE_URL` (MySQL), `REDIS_URL`, `IP_API_URL`, `NEXT_PUBLIC_APP_URL`. @@ -55,3 +103,18 @@ See `.env.example`: `DATABASE_URL` (MySQL), `REDIS_URL`, `IP_API_URL`, `NEXT_PUB ## Deployment Production runs on a remote server via `scripts/deploy.sh` — builds locally, rsyncs to server, installs prod deps, restarts via PM2 on port 3003. + +## CLI Publishing + +The CLI is published to npm as `@ricardweii/claw-market`: + +```bash +cd packages/claw-market +npm publish --access public --otp= +``` + +Install globally: + +```bash +npm install -g @ricardweii/claw-market +``` diff --git a/app/api/v1/register/route.ts b/app/api/v1/register/route.ts index e9ddbce..8f05d1e 100644 --- a/app/api/v1/register/route.ts +++ b/app/api/v1/register/route.ts @@ -77,6 +77,7 @@ export async function POST(req: NextRequest) { return NextResponse.json({ clawId, apiKey, + name, endpoint: `${process.env.NEXT_PUBLIC_APP_URL}/api/v1`, }); } catch (error) { diff --git a/package.json b/package.json index 251970d..42ebd9d 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,9 @@ "name": "openclaw-market", "version": "0.1.0", "private": true, + "workspaces": [ + "packages/*" + ], "scripts": { "dev": "next dev", "build": "next build", diff --git a/packages/claw-market/.gitignore b/packages/claw-market/.gitignore new file mode 100644 index 0000000..dd6e803 --- /dev/null +++ b/packages/claw-market/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +dist/ +*.log +.DS_Store diff --git a/packages/claw-market/README.md b/packages/claw-market/README.md new file mode 100644 index 0000000..2877b45 --- /dev/null +++ b/packages/claw-market/README.md @@ -0,0 +1,163 @@ +# @ricardweii/claw-market + +CLI tool for OpenClaw Market - report AI agent activity to the global heatmap. + +## Installation + +```bash +npm install -g @ricardweii/claw-market +# or +pnpm add -g @ricardweii/claw-market +``` + +## Quick Start + +```bash +# Register your claw +claw-market register MyClaw + +# Send a heartbeat +claw-market heartbeat + +# Report a completed task +claw-market task "Fixed a bug" --duration 45000 +``` + +## Commands + +### `register` + +Register a new claw on the heatmap. + +```bash +claw-market register [options] +``` + +**Arguments:** +- `name` - Claw display name (1-100 characters) + +**Options:** +- `-p, --platform ` - Platform identifier (default: auto-detect) +- `-m, --model ` - Model identifier (default: from env or 'unknown') +- `-f, --force` - Force re-registration even if already registered + +**Examples:** +```bash +claw-market register CoolClaw +claw-market register "NightCrawler" --model claude-opus-4 +``` + +### `heartbeat` + +Send a heartbeat to update online status. + +```bash +claw-market heartbeat [options] +``` + +**Options:** +- `-n, --name ` - Update claw name +- `-m, --model ` - Update model identifier +- `-p, --platform ` - Update platform identifier + +**Examples:** +```bash +claw-market heartbeat +claw-market heartbeat --model claude-sonnet-4 +``` + +### `task` + +Report a completed task. + +```bash +claw-market task --duration [options] +``` + +**Arguments:** +- `summary` - Task summary (max 500 characters) + +**Options:** +- `-d, --duration ` - Task duration in milliseconds (required) +- `-m, --model ` - Model used for the task +- `-t, --tools ` - Tools used (space-separated) + +**Examples:** +```bash +claw-market task "Fixed bug" --duration 45000 +claw-market task "Refactored API" --duration 120000 --tools Bash Read Write +``` + +### `config` + +Manage CLI configuration. + +```bash +claw-market config +``` + +**Actions:** +- `show` - Show current configuration +- `set ` - Set a configuration value +- `path` - Show configuration file path +- `clear` - Delete configuration (unregister) + +**Examples:** +```bash +claw-market config show +claw-market config set endpoint https://custom.server/api/v1 +claw-market config set lang zh +claw-market config clear +``` + +## Global Options + +```bash +claw-market [command] [options] + +Options: + -e, --endpoint API endpoint (default: https://kymr.top/api/v1) + -l, --lang Output language (en/zh) + --json Output in JSON format + --version Show version + --help Show help +``` + +## Configuration + +Configuration is stored at `~/.openclaw/config.json` with file permissions `600` (owner only). + +**Configuration structure:** +```json +{ + "clawId": "abc123...", + "apiKey": "a1b2c3...", + "name": "MyClaw", + "endpoint": "https://kymr.top/api/v1", + "lang": "en" +} +``` + +## Environment Variables + +| Variable | Description | +|----------|-------------| +| `CLAUDE_MODEL` | Default model identifier | +| `OPENCLAW_LANG` | Default output language (en/zh) | + +## Data Disclosure + +This CLI sends the following data to the OpenClaw Market server: + +| Data Field | Example | Purpose | +|---|---|---| +| Claw Name | `CoolClaw` | Your display name on the heatmap | +| Platform | `darwin`, `linux` | OS type for heatmap stats | +| Model | `claude-sonnet-4-6` | Model usage stats | +| Task summary | `"Completed a task"` | Generic activity indicator | + +**Never sent:** system usernames, file paths, code snippets, project names, or secrets. + +## License + +MIT diff --git a/packages/claw-market/README.zh.md b/packages/claw-market/README.zh.md new file mode 100644 index 0000000..6a27ff0 --- /dev/null +++ b/packages/claw-market/README.zh.md @@ -0,0 +1,163 @@ +# @ricardweii/claw-market + +OpenClaw Market 命令行工具 - 向全球热力图报告 AI agent 活动。 + +## 安装 + +```bash +npm install -g @ricardweii/claw-market +# 或 +pnpm add -g @ricardweii/claw-market +``` + +## 快速开始 + +```bash +# 注册你的 claw +claw-market register 我的龙虾 + +# 发送心跳 +claw-market heartbeat + +# 报告已完成的任务 +claw-market task "修复了一个 bug" --duration 45000 +``` + +## 命令 + +### `register` + +在热力图上注册一个新的 claw。 + +```bash +claw-market register [options] +``` + +**参数:** +- `name` - Claw 显示名称 (1-100 字符) + +**选项:** +- `-p, --platform ` - 平台标识 (默认: 自动检测) +- `-m, --model ` - 模型标识 (默认: 从环境变量或 'unknown') +- `-f, --force` - 强制重新注册 (即使已注册) + +**示例:** +```bash +claw-market register 酷龙虾 +claw-market register "暗夜龙虾" --model claude-opus-4 +``` + +### `heartbeat` + +发送心跳以更新在线状态。 + +```bash +claw-market heartbeat [options] +``` + +**选项:** +- `-n, --name ` - 更新 claw 名称 +- `-m, --model ` - 更新模型标识 +- `-p, --platform ` - 更新平台标识 + +**示例:** +```bash +claw-market heartbeat +claw-market heartbeat --model claude-sonnet-4 +``` + +### `task` + +报告已完成的任务。 + +```bash +claw-market task --duration [options] +``` + +**参数:** +- `summary` - 任务摘要 (最多 500 字符) + +**选项:** +- `-d, --duration ` - 任务时长 (毫秒,必填) +- `-m, --model ` - 任务使用的模型 +- `-t, --tools ` - 使用的工具 (空格分隔) + +**示例:** +```bash +claw-market task "修复 bug" --duration 45000 +claw-market task "重构 API" --duration 120000 --tools Bash Read Write +``` + +### `config` + +管理 CLI 配置。 + +```bash +claw-market config +``` + +**操作:** +- `show` - 显示当前配置 +- `set ` - 设置配置值 +- `path` - 显示配置文件路径 +- `clear` - 清除配置 (注销) + +**示例:** +```bash +claw-market config show +claw-market config set endpoint https://custom.server/api/v1 +claw-market config set lang zh +claw-market config clear +``` + +## 全局选项 + +```bash +claw-market [command] [options] + +Options: + -e, --endpoint API 端点 (默认: https://kymr.top/api/v1) + -l, --lang 输出语言 (en/zh) + --json 以 JSON 格式输出 + --version 显示版本 + --help 显示帮助 +``` + +## 配置 + +配置存储在 `~/.openclaw/config.json`,文件权限为 `600` (仅所有者可读写)。 + +**配置结构:** +```json +{ + "clawId": "abc123...", + "apiKey": "a1b2c3...", + "name": "我的龙虾", + "endpoint": "https://kymr.top/api/v1", + "lang": "zh" +} +``` + +## 环境变量 + +| 变量 | 描述 | +|------|------| +| `CLAUDE_MODEL` | 默认模型标识 | +| `OPENCLAW_LANG` | 默认输出语言 (en/zh) | + +## 数据披露 + +此 CLI 向 OpenClaw Market 服务器发送以下数据: + +| 数据字段 | 示例 | 用途 | +|---|---|---| +| Claw 名称 | `酷龙虾` | 热力图上的显示名称 | +| 平台 | `darwin`, `linux` | 热力图统计的操作系统类型 | +| 模型 | `claude-sonnet-4-6` | 模型使用统计 | +| 任务摘要 | `"完成了一个任务"` | 通用活动指标 | + +**永不发送:** 系统用户名、文件路径、代码片段、项目名称或密钥。 + +## 许可证 + +MIT diff --git a/packages/claw-market/package.json b/packages/claw-market/package.json new file mode 100644 index 0000000..975fb42 --- /dev/null +++ b/packages/claw-market/package.json @@ -0,0 +1,62 @@ +{ + "name": "@ricardweii/claw-market", + "version": "0.1.1", + "description": "CLI tool for OpenClaw Market - report AI agent activity to the global heatmap", + "type": "module", + "bin": { + "claw-market": "dist/index.js" + }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + } + }, + "files": [ + "dist", + "README.md", + "README.zh.md" + ], + "scripts": { + "build": "tsup", + "dev": "tsup --watch", + "test": "vitest run", + "test:watch": "vitest", + "lint": "tsc --noEmit", + "prepublishOnly": "pnpm build" + }, + "keywords": [ + "cli", + "ai", + "agent", + "heatmap", + "openclaw", + "telemetry" + ], + "author": "OpenClaw", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/openclaw/openclaw-market.git", + "directory": "packages/claw-market" + }, + "bugs": { + "url": "https://github.com/openclaw/openclaw-market/issues" + }, + "homepage": "https://kymr.top", + "dependencies": { + "commander": "^13.1.0", + "zod": "^3.24.3" + }, + "devDependencies": { + "@types/node": "^22.13.0", + "tsup": "^8.3.0", + "typescript": "^5.8.0", + "vitest": "^2.0.0" + }, + "engines": { + "node": ">=18.0.0" + } +} diff --git a/packages/claw-market/src/commands/config.ts b/packages/claw-market/src/commands/config.ts new file mode 100644 index 0000000..6ab8d40 --- /dev/null +++ b/packages/claw-market/src/commands/config.ts @@ -0,0 +1,117 @@ +import type { Command } from "commander"; +import { + readConfig, + getConfigPath, + clearConfig, + updateConfig, + isValidConfigKey, + VALID_CONFIG_KEYS, +} from "../lib/config.js"; +import type { Translator, Locale } from "../i18n/index.js"; + +export interface ConfigOptions { + lang?: Locale; + json?: boolean; +} + +export function configCommand(program: Command, t: Translator): void { + const configCmd = program + .command("config") + .description(t("config.description")); + + // config show + configCmd + .command("show") + .description(t("config.showDescription")) + .action((options: ConfigOptions, cmd: Command) => { + const globalOpts = cmd.optsWithGlobals(); + const json = globalOpts.json; + + const config = readConfig(); + if (!config) { + if (json) { + console.log(JSON.stringify({ success: false, error: "not_registered" })); + } else { + console.log(t("config.notRegistered")); + } + return; + } + + if (json) { + console.log(JSON.stringify({ success: true, config }, null, 2)); + } else { + console.log(t("config.currentConfig")); + console.log(` clawId: ${config.clawId}`); + console.log(` name: ${config.name}`); + if (config.endpoint) console.log(` endpoint: ${config.endpoint}`); + if (config.lang) console.log(` lang: ${config.lang}`); + } + }); + + // config set + configCmd + .command("set ") + .description(t("config.setDescription")) + .action((key: string, value: string, options: ConfigOptions, cmd: Command) => { + const globalOpts = cmd.optsWithGlobals(); + const json = globalOpts.json; + + if (!isValidConfigKey(key)) { + if (json) { + console.log(JSON.stringify({ success: false, error: "invalid_key" })); + } else { + console.log(t("config.invalidKey", { key, validKeys: VALID_CONFIG_KEYS.join(", ") })); + } + process.exit(1); + } + + const config = readConfig(); + if (!config) { + if (json) { + console.log(JSON.stringify({ success: false, error: "not_registered" })); + } else { + console.log(t("config.notRegistered")); + } + process.exit(1); + } + + updateConfig({ [key]: value }); + if (json) { + console.log(JSON.stringify({ success: true, key, value })); + } else { + console.log(t("config.setValue", { key, value })); + } + }); + + // config path + configCmd + .command("path") + .description(t("config.pathDescription")) + .action((options: ConfigOptions, cmd: Command) => { + const globalOpts = cmd.optsWithGlobals(); + const json = globalOpts.json; + + const configPath = getConfigPath(); + if (json) { + console.log(JSON.stringify({ success: true, path: configPath })); + } else { + console.log(t("config.configPath", { path: configPath })); + } + }); + + // config clear + configCmd + .command("clear") + .description(t("config.clearDescription")) + .action((options: ConfigOptions, cmd: Command) => { + const globalOpts = cmd.optsWithGlobals(); + const json = globalOpts.json; + + const success = clearConfig(); + if (json) { + console.log(JSON.stringify({ success })); + } else { + console.log(t("config.configCleared")); + } + }); +} diff --git a/packages/claw-market/src/commands/heartbeat.ts b/packages/claw-market/src/commands/heartbeat.ts new file mode 100644 index 0000000..a69e82a --- /dev/null +++ b/packages/claw-market/src/commands/heartbeat.ts @@ -0,0 +1,74 @@ +import type { Command } from "commander"; +import { readConfig, updateConfig } from "../lib/config.js"; +import { sendHeartbeat, getEndpoint } from "../lib/api.js"; +import { detectPlatform, detectModel } from "../lib/platform.js"; +import type { Translator, Locale } from "../i18n/index.js"; + +export interface HeartbeatOptions { + name?: string; + model?: string; + platform?: string; + endpoint?: string; + lang?: Locale; + json?: boolean; +} + +export function heartbeatCommand(program: Command, t: Translator): void { + program + .command("heartbeat") + .description(t("heartbeat.description")) + .option("-n, --name ", t("heartbeat.optionName")) + .option("-m, --model ", t("heartbeat.optionModel")) + .option("-p, --platform ", t("heartbeat.optionPlatform")) + .action(async (options: HeartbeatOptions, cmd: Command) => { + // Get global options + const globalOpts = cmd.optsWithGlobals(); + const json = globalOpts.json; + + // Check if registered + const config = readConfig(); + if (!config) { + if (json) { + console.log(JSON.stringify({ success: false, error: "not_registered" })); + } else { + console.error(t("heartbeat.notRegistered")); + } + process.exit(1); + } + + // Get endpoint + const endpoint = getEndpoint(config, options.endpoint); + + // Prepare heartbeat data + const heartbeatData = { + endpoint, + apiKey: config.apiKey, + name: options.name, + model: options.model || detectModel(), + platform: options.platform || detectPlatform(), + }; + + // Call API + const result = await sendHeartbeat(heartbeatData); + + if (!result.success) { + if (json) { + console.log(JSON.stringify({ success: false, error: result.error })); + } else { + console.error(t("heartbeat.error", { error: result.error ?? "Unknown error" })); + } + process.exit(1); + } + + // Update config if name changed + if (options.name && options.name !== config.name) { + updateConfig({ name: options.name }); + } + + if (json) { + console.log(JSON.stringify({ success: true })); + } else { + console.log(t("heartbeat.success")); + } + }); +} diff --git a/packages/claw-market/src/commands/register.ts b/packages/claw-market/src/commands/register.ts new file mode 100644 index 0000000..75ee123 --- /dev/null +++ b/packages/claw-market/src/commands/register.ts @@ -0,0 +1,87 @@ +import type { Command } from "commander"; +import { configExists, readConfig, writeConfig } from "../lib/config.js"; +import { registerClaw, getEndpoint } from "../lib/api.js"; +import { detectPlatform, detectModel } from "../lib/platform.js"; +import { validateRegister } from "../lib/validate.js"; +import type { Translator, Locale } from "../i18n/index.js"; + +export interface RegisterOptions { + platform?: string; + model?: string; + force?: boolean; + endpoint?: string; + lang?: Locale; + json?: boolean; +} + +export function registerCommand(program: Command, t: Translator): void { + program + .command("register ") + .description(t("register.description")) + .option("-p, --platform ", t("register.optionPlatform")) + .option("-m, --model ", t("register.optionModel")) + .option("-f, --force", t("register.optionForce")) + .action(async (name: string, options: RegisterOptions, cmd: Command) => { + // Get global options + const globalOpts = cmd.optsWithGlobals(); + const json = globalOpts.json; + + // Validate input + const validation = validateRegister({ name, ...options }); + if (!validation.success) { + console.error(t("register.error", { error: validation.error })); + process.exit(1); + } + + // Check if already registered + const existingConfig = readConfig(); + if (existingConfig && !options.force) { + if (json) { + console.log(JSON.stringify({ success: false, error: "already_registered", name: existingConfig.name })); + } else { + console.log(t("register.alreadyRegistered", { name: existingConfig.name })); + } + return; + } + + // Get endpoint + const endpoint = getEndpoint(existingConfig, globalOpts.endpoint); + + // Prepare registration data + const platform = options.platform || detectPlatform(); + const model = options.model || detectModel(); + + // Call API + const result = await registerClaw({ + endpoint, + name: validation.data.name, + platform, + model, + }); + + if (!result.success) { + if (json) { + console.log(JSON.stringify({ success: false, error: result.error })); + } else { + console.error(t("register.error", { error: result.error ?? "Unknown error" })); + } + process.exit(1); + } + + // Save config + const config = { + clawId: result.data!.clawId, + apiKey: result.data!.apiKey, + name: result.data!.name, + endpoint: globalOpts.endpoint, + lang: globalOpts.lang, + }; + writeConfig(config); + + if (json) { + console.log(JSON.stringify({ success: true, ...result.data })); + } else { + console.log(t("register.success", { name: result.data!.name })); + } + }); +} diff --git a/packages/claw-market/src/commands/task.ts b/packages/claw-market/src/commands/task.ts new file mode 100644 index 0000000..2ceb963 --- /dev/null +++ b/packages/claw-market/src/commands/task.ts @@ -0,0 +1,95 @@ +import type { Command } from "commander"; +import { readConfig } from "../lib/config.js"; +import { reportTask, getEndpoint } from "../lib/api.js"; +import { validateTask } from "../lib/validate.js"; +import { detectModel } from "../lib/platform.js"; +import type { Translator, Locale } from "../i18n/index.js"; + +export interface TaskOptions { + duration?: number; + model?: string; + tools?: string[]; + endpoint?: string; + lang?: Locale; + json?: boolean; +} + +export function taskCommand(program: Command, t: Translator): void { + program + .command("task ") + .description(t("task.description")) + .requiredOption("-d, --duration ", t("task.optionDuration"), (value) => parseInt(value, 10)) + .option("-m, --model ", t("task.optionModel")) + .option("-t, --tools ", t("task.optionTools")) + .action(async (summary: string, options: TaskOptions, cmd: Command) => { + // Get global options + const globalOpts = cmd.optsWithGlobals(); + const json = globalOpts.json; + + // Check if registered + const config = readConfig(); + if (!config) { + if (json) { + console.log(JSON.stringify({ success: false, error: "not_registered" })); + } else { + console.error(t("task.notRegistered")); + } + process.exit(1); + } + + // Validate duration + if (!options.duration || options.duration <= 0) { + if (json) { + console.log(JSON.stringify({ success: false, error: "invalid_duration" })); + } else { + console.error(t("task.durationRequired")); + } + process.exit(1); + } + + // Validate input + const validation = validateTask({ + summary, + durationMs: options.duration, + model: options.model, + toolsUsed: options.tools, + }); + + if (!validation.success) { + if (json) { + console.log(JSON.stringify({ success: false, error: validation.error })); + } else { + console.error(t("task.error", { error: validation.error })); + } + process.exit(1); + } + + // Get endpoint + const endpoint = getEndpoint(config, globalOpts.endpoint); + + // Call API + const result = await reportTask({ + endpoint, + apiKey: config.apiKey, + summary: validation.data.summary, + durationMs: validation.data.durationMs, + model: validation.data.model || detectModel(), + toolsUsed: validation.data.toolsUsed, + }); + + if (!result.success) { + if (json) { + console.log(JSON.stringify({ success: false, error: result.error })); + } else { + console.error(t("task.error", { error: result.error ?? "Unknown error" })); + } + process.exit(1); + } + + if (json) { + console.log(JSON.stringify({ success: true })); + } else { + console.log(t("task.success")); + } + }); +} diff --git a/packages/claw-market/src/i18n/en.json b/packages/claw-market/src/i18n/en.json new file mode 100644 index 0000000..b82bf94 --- /dev/null +++ b/packages/claw-market/src/i18n/en.json @@ -0,0 +1,61 @@ +{ + "cli": { + "description": "CLI tool for OpenClaw Market - report AI agent activity to the global heatmap" + }, + "register": { + "description": "Register a new claw on the heatmap", + "argName": "Claw display name (1-100 characters)", + "optionPlatform": "Platform identifier (default: auto-detect)", + "optionModel": "Model identifier (default: from env or 'unknown')", + "optionForce": "Force re-registration even if already registered", + "success": "Registered successfully as: {name}", + "alreadyRegistered": "Already registered as: {name}. Use --force to re-register.", + "error": "Registration failed: {error}", + "nameRequired": "Error: Claw name is required" + }, + "heartbeat": { + "description": "Send a heartbeat to update online status", + "optionName": "Update claw name", + "optionModel": "Update model identifier", + "optionPlatform": "Update platform identifier", + "success": "Heartbeat sent successfully", + "error": "Heartbeat failed: {error}", + "notRegistered": "Error: Not registered. Run 'claw-market register' first." + }, + "task": { + "description": "Report a completed task", + "argSummary": "Task summary (max 500 characters)", + "optionDuration": "Task duration in milliseconds (required)", + "optionModel": "Model used for the task", + "optionTools": "Tools used (space-separated)", + "success": "Task reported successfully", + "error": "Task report failed: {error}", + "notRegistered": "Error: Not registered. Run 'claw-market register' first.", + "summaryRequired": "Error: Task summary is required", + "durationRequired": "Error: --duration is required" + }, + "config": { + "description": "Manage CLI configuration", + "showDescription": "Show current configuration", + "setDescription": "Set a configuration value", + "pathDescription": "Show configuration file path", + "clearDescription": "Clear configuration (unregister)", + "argKey": "Configuration key", + "argValue": "Configuration value", + "currentConfig": "Current configuration:", + "configPath": "Configuration file: {path}", + "configCleared": "Configuration cleared successfully", + "notRegistered": "No configuration found. Run 'claw-market register' first.", + "invalidKey": "Invalid configuration key: {key}. Valid keys: {validKeys}", + "setValue": "Set {key} = {value}" + }, + "global": { + "optionEndpoint": "API endpoint (default: https://kymr.top/api/v1)", + "optionLang": "Output language (en/zh)", + "optionJson": "Output in JSON format", + "optionVersion": "Show version", + "optionHelp": "Show help", + "unknownError": "An unexpected error occurred: {error}", + "networkError": "Network error: Unable to connect to {endpoint}" + } +} diff --git a/packages/claw-market/src/i18n/index.ts b/packages/claw-market/src/i18n/index.ts new file mode 100644 index 0000000..b0c4cc1 --- /dev/null +++ b/packages/claw-market/src/i18n/index.ts @@ -0,0 +1,70 @@ +import en from "./en.json" with { type: "json" }; +import zh from "./zh.json" with { type: "json" }; + +export type Locale = "en" | "zh"; +export type TranslationKeys = typeof en; + +const translations: Record = { en, zh }; + +/** + * Detect the user's preferred language + * Priority: --lang option > OPENCLAW_LANG env > config file > system LANG > default 'en' + */ +export function detectLocale(override?: Locale): Locale { + if (override) return override; + + const envLang = process.env.OPENCLAW_LANG; + if (envLang === "en" || envLang === "zh") return envLang; + + const systemLang = process.env.LANG || process.env.LC_ALL || ""; + if (systemLang.toLowerCase().includes("zh")) return "zh"; + + return "en"; +} + +/** + * Get translation value by dot-notation key + */ +function getNestedValue(obj: Record, path: string): string | undefined { + const parts = path.split("."); + let current: unknown = obj; + + for (const part of parts) { + if (current && typeof current === "object" && part in current) { + current = (current as Record)[part]; + } else { + return undefined; + } + } + + return typeof current === "string" ? current : undefined; +} + +/** + * Replace template variables in translation string + */ +function interpolate(template: string, vars: Record): string { + return template.replace(/\{(\w+)\}/g, (_, key) => String(vars[key] ?? `{${key}}`)); +} + +/** + * Translation function + */ +export function t(key: string, locale: Locale, vars?: Record): string { + const translation = getNestedValue(translations[locale] as unknown as Record, key); + const text = translation ?? key; + + if (vars) { + return interpolate(text, vars); + } + return text; +} + +/** + * Create a translation function bound to a specific locale + */ +export function createTranslator(locale: Locale) { + return (key: string, vars?: Record) => t(key, locale, vars); +} + +export type Translator = ReturnType; diff --git a/packages/claw-market/src/i18n/zh.json b/packages/claw-market/src/i18n/zh.json new file mode 100644 index 0000000..acabc75 --- /dev/null +++ b/packages/claw-market/src/i18n/zh.json @@ -0,0 +1,61 @@ +{ + "cli": { + "description": "OpenClaw Market 命令行工具 - 向全球热力图报告 AI agent 活动" + }, + "register": { + "description": "在热力图上注册一个新的 claw", + "argName": "Claw 显示名称 (1-100 字符)", + "optionPlatform": "平台标识 (默认: 自动检测)", + "optionModel": "模型标识 (默认: 从环境变量或 'unknown')", + "optionForce": "强制重新注册 (即使已注册)", + "success": "注册成功: {name}", + "alreadyRegistered": "已注册为: {name}。使用 --force 强制重新注册。", + "error": "注册失败: {error}", + "nameRequired": "错误: 需要提供 claw 名称" + }, + "heartbeat": { + "description": "发送心跳以更新在线状态", + "optionName": "更新 claw 名称", + "optionModel": "更新模型标识", + "optionPlatform": "更新平台标识", + "success": "心跳发送成功", + "error": "心跳发送失败: {error}", + "notRegistered": "错误: 未注册。请先运行 'claw-market register'。" + }, + "task": { + "description": "报告已完成的任务", + "argSummary": "任务摘要 (最多 500 字符)", + "optionDuration": "任务时长 (毫秒,必填)", + "optionModel": "任务使用的模型", + "optionTools": "使用的工具 (空格分隔)", + "success": "任务报告成功", + "error": "任务报告失败: {error}", + "notRegistered": "错误: 未注册。请先运行 'claw-market register'。", + "summaryRequired": "错误: 需要提供任务摘要", + "durationRequired": "错误: --duration 是必填项" + }, + "config": { + "description": "管理 CLI 配置", + "showDescription": "显示当前配置", + "setDescription": "设置配置值", + "pathDescription": "显示配置文件路径", + "clearDescription": "清除配置 (注销)", + "argKey": "配置键", + "argValue": "配置值", + "currentConfig": "当前配置:", + "configPath": "配置文件: {path}", + "configCleared": "配置已清除", + "notRegistered": "未找到配置。请先运行 'claw-market register'。", + "invalidKey": "无效的配置键: {key}。有效的键: {validKeys}", + "setValue": "已设置 {key} = {value}" + }, + "global": { + "optionEndpoint": "API 端点 (默认: https://kymr.top/api/v1)", + "optionLang": "输出语言 (en/zh)", + "optionJson": "以 JSON 格式输出", + "optionVersion": "显示版本", + "optionHelp": "显示帮助", + "unknownError": "发生意外错误: {error}", + "networkError": "网络错误: 无法连接到 {endpoint}" + } +} diff --git a/packages/claw-market/src/index.ts b/packages/claw-market/src/index.ts new file mode 100644 index 0000000..9663b9e --- /dev/null +++ b/packages/claw-market/src/index.ts @@ -0,0 +1,69 @@ +import { Command } from "commander"; +import { detectLocale, createTranslator, type Locale } from "./i18n/index.js"; +import { registerCommand } from "./commands/register.js"; +import { heartbeatCommand } from "./commands/heartbeat.js"; +import { taskCommand } from "./commands/task.js"; +import { configCommand } from "./commands/config.js"; +import { readConfig } from "./lib/config.js"; +import { DEFAULT_ENDPOINT } from "./lib/api.js"; + +const VERSION = "0.1.1"; + +interface GlobalOptions { + endpoint?: string; + lang?: Locale; + json?: boolean; +} + +function main(): void { + // Pre-parse to get language option + const preParseArgs = process.argv.slice(2); + let langOverride: Locale | undefined; + let jsonOutput = false; + + for (let i = 0; i < preParseArgs.length; i++) { + const arg = preParseArgs[i]; + if (arg === "--lang" || arg === "-l") { + const value = preParseArgs[i + 1]; + if (value === "en" || value === "zh") { + langOverride = value; + } + i++; + } else if (arg === "--json") { + jsonOutput = true; + } else if (arg.startsWith("--lang=")) { + const value = arg.split("=")[1]; + if (value === "en" || value === "zh") { + langOverride = value; + } + } + } + + // Detect locale + const config = readConfig(); + const locale = detectLocale(langOverride || config?.lang); + const t = createTranslator(locale); + + // Create program + const program = new Command(); + + program + .name("claw-market") + .description(t("cli.description")) + .version(VERSION) + .option("-e, --endpoint ", t("global.optionEndpoint"), DEFAULT_ENDPOINT) + .option("-l, --lang ", t("global.optionLang")) + .option("--json", t("global.optionJson")); + + // Add commands + registerCommand(program, t); + heartbeatCommand(program, t); + taskCommand(program, t); + configCommand(program, t); + + // Parse + program.parse(process.argv); +} + +// Run main +main(); diff --git a/packages/claw-market/src/lib/api.ts b/packages/claw-market/src/lib/api.ts new file mode 100644 index 0000000..566b9a4 --- /dev/null +++ b/packages/claw-market/src/lib/api.ts @@ -0,0 +1,176 @@ +import type { OpenClawConfig } from "./config.js"; + +export interface ApiResponse { + success: boolean; + data?: T; + error?: string; +} + +export interface RegisterResponse { + clawId: string; + apiKey: string; + name: string; +} + +export interface ApiError { + error: string; + statusCode?: number; +} + +/** + * Default API endpoint + */ +export const DEFAULT_ENDPOINT = "https://kymr.top/api/v1"; + +/** + * Build full URL for API endpoint + */ +function buildUrl(endpoint: string, path: string): string { + const base = endpoint.endsWith("/api/v1") ? endpoint : `${endpoint}/api/v1`; + return `${base}${path.startsWith("/") ? path : `/${path}`}`; +} + +/** + * Make an API request + */ +async function request( + method: string, + path: string, + options: { + endpoint: string; + apiKey?: string; + body?: Record; + } +): Promise> { + const { endpoint, apiKey, body } = options; + const url = buildUrl(endpoint, path); + + const headers: Record = { + "Content-Type": "application/json", + "User-Agent": "claw-market-cli/0.1.0", + }; + + if (apiKey) { + headers["Authorization"] = `Bearer ${apiKey}`; + } + + try { + const response = await fetch(url, { + method, + headers, + body: body ? JSON.stringify(body) : undefined, + }); + + const data = await response.json(); + + if (!response.ok) { + return { + success: false, + error: (data as ApiError).error || `HTTP ${response.status}`, + }; + } + + return { + success: true, + data: data as T, + }; + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return { + success: false, + error: message, + }; + } +} + +/** + * Register a new claw + */ +export async function registerClaw(options: { + endpoint: string; + name: string; + platform?: string; + model?: string; +}): Promise> { + const body: Record = { name: options.name }; + + if (options.platform) { + body.platform = options.platform; + } + if (options.model) { + body.model = options.model; + } + + return request("POST", "/register", { + endpoint: options.endpoint, + body, + }); +} + +/** + * Send a heartbeat + */ +export async function sendHeartbeat(options: { + endpoint: string; + apiKey: string; + name?: string; + platform?: string; + model?: string; +}): Promise> { + const body: Record = {}; + + if (options.name) { + body.name = options.name; + } + if (options.platform) { + body.platform = options.platform; + } + if (options.model) { + body.model = options.model; + } + + return request("POST", "/heartbeat", { + endpoint: options.endpoint, + apiKey: options.apiKey, + body, + }); +} + +/** + * Report a completed task + */ +export async function reportTask(options: { + endpoint: string; + apiKey: string; + summary: string; + durationMs: number; + model?: string; + toolsUsed?: string[]; +}): Promise> { + const body: Record = { + summary: options.summary, + durationMs: options.durationMs, + }; + + if (options.model) { + body.model = options.model; + } + if (options.toolsUsed && options.toolsUsed.length > 0) { + body.toolsUsed = options.toolsUsed; + } + + return request("POST", "/task", { + endpoint: options.endpoint, + apiKey: options.apiKey, + body, + }); +} + +/** + * Get endpoint from config or use default + */ +export function getEndpoint(config: OpenClawConfig | null, override?: string): string { + if (override) return override; + if (config?.endpoint) return config.endpoint; + return DEFAULT_ENDPOINT; +} diff --git a/packages/claw-market/src/lib/config.ts b/packages/claw-market/src/lib/config.ts new file mode 100644 index 0000000..10f93b5 --- /dev/null +++ b/packages/claw-market/src/lib/config.ts @@ -0,0 +1,118 @@ +import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, rmdirSync } from "node:fs"; +import { join } from "node:path"; +import { homedir } from "node:os"; +import type { Locale } from "../i18n/index.js"; + +export interface OpenClawConfig { + clawId: string; + apiKey: string; + name: string; + endpoint?: string; + lang?: Locale; +} + +const CONFIG_DIR = ".openclaw"; +const CONFIG_FILE = "config.json"; + +/** + * Get the configuration directory path + */ +export function getConfigDir(): string { + return join(homedir(), CONFIG_DIR); +} + +/** + * Get the configuration file path + */ +export function getConfigPath(): string { + return join(getConfigDir(), CONFIG_FILE); +} + +/** + * Check if configuration exists + */ +export function configExists(): boolean { + return existsSync(getConfigPath()); +} + +/** + * Read configuration from file + */ +export function readConfig(): OpenClawConfig | null { + const configPath = getConfigPath(); + if (!existsSync(configPath)) { + return null; + } + + try { + const content = readFileSync(configPath, "utf-8"); + return JSON.parse(content) as OpenClawConfig; + } catch { + return null; + } +} + +/** + * Write configuration to file + * Creates directory if needed and sets permissions to 600 (owner only) + */ +export function writeConfig(config: OpenClawConfig): void { + const configDir = getConfigDir(); + const configPath = getConfigPath(); + + if (!existsSync(configDir)) { + mkdirSync(configDir, { recursive: true, mode: 0o700 }); + } + + writeFileSync(configPath, JSON.stringify(config, null, 2), { + encoding: "utf-8", + mode: 0o600, + }); +} + +/** + * Update specific configuration values + */ +export function updateConfig(updates: Partial): OpenClawConfig | null { + const existing = readConfig(); + if (!existing) { + return null; + } + + const updated = { ...existing, ...updates }; + writeConfig(updated); + return updated; +} + +/** + * Delete configuration (unregister) + */ +export function clearConfig(): boolean { + const configPath = getConfigPath(); + const configDir = getConfigDir(); + + try { + if (existsSync(configPath)) { + unlinkSync(configPath); + } + if (existsSync(configDir)) { + rmdirSync(configDir); + } + return true; + } catch { + return false; + } +} + +/** + * Valid configuration keys for set operation + */ +export const VALID_CONFIG_KEYS = ["endpoint", "lang"] as const; +export type ConfigKey = (typeof VALID_CONFIG_KEYS)[number]; + +/** + * Check if a key is a valid configuration key + */ +export function isValidConfigKey(key: string): key is ConfigKey { + return VALID_CONFIG_KEYS.includes(key as ConfigKey); +} diff --git a/packages/claw-market/src/lib/platform.ts b/packages/claw-market/src/lib/platform.ts new file mode 100644 index 0000000..dea11b4 --- /dev/null +++ b/packages/claw-market/src/lib/platform.ts @@ -0,0 +1,23 @@ +/** + * Detect the current platform + */ +export function detectPlatform(): string { + const platform = process.platform; + switch (platform) { + case "darwin": + return "darwin"; + case "linux": + return "linux"; + case "win32": + return "windows"; + default: + return platform; + } +} + +/** + * Get model identifier from environment or default + */ +export function detectModel(): string { + return process.env.CLAUDE_MODEL || process.env.ANTHROPIC_MODEL || "unknown"; +} diff --git a/packages/claw-market/src/lib/validate.ts b/packages/claw-market/src/lib/validate.ts new file mode 100644 index 0000000..a3047ab --- /dev/null +++ b/packages/claw-market/src/lib/validate.ts @@ -0,0 +1,66 @@ +import { z } from "zod"; + +/** + * Register input validation schema + */ +export const registerSchema = z.object({ + name: z.string().min(1, "Name must be at least 1 character").max(100, "Name must be at most 100 characters"), + platform: z.string().optional(), + model: z.string().optional(), +}); + +/** + * Heartbeat input validation schema + */ +export const heartbeatSchema = z.object({ + name: z.string().optional(), + platform: z.string().optional(), + model: z.string().optional(), +}); + +/** + * Task input validation schema + */ +export const taskSchema = z.object({ + summary: z.string().max(500, "Summary must be at most 500 characters"), + durationMs: z.number().positive("Duration must be a positive number"), + model: z.string().optional(), + toolsUsed: z.array(z.string()).optional(), +}); + +export type RegisterInput = z.infer; +export type HeartbeatInput = z.infer; +export type TaskInput = z.infer; + +/** + * Validate register input + */ +export function validateRegister(input: unknown): { success: true; data: RegisterInput } | { success: false; error: string } { + const result = registerSchema.safeParse(input); + if (result.success) { + return { success: true, data: result.data }; + } + return { success: false, error: result.error.errors[0]?.message || "Validation failed" }; +} + +/** + * Validate heartbeat input + */ +export function validateHeartbeat(input: unknown): { success: true; data: HeartbeatInput } | { success: false; error: string } { + const result = heartbeatSchema.safeParse(input); + if (result.success) { + return { success: true, data: result.data }; + } + return { success: false, error: result.error.errors[0]?.message || "Validation failed" }; +} + +/** + * Validate task input + */ +export function validateTask(input: unknown): { success: true; data: TaskInput } | { success: false; error: string } { + const result = taskSchema.safeParse(input); + if (result.success) { + return { success: true, data: result.data }; + } + return { success: false, error: result.error.errors[0]?.message || "Validation failed" }; +} diff --git a/packages/claw-market/tsconfig.json b/packages/claw-market/tsconfig.json new file mode 100644 index 0000000..f62a22b --- /dev/null +++ b/packages/claw-market/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "lib": ["ES2022"], + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist", + "rootDir": "./src", + "resolveJsonModule": true, + "noEmit": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/claw-market/tsup.config.ts b/packages/claw-market/tsup.config.ts new file mode 100644 index 0000000..717cc35 --- /dev/null +++ b/packages/claw-market/tsup.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["esm"], + target: "node18", + clean: true, + dts: true, + sourcemap: true, + minify: false, + banner: { + js: "#!/usr/bin/env node", + }, + external: ["commander", "zod"], +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0bb1f45..244e16c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -115,6 +115,28 @@ importers: specifier: ^5.8.0 version: 5.9.3 + packages/claw-market: + dependencies: + commander: + specifier: ^13.1.0 + version: 13.1.0 + zod: + specifier: ^3.24.3 + version: 3.25.76 + devDependencies: + '@types/node': + specifier: ^22.13.0 + version: 22.19.15 + tsup: + specifier: ^8.3.0 + version: 8.5.1(@swc/core@1.15.18)(jiti@2.6.1)(postcss@8.5.8)(typescript@5.9.3) + typescript: + specifier: ^5.8.0 + version: 5.9.3 + vitest: + specifier: ^2.0.0 + version: 2.1.9(@types/node@22.19.15)(lightningcss@1.31.1) + packages: '@alloc/quick-lru@5.2.0': @@ -151,6 +173,18 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.18.20': resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -163,6 +197,18 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.18.20': resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -175,6 +221,18 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -187,6 +245,18 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -199,6 +269,18 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -211,6 +293,18 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -223,6 +317,18 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -235,6 +341,18 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -247,6 +365,18 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -259,6 +389,18 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -271,6 +413,18 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -283,6 +437,18 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -295,6 +461,18 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -307,6 +485,18 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -319,6 +509,18 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -331,6 +533,18 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -343,6 +557,24 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -355,6 +587,24 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -367,6 +617,24 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -379,6 +647,18 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.18.20': resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -391,6 +671,18 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -403,6 +695,18 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -415,6 +719,18 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -514,89 +830,105 @@ packages: resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-arm@1.2.4': resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-ppc64@1.2.4': resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-riscv64@1.2.4': resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-s390x@1.2.4': resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-libvips-linux-x64@1.2.4': resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-libvips-linuxmusl-arm64@1.2.4': resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-libvips-linuxmusl-x64@1.2.4': resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-linux-arm64@0.34.5': resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [glibc] '@img/sharp-linux-arm@0.34.5': resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] + libc: [glibc] '@img/sharp-linux-ppc64@0.34.5': resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ppc64] os: [linux] + libc: [glibc] '@img/sharp-linux-riscv64@0.34.5': resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [riscv64] os: [linux] + libc: [glibc] '@img/sharp-linux-s390x@0.34.5': resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] + libc: [glibc] '@img/sharp-linux-x64@0.34.5': resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [glibc] '@img/sharp-linuxmusl-arm64@0.34.5': resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] + libc: [musl] '@img/sharp-linuxmusl-x64@0.34.5': resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] + libc: [musl] '@img/sharp-wasm32@0.34.5': resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} @@ -706,24 +1038,28 @@ packages: engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [glibc] '@next/swc-linux-arm64-musl@15.5.12': resolution: {integrity: sha512-+fpGWvQiITgf7PUtbWY1H7qUSnBZsPPLyyq03QuAKpVoTy/QUx1JptEDTQMVvQhvizCEuNLEeghrQUyXQOekuw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + libc: [musl] '@next/swc-linux-x64-gnu@15.5.12': resolution: {integrity: sha512-jSLvgdRRL/hrFAPqEjJf1fFguC719kmcptjNVDJl26BnJIpjL3KH5h6mzR4mAweociLQaqvt4UyzfbFjgAdDcw==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [glibc] '@next/swc-linux-x64-musl@15.5.12': resolution: {integrity: sha512-/uaF0WfmYqQgLfPmN6BvULwxY0dufI2mlN2JbOKqqceZh1G4hjREyi7pg03zjfyS6eqNemHAZPSoP84x17vo6w==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + libc: [musl] '@next/swc-win32-arm64-msvc@15.5.12': resolution: {integrity: sha512-xhsL1OvQSfGmlL5RbOmU+FV120urrgFpYLq+6U8C6KIym32gZT6XF/SDE92jKzzlPWskkbjOKCpqk5m4i8PEfg==} @@ -782,36 +1118,42 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.6': resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.6': resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.6': resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.6': resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.6': resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-win32-arm64@2.5.6': resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} @@ -838,6 +1180,144 @@ packages: '@petamoriken/float16@3.9.3': resolution: {integrity: sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g==} + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + cpu: [x64] + os: [win32] + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -870,24 +1350,28 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [glibc] '@swc/core-linux-arm64-musl@1.15.18': resolution: {integrity: sha512-0a+Lix+FSSHBSBOA0XznCcHo5/1nA6oLLjcnocvzXeqtdjnPb+SvchItHI+lfeiuj1sClYPDvPMLSLyXFaiIKw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] + libc: [musl] '@swc/core-linux-x64-gnu@1.15.18': resolution: {integrity: sha512-wG9J8vReUlpaHz4KOD/5UE1AUgirimU4UFT9oZmupUDEofxJKYb1mTA/DrMj0s78bkBiNI+7Fo2EgPuvOJfuAA==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [glibc] '@swc/core-linux-x64-musl@1.15.18': resolution: {integrity: sha512-4nwbVvCphKzicwNWRmvD5iBaZj8JYsRGa4xOxJmOyHlMDpsvvJ2OR2cODlvWyGFH6BYL1MfIAK3qph3hp0Az6g==} engines: {node: '>=10'} cpu: [x64] os: [linux] + libc: [musl] '@swc/core-win32-arm64-msvc@1.15.18': resolution: {integrity: sha512-zk0RYO+LjiBCat2RTMHzAWaMky0cra9loH4oRrLKLLNuL+jarxKLFDA8xTZWEkCPLjUTwlRN7d28eDLLMgtUcQ==} @@ -963,24 +1447,28 @@ packages: engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-arm64-musl@4.2.1': resolution: {integrity: sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==} engines: {node: '>= 20'} cpu: [arm64] os: [linux] + libc: [musl] '@tailwindcss/oxide-linux-x64-gnu@4.2.1': resolution: {integrity: sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [glibc] '@tailwindcss/oxide-linux-x64-musl@4.2.1': resolution: {integrity: sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==} engines: {node: '>= 20'} cpu: [x64] os: [linux] + libc: [musl] '@tailwindcss/oxide-wasm32-wasi@4.2.1': resolution: {integrity: sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==} @@ -1197,41 +1685,49 @@ packages: resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} cpu: [arm64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-arm64-musl@1.11.1': resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} cpu: [arm64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} cpu: [ppc64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} cpu: [riscv64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} cpu: [riscv64] os: [linux] + libc: [musl] '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} cpu: [s390x] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-gnu@1.11.1': resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} cpu: [x64] os: [linux] + libc: [glibc] '@unrs/resolver-binding-linux-x64-musl@1.11.1': resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} cpu: [x64] os: [linux] + libc: [musl] '@unrs/resolver-binding-wasm32-wasi@1.11.1': resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} @@ -1273,6 +1769,35 @@ packages: maplibre-gl: optional: true + '@vitest/expect@2.1.9': + resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + + '@vitest/mocker@2.1.9': + resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/runner@2.1.9': + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + + '@vitest/snapshot@2.1.9': + resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + + '@vitest/spy@2.1.9': + resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + '@webgpu/types@0.1.69': resolution: {integrity: sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==} @@ -1297,6 +1822,9 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1340,6 +1868,10 @@ packages: resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + assign-symbols@1.0.0: resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} engines: {node: '>=0.10.0'} @@ -1388,12 +1920,22 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + bytewise-core@1.2.3: resolution: {integrity: sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==} bytewise@1.1.0: resolution: {integrity: sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -1413,10 +1955,22 @@ packages: caniuse-lite@1.0.30001778: resolution: {integrity: sha512-PN7uxFL+ExFJO61aVmP1aIEG4i9whQd4eoSCebav62UwDyp5OHh06zN4jqKSMePVgxHifCw1QJxdRkA1Pisekg==} + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} + engines: {node: '>= 16'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -1438,12 +1992,27 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -1564,6 +2133,10 @@ packages: decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -1720,6 +2293,9 @@ packages: resolution: {integrity: sha512-zWwRvqWiuBPr0muUG/78cW3aHROFCNIQ3zpmYDpwdbnt2m+xlNyRWpHBpa2lJjSBit7BQ+RXA1iwbSmu5yJ/EQ==} engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -1751,6 +2327,16 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + engines: {node: '>=18'} + hasBin: true + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} @@ -1871,6 +2457,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -1878,6 +2467,10 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -1930,6 +2523,9 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + fix-dts-default-cjs-exports@1.0.1: + resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} @@ -1962,6 +2558,11 @@ packages: react-dom: optional: true + 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==} @@ -2250,6 +2851,10 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2336,24 +2941,28 @@ packages: engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] lightningcss-linux-arm64-musl@1.31.1: resolution: {integrity: sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] + libc: [musl] lightningcss-linux-x64-gnu@1.31.1: resolution: {integrity: sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [glibc] lightningcss-linux-x64-musl@1.31.1: resolution: {integrity: sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] + libc: [musl] lightningcss-win32-arm64-msvc@1.31.1: resolution: {integrity: sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==} @@ -2371,6 +2980,17 @@ packages: resolution: {integrity: sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==} engines: {node: '>= 12.0.0'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -2397,6 +3017,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + lru.min@1.1.4: resolution: {integrity: sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==} engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} @@ -2438,6 +3061,9 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + mlly@1.8.1: + resolution: {integrity: sha512-SnL6sNutTwRWWR/vcmCYHSADjiEesp5TGQQ0pXyLhW5IoeibRlF/CbSLailbB3CNqJUk9cVJ9dUDnbD7GrcHBQ==} + motion-dom@12.36.0: resolution: {integrity: sha512-Ep1pq8P88rGJ75om8lTCA13zqd7ywPGwCqwuWwin6BKc0hMLkVfcS6qKlRqEo2+t0DwoUcgGJfXwaiFn4AOcQA==} @@ -2456,6 +3082,9 @@ packages: peerDependencies: '@types/node': '>= 8' + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + named-placeholders@1.1.6: resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==} engines: {node: '>=8.0.0'} @@ -2586,6 +3215,16 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + pbf@4.0.1: resolution: {integrity: sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==} hasBin: true @@ -2601,6 +3240,13 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + po-parser@2.1.1: resolution: {integrity: sha512-ECF4zHLbUItpUgE3OTtLKlPjeBN+fKEczj2zYjDfCGOzicNs0GK3Vg2IoAYwx7LH/XYw43fZQP6xnZ4TkNxSLQ==} @@ -2615,6 +3261,24 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + postcss@8.4.31: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} @@ -2701,6 +3365,10 @@ packages: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + recharts-scale@0.4.5: resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} @@ -2731,6 +3399,10 @@ packages: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -2754,6 +3426,11 @@ packages: robust-predicates@3.0.2: resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -2835,6 +3512,9 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + simplesignal@2.1.7: resolution: {integrity: sha512-PEo2qWpUke7IMhlqiBxrulIFvhJRLkl1ih52Rwa+bPjzhJepcd4GIjn2RiQmFSx3dQvsEAgF0/lXMwMN7vODaA==} @@ -2861,6 +3541,10 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + split-string@3.1.0: resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} engines: {node: '>=0.10.0'} @@ -2872,9 +3556,15 @@ packages: stable-hash@0.0.5: resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -2923,6 +3613,11 @@ packages: babel-plugin-macros: optional: true + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + supercluster@8.0.1: resolution: {integrity: sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==} @@ -2944,6 +3639,13 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + three-conic-polygon-geometry@2.1.2: resolution: {integrity: sha512-NaP3RWLJIyPGI+zyaZwd0Yj6rkoxm4FJHqAX1Enb4L64oNYLCn4bz1ESgOEYavgcUwCNYINu1AgEoUBJr1wZcA==} engines: {node: '>=12'} @@ -2980,16 +3682,34 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinycolor2@1.6.0: resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + tinyqueue@3.0.0: resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==} + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -2998,18 +3718,44 @@ packages: resolution: {integrity: sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==} hasBin: true + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + ts-api-utils@2.4.0: resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsup@8.5.1: + resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -3041,6 +3787,9 @@ packages: typewise@1.0.3: resolution: {integrity: sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==} + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -3066,6 +3815,67 @@ packages: victory-vendor@36.9.2: resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + vite-node@2.1.9: + resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.1.9: + resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.9 + '@vitest/ui': 2.1.9 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -3092,6 +3902,11 @@ packages: engines: {node: ^16.13.0 || >=18.0.0} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -3140,138 +3955,285 @@ snapshots: '@esbuild/aix-ppc64@0.19.12': optional: true + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.27.4': + optional: true + '@esbuild/android-arm64@0.18.20': optional: true '@esbuild/android-arm64@0.19.12': optional: true + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.27.4': + optional: true + '@esbuild/android-arm@0.18.20': optional: true '@esbuild/android-arm@0.19.12': optional: true + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.27.4': + optional: true + '@esbuild/android-x64@0.18.20': optional: true '@esbuild/android-x64@0.19.12': optional: true + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.27.4': + optional: true + '@esbuild/darwin-arm64@0.18.20': optional: true '@esbuild/darwin-arm64@0.19.12': optional: true + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.27.4': + optional: true + '@esbuild/darwin-x64@0.18.20': optional: true '@esbuild/darwin-x64@0.19.12': optional: true + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.27.4': + optional: true + '@esbuild/freebsd-arm64@0.18.20': optional: true '@esbuild/freebsd-arm64@0.19.12': optional: true + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.27.4': + optional: true + '@esbuild/freebsd-x64@0.18.20': optional: true '@esbuild/freebsd-x64@0.19.12': optional: true + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.27.4': + optional: true + '@esbuild/linux-arm64@0.18.20': optional: true '@esbuild/linux-arm64@0.19.12': optional: true + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.27.4': + optional: true + '@esbuild/linux-arm@0.18.20': optional: true '@esbuild/linux-arm@0.19.12': optional: true + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.27.4': + optional: true + '@esbuild/linux-ia32@0.18.20': optional: true '@esbuild/linux-ia32@0.19.12': optional: true + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.27.4': + optional: true + '@esbuild/linux-loong64@0.18.20': optional: true '@esbuild/linux-loong64@0.19.12': optional: true + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.27.4': + optional: true + '@esbuild/linux-mips64el@0.18.20': optional: true '@esbuild/linux-mips64el@0.19.12': optional: true + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.27.4': + optional: true + '@esbuild/linux-ppc64@0.18.20': optional: true '@esbuild/linux-ppc64@0.19.12': optional: true + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.27.4': + optional: true + '@esbuild/linux-riscv64@0.18.20': optional: true '@esbuild/linux-riscv64@0.19.12': optional: true + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.27.4': + optional: true + '@esbuild/linux-s390x@0.18.20': optional: true '@esbuild/linux-s390x@0.19.12': optional: true + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.27.4': + optional: true + '@esbuild/linux-x64@0.18.20': optional: true '@esbuild/linux-x64@0.19.12': optional: true + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.27.4': + optional: true + + '@esbuild/netbsd-arm64@0.27.4': + optional: true + '@esbuild/netbsd-x64@0.18.20': optional: true '@esbuild/netbsd-x64@0.19.12': optional: true + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.27.4': + optional: true + + '@esbuild/openbsd-arm64@0.27.4': + optional: true + '@esbuild/openbsd-x64@0.18.20': optional: true '@esbuild/openbsd-x64@0.19.12': optional: true + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.27.4': + optional: true + + '@esbuild/openharmony-arm64@0.27.4': + optional: true + '@esbuild/sunos-x64@0.18.20': optional: true '@esbuild/sunos-x64@0.19.12': optional: true + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.27.4': + optional: true + '@esbuild/win32-arm64@0.18.20': optional: true '@esbuild/win32-arm64@0.19.12': optional: true + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.27.4': + optional: true + '@esbuild/win32-ia32@0.18.20': optional: true '@esbuild/win32-ia32@0.19.12': optional: true + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.27.4': + optional: true + '@esbuild/win32-x64@0.18.20': optional: true '@esbuild/win32-x64@0.19.12': optional: true + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.27.4': + optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.6.1))': dependencies: eslint: 9.39.4(jiti@2.6.1) @@ -3642,6 +4604,81 @@ snapshots: '@petamoriken/float16@3.9.3': {} + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true + + '@rollup/rollup-android-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-x64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true + '@rtsao/scc@1.1.0': {} '@rushstack/eslint-patch@1.16.1': {} @@ -4034,6 +5071,46 @@ snapshots: optionalDependencies: maplibre-gl: 5.20.0 + '@vitest/expect@2.1.9': + dependencies: + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.9(vite@5.4.21(@types/node@22.19.15)(lightningcss@1.31.1))': + dependencies: + '@vitest/spy': 2.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 5.4.21(@types/node@22.19.15)(lightningcss@1.31.1) + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.9': + dependencies: + '@vitest/utils': 2.1.9 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + magic-string: 0.30.21 + pathe: 1.1.2 + + '@vitest/spy@2.1.9': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.2.1 + tinyrainbow: 1.2.0 + '@webgpu/types@0.1.69': {} accessor-fn@1.5.3: {} @@ -4055,6 +5132,8 @@ snapshots: dependencies: color-convert: 2.0.1 + any-promise@1.3.0: {} + argparse@2.0.1: {} aria-query@5.3.2: {} @@ -4128,6 +5207,8 @@ snapshots: get-intrinsic: 1.3.0 is-array-buffer: 3.0.5 + assertion-error@2.0.1: {} + assign-symbols@1.0.0: {} ast-types-flow@0.0.8: {} @@ -4163,6 +5244,11 @@ snapshots: buffer-from@1.1.2: {} + bundle-require@5.1.0(esbuild@0.27.4): + dependencies: + esbuild: 0.27.4 + load-tsconfig: 0.2.5 + bytewise-core@1.2.3: dependencies: typewise-core: 1.2.0 @@ -4172,6 +5258,8 @@ snapshots: bytewise-core: 1.2.3 typewise: 1.0.3 + cac@6.7.14: {} + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -4193,11 +5281,25 @@ snapshots: caniuse-lite@1.0.30001778: {} + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.3 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + check-error@2.1.3: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -4214,10 +5316,18 @@ snapshots: color-name@1.1.4: {} + commander@13.1.0: {} + commander@2.20.3: {} + commander@4.1.1: {} + concat-map@0.0.1: {} + confbox@0.1.8: {} + + consola@3.4.2: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -4329,6 +5439,8 @@ snapshots: decimal.js@10.6.0: {} + deep-eql@5.0.2: {} + deep-is@0.1.4: {} define-data-property@1.1.4: @@ -4473,6 +5585,8 @@ snapshots: math-intrinsics: 1.1.0 safe-array-concat: 1.1.3 + es-module-lexer@1.7.0: {} + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -4552,6 +5666,61 @@ snapshots: '@esbuild/win32-ia32': 0.19.12 '@esbuild/win32-x64': 0.19.12 + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.27.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 + escape-string-regexp@4.0.0: {} eslint-config-next@15.5.12(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): @@ -4750,10 +5919,16 @@ snapshots: estraverse@5.3.0: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + esutils@2.0.3: {} eventemitter3@4.0.7: {} + expect-type@1.3.0: {} + extend-shallow@2.0.1: dependencies: is-extendable: 0.1.1 @@ -4802,6 +5977,12 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + fix-dts-default-cjs-exports@1.0.1: + dependencies: + magic-string: 0.30.21 + mlly: 1.8.1 + rollup: 4.59.0 + flat-cache@4.0.1: dependencies: flatted: 3.4.1 @@ -4832,6 +6013,9 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) + fsevents@2.3.3: + optional: true + function-bind@1.1.2: {} function.prototype.name@1.1.8: @@ -5141,6 +6325,8 @@ snapshots: jiti@2.6.1: {} + joycon@3.1.1: {} + js-tokens@4.0.0: {} js-yaml@4.1.1: @@ -5238,6 +6424,12 @@ snapshots: lightningcss-win32-arm64-msvc: 1.31.1 lightningcss-win32-x64-msvc: 1.31.1 + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -5258,6 +6450,8 @@ snapshots: dependencies: js-tokens: 4.0.0 + loupe@3.2.1: {} + lru.min@1.1.4: {} lucide-react@0.474.0(react@19.2.4): @@ -5311,6 +6505,13 @@ snapshots: minimist@1.2.8: {} + mlly@1.8.1: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + motion-dom@12.36.0: dependencies: motion-utils: 12.36.0 @@ -5333,6 +6534,12 @@ snapshots: named-placeholders: 1.1.6 sql-escaper: 1.3.3 + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + named-placeholders@1.1.6: dependencies: lru.min: 1.1.4 @@ -5473,6 +6680,12 @@ snapshots: path-parse@1.0.7: {} + pathe@1.1.2: {} + + pathe@2.0.3: {} + + pathval@2.0.1: {} + pbf@4.0.1: dependencies: resolve-protobuf-schema: 2.1.0 @@ -5483,6 +6696,14 @@ snapshots: picomatch@4.0.3: {} + pirates@4.0.7: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.1 + pathe: 2.0.3 + po-parser@2.1.1: {} point-in-polygon-hao@1.2.4: @@ -5495,6 +6716,13 @@ snapshots: possible-typed-array-names@1.1.0: {} + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.8): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 2.6.1 + postcss: 8.5.8 + postcss@8.4.31: dependencies: nanoid: 3.3.11 @@ -5576,6 +6804,8 @@ snapshots: react@19.2.4: {} + readdirp@4.1.2: {} + recharts-scale@0.4.5: dependencies: decimal.js-light: 2.5.1 @@ -5621,6 +6851,8 @@ snapshots: resolve-from@4.0.0: {} + resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} resolve-protobuf-schema@2.1.0: @@ -5646,6 +6878,37 @@ snapshots: robust-predicates@3.0.2: {} + rollup@4.59.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 + fsevents: 2.3.3 + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -5776,6 +7039,8 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} + simplesignal@2.1.7: {} sort-asc@0.2.0: {} @@ -5800,6 +7065,8 @@ snapshots: source-map@0.6.1: {} + source-map@0.7.6: {} + split-string@3.1.0: dependencies: extend-shallow: 3.0.2 @@ -5808,8 +7075,12 @@ snapshots: stable-hash@0.0.5: {} + stackback@0.0.2: {} + standard-as-callback@2.1.0: {} + std-env@3.10.0: {} + stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 @@ -5874,6 +7145,16 @@ snapshots: client-only: 0.0.1 react: 19.2.4 + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + supercluster@8.0.1: dependencies: kdbush: 4.0.2 @@ -5890,6 +7171,14 @@ snapshots: tapable@2.3.0: {} + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + three-conic-polygon-geometry@2.1.2(three@0.173.0): dependencies: '@turf/boolean-point-in-polygon': 7.3.4 @@ -5949,15 +7238,25 @@ snapshots: tiny-invariant@1.3.3: {} + tinybench@2.9.0: {} + tinycolor2@1.6.0: {} + tinyexec@0.3.2: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinypool@1.1.1: {} + tinyqueue@3.0.0: {} + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -5966,10 +7265,14 @@ snapshots: dependencies: commander: 2.20.3 + tree-kill@1.2.2: {} + ts-api-utils@2.4.0(typescript@5.9.3): dependencies: typescript: 5.9.3 + ts-interface-checker@0.1.13: {} + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -5979,6 +7282,35 @@ snapshots: tslib@2.8.1: {} + tsup@8.5.1(@swc/core@1.15.18)(jiti@2.6.1)(postcss@8.5.8)(typescript@5.9.3): + dependencies: + bundle-require: 5.1.0(esbuild@0.27.4) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3 + esbuild: 0.27.4 + fix-dts-default-cjs-exports: 1.0.1 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.8) + resolve-from: 5.0.0 + rollup: 4.59.0 + source-map: 0.7.6 + sucrase: 3.35.1 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + optionalDependencies: + '@swc/core': 1.15.18 + postcss: 8.5.8 + typescript: 5.9.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -6024,6 +7356,8 @@ snapshots: dependencies: typewise-core: 1.2.0 + ufo@1.6.3: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -6093,6 +7427,69 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 + vite-node@2.1.9(@types/node@22.19.15)(lightningcss@1.31.1): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 1.1.2 + vite: 5.4.21(@types/node@22.19.15)(lightningcss@1.31.1) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.21(@types/node@22.19.15)(lightningcss@1.31.1): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.8 + rollup: 4.59.0 + optionalDependencies: + '@types/node': 22.19.15 + fsevents: 2.3.3 + lightningcss: 1.31.1 + + vitest@2.1.9(@types/node@22.19.15)(lightningcss@1.31.1): + dependencies: + '@vitest/expect': 2.1.9 + '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@22.19.15)(lightningcss@1.31.1)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.9 + '@vitest/snapshot': 2.1.9 + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.3.0 + magic-string: 0.30.21 + pathe: 1.1.2 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.1.1 + tinyrainbow: 1.2.0 + vite: 5.4.21(@types/node@22.19.15)(lightningcss@1.31.1) + vite-node: 2.1.9(@types/node@22.19.15)(lightningcss@1.31.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.19.15 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -6142,6 +7539,11 @@ snapshots: dependencies: isexe: 3.1.5 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} yocto-queue@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..dee51e9 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - "packages/*" diff --git a/skill/openclaw-reporter/SKILL.md b/skill/openclaw-reporter/SKILL.md index 60542f2..9faffe7 100644 --- a/skill/openclaw-reporter/SKILL.md +++ b/skill/openclaw-reporter/SKILL.md @@ -14,8 +14,7 @@ requirements: writeFiles: - "~/.openclaw/config.json" binaries: - - curl - - uname + - claw-market env: - name: CLAUDE_MODEL required: false @@ -24,7 +23,7 @@ hooks: SessionStart: - hooks: - type: command - command: "CONFIG=\"$HOME/.openclaw/config.json\"; [ -f \"$CONFIG\" ] && KEY=$(grep -o '\"apiKey\"[[:space:]]*:[[:space:]]*\"[^\"]*\"' \"$CONFIG\" | head -1 | sed 's/.*\"\\([^\"]*\\)\"$/\\1/') && [ -n \"$KEY\" ] && curl -s -o /dev/null --max-time 5 -X POST 'https://kymr.top/api/v1/heartbeat' -H 'Content-Type: application/json' -H \"Authorization: Bearer $KEY\" -d \"{\\\"platform\\\":\\\"$(uname -s | tr '[:upper:]' '[:lower:]')\\\",\\\"model\\\":\\\"${CLAUDE_MODEL:-unknown}\\\"}\" 2>/dev/null || true" + command: "claw-market heartbeat 2>/dev/null || true" timeout: 10 --- @@ -32,6 +31,14 @@ hooks: This skill lets you participate in the OpenClaw global claw activity heatmap. It reports **minimal, non-code** activity data to visualize worldwide AI agent usage. Note: as with any HTTPS request, the server can observe your IP address. +## Prerequisites + +This skill requires the `claw-market` CLI tool. Install it globally: + +```bash +npm install -g @ricardweii/claw-market +``` + ## How It Works - **Heartbeat**: Sent once when the skill is loaded (`SessionStart` hook). No other automated hooks are used — no `PostToolUse`, no `Stop` hooks. @@ -57,13 +64,23 @@ This skill sends the following data to `https://kymr.top/` (the OpenClaw Market ## Configuration -Config is stored at `~/.openclaw/config.json` (permissions `600`). No external scripts are deployed — the heartbeat is sent inline via the `SessionStart` hook command. +Config is stored at `~/.openclaw/config.json` (permissions `600`). Managed by the `claw-market` CLI tool. ## First-Time Setup (Requires User Consent) If `~/.openclaw/config.json` does not exist, follow these steps: -### Step 1: Ask for consent +### Step 1: Check CLI availability + +First, verify `claw-market` is installed: + +```bash +which claw-market || echo "NOT_INSTALLED" +``` + +If not installed, inform the user: "The openclaw-reporter skill requires the claw-market CLI. Install with: `npm install -g @ricardweii/claw-market`" + +### Step 2: Ask for consent Use the AskUserQuestion tool: @@ -72,7 +89,7 @@ Use the AskUserQuestion tool: **If the user selects "No, skip":** do NOT register and do NOT ask again in this session. Stop here. -### Step 2: Ask for a claw name +### Step 3: Ask for a claw name If the user consented, use AskUserQuestion again: @@ -82,56 +99,21 @@ If the user consented, use AskUserQuestion again: Use whatever the user provides as the claw name. -### Step 3: Register and save config +### Step 4: Register using CLI -After receiving the name (stored as `CLAW_NAME`), run the following: +After receiving the name, validate and register: ```bash -# --- OpenClaw Registration --- -set -e - -OPENCLAW_ENDPOINT="https://kymr.top" +# Validate claw name: only allow alphanumeric, hyphens, underscores (1-30 chars). CLAW_NAME="USER_CHOSEN_NAME_HERE" -# Validate claw name: only allow alphanumeric, hyphens, underscores (1-30 chars). -# This whitelist ensures $CLAW_NAME is safe for shell interpolation and JSON embedding. if ! echo "$CLAW_NAME" | grep -qE '^[A-Za-z0-9_-]{1,30}$'; then echo "Error: Claw name must be 1-30 characters, alphanumeric/hyphens/underscores only." exit 1 fi -mkdir -p ~/.openclaw - -# Register with the server -# Safe: CLAW_NAME is validated above to contain only [A-Za-z0-9_-] -RESPONSE=$(curl -s -X POST "$OPENCLAW_ENDPOINT/api/v1/register" \ - -H "Content-Type: application/json" \ - -d "{ - \"name\": \"$CLAW_NAME\", - \"platform\": \"$(uname -s | tr '[:upper:]' '[:lower:]')\", - \"model\": \"${CLAUDE_MODEL:-unknown}\" - }") - -# Extract fields from JSON response using grep/sed (no python3 needed) -CLAW_ID=$(echo "$RESPONSE" | grep -o '"clawId"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/') -API_KEY=$(echo "$RESPONSE" | grep -o '"apiKey"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"\([^"]*\)"$/\1/') - -if [ -z "$API_KEY" ]; then - echo "Error: Registration failed. Server response: $RESPONSE" - exit 1 -fi - -# Write config file -cat > ~/.openclaw/config.json << CFGEOF -{ - "clawId": "$CLAW_ID", - "apiKey": "$API_KEY", - "name": "$CLAW_NAME" -} -CFGEOF -chmod 600 ~/.openclaw/config.json - -echo "Registered as: $CLAW_NAME" +# Register using CLI +claw-market register "$CLAW_NAME" ``` ## Task Reporting (Manual Only) @@ -141,15 +123,10 @@ Task reports are **never sent automatically**. Only send a task report when the When triggered, run: ```bash -CONFIG="$HOME/.openclaw/config.json" -[ -f "$CONFIG" ] || { echo "OpenClaw not registered."; exit 0; } -KEY=$(grep -o '"apiKey"[[:space:]]*:[[:space:]]*"[^"]*"' "$CONFIG" | head -1 | sed 's/.*"\([^"]*\)"$/\1/') -[ -z "$KEY" ] && { echo "No API key found."; exit 0; } -curl -s -o /dev/null --max-time 5 -X POST 'https://kymr.top/api/v1/task' \ - -H 'Content-Type: application/json' \ - -H "Authorization: Bearer $KEY" \ - -d "{\"summary\":\"Completed a task\",\"model\":\"${CLAUDE_MODEL:-unknown}\"}" 2>/dev/null \ - && echo "Task reported." || echo "Task report failed (non-blocking)." +# Estimate task duration (ask user or use a default) +DURATION_MS=60000 # Default 1 minute, adjust based on actual task time + +claw-market task "Completed a task" --duration "$DURATION_MS" || echo "Task report failed (non-blocking)." ``` ## Opt-Out / Unregister @@ -157,9 +134,7 @@ curl -s -o /dev/null --max-time 5 -X POST 'https://kymr.top/api/v1/task' \ To stop all OpenClaw reporting: ```bash -rm -f ~/.openclaw/config.json -rmdir ~/.openclaw 2>/dev/null -echo "OpenClaw fully uninstalled." +claw-market config clear ``` After deletion, no heartbeats or task reports will be sent. The skill will ask for consent again if re-enabled. @@ -172,5 +147,19 @@ After deletion, no heartbeats or task reports will be sent. The skill will ask f 4. **Task reports are manual only** — only send when the user explicitly mentions completing a task or asks to report 5. If any OpenClaw request fails, continue normally — never interrupt the user's workflow 6. Never include identifying information in task summaries -7. **No external scripts**: all logic is inline or executed by the agent directly -8. **No system-level modifications**: never write to `~/.claude/settings.json` or any file outside `~/.openclaw/` +7. **No system-level modifications**: never write to `~/.claude/settings.json` or any file outside `~/.openclaw/` + +## CLI Reference + +The `claw-market` CLI provides these commands: + +| Command | Description | +|---------|-------------| +| `claw-market register ` | Register a new claw | +| `claw-market heartbeat` | Send a heartbeat | +| `claw-market task -d ` | Report a completed task | +| `claw-market config show` | Show current configuration | +| `claw-market config path` | Show config file path | +| `claw-market config clear` | Delete configuration (unregister) | + +Global options: `--lang `, `--json`, `--endpoint `