dsh-skill-hub 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +11 -6
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
- package/src/client/slash-dots.tsx +13 -13
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["css","css","css","css","css","css","css","css","css","css","css","Fragment","css"],"sources":["../src/protocol.ts","../src/client/api.ts","../src/client/locales.ts","../src/client/settings-nav-icon.ts","../src/client/grouping.ts","../src/client/helpers.ts","../src/client/panel/format.ts","../src/client/slash-dots.tsx","../src/client/icons.tsx","../src/client/settings-card.tsx","../node_modules/zustand/esm/vanilla.mjs","../node_modules/zustand/esm/middleware.mjs","../node_modules/immer/dist/immer.mjs","../node_modules/@deepseek-ai/dsh-client-store/lib/index.js","../src/client/settings-form.ts","../src/client/SkillHubSettingsCard.tsx","../src/client/panel/SourceStatusBadge.tsx","../src/client/panel/SkillDetailView.tsx","../src/client/panel/TagEditorView.tsx","../src/client/panel/SkillRow.tsx","../src/client/panel/DisabledRow.tsx","../src/client/panel/GroupSummary.tsx","../src/client/panel/SourcesView.tsx","../src/client/panel/ScenesView.tsx","../src/client/market-catalog.ts","../src/client/panel/dialogs.tsx","../src/client/panel/MarketView.tsx","../src/client/panel/useSkillHub.ts","../src/client/panel/SkillHubPanel.tsx","../src/client/index.tsx"],"sourcesContent":["/**\n * Shared API contract for dsh-skill-hub: the route paths and payload shapes\n * both the host half and the browser half import. The browser half must never\n * depend on host SDK packages, so registry types are re-spelled here as\n * plain JSON-safe interfaces.\n */\n\n/** Browser-facing base paths of the skill-hub API family. */\nexport const SKILL_HUB_API = {\n catalog: '/api/skill-hub/catalog',\n skill: '/api/skill-hub/skill',\n skillDelete: '/api/skill-hub/skill/delete',\n toggle: '/api/skill-hub/toggle',\n toggleBatch: '/api/skill-hub/toggle-batch',\n create: '/api/skill-hub/create',\n stats: '/api/skill-hub/stats',\n config: '/api/skill-hub/config',\n market: '/api/skill-hub/market',\n marketSource: '/api/skill-hub/market/source',\n marketSourceDelete: '/api/skill-hub/market/source/delete',\n marketSourceRef: '/api/skill-hub/market/source/ref',\n marketCheck: '/api/skill-hub/market/check',\n marketSync: '/api/skill-hub/market/source/sync',\n repo: '/api/skill-hub/repo',\n repoImport: '/api/skill-hub/repo/import',\n repoImportProgress: '/api/skill-hub/repo/import/progress',\n repoImportCancel: '/api/skill-hub/repo/import/cancel',\n update: '/api/skill-hub/update',\n groups: '/api/skill-hub/groups',\n tag: '/api/skill-hub/tag',\n tagDelete: '/api/skill-hub/tag/delete',\n tagMembers: '/api/skill-hub/tag/members',\n tagReorder: '/api/skill-hub/tag/reorder',\n collectionReorder: '/api/skill-hub/collections/reorder',\n sourceGroupReorder: '/api/skill-hub/source-groups/reorder',\n sources: '/api/skill-hub/sources',\n sourceCheck: '/api/skill-hub/sources/check',\n sourceSync: '/api/skill-hub/sources/sync',\n sourceDelete: '/api/skill-hub/sources/delete',\n sourceRestore: '/api/skill-hub/sources/restore',\n sourceTrashClear: '/api/skill-hub/sources/trash/clear',\n} as const\n\n/** User-level roots the hub may write to (matches dsh-skill-filesystem ranks 400/500). */\nexport type WritableRoot = 'user-dsh' | 'user-agents'\n\n/** Invocation policy resolved by the registry, re-spelled for the wire. */\nexport interface HubInvocation {\n /** Whether model-facing catalogs may load this skill. */\n modelInvocable: boolean\n /** Whether human-facing command catalogs may load this skill. */\n userInvocable: boolean\n}\n\n/** One enabled skill row in the catalog. */\nexport interface CatalogSkill {\n name: string\n description: string\n whenToUse?: string\n invocation: HubInvocation\n provider: string\n /** Whether the hub may toggle this skill (user-level filesystem skills only). */\n writable: boolean\n /** 技能来源标识(user-dsh/user-agents/project-dsh/project-agents/...)。 */\n source: string\n /** SKILL.md creation time (epoch ms); used for \"added\" sorting. Absent when unknown. */\n addedAt?: number\n /** SKILL.md last-modified time (epoch ms); used for \"updated\" display. Absent when unknown. */\n updatedAt?: number\n /** 项目技能的所属工作区路径(仅 project-dsh/project-agents 来源携带)。 */\n workspace?: string\n /** 工作区显示标题(来自 workspace.json;无则回退为路径)。 */\n workspaceTitle?: string\n}\n\n/** One disabled skill tracked by the hub sidecar (SKILL.md renamed away). */\nexport interface DisabledSkill {\n name: string\n description: string\n /** Absolute path of the renamed file (SKILL.md.disabled / <name>.md.disabled). */\n path: string\n root: WritableRoot\n disabledAt: number\n}\n\n/** One discovery diagnostic: a file the filesystem provider skips, with the reason. */\nexport interface DiagnosticEntry {\n path: string\n root: string\n reason: string\n}\n\n/** GET /api/skill-hub/catalog */\nexport interface CatalogResponse {\n ok: true\n /** 已安装插件自身的版本号(package.json version),面板标题旁显示。 */\n pluginVersion: string\n /** Whether discovery completed within a stable catalog revision. */\n complete: boolean\n /** Sorted winning summaries of every enabled skill (all roots + providers). */\n skills: CatalogSkill[]\n /** Skills the hub has toggled off (kept outside provider discovery). */\n disabled: DisabledSkill[]\n /** Files in the writable roots the provider ignores, with reasons. */\n diagnostics: DiagnosticEntry[]\n}\n\n/** GET /api/skill-hub/skill */\nexport interface SkillDetail {\n name: string\n description: string\n whenToUse?: string\n invocation: HubInvocation\n provider: string\n /** Absolute file path when the skill came from disk. */\n path?: string\n /** SKILL.md creation time (epoch ms); absent when the file is unreadable. */\n addedAt?: number\n /** SKILL.md last-modified time (epoch ms); absent when the file is unreadable. */\n updatedAt?: number\n /** Markdown instruction body. */\n content: string\n}\n\nexport interface SkillDetailResponse {\n ok: true\n skill: SkillDetail\n}\n\n/** POST /api/skill-hub/skill/delete — 把单个技能移入回收站(可恢复)。 */\nexport interface SkillDeleteRequest {\n name: string\n}\n\n/** POST /api/skill-hub/skill/delete */\nexport interface SkillDeleteResponse {\n ok: true\n name: string\n /** 移入回收站后的路径(目录或文件)。 */\n path: string\n}\n\n/** POST /api/skill-hub/toggle */\nexport interface ToggleRequest {\n /** Kebab-case skill name. */\n name: string\n /** true re-enables a hub-disabled skill; false disables an enabled one. */\n enabled: boolean\n}\n\nexport interface ToggleResponse {\n ok: true\n /** Fresh catalog after the mutation (the filesystem provider may lag a beat). */\n catalog: CatalogResponse\n}\n\n/** POST /api/skill-hub/toggle-batch — one group of skills, one write. */\nexport interface ToggleBatchRequest {\n names: string[]\n enabled: boolean\n}\n\n/** POST /api/skill-hub/toggle-batch */\nexport interface ToggleBatchResponse {\n ok: true\n catalog: CatalogResponse\n /** Per-name failures (unknown/read-only skills); empty means all landed. */\n failures: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/create */\nexport interface CreateRequest {\n /** Kebab-case skill name (validated with the official isSkillName grammar). */\n name: string\n /** Optional one-line routing description for the frontmatter. */\n description?: string\n /** Target user root; defaults to user-dsh (~/.dsh/skills). */\n root?: WritableRoot\n}\n\nexport interface CreateResponse {\n ok: true\n path: string\n root: WritableRoot\n}\n\n/** One skill's invocation stats across the local session logs. */\nexport interface SkillStat {\n /** Kebab-case skill name. */\n name: string\n /** How many sessions recorded a user-explicit invocation of this skill. */\n count: number\n /** Unix epoch ms of the most recent invocation (absent when never called). */\n lastUsed?: number\n}\n\n/** GET /api/skill-hub/stats */\nexport interface StatsResponse {\n ok: true\n /** Whether a session-log source was available (false means counts are empty). */\n available: boolean\n /** Sorted per-skill invocation counts. */\n stats: SkillStat[]\n}\n\n/**\n * Persisted incremental-scan checkpoint for the usage statistics (sidecar\n * `skillStats` field). Sessions created before `frozenBefore` are treated as\n * finalized: their per-session counts live in `frozenSessions` (only sessions\n * with at least one invocation are kept) and they are not re-read on\n * incremental scans. A daily full reconciliation rebuilds the cache and\n * advances the watermark, so a resumed old session is eventually re-counted.\n */\nexport interface SkillStatsCheckpoint {\n /** The rolling-window configuration this checkpoint was built for (0 = all history). */\n windowDays: number\n /** Watermark: every session with header.createdAt < this value is frozen. */\n frozenBefore: number\n /** Per-session counts of finalized sessions, keyed by session id. */\n frozenSessions: Record<string, { createdAt: number; counts: Record<string, { count: number; lastUsed: number }> }>\n /** Epoch ms of the last full reconciliation (drives the daily cadence). */\n lastFullReconcile: number\n}\n\n/** JSON error body shared by every route. */\nexport interface ErrorResponse {\n error: string\n}\n\n/** The skill hub's own runtime configuration, edited from the settings card. */\nexport interface HubConfig {\n /** Master switch: routes, provider, and announcement all go live with this. */\n enabled: boolean\n /** When true, a system-prompt section announces the hub to every agent. */\n announceToAgent: boolean\n /** Model-invocable dot color (#rrggbb); absent means the panel default. */\n dotModelColor?: string\n /** User-invocable dot color (#rrggbb); absent means the panel default. */\n dotUserColor?: string\n /** Show per-skill invocation count chip. Default true. */\n showUseCount?: boolean\n /** Show per-skill last-used relative time. Default true. */\n showUseTime?: boolean\n /** Show group-header usage summaries (count + last used). Default true. */\n showGroupSummary?: boolean\n /** 统计滚动窗口天数:只统计最近 N 天的使用;0 = 全部历史。默认 0。 */\n statsWindowDays?: number\n /** 自动统计扫描间隔(分钟,最小 1)。默认 5。 */\n statsScanMinutes?: number\n}\n\n/**\n * The resolved shape of the hub's settings namespace (schema defaults, then\n * the composition base, then the user layer). Kept as a type alias so the\n * browser-side settings scope snapshot is index-compatible with the card\n * form's record shape.\n */\nexport type HubSettingsValue = {\n enabled: boolean\n announceToAgent: boolean\n showUseCount: boolean\n showUseTime: boolean\n showGroupSummary: boolean\n /** Model-invocable dot color (#rrggbb); absent means the panel default. */\n dotModelColor?: string\n /** User-invocable dot color (#rrggbb); absent means the panel default. */\n dotUserColor?: string\n /** 统计滚动窗口天数(0 = 全部历史)。 */\n statsWindowDays?: number\n /** 自动统计扫描间隔(分钟)。 */\n statsScanMinutes?: number\n}\n\n/**\n * Hub config defaults — the single source every layer reads: the cordis\n * schema (index.ts), the host's saved-override merge, and the routes'\n * fallback view. Changing a default here changes all three.\n */\nexport const HUB_CONFIG_DEFAULTS = {\n enabled: true,\n announceToAgent: true,\n showUseCount: true,\n showUseTime: true,\n showGroupSummary: true,\n statsWindowDays: 14,\n statsScanMinutes: 5,\n} as const\n\n/**\n * Resolve the effective hub config: saved sidecar overrides win over the\n * cordis composition entry (the web card owns runtime config), missing\n * booleans fall back to HUB_CONFIG_DEFAULTS, and dot colors pass through\n * (saved first, then base) only when set. Numeric stats knobs are clamped to\n * their sane ranges (window ≥ 0, scan interval ≥ 1 minute).\n */\nexport function resolveHubConfig(saved: Partial<HubConfig>, base: Partial<HubConfig> = {}): HubConfig {\n const dotModelColor = saved.dotModelColor !== undefined ? saved.dotModelColor : base.dotModelColor\n const dotUserColor = saved.dotUserColor !== undefined ? saved.dotUserColor : base.dotUserColor\n const windowDays = clampNumber(saved.statsWindowDays ?? base.statsWindowDays, 0) ?? HUB_CONFIG_DEFAULTS.statsWindowDays\n const scanMinutes = clampNumber(saved.statsScanMinutes ?? base.statsScanMinutes, 1) ?? HUB_CONFIG_DEFAULTS.statsScanMinutes\n return {\n enabled: saved.enabled ?? base.enabled ?? HUB_CONFIG_DEFAULTS.enabled,\n announceToAgent: saved.announceToAgent ?? base.announceToAgent ?? HUB_CONFIG_DEFAULTS.announceToAgent,\n showUseCount: saved.showUseCount ?? base.showUseCount ?? HUB_CONFIG_DEFAULTS.showUseCount,\n showUseTime: saved.showUseTime ?? base.showUseTime ?? HUB_CONFIG_DEFAULTS.showUseTime,\n showGroupSummary: saved.showGroupSummary ?? base.showGroupSummary ?? HUB_CONFIG_DEFAULTS.showGroupSummary,\n statsWindowDays: windowDays,\n statsScanMinutes: scanMinutes,\n ...(dotModelColor !== undefined ? { dotModelColor } : {}),\n ...(dotUserColor !== undefined ? { dotUserColor } : {}),\n }\n}\n\n/** Clamp a numeric override into a valid value; undefined/invalid stays undefined. */\nfunction clampNumber(value: unknown, min: number): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < min) return undefined\n return Math.floor(value)\n}\n\n/** HEX color validation shared by host routes and the settings card. */\nexport const HEX_COLOR_RE = /^#[0-9a-f]{6}$/i\n\n/** GET /api/skill-hub/config */\nexport interface ConfigResponse {\n ok: true\n /** 已安装插件自身的版本号(package.json version),设置卡标题旁显示。 */\n pluginVersion: string\n /** Effective configuration (saved overrides merged over the defaults). */\n config: HubConfig\n /** Raw user overrides persisted in the sidecar (absent fields inherit defaults). */\n saved: Partial<HubConfig>\n}\n\n/** POST /api/skill-hub/config — a partial patch; omitted fields keep their values. */\nexport interface ConfigRequest {\n /** Set the field; null clears the saved override so it re-inherits the default. */\n enabled?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n announceToAgent?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showUseCount?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showUseTime?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showGroupSummary?: boolean | null\n /** Set the dot color; null clears the saved override so it re-inherits the default. */\n dotModelColor?: string | null\n /** Set the dot color; null clears the saved override so it re-inherits the default. */\n dotUserColor?: string | null\n /** 统计滚动窗口天数(0 = 全部历史);null 清除覆盖回默认。 */\n statsWindowDays?: number | null\n /** 自动统计扫描间隔(分钟);null 清除覆盖回默认。 */\n statsScanMinutes?: number | null\n}\n\n/** One market source: a tracked upstream repo plus its pinned version. */\nexport interface MarketSourceRecord {\n /** Repo slug (owner/repo). */\n repo: string\n /** Pinned version: release tag, branch name, or custom ref. Absent = not yet pinned. */\n ref?: string\n /** Commit the pinned ref last resolved to (update-check baseline). */\n commitSha?: string\n}\n\n/** GET /api/skill-hub/market — the user's added market sources. */\nexport interface MarketSourcesResponse {\n ok: true\n /** Added market sources, in addition order. */\n repos: MarketSourceRecord[]\n}\n\n/** POST /api/skill-hub/market/source — add one repo as a market source. */\nexport interface MarketSourceRequest {\n /** owner/repo, owner/repo@ref, or a github.com URL. */\n repo: string\n}\n\n/** POST /api/skill-hub/market/source|delete */\nexport interface MarketSourceResponse {\n ok: true\n repos: MarketSourceRecord[]\n}\n\n/** POST /api/skill-hub/market/source/ref — pin a market source to an explicit ref. */\nexport interface MarketSourceRefRequest {\n repo: string\n /** Release tag or branch name chosen for the repo. */\n ref: string\n}\n\n/** GET /api/skill-hub/market/check — update check over market sources. */\nexport interface MarketCheckResponse {\n ok: true\n results: Array<{\n repo: string\n /** Pinned ref, when one is recorded. */\n ref?: string\n /** Latest release tag on the repo, when it has one. */\n latestTag?: string\n /** Whether the pinned ref (or the repo) has moved ahead. */\n updateAvailable: boolean\n /** Latest commit of the checked ref. */\n commitSha: string\n /** Throttled: the check was skipped within the interval. */\n throttled?: boolean\n error?: string\n }>\n}\n\n/** POST /api/skill-hub/market/source/sync — align a market source to its pinned ref. */\nexport interface MarketSyncResponse {\n ok: true\n repo: string\n /** The ref the source is now pinned to. */\n ref: string\n commitSha: string\n /** Local skills tracked from this repo (candidates for a batch update). */\n skills: string[]\n}\n\n/** A skill discovered in a GitHub repo under any top-level root (e.g. skills/, templates/). */\nexport interface RepoSkillEntry {\n /** Kebab-case skill name (directory basename). */\n name: string\n /** Root-relative skill directory, e.g. skills/code-review. */\n dir: string\n /** Root-relative SKILL.md path, e.g. skills/code-review/SKILL.md. */\n path: string\n /** Repo root the skill lives in. */\n root: RepoRoot\n /** Collection name recorded as origin after import. */\n origin: string\n /** Number of files in the skill directory. */\n fileCount: number\n /** Total bytes across all files in the skill directory. */\n totalBytes: number\n /** Whether a same-named skill already exists locally. */\n existing: boolean\n}\n\n/** Skill root in a GitHub repo: the top-level directory that contains skills (e.g. skills, design-templates, templates). Auto-derived from SKILL.md locations, not hard-coded. */\nexport type RepoRoot = string\n\n/** GET /api/skill-hub/repo — discover importable skills in a GitHub repo. */\nexport interface RepoDiscoverResponse {\n ok: true\n repo: string\n /**\n * Ref the discovery ran against (release tag / branch / default branch).\n * Null means the repo has no release and no pinned ref — the client must\n * ask the user to pick a branch (see `branches`) and pin it first.\n */\n ref: string | null\n /** Branch names to choose from when ref is null (default branch first). */\n branches?: string[]\n entries: RepoSkillEntry[]\n}\n\n/** POST /api/skill-hub/repo/import — install selected repo skills. */\nexport interface RepoImportRequest {\n repo: string\n /** Selected SKILL.md paths from the discover response. */\n paths: string[]\n /** The ref the discovery ran against; the import must use the same one. */\n ref?: string\n}\n\n/** POST /api/skill-hub/repo/import — now creates an async job (B方案) */\nexport interface RepoImportResponse {\n ok: true\n jobId: string\n total: number\n totalBytes: number\n}\n\n/** GET /api/skill-hub/repo/import/progress?jobId=xxx */\nexport interface RepoImportProgressResponse {\n ok: true\n jobId: string\n status: 'running' | 'done' | 'cancelled' | 'error'\n total: number\n done: number\n /** 当前正在下载的 skill 名,done < total 时有效 */\n current?: string\n /** 当前正在下载的文件路径(相对 skill dir) */\n currentFile?: string\n /** 字节级进度 */\n totalBytes: number\n downloadedBytes: number\n /** 下载速度 bytes/sec,running 时有效 */\n bytesPerSecond?: number\n imported: Array<{ name: string; origin: string; path: string }>\n skipped: Array<{ name: string; reason: 'exists' }>\n failed: Array<{ name: string; error: string }>\n /** error 状态时的原因 */\n error?: string\n}\n\n/** POST /api/skill-hub/repo/import/cancel */\nexport interface RepoImportCancelRequest {\n jobId: string\n}\nexport interface RepoImportCancelResponse {\n ok: true\n jobId: string\n status: 'cancelled' | 'done'\n}\n\n/** @deprecated 旧同步响应,保留供类型兼容,实际已由 Progress 代替 */\nexport interface RepoImportLegacyResponse {\n ok: true\n imported: Array<{ name: string; origin: string; path: string }>\n skipped: Array<{ name: string; reason: 'exists' }>\n failed: Array<{ name: string; error: string }>\n}\n\n/** GET /api/skill-hub/update — check the plugin's own latest GitHub release. */\nexport interface UpdateCheckResponse {\n ok: true\n /** Installed plugin version (from the bundled host build). */\n currentVersion: string\n /** Latest release tag, normalized without the leading v; null when unknown. */\n latestVersion: string | null\n /** True when latestVersion is strictly newer than currentVersion. */\n updateAvailable: boolean\n /** Release page URL; null when unavailable. */\n url: string | null\n /** Best-effort message when the check failed or no release exists. */\n error?: string\n}\n\n/** 用户自定义 tag 分组:纯组织视图,不改技能文件。 */\nexport interface SkillTag {\n /** 稳定 ID(新建时由宿主生成)。 */\n id: string\n /** 显示名。 */\n name: string\n /** 成员技能名(集合技能与独立技能都可加入)。 */\n skillNames: string[]\n /** 默认场景(「通用」):系统预置、不可删除、新技能自动归入。 */\n default?: boolean\n}\n\n/** 系统集合组:按 origin(来源集合标识)自动聚合。 */\nexport interface CollectionGroup {\n /** 集合名(origin 值,如 \"superpowers\" / \"anthropics/skills\")。 */\n name: string\n /** 该集合下的技能名,按名称排序。 */\n skillNames: string[]\n}\n\n/** GET /api/skill-hub/groups */\nexport interface GroupsResponse {\n ok: true\n /** 用户自定义 tag 分组(按拖拽顺序)。 */\n tags: SkillTag[]\n /** 系统集合组(按拖拽顺序,兜底按名称)。 */\n collections: CollectionGroup[]\n /** skillName → 集合名 的完整映射。 */\n origins: Record<string, string>\n /** 来源分组整体顺序(project / col:xxx / uncategorized-source),用于 SourcesView 顶层排序 */\n sourceGroupOrder?: string[]\n /** 兼容旧 collectionOrder 字段 */\n collectionOrder?: string[]\n}\n\n/** POST /api/skill-hub/tag — 新建(缺省 id)或重命名(带 id)。 */\nexport interface TagSaveRequest {\n /** 已有 tag 的 id;缺省表示新建。 */\n id?: string\n /** 显示名(去空格后非空)。 */\n name: string\n}\n\n/** POST /api/skill-hub/tag */\nexport interface TagSaveResponse {\n ok: true\n /** 变更后的全部 tag。 */\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/tag/delete */\nexport interface TagDeleteRequest {\n id: string\n}\n\n/** POST /api/skill-hub/tag/delete */\nexport interface TagDeleteResponse {\n ok: true\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/tag/members — 直接设置某 tag 的完整成员列表(幂等)。 */\nexport interface TagMembersRequest {\n id: string\n /** 目标成员技能名;后端只保留目录中存在的名字。 */\n skillNames: string[]\n}\n\n/** POST /api/skill-hub/tag/members */\nexport interface TagMembersResponse {\n ok: true\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/tag/reorder — 拖拽重排场景分组 */\nexport interface TagReorderRequest {\n /** 按新顺序排列的 tag id 列表(需包含全部 id) */\n orderedIds: string[]\n}\n/** POST /api/skill-hub/tag/reorder */\nexport interface TagReorderResponse {\n ok: true\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/collections/reorder — 拖拽重排来源集合 */\nexport interface CollectionReorderRequest {\n /** 按新顺序排列的集合名列表(需包含全部 name) */\n orderedNames: string[]\n}\n/** POST /api/skill-hub/collections/reorder */\nexport interface CollectionReorderResponse {\n ok: true\n collections: CollectionGroup[]\n order: string[]\n}\n\n/** POST /api/skill-hub/source-groups/reorder — 拖拽重排来源顶层分组(project / collections / personal) */\nexport interface SourceGroupReorderRequest {\n /** 按新顺序排列的顶层分组 key 列表(project / col:xxx / uncategorized-source) */\n orderedKeys: string[]\n}\nexport interface SourceGroupReorderResponse {\n ok: true\n order: string[]\n}\n\n/** 来源跟踪记录:一组来自同一上游仓库根目录的技能。 */\nexport interface SourceRecord {\n /** GitHub owner/repo。 */\n repo: string\n /** 显式分支/tag;缺省表示默认分支。 */\n ref?: string\n /** 技能在仓库中的根目录。 */\n root: RepoRoot\n /** 上次导入/同步时的上游 commit SHA;空 = 尚未核对过。 */\n commitSha: string\n /** 该来源下的技能名(来源组 = 这些技能)。 */\n skills: string[]\n /** 仓库内路径 → 文件大小 的基线清单(差异检测用;缺失 = 无基线)。 */\n manifest?: Record<string, number>\n}\n\n/** 回收站条目:上游删除后跟进删除(移入 .trash)的技能。 */\nexport interface TrashEntry {\n name: string\n /** .trash 下的绝对路径。 */\n path: string\n /** 移入回收站的时间(epoch ms)。 */\n movedAt: number\n /** 移入回收站前的原始路径(目录或文件);旧版本条目没有该字段。 */\n sourcePath?: string\n /**\n * 移入回收站前的来源跟踪快照(恢复时用它把技能重新挂回来源记录,\n * 否则恢复后的技能会丢失来源归属、变成「个人技能」)。\n */\n origin?: {\n repo: string\n root: RepoRoot\n ref?: string\n commitSha: string\n }\n /** 移入回收站前所属的场景(tag)ID;恢复时重新加回这些场景。 */\n tagIds?: string[]\n}\n\n/** GET /api/skill-hub/sources */\nexport interface SourcesResponse {\n ok: true\n /** 全部来源记录(按 repo 排序)。 */\n sources: SourceRecord[]\n /** skillName → 集合名(由 sources 派生)。 */\n origins: Record<string, string>\n /** 来源集合组(按 origin 聚合)。 */\n collections: CollectionGroup[]\n /** 回收站内容。 */\n trash: TrashEntry[]\n}\n\n/** POST /api/skill-hub/sources/check — 检查指定(或全部)来源的上游更新。 */\nexport interface SourceCheckRequest {\n /** 仅检查该 repo;缺省检查全部。 */\n repo?: string\n}\n\n/** 单个来源的检查结果。 */\nexport interface SourceCheckResult {\n repo: string\n ref?: string\n /** 检查失败时的原因(如仓库不可达/限流)。 */\n error?: string\n /** 上游 commit 是否变化。 */\n changed: boolean\n /** 上游最新 commit SHA(检查成功时)。 */\n commitSha?: string\n /** 上游有更新的技能名(changed 时经 tree 差异得出)。 */\n updated: string[]\n /** 上游已删除的技能名(changed 时经 tree 差异得出)。 */\n deleted: string[]\n /** 节流跳过(距上次检查不足 5 分钟,未访问网络)。 */\n throttled?: boolean\n /** 该来源此前没有快照(迁移/旧记录),本次已回填 commit,尚未有差异基线。 */\n unverified?: boolean\n}\n\n/** POST /api/skill-hub/sources/check */\nexport interface SourceCheckResponse {\n ok: true\n results: SourceCheckResult[]\n}\n\n/** POST /api/skill-hub/sources/sync — 按上游重新下载所选技能并更新快照。 */\nexport interface SourceSyncRequest {\n repo: string\n /** 要同步的技能名;缺省同步该来源全部技能。 */\n skills?: string[]\n}\n\n/** POST /api/skill-hub/sources/sync */\nexport interface SourceSyncResponse {\n ok: true\n repo: string\n /** 同步后的上游 commit SHA。 */\n commitSha: string\n /** 成功同步的技能。 */\n synced: string[]\n /** 失败的技能。 */\n failed: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/sources/delete — 跟进上游删除,本地移入回收站。 */\nexport interface SourceDeleteRequest {\n repo: string\n /** 要删除的技能名(移入 .trash)。 */\n skills: string[]\n}\n\n/** POST /api/skill-hub/sources/delete */\nexport interface SourceDeleteResponse {\n ok: true\n /** 已移入回收站的技能。 */\n trashed: string[]\n failed: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/sources/restore — 从回收站恢复一个技能。 */\nexport interface SourceRestoreRequest {\n name: string\n}\n\n/** POST /api/skill-hub/sources/restore */\nexport interface SourceRestoreResponse {\n ok: true\n name: string\n path: string\n}\n\n/** POST /api/skill-hub/sources/trash/clear — 永久删除回收站里的全部技能。 */\nexport interface SourceTrashClearResponse {\n ok: true\n /** 已永久删除的技能名。 */\n deleted: string[]\n /** 未能删除的技能(保留在回收站中)。 */\n failed: Array<{ name: string; error: string }>\n}\n","/**\n * Browser-side API client for the /api/skill-hub route family. The only\n * data access path the panel uses — plain fetch, same origin.\n */\nimport {\n SKILL_HUB_API,\n type CatalogResponse,\n type CollectionGroup,\n type ConfigRequest,\n type ConfigResponse,\n type CreateRequest,\n type CreateResponse,\n type CollectionReorderRequest,\n type CollectionReorderResponse,\n type SourceGroupReorderRequest,\n type SourceGroupReorderResponse,\n type MarketCheckResponse,\n type MarketSourceRefRequest,\n type MarketSourceRequest,\n type MarketSourceResponse,\n type MarketSourcesResponse,\n type MarketSyncResponse,\n type RepoDiscoverResponse,\n type RepoImportCancelResponse,\n type RepoImportProgressResponse,\n type RepoImportRequest,\n type RepoImportResponse,\n type SkillDetail,\n type SkillDetailResponse,\n type SkillDeleteRequest,\n type SkillDeleteResponse,\n type SkillTag,\n type SourceCheckRequest,\n type SourceCheckResponse,\n type SourceDeleteRequest,\n type SourceDeleteResponse,\n type SourceRestoreRequest,\n type SourceRestoreResponse,\n type SourceTrashClearResponse,\n type SourcesResponse,\n type SourceSyncRequest,\n type SourceSyncResponse,\n type StatsResponse,\n type TagReorderRequest,\n type TagReorderResponse,\n type ToggleBatchRequest,\n type ToggleBatchResponse,\n type UpdateCheckResponse,\n} from '../protocol.ts'\n\n/** Error carrying the route's JSON error message. */\nexport class SkillHubApiError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'SkillHubApiError'\n }\n}\n\n/** Parse a JSON response or throw a SkillHubApiError. */\nasync function readJson<T>(response: Response): Promise<T> {\n let body: unknown\n try {\n body = await response.json()\n } catch {\n throw new SkillHubApiError('HTTP ' + response.status + ': invalid JSON response')\n }\n if (!response.ok) {\n const message = typeof body === 'object' && body !== null && typeof (body as { error?: unknown }).error === 'string'\n ? (body as { error: string }).error\n : 'HTTP ' + response.status\n throw new SkillHubApiError(message)\n }\n return body as T\n}\n\n/**\n * Fetch with a hard timeout: a hung connection (proxy, stalled keep-alive,\n * host wedged) must never leave the panel stuck on \"loading\" forever — it\n * fails fast and surfaces the error banner instead.\n */\nasync function fetchWithTimeout(input: RequestInfo | URL, init?: RequestInit, ms = 10_000): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), ms)\n try {\n return await fetch(input, { ...init, signal: controller.signal })\n } finally {\n clearTimeout(timer)\n }\n}\n\n/** The browser half's only data entry point. */\nexport class SkillHubApi {\n /** Catalog lookup options (cwd selects a workspace's project skills). */\n catalog(options?: { cwd?: string }): Promise<CatalogResponse> {\n const url = options?.cwd !== undefined && options.cwd !== '' ? SKILL_HUB_API.catalog + '?cwd=' + encodeURIComponent(options.cwd) : SKILL_HUB_API.catalog\n return fetchWithTimeout(url).then((response) => readJson<CatalogResponse>(response))\n }\n\n /** One skill's detail (cwd selects a workspace's project skills). */\n async skill(name: string, options?: { cwd?: string }): Promise<SkillDetail> {\n const cwd = options?.cwd !== undefined && options.cwd !== '' ? '&cwd=' + encodeURIComponent(options.cwd) : ''\n const url = SKILL_HUB_API.skill + '?name=' + encodeURIComponent(name) + cwd\n const response = await fetchWithTimeout(url)\n const body = await readJson<SkillDetailResponse>(response)\n return body.skill\n }\n\n /** Move one writable skill into the restorable trash. */\n async deleteSkill(name: string): Promise<SkillDeleteResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.skillDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name } satisfies SkillDeleteRequest),\n })\n return readJson<SkillDeleteResponse>(response)\n }\n\n /** Toggle one skill; resolves with the fresh catalog from the route. */\n async toggle(name: string, enabled: boolean): Promise<CatalogResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.toggle, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name, enabled } satisfies import('../protocol.ts').ToggleRequest),\n })\n const body = await readJson<import('../protocol.ts').ToggleResponse>(response)\n return body.catalog\n }\n\n async create(payload: CreateRequest): Promise<CreateResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.create, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<CreateResponse>(response)\n }\n\n async stats(): Promise<StatsResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.stats)\n return readJson<StatsResponse>(response)\n }\n\n /** Toggle a whole group in one write; resolves with the fresh catalog + failures. */\n async toggleBatch(names: string[], enabled: boolean): Promise<ToggleBatchResponse> {\n const payload: ToggleBatchRequest = { names, enabled }\n const response = await fetchWithTimeout(SKILL_HUB_API.toggleBatch, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<ToggleBatchResponse>(response)\n }\n\n /** The user's added market sources. */\n async market(): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.market)\n return readJson<MarketSourcesResponse>(response)\n }\n\n /** Add a market source repo; resolves with the fresh list. */\n async addMarketSource(repo: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSource, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo } satisfies MarketSourceRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Remove a market source repo; resolves with the fresh list. */\n async removeMarketSource(repo: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSourceDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo } satisfies MarketSourceRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Check every market source for updates (throttled server-side). */\n async marketCheck(): Promise<MarketCheckResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketCheck)\n return readJson<MarketCheckResponse>(response)\n }\n\n /** Align a market source to its pinned ref; resolves with tracked skills. */\n async marketSync(repo: string): Promise<MarketSyncResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSync, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo }),\n })\n return readJson<MarketSyncResponse>(response)\n }\n\n /** Pin a market source to an explicit ref (branch picker). */\n async setMarketSourceRef(repo: string, ref: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSourceRef, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo, ref } satisfies MarketSourceRefRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Check the hub's own latest GitHub release. */\n async updateCheck(): Promise<UpdateCheckResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.update)\n return readJson<UpdateCheckResponse>(response)\n }\n\n /** Discover importable skills in a GitHub repo. */\n async repoDiscover(repo: string): Promise<RepoDiscoverResponse> {\n const url = SKILL_HUB_API.repo + '?repo=' + encodeURIComponent(repo)\n const response = await fetchWithTimeout(url)\n return readJson<RepoDiscoverResponse>(response)\n }\n\n /** Install selected repo skills into the user-dsh root (records the source). Returns jobId for polling. */\n async repoImport(repo: string, paths: string[], ref?: string): Promise<RepoImportResponse> {\n const payload: RepoImportRequest = { repo, paths, ...(ref !== undefined && ref !== '' ? { ref } : {}) }\n const response = await fetchWithTimeout(SKILL_HUB_API.repoImport, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<RepoImportResponse>(response)\n }\n\n /** Poll import job progress (B方案轮询) */\n async repoImportProgress(jobId: string): Promise<RepoImportProgressResponse> {\n const url = SKILL_HUB_API.repoImportProgress + '?jobId=' + encodeURIComponent(jobId)\n const response = await fetchWithTimeout(url)\n return readJson<RepoImportProgressResponse>(response)\n }\n\n /** Cancel a running import job (选项2:唯有取消才停) */\n async repoImportCancel(jobId: string): Promise<RepoImportCancelResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.repoImportCancel, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ jobId }),\n })\n return readJson<RepoImportCancelResponse>(response)\n }\n\n /** Read the hub's runtime config (effective values + saved overrides). */\n async config(): Promise<ConfigResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.config)\n return readJson<ConfigResponse>(response)\n }\n\n /** Patch the hub's runtime config (null clears a saved override). */\n async saveConfig(patch: ConfigRequest): Promise<ConfigResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.config, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(patch),\n })\n return readJson<ConfigResponse>(response)\n }\n\n /** 用户 tag 分组 + 系统集合组 + origin 映射。 */\n async groups(): Promise<import('../protocol.ts').GroupsResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.groups)\n return readJson<import('../protocol.ts').GroupsResponse>(response)\n }\n\n /** 新建(无 id)或重命名(带 id)一个 tag 分组;返回全部 tag。 */\n async saveTag(payload: import('../protocol.ts').TagSaveRequest): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tag, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n const body = await readJson<import('../protocol.ts').TagSaveResponse>(response)\n return body.tags\n }\n\n /** 删除一个 tag 分组;返回全部 tag。 */\n async deleteTag(id: string): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tagDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id } satisfies import('../protocol.ts').TagDeleteRequest),\n })\n const body = await readJson<import('../protocol.ts').TagDeleteResponse>(response)\n return body.tags\n }\n\n /** 直接设置某 tag 的完整成员列表;返回全部 tag。 */\n async setTagMembers(id: string, skillNames: string[]): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tagMembers, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id, skillNames } satisfies import('../protocol.ts').TagMembersRequest),\n })\n const body = await readJson<import('../protocol.ts').TagMembersResponse>(response)\n return body.tags\n }\n\n /** 拖拽重排场景分组 */\n async reorderTags(orderedIds: string[]): Promise<SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tagReorder, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ orderedIds } satisfies TagReorderRequest),\n })\n const body = await readJson<TagReorderResponse>(response)\n return body.tags\n }\n\n /** 拖拽重排来源集合 */\n async reorderCollections(orderedNames: string[]): Promise<CollectionGroup[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.collectionReorder, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ orderedNames } satisfies CollectionReorderRequest),\n })\n const body = await readJson<CollectionReorderResponse>(response)\n return body.collections\n }\n\n /** 拖拽重排来源顶层分组(project / collections / personal) */\n async reorderSourceGroups(orderedKeys: string[]): Promise<string[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceGroupReorder, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ orderedKeys } satisfies SourceGroupReorderRequest),\n })\n const body = await readJson<SourceGroupReorderResponse>(response)\n return body.order\n }\n\n /** 来源列表 + 派生 origin 映射 + 集合组 + 回收站。 */\n async sources(): Promise<SourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.sources)\n return readJson<SourcesResponse>(response)\n }\n\n /** 检查指定(或全部)来源的上游更新。 */\n async checkSources(repo?: string): Promise<SourceCheckResponse> {\n const payload: SourceCheckRequest = repo !== undefined ? { repo } : {}\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceCheck, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceCheckResponse>(response)\n }\n\n /** 同步一个来源的所选(或全部)技能到上游最新版本。 */\n async syncSource(repo: string, skills?: string[]): Promise<SourceSyncResponse> {\n const payload: SourceSyncRequest = skills !== undefined ? { repo, skills } : { repo }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceSync, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceSyncResponse>(response)\n }\n\n /** 跟进上游删除:把所选技能移入回收站。 */\n async confirmDeleteSource(repo: string, skills: string[]): Promise<SourceDeleteResponse> {\n const payload: SourceDeleteRequest = { repo, skills }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceDeleteResponse>(response)\n }\n\n /** 从回收站恢复一个技能。 */\n async restoreSource(name: string): Promise<SourceRestoreResponse> {\n const payload: SourceRestoreRequest = { name }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceRestore, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceRestoreResponse>(response)\n }\n\n /** Permanently delete every skill currently in the trash. */\n async clearTrash(): Promise<SourceTrashClearResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceTrashClear, { method: 'POST' })\n return readJson<SourceTrashClearResponse>(response)\n }\n}\n","/**\n * dsh-skill-hub surface copy (zh/en). The dictionary type is re-exported\n * so the LocaleNamespaceMap module augmentation in client/index.ts can\n * reference it without a value import.\n */\n\nexport const zh = {\n 'entry.label': '技能',\n 'entry.tooltip': '技能中枢:浏览、分组与同步管理本地技能',\n 'view.sources': '来源',\n 'view.scenes': '场景',\n 'view.market': '市场',\n 'view.flat': '平铺',\n 'view.grouped': '分组',\n 'panel.title': '技能中枢',\n 'panel.count': '共 {count} 个技能',\n 'panel.disabledCount': '已禁用 {count}',\n 'panel.new': '新建技能',\n 'panel.search': '搜索技能…',\n 'legend.model': '模型可调 — Agent 可自动调用',\n 'legend.user': '用户可调 — 仅显式点名时触发',\n 'legend.hint': '每个技能最多一个圆点;无圆点 = 不可被调用。',\n 'panel.enabled': '已启用',\n 'panel.disabled': '已禁用',\n 'panel.diagnostics': '发现诊断',\n 'panel.empty': '没有匹配的技能。',\n 'panel.emptyAll': '本地还没有技能。点击「新建技能」创建第一个。',\n 'panel.loading': '读取中…',\n 'panel.incomplete': '(目录可能不完整)',\n 'panel.workspacePlaceholder': '工作区路径(回车应用)',\n 'panel.workspaceHint': '填写项目路径后,面板同时显示该项目 .dsh/skills 与 .agents/skills 下的技能(只读);留空回车恢复用户级视图。',\n 'panel.workspaceClear': '清除工作区',\n 'market.addPlaceholder': 'owner/repo 或 https://github.com/…',\n 'market.addSource': '添加源',\n 'market.noSources': '还没有市场源。从下方内置市场添加,或输入一个 GitHub 仓库。',\n 'market.title': '市场',\n 'market.catalogHint': '精选技能仓库,添加后即可扫描安装,并持续检查更新。',\n 'market.catalog.anthropics': 'Anthropic 官方技能合集(Claude Skills)',\n 'market.catalog.superpowers': 'Superpowers 社区技能合集',\n 'market.catalog.mattpocock': 'Matt Pocock 技能集',\n 'market.catalog.openDesign': '设计技能合集(design-templates)',\n 'market.add': '添加',\n 'market.installed': '已装 {count}',\n 'market.updatable': '可更新 {count}',\n 'market.deletedUpstream': '上游已删 {count}',\n 'market.checkAll': '检查全部',\n 'market.updateAll': '全部更新',\n 'market.updateAllConfirmTitle': '批量更新全部技能?',\n 'market.updateAllConfirmText': '将把以下来源的可更新技能更新到上游最新版本(覆盖本地修改):',\n 'market.updateAllItem': '{repo}({count} 个技能)',\n 'market.updateAllDone': '已更新 {count} 个来源',\n 'market.deleteSource': '移除源',\n 'market.scan': '扫描',\n 'market.scanning': '扫描中…',\n 'market.check': '检查',\n 'market.checkUpdate': '检查更新',\n 'market.checking': '检查中…',\n 'market.upToDate': '已是最新',\n 'market.update': '更新',\n 'market.updateCount': '更新 {count} 个',\n 'market.sync': '同步',\n 'market.syncing': '同步中…',\n 'market.updated': '有更新',\n 'market.newRelease': '新版本 v{version}',\n 'market.branchTitle': '选择分支',\n 'market.branchHint': '该仓库没有正式发布,选择要跟踪的分支(默认为 main):',\n 'market.branchConfirm': '确定',\n 'market.syncTitle': '同步本地技能',\n 'market.syncText': '市场源已对齐到 {ref},要同步更新以下本地技能吗?',\n 'market.syncNone': '该来源还没有导入本地技能。',\n 'market.syncCancel': '跳过',\n 'market.removeHint': '移除源不影响已安装的技能。',\n 'repo.ready': '发现 {count} 个可导入技能',\n 'repo.empty': '没有找到可导入技能。',\n 'repo.selectAll': '全选',\n 'repo.clearAll': '清空',\n 'repo.import': '导入所选 ({count})',\n 'repo.importing': '导入中…',\n 'repo.existing': '已存在',\n 'repo.files': '{count} 个文件 · {size}',\n 'repo.imported': '导入成功 {count} 个',\n 'repo.skippedExisting': '跳过已存在 {count} 个',\n 'repo.failed': '失败 {count} 个',\n 'repo.cancel': '取消',\n 'repo.cancelled': '已取消 · 已导入 {imported}/{total} 已保留,临时文件已清理',\n 'repo.importingCurrent': '正在导入: {name} ({done}/{total})',\n 'repo.root.skills': '技能 skills',\n 'repo.root.designTemplates': '模板 design-templates',\n 'repo.root.generic': '{root}',\n 'update.check': '检查更新',\n 'update.checking': '检查中…',\n 'update.upToDate': '已是最新版本 v{version}',\n 'update.available': '发现新版本 v{version}(当前 v{current})',\n 'update.newVersion': '新版本 v{version}',\n 'update.viewRelease': '查看发布',\n 'update.error': '检查更新失败:{error}',\n 'update.unavailable': '暂无可用的发布版本',\n 'group.project-dsh': '项目 .dsh/skills',\n 'group.project-agents': '项目 .agents/skills',\n 'group.custom': '自定义目录',\n 'group.runtime': '运行时',\n 'group.user-dsh': '用户 ~/.dsh/skills',\n 'group.user-agents': '用户 ~/.agents/skills',\n 'group.bundled': '内置',\n 'group.other': '其他来源',\n 'groups.new': '新建场景',\n 'groups.namePlaceholder': '场景名',\n 'groups.edit': '编辑',\n 'groups.rename': '保存名称',\n 'groups.delete': '删除场景',\n 'groups.saveMembers': '保存成员',\n 'groups.membersHint': '勾选技能加入此场景(含已禁用)。',\n 'groups.empty': '还没有场景。先新建一个,再把技能归类。',\n 'groups.noCollections': '暂无来源组。从市场导入技能后自动按来源聚合。',\n 'groups.personal': '个人',\n 'groups.project': '项目级',\n 'groups.subdivide': '细分',\n 'groups.merge': '合并',\n 'groups.noWritable': '该组没有可写技能(只读技能无法由中枢开关)',\n 'groups.closeAll': '全部关闭',\n 'groups.keepOn': '保留开启',\n 'groups.conflictTitle': '关闭此组?',\n 'groups.conflictText': '以下技能也在其他组中开启,关闭它们会影响那些组:',\n 'filter.allSources': '全部来源',\n 'filter.private': '个人',\n 'sort.name': '按名称',\n 'sort.added': '按添加时间',\n 'sort.uses': '按调用次数',\n 'time.justNow': '刚刚',\n 'time.minutesAgo': '{value} 分钟前',\n 'time.hoursAgo': '{value} 小时前',\n 'time.daysAgo': '{value} 天前',\n 'time.weeksAgo': '{value} 周前',\n 'badge.source.project-dsh': '项目 .dsh',\n 'badge.source.project-agents': '项目 .agents',\n 'badge.source.custom': '自定义',\n 'badge.source.runtime': '运行时',\n 'badge.source.user-dsh': '用户 .dsh',\n 'badge.source.user-agents': '用户 .agents',\n 'badge.source.bundled': '内置',\n 'row.readonly': '只读',\n 'row.disable': '禁用',\n 'row.enable': '启用',\n 'row.delete': '移入回收站',\n 'row.open': '查看 {name} 详情(回车)',\n 'delete.confirmTitle': '移入回收站?',\n 'delete.confirmText': '确定把「{name}」移入回收站吗?可随时恢复。',\n 'delete.confirm': '移入回收站',\n 'detail.back': '返回列表',\n 'detail.provider': '提供者',\n 'detail.addedAt': '添加时间',\n 'detail.updatedAt': '更新时间',\n 'detail.path': '路径',\n 'detail.whenToUse': '适用场景',\n 'detail.uses': '调用次数',\n 'detail.groups': '所属场景',\n 'detail.loading': '读取技能正文…',\n 'source.private': '个人技能(未绑定上游,不检查更新)',\n 'source.commit': '已同步版本',\n 'source.unverified': '尚未核对上游',\n 'source.check': '检查更新',\n 'source.checkHint': '点击检查上游更新',\n 'source.checking': '检查中…',\n 'source.upToDate': '已是最新',\n 'source.updated': '有更新 {count} 个',\n 'source.deleted': '上游已删除 {count} 个',\n 'source.error': '检查失败',\n 'source.throttled': '刚刚检查过',\n 'source.sync': '同步',\n 'source.syncing': '同步中…',\n 'source.syncConfirmTitle': '同步技能?',\n 'source.syncConfirmText': '将用上游最新版本覆盖本地对以下技能的所有修改:',\n 'source.followDelete': '跟进删除',\n 'source.deleteConfirmTitle': '跟进上游删除?',\n 'source.deleteConfirmText': '以下技能已从上游仓库移除,本地目录将移入回收站(可恢复):',\n 'source.deleteGroup': '删除整组',\n 'source.deleteGroupHint': '删除该分组下的全部 {count} 个技能',\n 'source.deleteGroupTitle': '删除整组?',\n 'source.deleteGroupText': '将把分组“{name}”下的全部 {count} 个技能移入回收站(可恢复),只读技能会跳过:',\n 'source.trash': '回收站',\n 'source.restore': '恢复',\n 'source.clearTrash': '清空回收站',\n 'source.clearTrashConfirmTitle': '清空回收站?',\n 'source.clearTrashConfirmText': '回收站里的技能会被永久删除,无法恢复。此操作不可撤销。',\n 'source.clearTrashConfirm': '永久删除',\n 'form.capabilityHint': '能力怎么选:重复方法 → 技能;外部系统 → MCP;长期资料 → 知识库。',\n 'form.descPlaceholder': '一句话说明用途(含触发词),Agent 靠它自动激活技能',\n 'form.name': '技能名(kebab-case,如 code-review)',\n 'form.desc': '描述(一句话路由说明)',\n 'form.root': '目标目录',\n 'form.submit': '创建',\n 'form.cancel': '取消',\n 'form.busy': '创建中…',\n 'form.success': '已创建:',\n 'form.error': '创建失败:',\n 'err.dismiss': '知道了',\n 'settings.title': '技能中枢',\n 'settings.description': '管理 dsh 本地技能目录:浏览、分组、来源同步与新建。',\n 'settings.enabled': '启用插件',\n 'settings.enabledHint': '关闭后技能中枢的路由、入口与公告全部下线。',\n 'settings.announceToAgent': '向 Agent 公告',\n 'settings.announceToAgentHint': '在系统提示中加入本插件说明,用户提到技能管理时 Agent 知道如何协作。',\n 'settings.dotModelColor': '模型可调圆点颜色',\n 'settings.dotModelColorHint': '技能行/聊天 / 菜单中「模型可调」蓝色圆点的颜色(#rrggbb)。',\n 'settings.dotUserColor': '用户可调圆点颜色',\n 'settings.dotUserColorHint': '技能行/聊天 / 菜单中「仅用户可调」绿色圆点的颜色(#rrggbb)。',\n 'settings.showUseCount': '显示调用次数',\n 'settings.showUseCountHint': '在技能名旁显示琥珀色调用次数。',\n 'settings.showUseTime': '显示最近调用时间',\n 'settings.showUseTimeHint': '在技能名行右侧显示相对时间(如「3 天前」)。',\n 'settings.showGroupSummary': '显示分组汇总',\n 'settings.showGroupSummaryHint': '在分组标题后汇总调用次数与最近调用时间。',\n 'settings.statsWindowDays': '统计窗口(天)',\n 'settings.statsWindowDaysHint': '只统计最近 N 天的使用次数,默认 14 天;0 = 全部历史。改动立即生效。',\n 'settings.statsScanMinutes': '自动统计间隔(分钟)',\n 'settings.statsScanMinutesHint': '后台扫描会话日志的间隔,最小 1 分钟;扫描耗时会自动拉长间隔。',\n 'settings.inherit': '继承',\n 'settings.on': '开',\n 'settings.off': '关',\n 'settings.overridden': '已覆盖',\n 'settings.reset': '恢复默认',\n 'settings.unsaved': '未保存',\n 'settings.save': '保存',\n 'settings.saving': '保存中…',\n 'settings.discard': '放弃修改',\n 'settings.saveFailed': '本部署没有接受这些值,已保留供你修改。',\n 'settings.readOnly': '本部署的设置为只读。',\n 'settings.notExposed': '本部署没有挂载该设置命名空间。',\n 'settings.collapse': '收起设置',\n 'settings.expand': '展开设置',\n} as const\n\nexport const en: Record<HubKey, string> = {\n 'entry.label': 'Skills',\n 'entry.tooltip': 'Skill hub: browse, group, and sync local skills',\n 'view.sources': 'Sources',\n 'view.scenes': 'Scenes',\n 'view.market': 'Market',\n 'view.flat': 'Flat',\n 'view.grouped': 'Grouped',\n 'panel.title': 'Skill Hub',\n 'panel.count': '{count} skills total',\n 'panel.disabledCount': '{count} disabled',\n 'panel.new': 'New Skill',\n 'panel.search': 'Search skills…',\n 'legend.model': 'Model-invocable — agents may call automatically',\n 'legend.user': 'User-invocable — explicit invocation only',\n 'legend.hint': 'At most one dot per skill; no dot = not invocable.',\n 'panel.enabled': 'Enabled',\n 'panel.disabled': 'Disabled',\n 'panel.diagnostics': 'Discovery diagnostics',\n 'panel.empty': 'No matching skills.',\n 'panel.emptyAll': 'No skills installed yet. Create the first one.',\n 'panel.loading': 'Loading…',\n 'panel.incomplete': '(catalog may be incomplete)',\n 'panel.workspacePlaceholder': 'Workspace path (Enter to apply)',\n 'panel.workspaceHint': 'Enter a project path to also show that workspace\\'s .dsh/skills and .agents/skills skills (read-only); clear + Enter to return to the user-level view.',\n 'panel.workspaceClear': 'Clear workspace',\n 'market.addPlaceholder': 'owner/repo or https://github.com/…',\n 'market.addSource': 'Add source',\n 'market.noSources': 'No market sources yet. Add one from the built-in catalog below, or enter a GitHub repo.',\n 'market.title': 'Market',\n 'market.catalogHint': 'Curated skill repos — add one to scan and install, with ongoing update checks.',\n 'market.catalog.anthropics': 'Official Anthropic skill collection (Claude Skills)',\n 'market.catalog.superpowers': 'Superpowers community skill collection',\n 'market.catalog.mattpocock': 'Matt Pocock skill collection',\n 'market.catalog.openDesign': 'Design skill collection (design-templates)',\n 'market.add': 'Add',\n 'market.installed': '{count} installed',\n 'market.updatable': '{count} updatable',\n 'market.deletedUpstream': '{count} deleted upstream',\n 'market.checkAll': 'Check all',\n 'market.updateAll': 'Update all',\n 'market.updateAllConfirmTitle': 'Update every skill?',\n 'market.updateAllConfirmText': 'The updatable skills of these sources will be overwritten with their latest upstream versions:',\n 'market.updateAllItem': '{repo} ({count} skills)',\n 'market.updateAllDone': 'Updated {count} sources',\n 'market.deleteSource': 'Remove source',\n 'market.scan': 'Scan',\n 'market.scanning': 'Scanning…',\n 'market.check': 'Check',\n 'market.checkUpdate': 'Check for updates',\n 'market.checking': 'Checking…',\n 'market.upToDate': 'Up to date',\n 'market.update': 'Update',\n 'market.updateCount': 'Update {count}',\n 'market.sync': 'Sync',\n 'market.syncing': 'Syncing…',\n 'market.updated': 'Updates available',\n 'market.newRelease': 'New release v{version}',\n 'market.branchTitle': 'Choose a branch',\n 'market.branchHint': 'This repo has no releases. Pick a branch to track (main by default):',\n 'market.branchConfirm': 'Confirm',\n 'market.syncTitle': 'Update local skills',\n 'market.syncText': 'Market source aligned to {ref}. Update these local skills?',\n 'market.syncNone': 'No local skills tracked from this repo yet.',\n 'market.syncCancel': 'Skip',\n 'market.removeHint': 'Removing a source does not affect installed skills.',\n 'repo.ready': '{count} importable skills found',\n 'repo.empty': 'No importable skills found.',\n 'repo.selectAll': 'Select all',\n 'repo.clearAll': 'Clear',\n 'repo.import': 'Import selected ({count})',\n 'repo.importing': 'Importing…',\n 'repo.existing': 'Existing',\n 'repo.files': '{count} files · {size}',\n 'repo.imported': 'Imported {count}',\n 'repo.skippedExisting': 'Skipped existing {count}',\n 'repo.failed': 'Failed {count}',\n 'repo.cancel': 'Cancel',\n 'repo.cancelled': 'Cancelled · {imported}/{total} kept, temp files cleaned',\n 'repo.importingCurrent': 'Importing: {name} ({done}/{total})',\n 'repo.root.skills': 'Skills',\n 'repo.root.designTemplates': 'Templates design-templates',\n 'repo.root.generic': '{root}',\n 'update.check': 'Check for updates',\n 'update.checking': 'Checking…',\n 'update.upToDate': 'Up to date: v{version}',\n 'update.available': 'Update available: v{version} (current v{current})',\n 'update.newVersion': 'New version v{version}',\n 'update.viewRelease': 'View release',\n 'update.error': 'Update check failed: {error}',\n 'update.unavailable': 'No release available',\n 'group.project-dsh': 'Project .dsh/skills',\n 'group.project-agents': 'Project .agents/skills',\n 'group.custom': 'Custom directories',\n 'group.runtime': 'Runtime',\n 'group.user-dsh': 'User ~/.dsh/skills',\n 'group.user-agents': 'User ~/.agents/skills',\n 'group.bundled': 'Bundled',\n 'group.other': 'Other sources',\n 'groups.new': 'New scene',\n 'groups.namePlaceholder': 'Scene name',\n 'groups.edit': 'Edit',\n 'groups.rename': 'Save name',\n 'groups.delete': 'Delete scene',\n 'groups.saveMembers': 'Save members',\n 'groups.membersHint': 'Check skills to add to this scene (disabled skills included).',\n 'groups.empty': 'No scenes yet. Create one and start categorizing skills.',\n 'groups.noCollections': 'No source groups yet. Import skills from the market to group them by source.',\n 'groups.personal': 'Personal',\n 'groups.project': 'Project',\n 'groups.subdivide': 'Split',\n 'groups.merge': 'Merge',\n 'groups.noWritable': 'No writable skills in this group (read-only skills cannot be switched from the hub)',\n 'groups.closeAll': 'Close all',\n 'groups.keepOn': 'Keep on',\n 'groups.conflictTitle': 'Close this group?',\n 'groups.conflictText': 'These skills are also enabled in other groups; closing them affects those groups:',\n 'filter.allSources': 'All sources',\n 'filter.private': 'Personal',\n 'sort.name': 'By name',\n 'sort.added': 'By added',\n 'sort.uses': 'By uses',\n 'time.justNow': 'just now',\n 'time.minutesAgo': '{value} min ago',\n 'time.hoursAgo': '{value} h ago',\n 'time.daysAgo': '{value} d ago',\n 'time.weeksAgo': '{value} w ago',\n 'badge.source.project-dsh': 'project .dsh',\n 'badge.source.project-agents': 'project .agents',\n 'badge.source.custom': 'custom',\n 'badge.source.runtime': 'runtime',\n 'badge.source.user-dsh': 'user .dsh',\n 'badge.source.user-agents': 'user .agents',\n 'badge.source.bundled': 'bundled',\n 'row.readonly': 'read-only',\n 'row.disable': 'Disable',\n 'row.enable': 'Enable',\n 'row.delete': 'Move to trash',\n 'row.open': 'View {name} details (Enter)',\n 'delete.confirmTitle': 'Move to trash?',\n 'delete.confirmText': 'Move \"{name}\" to trash? It can be restored anytime.',\n 'delete.confirm': 'Move to trash',\n 'detail.back': 'Back to list',\n 'detail.provider': 'Provider',\n 'detail.addedAt': 'Added',\n 'detail.updatedAt': 'Updated',\n 'detail.path': 'Path',\n 'detail.whenToUse': 'When to use',\n 'detail.uses': 'Uses',\n 'detail.groups': 'Groups',\n 'detail.loading': 'Loading skill body…',\n 'source.private': 'Personal skill (not bound to an upstream; no update checks)',\n 'source.commit': 'Synced commit',\n 'source.unverified': 'upstream not verified yet',\n 'source.check': 'Check for updates',\n 'source.checkHint': 'Click to check the upstream for updates',\n 'source.checking': 'Checking…',\n 'source.upToDate': 'Up to date',\n 'source.updated': '{count} updates',\n 'source.deleted': '{count} deleted upstream',\n 'source.error': 'Check failed',\n 'source.throttled': 'Checked recently',\n 'source.sync': 'Sync',\n 'source.syncing': 'Syncing…',\n 'source.syncConfirmTitle': 'Sync skills?',\n 'source.syncConfirmText': 'This overwrites local changes to these skills with the latest upstream version:',\n 'source.followDelete': 'Follow deletion',\n 'source.deleteConfirmTitle': 'Follow upstream deletion?',\n 'source.deleteConfirmText': 'These skills were removed upstream; their local directories move to trash (restorable):',\n 'source.deleteGroup': 'Delete group',\n 'source.deleteGroupHint': 'Delete all {count} skills in this group',\n 'source.deleteGroupTitle': 'Delete group?',\n 'source.deleteGroupText': 'All {count} skills in group \"{name}\" will be moved to trash (restorable); read-only skills will be skipped:',\n 'source.trash': 'Trash',\n 'source.restore': 'Restore',\n 'source.clearTrash': 'Empty trash',\n 'source.clearTrashConfirmTitle': 'Empty the trash?',\n 'source.clearTrashConfirmText': 'Skills in the trash will be permanently deleted and cannot be restored.',\n 'source.clearTrashConfirm': 'Delete permanently',\n 'form.capabilityHint': 'Choosing a capability: repeatable method → skill; external system → MCP; long-term knowledge → knowledge base.',\n 'form.descPlaceholder': 'One line on what it does (with trigger words) — agents auto-activate from this',\n 'form.name': 'Skill name (kebab-case, e.g. code-review)',\n 'form.desc': 'Description (one routing sentence)',\n 'form.root': 'Target root',\n 'form.submit': 'Create',\n 'form.cancel': 'Cancel',\n 'form.busy': 'Creating…',\n 'form.success': 'Created: ',\n 'form.error': 'Create failed: ',\n 'err.dismiss': 'Dismiss',\n 'settings.title': 'Skill Hub',\n 'settings.description': 'Manage the local dsh skill catalog: browse, group, sync, and scaffold skills.',\n 'settings.enabled': 'Enable plugin',\n 'settings.enabledHint': 'Disables the hub routes, entries, and announcement.',\n 'settings.announceToAgent': 'Announce to agent',\n 'settings.announceToAgentHint': 'Adds a system-prompt section so agents know how to collaborate when users mention skill management.',\n 'settings.dotModelColor': 'Model-invocable dot color',\n 'settings.dotModelColorHint': 'Color of the blue \"model-callable\" dot in the skill panel and the chat / menu (#rrggbb).',\n 'settings.dotUserColor': 'User-invocable dot color',\n 'settings.dotUserColorHint': 'Color of the green \"user-only\" dot in the skill panel and the chat / menu (#rrggbb).',\n 'settings.showUseCount': 'Show invocation count',\n 'settings.showUseCountHint': 'Show the amber invocation count beside each skill name.',\n 'settings.showUseTime': 'Show last-used time',\n 'settings.showUseTimeHint': 'Show relative last-used time on the name row (e.g. \"3 d ago\").',\n 'settings.showGroupSummary': 'Show group summaries',\n 'settings.showGroupSummaryHint': 'Summarize invocation count and last-used time after group titles.',\n 'settings.statsWindowDays': 'Stats window (days)',\n 'settings.statsWindowDaysHint': 'Count only usage within the last N days (default 14); 0 = full history. Changes apply immediately.',\n 'settings.statsScanMinutes': 'Auto stats interval (minutes)',\n 'settings.statsScanMinutesHint': 'How often the background session-log scan runs (min 1); heavy scans automatically stretch it.',\n 'settings.inherit': 'Inherit',\n 'settings.on': 'On',\n 'settings.off': 'Off',\n 'settings.overridden': 'Overridden',\n 'settings.reset': 'Reset to default',\n 'settings.unsaved': 'Unsaved',\n 'settings.save': 'Save',\n 'settings.saving': 'Saving…',\n 'settings.discard': 'Discard',\n 'settings.saveFailed': 'The deployment did not accept these values; they were left for you to correct.',\n 'settings.readOnly': 'This deployment stores settings read-only.',\n 'settings.notExposed': 'This deployment does not expose the settings namespace.',\n 'settings.collapse': 'Hide settings',\n 'settings.expand': 'Show settings',\n}\n\n/** Union of every translatable key (the namespace's registered dictionary type). */\nexport type HubKey = keyof typeof zh\n\n/** Template values accepted by the interpolator. */\nexport type TranslateValues = Record<string, string | number>\n\n/** Interpolate a {name} template with the given values. */\nexport function t(dict: Record<string, string>, key: HubKey, values?: TranslateValues): string {\n let text = dict[key] ?? key\n if (values !== undefined) {\n for (const [name, value] of Object.entries(values)) {\n text = text.replaceAll('{' + name + '}', String(value))\n }\n }\n return text\n}\n","/**\n * The settings shell renders section nav icons from a hard-coded id map and\n * exposes no registrant icon option, so the skill-hub section falls back to\n * the generic gear. This scoped DOM patch swaps in the official skill icon\n * whenever the settings dialog re-renders.\n */\n\nconst SKILL_SECTION_LABELS = ['技能', 'Skills']\n\nconst SKILL_ICON_SVG = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-skill-hub-nav-icon=\"true\"><path d=\"M12.5113 15.4067C12.4395 15.6249 12.1308 15.6249 12.059 15.4067L11.643 14.1416C11.454 13.567 11.0033 13.1164 10.4288 12.9274L9.16369 12.5113C8.94544 12.4395 8.94544 12.1308 9.16369 12.059L10.4288 11.643C11.0033 11.454 11.454 11.0033 11.643 10.4288L12.059 9.16369C12.1308 8.94544 12.4395 8.94544 12.5113 9.16369L12.9274 10.4288C13.1164 11.0033 13.567 11.454 14.1416 11.643L15.4067 12.059C15.6249 12.1308 15.6249 12.4395 15.4067 12.5113L14.1416 12.9274C13.567 13.1164 13.1164 13.567 12.9274 14.1416L12.5113 15.4067Z\" fill=\"currentColor\"/><path d=\"M9.02246 0.546878C9.9822 0.546878 10.7564 0.545403 11.374 0.612307C12.0042 0.680586 12.5515 0.826244 13.0273 1.17188C13.3052 1.37376 13.5501 1.61868 13.752 1.89649C14.0975 2.37225 14.2432 2.91984 14.3115 3.54981C14.3784 4.16727 14.377 4.94206 14.377 5.90137V8.51367C13.9611 8.29533 13.5071 8.13985 13.0273 8.06055V5.90137C13.0273 4.9121 13.0259 4.22322 12.9688 3.69532C12.9129 3.18044 12.8098 2.89782 12.6592 2.69043C12.5406 2.52724 12.3966 2.38326 12.2334 2.26465C12.026 2.11404 11.7437 2.0109 11.2285 1.95508C10.7005 1.89789 10.0122 1.89649 9.02246 1.89649H6.55371C5.56395 1.89649 4.87569 1.89787 4.34766 1.95508C3.83242 2.01092 3.55022 2.11398 3.34278 2.26465C3.17953 2.38329 3.03564 2.52719 2.91699 2.69043C2.76642 2.89782 2.66325 3.18042 2.60742 3.69532C2.55027 4.22322 2.54883 4.9121 2.54883 5.90137V10.0986C2.54883 11.0878 2.55031 11.7768 2.60742 12.3047C2.66326 12.8196 2.76642 13.1032 2.91699 13.3105C3.03558 13.4736 3.17966 13.6178 3.34278 13.7363C3.5502 13.8869 3.83265 13.9901 4.34766 14.0459C4.87568 14.1031 5.56398 14.1035 6.55371 14.1035H8.08399C8.27443 14.6025 8.55077 15.0585 8.89551 15.4541H6.55371C5.59402 15.4541 4.81976 15.4546 4.20215 15.3877C3.57204 15.3194 3.02468 15.1738 2.54883 14.8281C2.27111 14.6263 2.02606 14.3813 1.82422 14.1035C1.47883 13.6278 1.33293 13.08 1.26465 12.4502C1.19783 11.8327 1.19922 11.0579 1.19922 10.0986V5.90137C1.19922 4.94206 1.1978 4.16727 1.26465 3.54981C1.33295 2.91984 1.47867 2.37225 1.82422 1.89649C2.02613 1.61864 2.27098 1.37379 2.54883 1.17188C3.02472 0.826181 3.57197 0.6806 4.20215 0.612307C4.81976 0.545393 5.594 0.546877 6.55371 0.546878H9.02246ZM9.19629 9.14649H4.5459V7.84571H9.19629V9.14649ZM11.0303 6.10645H4.5459V4.80567H11.0303V6.10645Z\" fill=\"currentColor\"/></svg>`\n\nlet iconTemplate: SVGSVGElement | null = null\n\nfunction skillIcon(): SVGSVGElement {\n if (iconTemplate === null) {\n iconTemplate = new DOMParser().parseFromString(SKILL_ICON_SVG, 'image/svg+xml').documentElement as unknown as SVGSVGElement\n }\n return iconTemplate.cloneNode(true) as SVGSVGElement\n}\n\nfunction patchNavIcon(): void {\n const dialog = document.querySelector('[role=\"dialog\"]')\n if (dialog === null) return\n for (const button of dialog.querySelectorAll<HTMLButtonElement>('button')) {\n const label = button.querySelector('span')\n if (label === null || !SKILL_SECTION_LABELS.includes(label.textContent?.trim() ?? '')) continue\n if (button.querySelector('svg[data-skill-hub-nav-icon]') !== null) continue\n const current = button.querySelector('svg')\n const icon = skillIcon()\n if (current !== null) current.replaceWith(icon)\n else button.insertBefore(icon, button.firstChild)\n }\n}\n\n/** Swap the settings nav gear for the skill icon and keep it in sync. */\nexport function applySettingsNavIcon(): () => void {\n if (typeof document === 'undefined' || typeof MutationObserver === 'undefined') return () => {}\n patchNavIcon()\n const observer = new MutationObserver(() => { patchNavIcon() })\n observer.observe(document.body, { childList: true, subtree: true })\n return () => { observer.disconnect() }\n}\n","/**\n * Pure grouping helpers for the skill-hub panel (no React/DOM deps, so the\n * merge/classify/filter logic stays unit-testable).\n *\n * The \"分组\" view unifies two ways a skill can belong to a group:\n * - user tags (sidecar SkillTag)\n * - origin collections (sidecar sources → backend-aggregated CollectionGroup)\n *\n * Switch semantics: a skill's enabled state is global (the file is renamed\n * once), so a group switch is derived from its members' actual states:\n * all members enabled → 'on', all disabled → 'off', otherwise 'mixed'.\n * Closing a group whose member is enabled in another group is a conflict the\n * GUI resolves with a dialog; the helpers below compute both sides.\n */\n\nimport type { CatalogSkill, CollectionGroup, SkillTag } from '../protocol.ts'\n\n/** Grouped switch state derived from member enablement. */\nexport type GroupSwitchState = 'on' | 'off' | 'mixed'\n\n/** The derived switch view of one group. */\nexport interface GroupSwitchView {\n state: GroupSwitchState\n /** Writable members currently enabled. */\n enabled: string[]\n /** Writable members currently disabled. */\n disabled: string[]\n}\n\n/**\n * Derive a group switch view from its member names and the set of currently\n * enabled skill names (catalog.skills). Members not in the enabled set count\n * as disabled (catalog.disabled or absent read-only rows).\n */\nexport function groupSwitchView(members: readonly string[], enabledNames: ReadonlySet<string>): GroupSwitchView {\n const enabled: string[] = []\n const disabled: string[] = []\n for (const name of members) {\n if (enabledNames.has(name)) enabled.push(name)\n else disabled.push(name)\n }\n const state: GroupSwitchState = disabled.length === 0 ? 'on' : enabled.length === 0 ? 'off' : 'mixed'\n return { state, enabled, disabled }\n}\n\n/** Names of every group a skill belongs to (tags + collections). */\nexport function groupNamesOf(name: string, tags: readonly SkillTag[], collections: readonly CollectionGroup[]): string[] {\n const names: string[] = []\n for (const tag of tags) if (tag.skillNames.includes(name)) names.push(tag.name)\n for (const collection of collections) if (collection.skillNames.includes(name)) names.push(collection.name)\n return names\n}\n\n/**\n * Members of a group that are currently enabled AND also belong to at least\n * one other group — the set a \"close\" action must ask about.\n */\nexport function conflictsOnClose(\n members: readonly string[],\n enabledNames: ReadonlySet<string>,\n otherGroups: ReadonlyArray<{ members: readonly string[] }>,\n): string[] {\n return members.filter((name) => {\n if (!enabledNames.has(name)) return false\n return otherGroups.some((group) => group.members.includes(name))\n })\n}\n\n/** Origin-repo filter value: skills with no source record (private skills). */\nexport const PRIVATE_SOURCE = 'private'\n\n/** 项目级技能来源(它们有 workspace 归属,不属于「个人」组)。 */\nexport function isProjectSource(source: string): boolean {\n return source === 'project-dsh' || source === 'project-agents'\n}\n\n/**\n * Apply the origin filter ('all' or a specific origin repo; skills without a\n * source record count as PRIVATE_SOURCE). The origins map is the store's\n * skillName → repo derivation, so filtering follows the tracked source\n * records instead of the filesystem root a skill happens to live under.\n * 项目级技能(有 workspace 归属)永远不算「个人」。\n */\nexport function filterBySource(skills: readonly CatalogSkill[], source: string, origins: Readonly<Record<string, string>>): CatalogSkill[] {\n if (source === 'all') return [...skills]\n return skills.filter((skill) => {\n if (isProjectSource(skill.source)) return false\n return (origins[skill.name] ?? PRIVATE_SOURCE) === source\n })\n}\n\n/** Catalog sort keys offered by the filter bar. */\nexport type SortKey = 'name' | 'added' | 'uses'\n\n/**\n * Sort a skill list in place-safe copy order: name ascending, added\n * descending (newest first, unknown addedAt last), or uses descending\n * (most-called first). Unknown values always trail.\n */\nexport function sortSkills(skills: readonly CatalogSkill[], key: SortKey, getUses?: (name: string) => number | undefined): CatalogSkill[] {\n const list = [...skills]\n if (key === 'name') {\n list.sort((a, b) => a.name.localeCompare(b.name))\n } else if (key === 'added') {\n list.sort((a, b) => (b.addedAt ?? -Infinity) - (a.addedAt ?? -Infinity))\n } else if (key === 'uses') {\n list.sort((a, b) => (getUses?.(b.name) ?? 0) - (getUses?.(a.name) ?? 0))\n }\n return list\n}\n\n/** Localized relative-time tuple; the caller resolves it via tt(). */\nexport interface RelativeTime {\n key: 'time.justNow' | 'time.minutesAgo' | 'time.hoursAgo' | 'time.daysAgo' | 'time.weeksAgo'\n value?: number\n}\n\n/** Format an epoch-ms timestamp as a short relative time bucket. */\nexport function formatRelativeTime(ms: number, now = Date.now()): RelativeTime {\n const diff = Math.max(0, now - ms)\n const minutes = Math.floor(diff / 60_000)\n if (minutes < 1) return { key: 'time.justNow' }\n if (minutes < 60) return { key: 'time.minutesAgo', value: minutes }\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return { key: 'time.hoursAgo', value: hours }\n const days = Math.floor(hours / 24)\n if (days < 7) return { key: 'time.daysAgo', value: days }\n return { key: 'time.weeksAgo', value: Math.floor(days / 7) }\n}\n","/**\n * Shared panel helpers: the active-dictionary pick (document-language\n * based, family precedent) plus a small error-message extractor.\n */\nimport { en, t, zh, type HubKey, type TranslateValues } from './locales.ts'\n\n/** Active dictionary, picked by the document language at call time. */\nexport function dictionary(): Record<string, string> {\n const lang = typeof document !== 'undefined' ? document.documentElement.lang : 'zh'\n return lang.toLowerCase().startsWith('en') ? { ...en } : { ...zh }\n}\n\n/** Translate a key with optional {name} template params (current language). */\nexport function tt(key: HubKey, values?: TranslateValues): string {\n return t(dictionary(), key, values)\n}\n\n/** Human-readable error text from an unknown thrown value. */\nexport function errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message\n return String(error)\n}\n\n","/**\n * Shared display helpers for the panel views (skill rows, detail view, and\n * dialogs): dot color styling, relative/absolute time text, and commit-SHA\n * shortening. Kept in one place so the views render identically.\n *\n * The invocation-status dot defaults live here (not in the settings card) so\n * both the panel legend and the chat `/` skill menu draw from one source and\n * so this primitives-free module stays unit-testable.\n */\n\nimport type { CSSProperties } from 'react'\nimport { formatRelativeTime } from '../grouping.ts'\nimport { tt } from '../helpers.ts'\n\n/** Model-invocable dot color default. Single source for the TS side; the\n * panel's CSS mirrors it via --hub-model (panel.module.css). */\nexport const DEFAULT_DOT_MODEL_COLOR = '#2f81f7'\n/** User-invocable dot color default. Single source for the TS side; the\n * panel's CSS mirrors it via --hub-user (panel.module.css). */\nexport const DEFAULT_DOT_USER_COLOR = '#3fb950'\n\n/** Dot inline style from the user-chosen color (undefined keeps the CSS default). */\nexport function dotStyle(color: string | undefined): CSSProperties | undefined {\n if (color === undefined) return undefined\n return { background: color, borderColor: color }\n}\n\n/** Localized relative-time text for a Unix-ms timestamp. */\nexport function relativeTimeText(ms: number): string {\n const rt = formatRelativeTime(ms)\n return tt(rt.key, rt.value !== undefined ? { value: rt.value } : undefined)\n}\n\n/** Localized absolute time for the detail meta (e.g. \"2026/8/16 11:00:00\"). */\nexport function formatDateTime(ms: number): string {\n return new Date(ms).toLocaleString()\n}\n\n/** Short form of a commit SHA for display. */\nexport function shortSha(sha: string): string {\n return sha.length > 7 ? sha.slice(0, 7) : sha\n}\n","/**\n * Slash-menu skill dots: puts the invocation-status dot (model-callable blue /\n * user-only green) in front of every skill candidate in the chat `/` menu.\n *\n * Mechanism (mirrors how dsh-at-file fills the menu icon slot): the candidate\n * menu's rows already render an optional `icon` slot (`MenuView` renders\n * `item.icon` in a 16×16 leading span when it's defined), but the core `/skill`\n * source (`dsh-client-ui-skill`) returns candidates without `icon`. This module\n * wraps that source's `candidates` and stamps each row with a colored dot,\n * reusing the same settings (dotModelColor / dotUserColor) and the same\n * `modelInvocable` classification the panel legend uses — so the chat menu and\n * the Settings → 技能 panel stay in sync, and editing the color updates both.\n *\n * The skill source is registered by the core plugin under the `name` \"skill\"\n * on the `/` trigger; re-registering the same name would throw, so this wraps\n * the already-registered source object instead (found through the runtime\n * source registry, which the frozen contract exposes only as `registerSource`\n * / `sessionOf` — the lookup below is defensive: it never throws).\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the Context merge for ctx.inputTriggers.\nimport type {} from '@deepseek-ai/dsh-client-ui-input-trigger/client'\n// Type-only: pulls the connection/reset event.\nimport type {} from '@deepseek-ai/dsh-client-connection/client'\nimport type { InputTriggerCandidate, InputTriggerServiceContract, InputTriggerSource } from '@deepseek-ai/dsh-client-ui-input-trigger/client'\nimport { createElement } from 'react'\nimport type { HubSettingsValue } from '../protocol.ts'\nimport type { SkillHubApi } from './api.ts'\nimport { DEFAULT_DOT_MODEL_COLOR, DEFAULT_DOT_USER_COLOR } from './panel/format.ts'\n\n/** The core plugin's skill source identity on the '/' trigger. */\nconst SKILL_SOURCE = { trigger: '/', name: 'skill' } as const\n\n/** How long one catalog-derived modelInvocable map stays hot before refresh. */\nconst MODEL_TTL_MS = 60_000\n\n/** Runtime view of the source registry (the contract keeps `live` private). */\ntype SourceRegistry = {\n live?: { sources?: InputTriggerSource[] }\n}\n\n/**\n * Find the core `/skill` source through the runtime registry, or undefined.\n * The lookup never throws: a missing/reshaped registry just means no dots. Exported\n * for unit tests; the apply path only calls it indirectly through setupSkillSlashDots.\n * @param service - the ctx.inputTriggers service face.\n * @returns the registered skill source, or undefined.\n */\nexport function findSkillSource(service: InputTriggerServiceContract): InputTriggerSource | undefined {\n const live = (service as unknown as SourceRegistry).live\n if (live?.sources === undefined) return undefined\n return live.sources.find((source) => source.trigger === SKILL_SOURCE.trigger && source.name === SKILL_SOURCE.name)\n}\n\n/** One catalog-derived name → modelInvocable snapshot with a load timestamp. */\nlet modelCache: { at: number; map: Map<string, boolean> } | { at: number; failed: true } | undefined\n\n/**\n * Clear the modelInvocable cache. Called on connection/reset so a fresh\n * catalog wins after reconnect; exported for deterministic unit tests.\n */\nexport function resetModelCache(): void {\n modelCache = undefined\n}\n\n/**\n * Resolve name → modelInvocable from the hub's catalog, cached for\n * MODEL_TTL_MS. A failed load caches the failure briefly so a downed route\n * doesn't hammer the host on every keystroke; the returned map is empty then\n * (callers fall back to the model dot for unknown names).\n * @param api - the hub browser API.\n * @returns name → whether the model may call the skill.\n */\nasync function modelInvocableMap(api: SkillHubApi): Promise<Map<string, boolean>> {\n const now = Date.now()\n const cached = modelCache\n if (cached !== undefined && now - cached.at < MODEL_TTL_MS) {\n return 'failed' in cached ? new Map() : cached.map\n }\n try {\n const catalog = await api.catalog()\n const map = new Map<string, boolean>(catalog.skills.map((skill) => [skill.name, skill.invocation.modelInvocable]))\n modelCache = { at: now, map }\n return map\n } catch (error) {\n console.error('[dsh-skill-hub] slash dot color lookup failed:', error)\n modelCache = { at: now, failed: true }\n return new Map()\n }\n}\n\n/**\n * One menu-row dot element. Inline span so it needs no CSS module; the\n * candidate menu centers it inside its 16×16 leading icon slot.\n * @param color - the dot's background color.\n * @returns a React node (memory-only, never crosses the Host boundary).\n */\nfunction dotIcon(color: string): InputTriggerCandidate['icon'] {\n return createElement('span', {\n 'aria-hidden': true,\n style: {\n display: 'inline-block',\n width: 6,\n height: 6,\n borderRadius: 3,\n background: color,\n flex: 'none',\n },\n }) as unknown as InputTriggerCandidate['icon']\n}\n\n/**\n * Wrap the core skill source so every menu row carries the invocation dot.\n * Exported for unit tests; production wiring goes through setupSkillSlashDots.\n * @param source - the registered `/skill` source.\n * @param api - hub browser API for the modelInvocable lookup.\n * @param scope - hub settings scope for the dot colors.\n * @returns a disposer restoring the original candidates.\n */\n/**\n * DOM 兜底:在 alpha.2 新版 MenuView(icon 仅枚举)下通过直接操作\n * 已渲染的 `[role=\"option\"]` 列表注入彩色点,绕过 `icon` 限制。\n * 旧版仍走 `icon` 注入,此处仅为新版。\n */\nfunction injectDotsViaDOM(modelByName: Map<string, boolean>, modelColor: string, userColor: string): void {\n if (typeof document === 'undefined' || typeof requestAnimationFrame === 'undefined') return\n const run = (): void => {\n const options = document.querySelectorAll('[role=\"option\"]')\n for (const opt of options) {\n // 已注入则跳过(由 data 属性标记)\n if (opt.querySelector('[data-skill-dot]') !== null) continue\n // 技能名在 .itemName 中,取文本匹配 catalog\n const nameEl = opt.querySelector('[class*=\"itemName\"]') as HTMLElement | null\n if (nameEl === null) continue\n const name = (nameEl.textContent ?? '').trim()\n if (name.length === 0) continue\n if (!modelByName.has(name) && nameEl.textContent !== name) continue // 保守:仅处理已知名\n const color = (modelByName.get(name) ?? true) ? modelColor : userColor\n const dot = document.createElement('span')\n dot.setAttribute('data-skill-dot', '')\n dot.setAttribute('aria-hidden', 'true')\n dot.style.display = 'inline-block'\n dot.style.width = '6px'\n dot.style.height = '6px'\n dot.style.borderRadius = '3px'\n dot.style.background = color\n dot.style.flex = 'none'\n // 插在名称前;若存在 icon 槽则插在其后,兼容旧版结构\n const iconEl = opt.querySelector('[class*=\"itemIcon\"]')\n if (iconEl !== null && iconEl.nextSibling !== null) {\n iconEl.parentElement?.insertBefore(dot, iconEl.nextSibling)\n } else {\n nameEl.parentElement?.insertBefore(dot, nameEl)\n }\n }\n }\n // 菜单由 React 异步渲染,需等下一帧\n requestAnimationFrame(() => setTimeout(run, 0))\n}\n\nexport function wrapSkillSource(source: InputTriggerSource, api: SkillHubApi, scope: SettingsScope<HubSettingsValue>): () => void {\n const original = source.candidates\n source.candidates = async (session, req) => {\n const items = await original(session, req)\n if (req.signal.aborted) return items\n // Dual-compat: 0.1.2-alpha.2 的 MenuView 将 icon 收窄为 'file'|'folder'|'session'\n // 并通过 ReferenceIcon 渲染,旧版的自定义 ReactElement 点已无法展示。\n // 以 `drilled` 是否存在探测新版(alpha.2 必有,rc 无)。\n const isNewHost = req !== null && typeof req === 'object' && 'drilled' in (req as unknown as Record<string, unknown>)\n const modelByName = await modelInvocableMap(api)\n if (req.signal.aborted) return items\n const snapshot = scope.getSnapshot()\n const modelColor = snapshot.value?.dotModelColor ?? DEFAULT_DOT_MODEL_COLOR\n const userColor = snapshot.value?.dotUserColor ?? DEFAULT_DOT_USER_COLOR\n if (isNewHost) {\n // 新版:不通过 icon(枚举限制),改为 DOM 注入\n injectDotsViaDOM(modelByName, modelColor, userColor)\n return items\n }\n // 旧版:保持原有 icon 注入\n return items.map((item) => ({\n ...item,\n icon: dotIcon((modelByName.get(item.name) ?? true) ? modelColor : userColor),\n }))\n }\n return () => {\n source.candidates = original\n }\n}\n\n/**\n * Mount the slash-menu dots on the registered `/skill` source. Idempotent and\n * defensive: if the core source isn't registered yet (or the registry shape\n * changes), it retries briefly and then gives up silently — the chat keeps\n * working, it simply shows no dots. The returned disposer restores the\n * original candidates and clears the model cache.\n * @param ctx - the client root context (inputTriggers + events).\n * @param api - hub browser API.\n * @param scope - hub settings scope for dot colors.\n * @returns a cleanup function for `ctx.effect`.\n */\nexport function setupSkillSlashDots(\n ctx: ClientContext,\n api: SkillHubApi,\n scope: SettingsScope<HubSettingsValue>,\n): () => void {\n const inputTriggers = ctx.get('inputTriggers')\n if (inputTriggers === undefined) return () => {}\n\n let disposed = false\n let restore: (() => void) | undefined\n let attempts = 0\n\n // The core ui-skill source registers early in the bundle, but not strictly\n // before this apply runs — poll briefly so order never matters.\n const attempt = (): void => {\n if (disposed) return\n const source = findSkillSource(inputTriggers)\n if (source === undefined) {\n if (attempts < 10) {\n attempts += 1\n setTimeout(attempt, 100)\n }\n return\n }\n restore = wrapSkillSource(source, api, scope)\n }\n attempt()\n\n const clearCache = (): void => {\n resetModelCache()\n }\n // ctx.on returns the listener disposer; cordis has no ctx.off.\n const offReset = ctx.on('connection/reset', clearCache)\n\n return () => {\n disposed = true\n offReset()\n restore?.()\n restore = undefined\n }\n}\n","/**\n * Vendored UI icons for dsh-skill-hub.\n *\n * These were originally imported from `@deepseek-ai/dsh-client-ui-primitives`.\n * That package is still published for the rc.7/rc.2 SDK families, but newer dsh\n * web builds no longer expose it as a standalone plugin module — they keep a\n * static compatibility module instead. Vendoring the few tiny outline icons the\n * hub uses makes the browser half self-contained and equally compatible with\n * older and newer dsh hosts.\n *\n * SVG paths are copied verbatim from dsh-client-ui-primitives (MIT licensed)\n * so the visuals remain pixel-identical to the dsh icon family.\n */\n\nimport type { JSX } from 'react'\n\n/** Props understood by the dsh icon family: size + optional className. */\nexport interface IconProps {\n size?: number\n className?: string\n}\n\n/** ic_ds_chevron_down_outline_14 */\nexport function IconChevronDownOutline14({ size = 14, className }: IconProps): JSX.Element {\n return (\n <svg width={size} height={size} className={className} viewBox='0 0 14 14' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z'\n fill='currentColor'\n />\n </svg>\n )\n}\n\n/** ic_ds_trash_outline_16 */\nexport function IconTrashOutline16({ size = 16, className }: IconProps): JSX.Element {\n return (\n <svg width={size} height={size} className={className} viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M14.4782 4.84067L14.2138 10.1152C14.1102 12.1872 14.067 13.0115 13.3866 13.9607C13.1044 14.3546 12.7498 14.6912 12.3424 14.9535C11.8239 15.2872 11.2415 15.4316 10.5585 15.4998C9.88727 15.5668 9.04946 15.5656 7.99998 15.5656C6.95051 15.5656 6.1127 15.5668 5.44142 15.4998C4.75851 15.4316 4.17602 15.2872 3.65753 14.9535C3.25012 14.6912 2.89559 14.3546 2.61332 13.9607C1.93296 13.0115 1.88979 12.1872 1.78619 10.1152L1.52179 4.84067L2.89006 4.77277L3.15343 10.0463C3.26221 12.2218 3.32452 12.6015 3.72646 13.1624C3.90825 13.4161 4.13686 13.6334 4.39927 13.8023C4.66204 13.9714 5.00263 14.0792 5.57825 14.1367C6.16562 14.1953 6.92298 14.1963 7.99998 14.1963C9.07699 14.1963 9.83434 14.1953 10.4217 14.1367C10.9973 14.0792 11.3379 13.9714 11.6007 13.8023C11.8631 13.6334 12.0917 13.4161 12.2735 13.1624C12.6755 12.6015 12.7378 12.2218 12.8465 10.0463L13.1099 4.77277L14.4782 4.84067ZM5.43011 6.22849H6.7994V11.3909H5.43011V6.22849ZM9.20056 6.22849H10.5699V11.3909H9.20056V6.22849ZM8.53597 0.434431C9.17976 0.434431 9.6522 0.426926 10.0966 0.571258C10.2357 0.616451 10.3717 0.672554 10.502 0.738948C10.9182 0.951107 11.2464 1.29099 11.7015 1.74612L12.4978 2.54136H15.3742V3.91169H0.625732V2.54136H3.50218L4.29845 1.74612C4.75358 1.29099 5.08174 0.951107 5.49801 0.738948C5.62831 0.672554 5.76425 0.616451 5.90334 0.571258C6.34776 0.426926 6.82021 0.434431 7.46399 0.434431H8.53597ZM7.46399 1.80476C6.73208 1.80476 6.51641 1.81187 6.32617 1.87369C6.25545 1.89667 6.18668 1.92533 6.12041 1.95907C5.96398 2.03878 5.82348 2.16253 5.44142 2.54136H10.5585C10.1765 2.16253 10.036 2.03878 9.87955 1.95907C9.81329 1.92533 9.74452 1.89667 9.6738 1.87369C9.48356 1.81187 9.26789 1.80476 8.53597 1.80476H7.46399Z'\n fill='currentColor'\n />\n </svg>\n )\n}\n\n/** ic_ds_skill_outline_16 */\nexport function IconSkillOutline16({ size = 16, className }: IconProps): JSX.Element {\n return (\n <svg width={size} height={size} className={className} viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M12.5113 15.4067C12.4395 15.6249 12.1308 15.6249 12.059 15.4067L11.643 14.1416C11.454 13.567 11.0033 13.1164 10.4288 12.9274L9.16369 12.5113C8.94544 12.4395 8.94544 12.1308 9.16369 12.059L10.4288 11.643C11.0033 11.454 11.454 11.0033 11.643 10.4288L12.059 9.16369C12.1308 8.94544 12.4395 8.94544 12.5113 9.16369L12.9274 10.4288C13.1164 11.0033 13.567 11.454 14.1416 11.643L15.4067 12.059C15.6249 12.1308 15.6249 12.4395 15.4067 12.5113L14.1416 12.9274C13.567 13.1164 13.1164 13.567 12.9274 14.1416L12.5113 15.4067Z'\n fill='currentColor'\n />\n <path\n d='M9.02246 0.546878C9.9822 0.546878 10.7564 0.545403 11.374 0.612307C12.0042 0.680586 12.5515 0.826244 13.0273 1.17188C13.3052 1.37376 13.5501 1.61868 13.752 1.89649C14.0975 2.37225 14.2432 2.91984 14.3115 3.54981C14.3784 4.16727 14.377 4.94206 14.377 5.90137V8.51367C13.9611 8.29533 13.5071 8.13985 13.0273 8.06055V5.90137C13.0273 4.9121 13.0259 4.22322 12.9688 3.69532C12.9129 3.18044 12.8098 2.89782 12.6592 2.69043C12.5406 2.52724 12.3966 2.38326 12.2334 2.26465C12.026 2.11404 11.7437 2.0109 11.2285 1.95508C10.7005 1.89789 10.0122 1.89649 9.02246 1.89649H6.55371C5.56395 1.89649 4.87569 1.89787 4.34766 1.95508C3.83242 2.01092 3.55022 2.11398 3.34278 2.26465C3.17953 2.38329 3.03564 2.52719 2.91699 2.69043C2.76642 2.89782 2.66325 3.18042 2.60742 3.69532C2.55027 4.22322 2.54883 4.9121 2.54883 5.90137V10.0986C2.54883 11.0878 2.55031 11.7768 2.60742 12.3047C2.66326 12.8196 2.76642 13.1032 2.91699 13.3105C3.03558 13.4736 3.17966 13.6178 3.34278 13.7363C3.5502 13.8869 3.83265 13.9901 4.34766 14.0459C4.87568 14.1031 5.56398 14.1035 6.55371 14.1035H8.08399C8.27443 14.6025 8.55077 15.0585 8.89551 15.4541H6.55371C5.59402 15.4541 4.81976 15.4546 4.20215 15.3877C3.57204 15.3194 3.02468 15.1738 2.54883 14.8281C2.27111 14.6263 2.02606 14.3813 1.82422 14.1035C1.47883 13.6278 1.33293 13.08 1.26465 12.4502C1.19783 11.8327 1.19922 11.0579 1.19922 10.0986V5.90137C1.19922 4.94206 1.1978 4.16727 1.26465 3.54981C1.33295 2.91984 1.47867 2.37225 1.82422 1.89649C2.02613 1.61864 2.27098 1.37379 2.54883 1.17188C3.02472 0.826181 3.57197 0.6806 4.20215 0.612307C4.81976 0.545393 5.594 0.546877 6.55371 0.546878H9.02246ZM9.19629 9.14649H4.5459V7.84571H9.19629V9.14649ZM11.0303 6.10645H4.5459V4.80567H11.0303V6.10645Z'\n fill='currentColor'\n />\n </svg>\n )\n}","/**\n * Shared chrome for the plugin settings card, aligned with the official\n * dsh-client-ui-settings-plugins PluginCard design language: the same tokens,\n * disclosure header, field rhythm, and copy. Renders nothing while the\n * namespace is unavailable — a deployment that does not compose the owning\n * plugin should show no trace of it.\n */\n\nimport { useState, type ReactElement } from 'react'\nimport { IconChevronDownOutline14 } from './icons.tsx'\nimport type { HubKey } from './locales.ts'\nimport type { CardShell } from './settings-form.ts'\nimport css from './settings-card.module.css'\n\n/** Card-level chrome props. */\nexport interface PluginSettingsCardProps {\n /** Locale translator for the owning plugin's namespace (its own key domain). */\n t: (key: HubKey) => string\n /** Locale key of the card title. */\n titleKey: HubKey\n /** Locale key of the card description. */\n descriptionKey: HubKey\n /** 插件自身版本(可选):显示在标题旁的小徽标;缺省不渲染。 */\n version?: string\n /** The form shell state. */\n state: CardShell\n onSave: () => void\n onDiscard: () => void\n children?: ReactElement | ReactElement[]\n}\n\n/**\n * Render one plugin settings card.\n * @param props - the plugin's copy keys, its form state, and its controls.\n * @returns the card, or nothing while the namespace is still loading.\n */\nexport function PluginSettingsCard(props: PluginSettingsCardProps): ReactElement | null {\n const [open, setOpen] = useState(false)\n const { state } = props\n if (!state.available) return null\n const title = props.t(props.titleKey)\n const blocked = !state.dirty || state.invalid || state.saving\n\n const header = (\n <button\n type='button'\n className={css.header}\n aria-expanded={open}\n aria-label={props.t(open ? 'settings.collapse' : 'settings.expand') + ': ' + title}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{title}{props.version !== undefined ? <span className={css.versionTag}>v{props.version}</span> : null}</span>\n <span className={css.description}>{props.t(props.descriptionKey)}</span>\n </span>\n {state.dirty ? <span className={css.pending}>{props.t('settings.unsaved')}</span> : null}\n <IconChevronDownOutline14 className={open ? css.chevronOpen : css.chevron} />\n </button>\n )\n\n if (!state.exposed) {\n return (\n <li className={css.card + (open ? ' ' + css.cardOpen : '')}>\n {header}\n {open ? <div className={css.body}><p className={css.notExposed} role='status'>{props.t('settings.notExposed')}</p></div> : null}\n </li>\n )\n }\n\n return (\n <li className={css.card + (open ? ' ' + css.cardOpen : '')}>\n {header}\n {open ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role='status'>{props.t('settings.readOnly')}</p> : null}\n {props.children}\n <div className={css.footer}>\n {state.failed ? <p className={css.failed} role='status'>{props.t('settings.saveFailed')}</p> : null}\n <button type='button' className={css.discard} disabled={!state.dirty || state.saving} onClick={props.onDiscard}>\n {props.t('settings.discard')}\n </button>\n <button type='button' className={css.save} disabled={blocked} onClick={props.onSave}>\n {props.t(!state.saving ? 'settings.save' : 'settings.saving')}\n </button>\n </div>\n </div>\n ) : null}\n </li>\n )\n}\n\n/** One staged boolean field: 继承 / 开 / 关. */\nexport interface BooleanFieldProps {\n id: string\n label: string\n hint: string\n inheritLabel: string\n onLabel: string\n offLabel: string\n overriddenLabel: string\n resetLabel: string\n disabled: boolean\n text: string\n overridden: boolean\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function BooleanField(props: BooleanFieldProps): ReactElement {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <select id={props.id} className={css.input} value={props.text} disabled={props.disabled} onChange={(event) => { props.onEdit(event.target.value) }}>\n <option value=''>{props.inheritLabel}</option>\n <option value='true'>{props.onLabel}</option>\n <option value='false'>{props.offLabel}</option>\n </select>\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n\n\n/**\n * A compact sliding switch for the card's master enable/disable control.\n * An empty text value means the field inherits its default; the switch still\n * reflects the effective default and becomes an explicit override on click.\n */\nexport interface SwitchFieldProps {\n label: string\n hint: string\n disabled: boolean\n text: string\n overridden: boolean\n overriddenLabel: string\n resetLabel: string\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function SwitchField(props: SwitchFieldProps): ReactElement {\n const checked = props.text !== 'false'\n return (\n <div className={css.field}>\n <div className={css.switchRow}>\n <div className={css.switchText}>\n <div className={css.head}>\n <span className={css.label}>{props.label}</span>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <p className={css.hint}>{props.hint}</p>\n </div>\n <button\n type='button'\n className={checked ? css.switchOn : css.switch}\n role='switch'\n aria-checked={checked}\n aria-label={props.label}\n disabled={props.disabled}\n onClick={() => { props.onEdit(String(!checked)) }}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n </div>\n )\n}\n\n/** One staged color field: a native color picker plus the hex draft text. */\nexport interface ColorFieldProps {\n id: string\n label: string\n hint: string\n inheritLabel: string\n overriddenLabel: string\n resetLabel: string\n disabled: boolean\n /** Effective hex (#rrggbb) when overridden; empty string means inherit. */\n text: string\n /** The default color the picker shows while inheriting (per-field). */\n defaultColor: string\n overridden: boolean\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function ColorField(props: ColorFieldProps): ReactElement {\n const value = /^#[0-9a-f]{6}$/i.test(props.text) ? props.text : props.defaultColor\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <div className={css.colorRow}>\n <input\n id={props.id}\n type='color'\n className={css.colorInput}\n value={value}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <input\n type='text'\n className={css.input + ' ' + css.colorText}\n value={props.text}\n disabled={props.disabled}\n placeholder={props.inheritLabel}\n onChange={(event) => { props.onEdit(event.target.value.trim()) }}\n />\n </div>\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n\n/** One staged numeric field: a numeric draft text input with inherit/reset semantics. */\nexport interface NumberFieldProps {\n id: string\n label: string\n hint: string\n /** Placeholder shown while the field inherits its default. */\n inheritLabel: string\n overriddenLabel: string\n resetLabel: string\n disabled: boolean\n /** Effective number when overridden; empty string means inherit. */\n text: string\n overridden: boolean\n invalid?: boolean\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function NumberField(props: NumberFieldProps): ReactElement {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <input\n id={props.id}\n type='text'\n inputMode='numeric'\n className={css.input}\n value={props.text}\n disabled={props.disabled}\n placeholder={props.inheritLabel}\n aria-invalid={props.invalid === true}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const destroy = () => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") {\n console.warn(\n \"[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected.\"\n );\n }\n listeners.clear();\n };\n const api = { setState, getState, subscribe, destroy };\n state = createState(setState, getState, api);\n return api;\n};\nconst createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;\nvar vanilla = (createState) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") {\n console.warn(\n \"[DEPRECATED] Default export is deprecated. Instead use import { createStore } from 'zustand/vanilla'.\"\n );\n }\n return createStore(createState);\n};\n\nexport { createStore, vanilla as default };\n","const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...a) => api.dispatch(...a), ...initial };\n};\nconst redux = reduxImpl;\n\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api)\n return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && enabled) {\n console.warn(\n \"[zustand devtools middleware] Please install/enable Redux devtools extension\"\n );\n }\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = (state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording)\n return r;\n const action = nameOrAction === void 0 ? { type: anonymousActionType || \"anonymous\" } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (api.dispatchFromDevtools && typeof api.dispatch === \"function\") {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...a) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && a[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...a);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format. \n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (!api.dispatchFromDevtools)\n return;\n if (typeof api.dispatch !== \"function\")\n return;\n api.dispatch(action);\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState)\n return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, f) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0)\n f(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = (selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n };\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nconst combine = (initialState, create) => (...a) => Object.assign({}, initialState, create(...a));\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(\n name,\n JSON.stringify(newValue, options == null ? void 0 : options.replacer)\n ),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst oldImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n getStorage: () => localStorage,\n serialize: JSON.stringify,\n deserialize: JSON.parse,\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage;\n try {\n storage = options.getStorage();\n } catch (e) {\n }\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const thenableSerialize = toThenable(options.serialize);\n const setItem = () => {\n const state = options.partialize({ ...get() });\n let errorInSync;\n const thenable = thenableSerialize({ state, version: options.version }).then(\n (serializedValue) => storage.setItem(options.name, serializedValue)\n ).catch((e) => {\n errorInSync = e;\n });\n if (errorInSync) {\n throw errorInSync;\n }\n return thenable;\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n void setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n void setItem();\n },\n get,\n api\n );\n let stateFromStorage;\n const hydrate = () => {\n var _a;\n if (!storage)\n return;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => cb(get()));\n const postRehydrationCallback = ((_a = options.onRehydrateStorage) == null ? void 0 : _a.call(options, get())) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((storageValue) => {\n if (storageValue) {\n return options.deserialize(storageValue);\n }\n }).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n return options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return deserializedStorageValue.state;\n }\n }\n }).then((migratedState) => {\n var _a2;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n return setItem();\n }).then(() => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.getStorage) {\n storage = newOptions.getStorage();\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n hydrate();\n return stateFromStorage || configResult;\n};\nconst newImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n void setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n void setItem();\n },\n get,\n api\n );\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage)\n return;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n return options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return deserializedStorageValue.state;\n }\n }\n }).then((migratedState) => {\n var _a2;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n return setItem();\n }).then(() => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persistImpl = (config, baseOptions) => {\n if (\"getStorage\" in baseOptions || \"serialize\" in baseOptions || \"deserialize\" in baseOptions) {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") {\n console.warn(\n \"[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead.\"\n );\n }\n return oldImpl(config, baseOptions);\n }\n return newImpl(config, baseOptions);\n};\nconst persist = persistImpl;\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector };\n","// src/utils/env.ts\nvar NOTHING = Symbol.for(\"immer-nothing\");\nvar DRAFTABLE = Symbol.for(\"immer-draftable\");\nvar DRAFT_STATE = Symbol.for(\"immer-state\");\n\n// src/utils/errors.ts\nvar errors = process.env.NODE_ENV !== \"production\" ? [\n // All error codes, starting by 0:\n function(plugin) {\n return `The plugin for '${plugin}' has not been loaded into Immer. To enable the plugin, import and call \\`enable${plugin}()\\` when initializing your application.`;\n },\n function(thing) {\n return `produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '${thing}'`;\n },\n \"This object has been frozen and should not be mutated\",\n function(data) {\n return \"Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? \" + data;\n },\n \"An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.\",\n \"Immer forbids circular references\",\n \"The first or second argument to `produce` must be a function\",\n \"The third argument to `produce` must be a function or undefined\",\n \"First argument to `createDraft` must be a plain object, an array, or an immerable object\",\n \"First argument to `finishDraft` must be a draft returned by `createDraft`\",\n function(thing) {\n return `'current' expects a draft, got: ${thing}`;\n },\n \"Object.defineProperty() cannot be used on an Immer draft\",\n \"Object.setPrototypeOf() cannot be used on an Immer draft\",\n \"Immer only supports deleting array indices\",\n \"Immer only supports setting array indices and the 'length' property\",\n function(thing) {\n return `'original' expects a draft, got: ${thing}`;\n }\n // Note: if more errors are added, the errorOffset in Patches.ts should be increased\n // See Patches.ts for additional errors\n] : [];\nfunction die(error, ...args) {\n if (process.env.NODE_ENV !== \"production\") {\n const e = errors[error];\n const msg = typeof e === \"function\" ? e.apply(null, args) : e;\n throw new Error(`[Immer] ${msg}`);\n }\n throw new Error(\n `[Immer] minified error nr: ${error}. Full error at: https://bit.ly/3cXEKWf`\n );\n}\n\n// src/utils/common.ts\nvar getPrototypeOf = Object.getPrototypeOf;\nfunction isDraft(value) {\n return !!value && !!value[DRAFT_STATE];\n}\nfunction isDraftable(value) {\n if (!value)\n return false;\n return isPlainObject(value) || Array.isArray(value) || !!value[DRAFTABLE] || !!value.constructor?.[DRAFTABLE] || isMap(value) || isSet(value);\n}\nvar objectCtorString = Object.prototype.constructor.toString();\nvar cachedCtorStrings = /* @__PURE__ */ new WeakMap();\nfunction isPlainObject(value) {\n if (!value || typeof value !== \"object\")\n return false;\n const proto = Object.getPrototypeOf(value);\n if (proto === null || proto === Object.prototype)\n return true;\n const Ctor = Object.hasOwnProperty.call(proto, \"constructor\") && proto.constructor;\n if (Ctor === Object)\n return true;\n if (typeof Ctor !== \"function\")\n return false;\n let ctorString = cachedCtorStrings.get(Ctor);\n if (ctorString === void 0) {\n ctorString = Function.toString.call(Ctor);\n cachedCtorStrings.set(Ctor, ctorString);\n }\n return ctorString === objectCtorString;\n}\nfunction original(value) {\n if (!isDraft(value))\n die(15, value);\n return value[DRAFT_STATE].base_;\n}\nfunction each(obj, iter, strict = true) {\n if (getArchtype(obj) === 0 /* Object */) {\n const keys = strict ? Reflect.ownKeys(obj) : Object.keys(obj);\n keys.forEach((key) => {\n iter(key, obj[key], obj);\n });\n } else {\n obj.forEach((entry, index) => iter(index, entry, obj));\n }\n}\nfunction getArchtype(thing) {\n const state = thing[DRAFT_STATE];\n return state ? state.type_ : Array.isArray(thing) ? 1 /* Array */ : isMap(thing) ? 2 /* Map */ : isSet(thing) ? 3 /* Set */ : 0 /* Object */;\n}\nfunction has(thing, prop) {\n return getArchtype(thing) === 2 /* Map */ ? thing.has(prop) : Object.prototype.hasOwnProperty.call(thing, prop);\n}\nfunction get(thing, prop) {\n return getArchtype(thing) === 2 /* Map */ ? thing.get(prop) : thing[prop];\n}\nfunction set(thing, propOrOldValue, value) {\n const t = getArchtype(thing);\n if (t === 2 /* Map */)\n thing.set(propOrOldValue, value);\n else if (t === 3 /* Set */) {\n thing.add(value);\n } else\n thing[propOrOldValue] = value;\n}\nfunction is(x, y) {\n if (x === y) {\n return x !== 0 || 1 / x === 1 / y;\n } else {\n return x !== x && y !== y;\n }\n}\nfunction isMap(target) {\n return target instanceof Map;\n}\nfunction isSet(target) {\n return target instanceof Set;\n}\nfunction latest(state) {\n return state.copy_ || state.base_;\n}\nfunction shallowCopy(base, strict) {\n if (isMap(base)) {\n return new Map(base);\n }\n if (isSet(base)) {\n return new Set(base);\n }\n if (Array.isArray(base))\n return Array.prototype.slice.call(base);\n const isPlain = isPlainObject(base);\n if (strict === true || strict === \"class_only\" && !isPlain) {\n const descriptors = Object.getOwnPropertyDescriptors(base);\n delete descriptors[DRAFT_STATE];\n let keys = Reflect.ownKeys(descriptors);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const desc = descriptors[key];\n if (desc.writable === false) {\n desc.writable = true;\n desc.configurable = true;\n }\n if (desc.get || desc.set)\n descriptors[key] = {\n configurable: true,\n writable: true,\n // could live with !!desc.set as well here...\n enumerable: desc.enumerable,\n value: base[key]\n };\n }\n return Object.create(getPrototypeOf(base), descriptors);\n } else {\n const proto = getPrototypeOf(base);\n if (proto !== null && isPlain) {\n return { ...base };\n }\n const obj = Object.create(proto);\n return Object.assign(obj, base);\n }\n}\nfunction freeze(obj, deep = false) {\n if (isFrozen(obj) || isDraft(obj) || !isDraftable(obj))\n return obj;\n if (getArchtype(obj) > 1) {\n Object.defineProperties(obj, {\n set: dontMutateMethodOverride,\n add: dontMutateMethodOverride,\n clear: dontMutateMethodOverride,\n delete: dontMutateMethodOverride\n });\n }\n Object.freeze(obj);\n if (deep)\n Object.values(obj).forEach((value) => freeze(value, true));\n return obj;\n}\nfunction dontMutateFrozenCollections() {\n die(2);\n}\nvar dontMutateMethodOverride = {\n value: dontMutateFrozenCollections\n};\nfunction isFrozen(obj) {\n if (obj === null || typeof obj !== \"object\")\n return true;\n return Object.isFrozen(obj);\n}\n\n// src/utils/plugins.ts\nvar plugins = {};\nfunction getPlugin(pluginKey) {\n const plugin = plugins[pluginKey];\n if (!plugin) {\n die(0, pluginKey);\n }\n return plugin;\n}\nfunction loadPlugin(pluginKey, implementation) {\n if (!plugins[pluginKey])\n plugins[pluginKey] = implementation;\n}\n\n// src/core/scope.ts\nvar currentScope;\nfunction getCurrentScope() {\n return currentScope;\n}\nfunction createScope(parent_, immer_) {\n return {\n drafts_: [],\n parent_,\n immer_,\n // Whenever the modified draft contains a draft from another scope, we\n // need to prevent auto-freezing so the unowned draft can be finalized.\n canAutoFreeze_: true,\n unfinalizedDrafts_: 0\n };\n}\nfunction usePatchesInScope(scope, patchListener) {\n if (patchListener) {\n getPlugin(\"Patches\");\n scope.patches_ = [];\n scope.inversePatches_ = [];\n scope.patchListener_ = patchListener;\n }\n}\nfunction revokeScope(scope) {\n leaveScope(scope);\n scope.drafts_.forEach(revokeDraft);\n scope.drafts_ = null;\n}\nfunction leaveScope(scope) {\n if (scope === currentScope) {\n currentScope = scope.parent_;\n }\n}\nfunction enterScope(immer2) {\n return currentScope = createScope(currentScope, immer2);\n}\nfunction revokeDraft(draft) {\n const state = draft[DRAFT_STATE];\n if (state.type_ === 0 /* Object */ || state.type_ === 1 /* Array */)\n state.revoke_();\n else\n state.revoked_ = true;\n}\n\n// src/core/finalize.ts\nfunction processResult(result, scope) {\n scope.unfinalizedDrafts_ = scope.drafts_.length;\n const baseDraft = scope.drafts_[0];\n const isReplaced = result !== void 0 && result !== baseDraft;\n if (isReplaced) {\n if (baseDraft[DRAFT_STATE].modified_) {\n revokeScope(scope);\n die(4);\n }\n if (isDraftable(result)) {\n result = finalize(scope, result);\n if (!scope.parent_)\n maybeFreeze(scope, result);\n }\n if (scope.patches_) {\n getPlugin(\"Patches\").generateReplacementPatches_(\n baseDraft[DRAFT_STATE].base_,\n result,\n scope.patches_,\n scope.inversePatches_\n );\n }\n } else {\n result = finalize(scope, baseDraft, []);\n }\n revokeScope(scope);\n if (scope.patches_) {\n scope.patchListener_(scope.patches_, scope.inversePatches_);\n }\n return result !== NOTHING ? result : void 0;\n}\nfunction finalize(rootScope, value, path) {\n if (isFrozen(value))\n return value;\n const useStrictIteration = rootScope.immer_.shouldUseStrictIteration();\n const state = value[DRAFT_STATE];\n if (!state) {\n each(\n value,\n (key, childValue) => finalizeProperty(rootScope, state, value, key, childValue, path),\n useStrictIteration\n );\n return value;\n }\n if (state.scope_ !== rootScope)\n return value;\n if (!state.modified_) {\n maybeFreeze(rootScope, state.base_, true);\n return state.base_;\n }\n if (!state.finalized_) {\n state.finalized_ = true;\n state.scope_.unfinalizedDrafts_--;\n const result = state.copy_;\n let resultEach = result;\n let isSet2 = false;\n if (state.type_ === 3 /* Set */) {\n resultEach = new Set(result);\n result.clear();\n isSet2 = true;\n }\n each(\n resultEach,\n (key, childValue) => finalizeProperty(\n rootScope,\n state,\n result,\n key,\n childValue,\n path,\n isSet2\n ),\n useStrictIteration\n );\n maybeFreeze(rootScope, result, false);\n if (path && rootScope.patches_) {\n getPlugin(\"Patches\").generatePatches_(\n state,\n path,\n rootScope.patches_,\n rootScope.inversePatches_\n );\n }\n }\n return state.copy_;\n}\nfunction finalizeProperty(rootScope, parentState, targetObject, prop, childValue, rootPath, targetIsSet) {\n if (childValue == null) {\n return;\n }\n if (typeof childValue !== \"object\" && !targetIsSet) {\n return;\n }\n const childIsFrozen = isFrozen(childValue);\n if (childIsFrozen && !targetIsSet) {\n return;\n }\n if (process.env.NODE_ENV !== \"production\" && childValue === targetObject)\n die(5);\n if (isDraft(childValue)) {\n const path = rootPath && parentState && parentState.type_ !== 3 /* Set */ && // Set objects are atomic since they have no keys.\n !has(parentState.assigned_, prop) ? rootPath.concat(prop) : void 0;\n const res = finalize(rootScope, childValue, path);\n set(targetObject, prop, res);\n if (isDraft(res)) {\n rootScope.canAutoFreeze_ = false;\n } else\n return;\n } else if (targetIsSet) {\n targetObject.add(childValue);\n }\n if (isDraftable(childValue) && !childIsFrozen) {\n if (!rootScope.immer_.autoFreeze_ && rootScope.unfinalizedDrafts_ < 1) {\n return;\n }\n if (parentState && parentState.base_ && parentState.base_[prop] === childValue && childIsFrozen) {\n return;\n }\n finalize(rootScope, childValue);\n if ((!parentState || !parentState.scope_.parent_) && typeof prop !== \"symbol\" && (isMap(targetObject) ? targetObject.has(prop) : Object.prototype.propertyIsEnumerable.call(targetObject, prop)))\n maybeFreeze(rootScope, childValue);\n }\n}\nfunction maybeFreeze(scope, value, deep = false) {\n if (!scope.parent_ && scope.immer_.autoFreeze_ && scope.canAutoFreeze_) {\n freeze(value, deep);\n }\n}\n\n// src/core/proxy.ts\nfunction createProxyProxy(base, parent) {\n const isArray = Array.isArray(base);\n const state = {\n type_: isArray ? 1 /* Array */ : 0 /* Object */,\n // Track which produce call this is associated with.\n scope_: parent ? parent.scope_ : getCurrentScope(),\n // True for both shallow and deep changes.\n modified_: false,\n // Used during finalization.\n finalized_: false,\n // Track which properties have been assigned (true) or deleted (false).\n assigned_: {},\n // The parent draft state.\n parent_: parent,\n // The base state.\n base_: base,\n // The base proxy.\n draft_: null,\n // set below\n // The base copy with any updated values.\n copy_: null,\n // Called by the `produce` function.\n revoke_: null,\n isManual_: false\n };\n let target = state;\n let traps = objectTraps;\n if (isArray) {\n target = [state];\n traps = arrayTraps;\n }\n const { revoke, proxy } = Proxy.revocable(target, traps);\n state.draft_ = proxy;\n state.revoke_ = revoke;\n return proxy;\n}\nvar objectTraps = {\n get(state, prop) {\n if (prop === DRAFT_STATE)\n return state;\n const source = latest(state);\n if (!has(source, prop)) {\n return readPropFromProto(state, source, prop);\n }\n const value = source[prop];\n if (state.finalized_ || !isDraftable(value)) {\n return value;\n }\n if (value === peek(state.base_, prop)) {\n prepareCopy(state);\n return state.copy_[prop] = createProxy(value, state);\n }\n return value;\n },\n has(state, prop) {\n return prop in latest(state);\n },\n ownKeys(state) {\n return Reflect.ownKeys(latest(state));\n },\n set(state, prop, value) {\n const desc = getDescriptorFromProto(latest(state), prop);\n if (desc?.set) {\n desc.set.call(state.draft_, value);\n return true;\n }\n if (!state.modified_) {\n const current2 = peek(latest(state), prop);\n const currentState = current2?.[DRAFT_STATE];\n if (currentState && currentState.base_ === value) {\n state.copy_[prop] = value;\n state.assigned_[prop] = false;\n return true;\n }\n if (is(value, current2) && (value !== void 0 || has(state.base_, prop)))\n return true;\n prepareCopy(state);\n markChanged(state);\n }\n if (state.copy_[prop] === value && // special case: handle new props with value 'undefined'\n (value !== void 0 || prop in state.copy_) || // special case: NaN\n Number.isNaN(value) && Number.isNaN(state.copy_[prop]))\n return true;\n state.copy_[prop] = value;\n state.assigned_[prop] = true;\n return true;\n },\n deleteProperty(state, prop) {\n if (peek(state.base_, prop) !== void 0 || prop in state.base_) {\n state.assigned_[prop] = false;\n prepareCopy(state);\n markChanged(state);\n } else {\n delete state.assigned_[prop];\n }\n if (state.copy_) {\n delete state.copy_[prop];\n }\n return true;\n },\n // Note: We never coerce `desc.value` into an Immer draft, because we can't make\n // the same guarantee in ES5 mode.\n getOwnPropertyDescriptor(state, prop) {\n const owner = latest(state);\n const desc = Reflect.getOwnPropertyDescriptor(owner, prop);\n if (!desc)\n return desc;\n return {\n writable: true,\n configurable: state.type_ !== 1 /* Array */ || prop !== \"length\",\n enumerable: desc.enumerable,\n value: owner[prop]\n };\n },\n defineProperty() {\n die(11);\n },\n getPrototypeOf(state) {\n return getPrototypeOf(state.base_);\n },\n setPrototypeOf() {\n die(12);\n }\n};\nvar arrayTraps = {};\neach(objectTraps, (key, fn) => {\n arrayTraps[key] = function() {\n arguments[0] = arguments[0][0];\n return fn.apply(this, arguments);\n };\n});\narrayTraps.deleteProperty = function(state, prop) {\n if (process.env.NODE_ENV !== \"production\" && isNaN(parseInt(prop)))\n die(13);\n return arrayTraps.set.call(this, state, prop, void 0);\n};\narrayTraps.set = function(state, prop, value) {\n if (process.env.NODE_ENV !== \"production\" && prop !== \"length\" && isNaN(parseInt(prop)))\n die(14);\n return objectTraps.set.call(this, state[0], prop, value, state[0]);\n};\nfunction peek(draft, prop) {\n const state = draft[DRAFT_STATE];\n const source = state ? latest(state) : draft;\n return source[prop];\n}\nfunction readPropFromProto(state, source, prop) {\n const desc = getDescriptorFromProto(source, prop);\n return desc ? `value` in desc ? desc.value : (\n // This is a very special case, if the prop is a getter defined by the\n // prototype, we should invoke it with the draft as context!\n desc.get?.call(state.draft_)\n ) : void 0;\n}\nfunction getDescriptorFromProto(source, prop) {\n if (!(prop in source))\n return void 0;\n let proto = getPrototypeOf(source);\n while (proto) {\n const desc = Object.getOwnPropertyDescriptor(proto, prop);\n if (desc)\n return desc;\n proto = getPrototypeOf(proto);\n }\n return void 0;\n}\nfunction markChanged(state) {\n if (!state.modified_) {\n state.modified_ = true;\n if (state.parent_) {\n markChanged(state.parent_);\n }\n }\n}\nfunction prepareCopy(state) {\n if (!state.copy_) {\n state.copy_ = shallowCopy(\n state.base_,\n state.scope_.immer_.useStrictShallowCopy_\n );\n }\n}\n\n// src/core/immerClass.ts\nvar Immer2 = class {\n constructor(config) {\n this.autoFreeze_ = true;\n this.useStrictShallowCopy_ = false;\n this.useStrictIteration_ = true;\n /**\n * The `produce` function takes a value and a \"recipe function\" (whose\n * return value often depends on the base state). The recipe function is\n * free to mutate its first argument however it wants. All mutations are\n * only ever applied to a __copy__ of the base state.\n *\n * Pass only a function to create a \"curried producer\" which relieves you\n * from passing the recipe function every time.\n *\n * Only plain objects and arrays are made mutable. All other objects are\n * considered uncopyable.\n *\n * Note: This function is __bound__ to its `Immer` instance.\n *\n * @param {any} base - the initial state\n * @param {Function} recipe - function that receives a proxy of the base state as first argument and which can be freely modified\n * @param {Function} patchListener - optional function that will be called with all the patches produced here\n * @returns {any} a new state, or the initial state if nothing was modified\n */\n this.produce = (base, recipe, patchListener) => {\n if (typeof base === \"function\" && typeof recipe !== \"function\") {\n const defaultBase = recipe;\n recipe = base;\n const self = this;\n return function curriedProduce(base2 = defaultBase, ...args) {\n return self.produce(base2, (draft) => recipe.call(this, draft, ...args));\n };\n }\n if (typeof recipe !== \"function\")\n die(6);\n if (patchListener !== void 0 && typeof patchListener !== \"function\")\n die(7);\n let result;\n if (isDraftable(base)) {\n const scope = enterScope(this);\n const proxy = createProxy(base, void 0);\n let hasError = true;\n try {\n result = recipe(proxy);\n hasError = false;\n } finally {\n if (hasError)\n revokeScope(scope);\n else\n leaveScope(scope);\n }\n usePatchesInScope(scope, patchListener);\n return processResult(result, scope);\n } else if (!base || typeof base !== \"object\") {\n result = recipe(base);\n if (result === void 0)\n result = base;\n if (result === NOTHING)\n result = void 0;\n if (this.autoFreeze_)\n freeze(result, true);\n if (patchListener) {\n const p = [];\n const ip = [];\n getPlugin(\"Patches\").generateReplacementPatches_(base, result, p, ip);\n patchListener(p, ip);\n }\n return result;\n } else\n die(1, base);\n };\n this.produceWithPatches = (base, recipe) => {\n if (typeof base === \"function\") {\n return (state, ...args) => this.produceWithPatches(state, (draft) => base(draft, ...args));\n }\n let patches, inversePatches;\n const result = this.produce(base, recipe, (p, ip) => {\n patches = p;\n inversePatches = ip;\n });\n return [result, patches, inversePatches];\n };\n if (typeof config?.autoFreeze === \"boolean\")\n this.setAutoFreeze(config.autoFreeze);\n if (typeof config?.useStrictShallowCopy === \"boolean\")\n this.setUseStrictShallowCopy(config.useStrictShallowCopy);\n if (typeof config?.useStrictIteration === \"boolean\")\n this.setUseStrictIteration(config.useStrictIteration);\n }\n createDraft(base) {\n if (!isDraftable(base))\n die(8);\n if (isDraft(base))\n base = current(base);\n const scope = enterScope(this);\n const proxy = createProxy(base, void 0);\n proxy[DRAFT_STATE].isManual_ = true;\n leaveScope(scope);\n return proxy;\n }\n finishDraft(draft, patchListener) {\n const state = draft && draft[DRAFT_STATE];\n if (!state || !state.isManual_)\n die(9);\n const { scope_: scope } = state;\n usePatchesInScope(scope, patchListener);\n return processResult(void 0, scope);\n }\n /**\n * Pass true to automatically freeze all copies created by Immer.\n *\n * By default, auto-freezing is enabled.\n */\n setAutoFreeze(value) {\n this.autoFreeze_ = value;\n }\n /**\n * Pass true to enable strict shallow copy.\n *\n * By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties.\n */\n setUseStrictShallowCopy(value) {\n this.useStrictShallowCopy_ = value;\n }\n /**\n * Pass false to use faster iteration that skips non-enumerable properties\n * but still handles symbols for compatibility.\n *\n * By default, strict iteration is enabled (includes all own properties).\n */\n setUseStrictIteration(value) {\n this.useStrictIteration_ = value;\n }\n shouldUseStrictIteration() {\n return this.useStrictIteration_;\n }\n applyPatches(base, patches) {\n let i;\n for (i = patches.length - 1; i >= 0; i--) {\n const patch = patches[i];\n if (patch.path.length === 0 && patch.op === \"replace\") {\n base = patch.value;\n break;\n }\n }\n if (i > -1) {\n patches = patches.slice(i + 1);\n }\n const applyPatchesImpl = getPlugin(\"Patches\").applyPatches_;\n if (isDraft(base)) {\n return applyPatchesImpl(base, patches);\n }\n return this.produce(\n base,\n (draft) => applyPatchesImpl(draft, patches)\n );\n }\n};\nfunction createProxy(value, parent) {\n const draft = isMap(value) ? getPlugin(\"MapSet\").proxyMap_(value, parent) : isSet(value) ? getPlugin(\"MapSet\").proxySet_(value, parent) : createProxyProxy(value, parent);\n const scope = parent ? parent.scope_ : getCurrentScope();\n scope.drafts_.push(draft);\n return draft;\n}\n\n// src/core/current.ts\nfunction current(value) {\n if (!isDraft(value))\n die(10, value);\n return currentImpl(value);\n}\nfunction currentImpl(value) {\n if (!isDraftable(value) || isFrozen(value))\n return value;\n const state = value[DRAFT_STATE];\n let copy;\n let strict = true;\n if (state) {\n if (!state.modified_)\n return state.base_;\n state.finalized_ = true;\n copy = shallowCopy(value, state.scope_.immer_.useStrictShallowCopy_);\n strict = state.scope_.immer_.shouldUseStrictIteration();\n } else {\n copy = shallowCopy(value, true);\n }\n each(\n copy,\n (key, childValue) => {\n set(copy, key, currentImpl(childValue));\n },\n strict\n );\n if (state) {\n state.finalized_ = false;\n }\n return copy;\n}\n\n// src/plugins/patches.ts\nfunction enablePatches() {\n const errorOffset = 16;\n if (process.env.NODE_ENV !== \"production\") {\n errors.push(\n 'Sets cannot have \"replace\" patches.',\n function(op) {\n return \"Unsupported patch operation: \" + op;\n },\n function(path) {\n return \"Cannot apply patch, path doesn't resolve: \" + path;\n },\n \"Patching reserved attributes like __proto__, prototype and constructor is not allowed\"\n );\n }\n const REPLACE = \"replace\";\n const ADD = \"add\";\n const REMOVE = \"remove\";\n function generatePatches_(state, basePath, patches, inversePatches) {\n switch (state.type_) {\n case 0 /* Object */:\n case 2 /* Map */:\n return generatePatchesFromAssigned(\n state,\n basePath,\n patches,\n inversePatches\n );\n case 1 /* Array */:\n return generateArrayPatches(state, basePath, patches, inversePatches);\n case 3 /* Set */:\n return generateSetPatches(\n state,\n basePath,\n patches,\n inversePatches\n );\n }\n }\n function generateArrayPatches(state, basePath, patches, inversePatches) {\n let { base_, assigned_ } = state;\n let copy_ = state.copy_;\n if (copy_.length < base_.length) {\n ;\n [base_, copy_] = [copy_, base_];\n [patches, inversePatches] = [inversePatches, patches];\n }\n for (let i = 0; i < base_.length; i++) {\n if (assigned_[i] && copy_[i] !== base_[i]) {\n const path = basePath.concat([i]);\n patches.push({\n op: REPLACE,\n path,\n // Need to maybe clone it, as it can in fact be the original value\n // due to the base/copy inversion at the start of this function\n value: clonePatchValueIfNeeded(copy_[i])\n });\n inversePatches.push({\n op: REPLACE,\n path,\n value: clonePatchValueIfNeeded(base_[i])\n });\n }\n }\n for (let i = base_.length; i < copy_.length; i++) {\n const path = basePath.concat([i]);\n patches.push({\n op: ADD,\n path,\n // Need to maybe clone it, as it can in fact be the original value\n // due to the base/copy inversion at the start of this function\n value: clonePatchValueIfNeeded(copy_[i])\n });\n }\n for (let i = copy_.length - 1; base_.length <= i; --i) {\n const path = basePath.concat([i]);\n inversePatches.push({\n op: REMOVE,\n path\n });\n }\n }\n function generatePatchesFromAssigned(state, basePath, patches, inversePatches) {\n const { base_, copy_ } = state;\n each(state.assigned_, (key, assignedValue) => {\n const origValue = get(base_, key);\n const value = get(copy_, key);\n const op = !assignedValue ? REMOVE : has(base_, key) ? REPLACE : ADD;\n if (origValue === value && op === REPLACE)\n return;\n const path = basePath.concat(key);\n patches.push(op === REMOVE ? { op, path } : { op, path, value });\n inversePatches.push(\n op === ADD ? { op: REMOVE, path } : op === REMOVE ? { op: ADD, path, value: clonePatchValueIfNeeded(origValue) } : { op: REPLACE, path, value: clonePatchValueIfNeeded(origValue) }\n );\n });\n }\n function generateSetPatches(state, basePath, patches, inversePatches) {\n let { base_, copy_ } = state;\n let i = 0;\n base_.forEach((value) => {\n if (!copy_.has(value)) {\n const path = basePath.concat([i]);\n patches.push({\n op: REMOVE,\n path,\n value\n });\n inversePatches.unshift({\n op: ADD,\n path,\n value\n });\n }\n i++;\n });\n i = 0;\n copy_.forEach((value) => {\n if (!base_.has(value)) {\n const path = basePath.concat([i]);\n patches.push({\n op: ADD,\n path,\n value\n });\n inversePatches.unshift({\n op: REMOVE,\n path,\n value\n });\n }\n i++;\n });\n }\n function generateReplacementPatches_(baseValue, replacement, patches, inversePatches) {\n patches.push({\n op: REPLACE,\n path: [],\n value: replacement === NOTHING ? void 0 : replacement\n });\n inversePatches.push({\n op: REPLACE,\n path: [],\n value: baseValue\n });\n }\n function applyPatches_(draft, patches) {\n patches.forEach((patch) => {\n const { path, op } = patch;\n let base = draft;\n for (let i = 0; i < path.length - 1; i++) {\n const parentType = getArchtype(base);\n let p = path[i];\n if (typeof p !== \"string\" && typeof p !== \"number\") {\n p = \"\" + p;\n }\n if ((parentType === 0 /* Object */ || parentType === 1 /* Array */) && (p === \"__proto__\" || p === \"constructor\"))\n die(errorOffset + 3);\n if (typeof base === \"function\" && p === \"prototype\")\n die(errorOffset + 3);\n base = get(base, p);\n if (typeof base !== \"object\")\n die(errorOffset + 2, path.join(\"/\"));\n }\n const type = getArchtype(base);\n const value = deepClonePatchValue(patch.value);\n const key = path[path.length - 1];\n switch (op) {\n case REPLACE:\n switch (type) {\n case 2 /* Map */:\n return base.set(key, value);\n case 3 /* Set */:\n die(errorOffset);\n default:\n return base[key] = value;\n }\n case ADD:\n switch (type) {\n case 1 /* Array */:\n return key === \"-\" ? base.push(value) : base.splice(key, 0, value);\n case 2 /* Map */:\n return base.set(key, value);\n case 3 /* Set */:\n return base.add(value);\n default:\n return base[key] = value;\n }\n case REMOVE:\n switch (type) {\n case 1 /* Array */:\n return base.splice(key, 1);\n case 2 /* Map */:\n return base.delete(key);\n case 3 /* Set */:\n return base.delete(patch.value);\n default:\n return delete base[key];\n }\n default:\n die(errorOffset + 1, op);\n }\n });\n return draft;\n }\n function deepClonePatchValue(obj) {\n if (!isDraftable(obj))\n return obj;\n if (Array.isArray(obj))\n return obj.map(deepClonePatchValue);\n if (isMap(obj))\n return new Map(\n Array.from(obj.entries()).map(([k, v]) => [k, deepClonePatchValue(v)])\n );\n if (isSet(obj))\n return new Set(Array.from(obj).map(deepClonePatchValue));\n const cloned = Object.create(getPrototypeOf(obj));\n for (const key in obj)\n cloned[key] = deepClonePatchValue(obj[key]);\n if (has(obj, DRAFTABLE))\n cloned[DRAFTABLE] = obj[DRAFTABLE];\n return cloned;\n }\n function clonePatchValueIfNeeded(obj) {\n if (isDraft(obj)) {\n return deepClonePatchValue(obj);\n } else\n return obj;\n }\n loadPlugin(\"Patches\", {\n applyPatches_,\n generatePatches_,\n generateReplacementPatches_\n });\n}\n\n// src/plugins/mapset.ts\nfunction enableMapSet() {\n class DraftMap extends Map {\n constructor(target, parent) {\n super();\n this[DRAFT_STATE] = {\n type_: 2 /* Map */,\n parent_: parent,\n scope_: parent ? parent.scope_ : getCurrentScope(),\n modified_: false,\n finalized_: false,\n copy_: void 0,\n assigned_: void 0,\n base_: target,\n draft_: this,\n isManual_: false,\n revoked_: false\n };\n }\n get size() {\n return latest(this[DRAFT_STATE]).size;\n }\n has(key) {\n return latest(this[DRAFT_STATE]).has(key);\n }\n set(key, value) {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n if (!latest(state).has(key) || latest(state).get(key) !== value) {\n prepareMapCopy(state);\n markChanged(state);\n state.assigned_.set(key, true);\n state.copy_.set(key, value);\n state.assigned_.set(key, true);\n }\n return this;\n }\n delete(key) {\n if (!this.has(key)) {\n return false;\n }\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n prepareMapCopy(state);\n markChanged(state);\n if (state.base_.has(key)) {\n state.assigned_.set(key, false);\n } else {\n state.assigned_.delete(key);\n }\n state.copy_.delete(key);\n return true;\n }\n clear() {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n if (latest(state).size) {\n prepareMapCopy(state);\n markChanged(state);\n state.assigned_ = /* @__PURE__ */ new Map();\n each(state.base_, (key) => {\n state.assigned_.set(key, false);\n });\n state.copy_.clear();\n }\n }\n forEach(cb, thisArg) {\n const state = this[DRAFT_STATE];\n latest(state).forEach((_value, key, _map) => {\n cb.call(thisArg, this.get(key), key, this);\n });\n }\n get(key) {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n const value = latest(state).get(key);\n if (state.finalized_ || !isDraftable(value)) {\n return value;\n }\n if (value !== state.base_.get(key)) {\n return value;\n }\n const draft = createProxy(value, state);\n prepareMapCopy(state);\n state.copy_.set(key, draft);\n return draft;\n }\n keys() {\n return latest(this[DRAFT_STATE]).keys();\n }\n values() {\n const iterator = this.keys();\n return {\n [Symbol.iterator]: () => this.values(),\n next: () => {\n const r = iterator.next();\n if (r.done)\n return r;\n const value = this.get(r.value);\n return {\n done: false,\n value\n };\n }\n };\n }\n entries() {\n const iterator = this.keys();\n return {\n [Symbol.iterator]: () => this.entries(),\n next: () => {\n const r = iterator.next();\n if (r.done)\n return r;\n const value = this.get(r.value);\n return {\n done: false,\n value: [r.value, value]\n };\n }\n };\n }\n [(DRAFT_STATE, Symbol.iterator)]() {\n return this.entries();\n }\n }\n function proxyMap_(target, parent) {\n return new DraftMap(target, parent);\n }\n function prepareMapCopy(state) {\n if (!state.copy_) {\n state.assigned_ = /* @__PURE__ */ new Map();\n state.copy_ = new Map(state.base_);\n }\n }\n class DraftSet extends Set {\n constructor(target, parent) {\n super();\n this[DRAFT_STATE] = {\n type_: 3 /* Set */,\n parent_: parent,\n scope_: parent ? parent.scope_ : getCurrentScope(),\n modified_: false,\n finalized_: false,\n copy_: void 0,\n base_: target,\n draft_: this,\n drafts_: /* @__PURE__ */ new Map(),\n revoked_: false,\n isManual_: false\n };\n }\n get size() {\n return latest(this[DRAFT_STATE]).size;\n }\n has(value) {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n if (!state.copy_) {\n return state.base_.has(value);\n }\n if (state.copy_.has(value))\n return true;\n if (state.drafts_.has(value) && state.copy_.has(state.drafts_.get(value)))\n return true;\n return false;\n }\n add(value) {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n if (!this.has(value)) {\n prepareSetCopy(state);\n markChanged(state);\n state.copy_.add(value);\n }\n return this;\n }\n delete(value) {\n if (!this.has(value)) {\n return false;\n }\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n prepareSetCopy(state);\n markChanged(state);\n return state.copy_.delete(value) || (state.drafts_.has(value) ? state.copy_.delete(state.drafts_.get(value)) : (\n /* istanbul ignore next */\n false\n ));\n }\n clear() {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n if (latest(state).size) {\n prepareSetCopy(state);\n markChanged(state);\n state.copy_.clear();\n }\n }\n values() {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n prepareSetCopy(state);\n return state.copy_.values();\n }\n entries() {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n prepareSetCopy(state);\n return state.copy_.entries();\n }\n keys() {\n return this.values();\n }\n [(DRAFT_STATE, Symbol.iterator)]() {\n return this.values();\n }\n forEach(cb, thisArg) {\n const iterator = this.values();\n let result = iterator.next();\n while (!result.done) {\n cb.call(thisArg, result.value, result.value, this);\n result = iterator.next();\n }\n }\n }\n function proxySet_(target, parent) {\n return new DraftSet(target, parent);\n }\n function prepareSetCopy(state) {\n if (!state.copy_) {\n state.copy_ = /* @__PURE__ */ new Set();\n state.base_.forEach((value) => {\n if (isDraftable(value)) {\n const draft = createProxy(value, state);\n state.drafts_.set(value, draft);\n state.copy_.add(draft);\n } else {\n state.copy_.add(value);\n }\n });\n }\n }\n function assertUnrevoked(state) {\n if (state.revoked_)\n die(3, JSON.stringify(latest(state)));\n }\n loadPlugin(\"MapSet\", { proxyMap_, proxySet_ });\n}\n\n// src/immer.ts\nvar immer = new Immer2();\nvar produce = immer.produce;\nvar produceWithPatches = /* @__PURE__ */ immer.produceWithPatches.bind(\n immer\n);\nvar setAutoFreeze = /* @__PURE__ */ immer.setAutoFreeze.bind(immer);\nvar setUseStrictShallowCopy = /* @__PURE__ */ immer.setUseStrictShallowCopy.bind(\n immer\n);\nvar setUseStrictIteration = /* @__PURE__ */ immer.setUseStrictIteration.bind(\n immer\n);\nvar applyPatches = /* @__PURE__ */ immer.applyPatches.bind(immer);\nvar createDraft = /* @__PURE__ */ immer.createDraft.bind(immer);\nvar finishDraft = /* @__PURE__ */ immer.finishDraft.bind(immer);\nfunction castDraft(value) {\n return value;\n}\nfunction castImmutable(value) {\n return value;\n}\nexport {\n Immer2 as Immer,\n applyPatches,\n castDraft,\n castImmutable,\n createDraft,\n current,\n enableMapSet,\n enablePatches,\n finishDraft,\n freeze,\n DRAFTABLE as immerable,\n isDraft,\n isDraftable,\n NOTHING as nothing,\n original,\n produce,\n produceWithPatches,\n setAutoFreeze,\n setUseStrictIteration,\n setUseStrictShallowCopy\n};\n//# sourceMappingURL=immer.mjs.map","import { createStore } from \"zustand/vanilla\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\nimport { shallow } from \"zustand/shallow\";\nimport { freeze, produce } from \"immer\";\n//#region lib/types/index.js\n/**\n* React-free snapshot store engine (zustand vanilla + immer + subscribeWithSelector +\n* rafFlush middleware + opt-in persist + dev freeze) plus the declarative\n* shell over it: {@link defineStore} bakes an init/persist/actions literal\n* into a {@link StoreHandle}, the registration-side store seat of slot\n* terminals. Engine products are bare observables — subscribe/getSnapshot/\n* update/set, NO selector hook. Hook synthesis is ui-renderer's (the one\n* uSES bridge, cached per source at the binding site).\n*/\n/**\n* Notify an observer set without allowing one callback to starve the rest.\n* @param listeners - current observer callbacks; copied before dispatch.\n* @param label - diagnostic owner prefix.\n* @param args - callback arguments.\n*/\nfunction notifySubscribers(listeners, label, ...args) {\n\tfor (const listener of [...listeners]) try {\n\t\tlistener(...args);\n\t} catch (error) {\n\t\tconsole.error(`${label} subscriber failed:`, error);\n\t}\n}\n/**\n* Shallow equality for selector slices (zustand/shallow semantics; travels\n* with the engine so hook consumers need no zustand dependency).\n* @param a - left value.\n* @param b - right value.\n* @returns whether the values are shallowly equal.\n*/\nfunction shallowEqual(a, b) {\n\treturn shallow(a, b);\n}\n/** Batches subscriber notification into one flush per animation frame. */\nfunction rafBatch(notify) {\n\tconst schedule = typeof requestAnimationFrame === \"function\" ? (fn) => {\n\t\trequestAnimationFrame(() => {\n\t\t\tfn();\n\t\t});\n\t} : (fn) => {\n\t\tqueueMicrotask(fn);\n\t};\n\tlet scheduled = false;\n\treturn () => {\n\t\tif (scheduled) return;\n\t\tscheduled = true;\n\t\tschedule(() => {\n\t\t\tscheduled = false;\n\t\t\tnotify();\n\t\t});\n\t};\n}\n/**\n* Create a snapshot store.\n*\n* Flush default is 'sync' (controlled inputs need same-tick echo); frame-driven\n* stores opt into 'raf', where a frame's worth of updates coalesces into one\n* notification. Known raf-mode tradeoff: a component mounting mid-frame reads\n* fresh state while existing subscribers hear it next flush — transient\n* frame-level skew, same nature as the object layer's microtask batching.\n*\n* @param init - initial state.\n* @param opts - flush mode and opt-in persistence (localStorage, keyed by name).\n* @returns the store.\n*/\nfunction createSnapshotStore(init, opts) {\n\tconst withSelector = subscribeWithSelector(() => init);\n\tconst api = createStore()(withSelector);\n\tif (opts?.persist) attachPersistence(api, opts.persist.name);\n\tlet subscribe = (fn) => api.subscribe(() => {\n\t\tnotifySubscribers([fn], \"[client-store]\");\n\t});\n\tif (opts?.flush === \"raf\") {\n\t\tconst listeners = /* @__PURE__ */ new Set();\n\t\tconst flush = rafBatch(() => {\n\t\t\tnotifySubscribers(listeners, \"[client-store]\");\n\t\t});\n\t\tapi.subscribe(flush);\n\t\tsubscribe = (fn) => {\n\t\t\tlisteners.add(fn);\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(fn);\n\t\t\t};\n\t\t};\n\t}\n\treturn {\n\t\tgetSnapshot: () => api.getState(),\n\t\tsubscribe: (fn) => subscribe(fn),\n\t\tupdate: (mutator) => {\n\t\t\tapi.setState(produce(api.getState(), (draft) => {\n\t\t\t\tmutator(draft);\n\t\t\t}), true);\n\t\t},\n\t\tset: (next) => {\n\t\t\tapi.setState(devFreeze(next), true);\n\t\t}\n\t};\n}\n/**\n* Whole-value JSON persistence to localStorage. Hand-rolled instead of the\n* zustand persist middleware: its write path spreads state into an object\n* (`partialize({ ...get() })`), exploding primitive state (a persisted string\n* draft becomes {0:'h',1:'e',...}) — not fixable via merge/deserialize options\n* because the corruption happens before serialization. Storage failures\n* (quota, private mode) only disable persistence, never break the store.\n*/\nfunction attachPersistence(api, name) {\n\tif (typeof localStorage === \"undefined\") return;\n\ttry {\n\t\tconst raw = localStorage.getItem(name);\n\t\tif (raw !== null) api.setState(devFreeze(JSON.parse(raw)), true);\n\t} catch (error) {\n\t\tconsole.error(`snapshot store '${name}' rehydration failed:`, error);\n\t}\n\tapi.subscribe((state) => {\n\t\ttry {\n\t\t\tlocalStorage.setItem(name, JSON.stringify(state));\n\t\t} catch (error) {\n\t\t\tconsole.error(`snapshot store '${name}' persistence failed:`, error);\n\t\t}\n\t});\n}\n/** Deep-freeze draftable wholesale-set state outside production: set() bypasses immer's freeze. */\nfunction devFreeze(value) {\n\treturn freeze(value, true);\n}\n/**\n* Declare a store: initial state, optional persistence, and the full write\n* set as pure draft mutators. The returned handle is the registration\n* currency of the store seat — its identity keys instance sharing. Satisfies\n* ui-slots' DefineStore contract (the handle/instance are the engine-extended\n* subtypes).\n*\n* The `A & ActionsDecl<T>` actions position is load-bearing: T resolves from\n* `init` in the first inference round, and the intersection then contextually\n* types each mutator's draft parameter (context-sensitive functions defer),\n* so call sites write `(d, x: X) => { ... }` with no draft annotation. If a\n* future TS version breaks this single-literal inference, the design's\n* documented fallback is currying (`defineStore(init).actions({...})`).\n* @param decl - init lambda (fresh state per instance), optional persist key, actions table.\n* @returns the store handle.\n*/\nfunction defineStore(decl) {\n\treturn {\n\t\tspec: decl,\n\t\tcreate(scopeKey) {\n\t\t\tconst persistKey = decl.persist === void 0 ? void 0 : scopeKey === void 0 ? decl.persist : `${decl.persist}.${scopeKey}`;\n\t\t\tconst store = createSnapshotStore(decl.init(), persistKey !== void 0 ? { persist: { name: persistKey } } : void 0);\n\t\t\tconst actions = {};\n\t\t\tfor (const key of Object.keys(decl.actions)) {\n\t\t\t\tconst mutate = decl.actions[key];\n\t\t\t\tactions[key] = (...params) => {\n\t\t\t\t\tstore.update((draft) => {\n\t\t\t\t\t\tmutate(draft, ...params);\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tactions,\n\t\t\t\tgetSnapshot: () => store.getSnapshot(),\n\t\t\t\tsubscribe: (fn) => store.subscribe(fn),\n\t\t\t\tstore,\n\t\t\t\tclearPersisted: () => {\n\t\t\t\t\tif (persistKey === void 0 || typeof localStorage === \"undefined\") return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlocalStorage.removeItem(persistKey);\n\t\t\t\t\t} catch {}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t};\n}\n//#endregion\nexport { createSnapshotStore, defineStore, notifySubscribers, shallowEqual };\n\n//# sourceMappingURL=index.js.map","/**\n * Settings-card form machinery, vendored from the dsh-web-ui family bucket\n * (packages/dsh-task-board/src/client/settings-form.ts) and re-typed. Stages\n * one card's edits over one settings namespace and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted — its\n * validators own the constraints no schema can express — so the outcome is\n * read back from the section rather than predicted here. A save that did not\n * land keeps its drafts, so the user can correct them instead of retyping.\n */\n\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client'\n\n/** One staged field: its draft text plus the clear/reset marker. */\ninterface StagedEdit {\n text: string\n clear: boolean\n}\n\n/** One editable field spec: formatting plus text parsing. */\nexport interface FieldSpec {\n field: string\n format: (value: unknown) => string\n parse: (text: string) => { kind: 'set'; value: unknown } | { kind: 'clear' } | undefined\n}\n\n/** A boolean field, edited through true/false draft text. */\nexport function booleanField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'boolean' ? String(value) : ''),\n parse: (text) => {\n if (text === 'true') return { kind: 'set', value: true }\n if (text === 'false') return { kind: 'set', value: false }\n return undefined\n },\n }\n}\n\n/** A #rrggbb color field, edited through hex draft text. */\nexport function colorField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value) ? value : ''),\n parse: (text) => {\n if (/^#[0-9a-f]{6}$/i.test(text)) return { kind: 'set', value: text }\n return undefined\n },\n }\n}\n\n/**\n * A numeric field with range clamping. Integer by default: a fractional draft\n * is truncated so \"5.5 分钟\" cannot sneak past an integer-only schema.\n */\nexport function numberField(field: string, options: { min?: number; max?: number; integer?: boolean } = {}): FieldSpec {\n const min = options.min ?? Number.NEGATIVE_INFINITY\n const max = options.max ?? Number.POSITIVE_INFINITY\n const integer = options.integer ?? true\n return {\n field,\n format: (value) => (typeof value === 'number' && Number.isFinite(value) ? String(value) : ''),\n parse: (text) => {\n const trimmed = text.trim()\n if (!/^-?\\d+(\\.\\d+)?$/.test(trimmed)) return undefined\n const parsed = integer ? Math.trunc(Number(trimmed)) : Number(trimmed)\n if (!Number.isFinite(parsed) || parsed < min || parsed > max) return undefined\n return { kind: 'set', value: parsed }\n },\n }\n}\n\n/** Card-level state the chrome renders. */\nexport interface CardShell {\n available: boolean\n exposed: boolean\n writable: boolean\n dirty: boolean\n invalid: boolean\n saving: boolean\n failed: boolean\n}\n\n/** One field's state from the effective section and its staged draft. */\nexport interface FieldState {\n text: string\n overridden: boolean\n invalid: boolean\n}\n\n/** The settings scope face the form consumes (subset of SettingsScope<T>). */\nexport interface FormScope {\n subscribe(listener: () => void): () => void\n getSnapshot(): { status: string; writable: boolean; value?: Record<string, unknown>; base?: unknown; user?: unknown }\n set(field: string, value: unknown): Promise<void>\n unset(field: string): Promise<void>\n}\n\n/** Stages one card's edits and writes them through the settings transport. */\nexport class CardForm {\n private readonly scope: FormScope\n private readonly specs = new Map<string, FieldSpec>()\n private readonly staged = new Map<string, StagedEdit>()\n private readonly listeners = new Set<() => void>()\n private saving = false\n private failed = false\n\n /** @param scope - the bound settings scope for this card's namespace. */\n constructor(scope: FormScope, specs: FieldSpec[]) {\n this.scope = scope\n for (const spec of specs) this.specs.set(spec.field, spec)\n scope.subscribe(() => { this.publish() })\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<T>(project: () => T) {\n const store = createSnapshotStore(project())\n this.listeners.add(() => { store.set(project()) })\n return store\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n return {\n available: snapshot.status !== 'loading',\n exposed: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: plan.length > 0,\n invalid: plan.some((item) => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n }\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): FieldState {\n const spec = this.specOf(field)\n const staged = this.staged.get(field)\n if (staged === undefined) {\n return { text: spec.format(this.sectionValue(field)), overridden: this.stored(field), invalid: false }\n }\n const write = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return { text: staged.text, overridden: write?.kind === 'set', invalid: write === undefined }\n }\n\n /** The actions the card's slot registration injects. */\n actions() {\n return {\n edit: (field: string, text: string) => { this.stage(field, { text, clear: false }) },\n resetField: (field: string) => {\n this.stage(field, { text: this.specOf(field).format(this.baseValue(field)), clear: true })\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return\n this.staged.clear()\n this.failed = false\n this.publish()\n },\n }\n }\n\n /** Write every staged edit, then re-seed from what the Host accepted. */\n async save(): Promise<void> {\n const plan = this.plan()\n const writes = plan.flatMap((item) => (item.run === undefined ? [] : [item.run]))\n if (plan.length === 0 || this.saving || writes.length !== plan.length) return\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n for (const write of writes) landed = (await write()) && landed\n if (landed) this.staged.clear()\n this.saving = false\n this.failed = !landed\n this.publish()\n }\n\n /** Every staged edit a save would write, in staging order. */\n plan(): Array<{ field: string; run: (() => Promise<boolean>) | undefined }> {\n const plan: Array<{ field: string; run: (() => Promise<boolean>) | undefined }> = []\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(field)\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, run: () => this.clear(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const write = spec.parse(staged.text)\n if (write === undefined) plan.push({ field, run: undefined })\n else if (write.kind === 'clear') plan.push({ field, run: () => this.clear(field) })\n else plan.push({ field, run: () => this.store(field, write.value) })\n }\n return plan\n }\n\n private async clear(field: string): Promise<boolean> {\n await this.scope.unset(field)\n return !this.stored(field)\n }\n\n private async store(field: string, value: unknown): Promise<boolean> {\n await this.scope.set(field, value)\n return this.userLayer()?.[field] === value\n }\n\n private userRecord(): Record<string, unknown> | undefined {\n const user = this.scope.getSnapshot().user\n return typeof user === 'object' && user !== null ? user as Record<string, unknown> : undefined\n }\n\n private stage(field: string, edit: StagedEdit): void {\n this.staged.set(field, edit)\n this.failed = false\n this.publish()\n }\n\n private specOf(field: string): FieldSpec {\n const spec = this.specs.get(field)\n if (spec === undefined) throw new Error('settings card has no field ' + field)\n return spec\n }\n\n private sectionValue(field: string): unknown {\n return this.scope.getSnapshot().value?.[field]\n }\n\n private baseValue(field: string): unknown {\n const base = this.scope.getSnapshot().base\n return typeof base === 'object' && base !== null ? (base as Record<string, unknown>)[field] : undefined\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.userRecord()\n }\n\n private stored(field: string): boolean {\n const user = this.userRecord()\n return user !== undefined && Object.hasOwn(user, field)\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n\n","/**\n * The dsh-skill-hub plugin settings card: bridges the hub's settings\n * namespace (bound through the official settings transport) onto the\n * family-style staged card form (enabled master switch + agent announcement).\n * Registered into the official `settings.plugin.item` slot keyed by that\n * namespace, so the plugin shows up in Settings → 插件 on dsh rc.7+.\n */\n\nimport { useEffect, useState, type ReactElement } from 'react'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { SkillHubApi } from './api.ts'\nimport { ColorField, NumberField, PluginSettingsCard, SwitchField } from './settings-card.tsx'\nimport { booleanField, CardForm, colorField, numberField, type CardShell, type FieldState, type FormScope } from './settings-form.ts'\n// Single source for the TS-side dot defaults (the panel CSS mirrors these).\nimport { DEFAULT_DOT_MODEL_COLOR, DEFAULT_DOT_USER_COLOR } from './panel/format.ts'\n// Re-export for any consumer that imported them from the card before the move.\nexport { DEFAULT_DOT_MODEL_COLOR, DEFAULT_DOT_USER_COLOR }\n\n/** The card's projected state. */\nexport interface SkillHubSettingsState extends CardShell {\n enabled: FieldState\n announceToAgent: FieldState\n dotModelColor: FieldState\n dotUserColor: FieldState\n showUseCount: FieldState\n showUseTime: FieldState\n showGroupSummary: FieldState\n statsWindowDays: FieldState\n statsScanMinutes: FieldState\n}\n\n/** The business face the card's slot registration injects. */\nexport interface SkillHubSettingsCardFace {\n hooks: {\n /** The card's snapshot store (projected form state). */\n skillHubSettingsCard: SnapshotStore<SkillHubSettingsState>\n }\n save: () => void\n discard: () => void\n edit: (field: string, text: string) => void\n resetField: (field: string) => void\n}\n\n/** Props the slot renderer binds (locale copy + injected form actions). */\nexport type SkillHubSettingsCardProps =\n PropsRuntime<'settings.plugin.item'> & PropsLocale<'dsh-skill-hub'> & InjectFace<SkillHubSettingsCardFace>\n\n/** Bridges the hub's config scope onto the card's staged form. */\nexport class SkillHubSettingsCardController {\n private readonly form: CardForm\n private readonly store: SnapshotStore<SkillHubSettingsState>\n\n /** @param scope - the hub settings scope the card edits (FormScope-compatible). */\n constructor(scope: FormScope) {\n this.form = new CardForm(scope, [booleanField('enabled'), booleanField('announceToAgent'), colorField('dotModelColor'), colorField('dotUserColor'), booleanField('showUseCount'), booleanField('showUseTime'), booleanField('showGroupSummary'), numberField('statsWindowDays', { min: 0, max: 3650 }), numberField('statsScanMinutes', { min: 1, max: 1440 })])\n this.store = this.form.bind(() => this.projection())\n }\n\n private projection(): SkillHubSettingsState {\n return {\n ...this.form.shell(),\n enabled: this.form.field('enabled'),\n announceToAgent: this.form.field('announceToAgent'),\n dotModelColor: this.form.field('dotModelColor'),\n dotUserColor: this.form.field('dotUserColor'),\n showUseCount: this.form.field('showUseCount'),\n showUseTime: this.form.field('showUseTime'),\n showGroupSummary: this.form.field('showGroupSummary'),\n statsWindowDays: this.form.field('statsWindowDays'),\n statsScanMinutes: this.form.field('statsScanMinutes'),\n }\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot hook and its form actions.\n */\n inject(): SkillHubSettingsCardFace {\n return {\n hooks: { skillHubSettingsCard: this.store },\n ...this.form.actions(),\n }\n }\n}\n\n/**\n * Render the dsh-skill-hub card.\n * @param props - locale copy, the card snapshot, and its form actions.\n * @returns the card.\n */\nexport function SkillHubSettingsCard(props: SkillHubSettingsCardProps): ReactElement {\n const { t } = props\n const state = props.useSkillHubSettingsCard((snapshot) => snapshot)\n // 插件自身版本:挂载时从 config 路由取一次(与面板标题徽标同源),失败静默不显示。\n const [version, setVersion] = useState<string | undefined>(undefined)\n useEffect(() => {\n let cancelled = false\n void new SkillHubApi().config()\n .then((res) => { if (!cancelled && res.ok) setVersion(res.pluginVersion) })\n .catch(() => { /* 版本徽标是装饰性的,失败不提示 */ })\n return () => { cancelled = true }\n }, [])\n const disabled = !state.writable\n const fieldProps = {\n overriddenLabel: t('settings.overridden'),\n resetLabel: t('settings.reset'),\n disabled,\n }\n return (\n <PluginSettingsCard\n t={t}\n titleKey='settings.title'\n descriptionKey='settings.description'\n version={version}\n state={state}\n onSave={props.save}\n onDiscard={props.discard}\n >\n <SwitchField\n label={t('settings.enabled')}\n hint={t('settings.enabledHint')}\n {...fieldProps}\n {...state.enabled}\n onEdit={(text) => { props.edit('enabled', text) }}\n onReset={() => { props.resetField('enabled') }}\n />\n <SwitchField\n label={t('settings.announceToAgent')}\n hint={t('settings.announceToAgentHint')}\n {...fieldProps}\n {...state.announceToAgent}\n onEdit={(text) => { props.edit('announceToAgent', text) }}\n onReset={() => { props.resetField('announceToAgent') }}\n />\n <ColorField\n id='skill-hub-dot-model-color'\n label={t('settings.dotModelColor')}\n hint={t('settings.dotModelColorHint')}\n inheritLabel={t('settings.inherit')}\n defaultColor={DEFAULT_DOT_MODEL_COLOR}\n {...fieldProps}\n {...state.dotModelColor}\n onEdit={(text) => { props.edit('dotModelColor', text) }}\n onReset={() => { props.resetField('dotModelColor') }}\n />\n <ColorField\n id='skill-hub-dot-user-color'\n label={t('settings.dotUserColor')}\n hint={t('settings.dotUserColorHint')}\n inheritLabel={t('settings.inherit')}\n defaultColor={DEFAULT_DOT_USER_COLOR}\n {...fieldProps}\n {...state.dotUserColor}\n onEdit={(text) => { props.edit('dotUserColor', text) }}\n onReset={() => { props.resetField('dotUserColor') }}\n />\n <SwitchField\n label={t('settings.showUseCount')}\n hint={t('settings.showUseCountHint')}\n {...fieldProps}\n {...state.showUseCount}\n onEdit={(text) => { props.edit('showUseCount', text) }}\n onReset={() => { props.resetField('showUseCount') }}\n />\n <SwitchField\n label={t('settings.showUseTime')}\n hint={t('settings.showUseTimeHint')}\n {...fieldProps}\n {...state.showUseTime}\n onEdit={(text) => { props.edit('showUseTime', text) }}\n onReset={() => { props.resetField('showUseTime') }}\n />\n <SwitchField\n label={t('settings.showGroupSummary')}\n hint={t('settings.showGroupSummaryHint')}\n {...fieldProps}\n {...state.showGroupSummary}\n onEdit={(text) => { props.edit('showGroupSummary', text) }}\n onReset={() => { props.resetField('showGroupSummary') }}\n />\n <NumberField\n id='skill-hub-stats-window-days'\n label={t('settings.statsWindowDays')}\n hint={t('settings.statsWindowDaysHint')}\n inheritLabel={t('settings.inherit')}\n {...fieldProps}\n text={state.statsWindowDays.text}\n overridden={state.statsWindowDays.overridden}\n invalid={state.statsWindowDays.invalid}\n onEdit={(text) => { props.edit('statsWindowDays', text) }}\n onReset={() => { props.resetField('statsWindowDays') }}\n />\n <NumberField\n id='skill-hub-stats-scan-minutes'\n label={t('settings.statsScanMinutes')}\n hint={t('settings.statsScanMinutesHint')}\n inheritLabel={t('settings.inherit')}\n {...fieldProps}\n text={state.statsScanMinutes.text}\n overridden={state.statsScanMinutes.overridden}\n invalid={state.statsScanMinutes.invalid}\n onEdit={(text) => { props.edit('statsScanMinutes', text) }}\n onReset={() => { props.resetField('statsScanMinutes') }}\n />\n </PluginSettingsCard>\n )\n}\n","/**\n * Source check-status badges (up-to-date / updated / deleted / error /\n * throttled / unverified). Shared by the panel's source-group headers and\n * the skill detail view.\n *\n * In the group headers the badge doubles as the re-check affordance: it\n * shows a clickable \"检查更新\" badge before the first check, \"检查中…\" while\n * checking, and the status badge (clickable again to re-check) afterwards.\n */\n\nimport type { JSX } from 'react'\nimport type { SourceCheckResult } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\n\nexport function SourceStatusBadge(props: {\n check: SourceCheckResult | undefined\n /** 正在检查该来源(显示「检查中…」)。 */\n checking?: boolean\n /** 提供后徽章区域可点击触发检查(组头用;详情页有自己的检查按钮)。 */\n onCheck?: () => void\n}): JSX.Element | null {\n const { check, checking, onCheck } = props\n if (checking === true) {\n return <span className={css.statusBadge}>{tt('source.checking')}</span>\n }\n if (check === undefined) {\n if (onCheck === undefined) return null\n return (\n <button type='button' className={css.statusBadge + ' ' + css.statusButton} title={tt('source.checkHint')} onClick={onCheck}>\n {tt('source.check')}\n </button>\n )\n }\n const badges = ((): JSX.Element | null => {\n if (check.error !== undefined) {\n return <span className={css.statusBadge + ' ' + css.statusError}>{tt('source.error')}</span>\n }\n if (check.throttled === true) {\n return <span className={css.statusBadge}>{tt('source.throttled')}</span>\n }\n if (check.unverified === true) {\n return <span className={css.statusBadge}>{tt('source.unverified')}</span>\n }\n if (check.changed) {\n return (\n <span className={css.statusBadges}>\n {check.updated.length > 0 ? <span className={css.statusBadge + ' ' + css.statusUpdated}>{tt('source.updated', { count: check.updated.length })}</span> : null}\n {check.deleted.length > 0 ? <span className={css.statusBadge + ' ' + css.statusError}>{tt('source.deleted', { count: check.deleted.length })}</span> : null}\n </span>\n )\n }\n return <span className={css.statusBadge + ' ' + css.statusOk}>{tt('source.upToDate')}</span>\n })()\n if (onCheck === undefined) return badges\n return (\n <button type='button' className={css.statusWrap} title={tt('source.checkHint')} onClick={onCheck}>\n {badges}\n </button>\n )\n}\n","/**\n * Full-page skill detail view: metadata, upstream source card with\n * check/sync/follow-delete actions, and the raw SKILL.md body. Pure\n * presentation — every state value and action arrives as a prop, so the\n * panel stays the single owner of state.\n */\n\nimport type { JSX } from 'react'\nimport type { GroupsResponse, HubConfig, SkillDetail, SourceCheckResult, SourcesResponse } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\nimport { dotStyle, formatDateTime, shortSha } from './format.ts'\nimport { SourceStatusBadge } from './SourceStatusBadge.tsx'\n\nexport interface SkillDetailViewProps {\n detail: SkillDetail\n hubConfig: HubConfig | null\n /** skillName → usage stat (count + last used). */\n uses: ReadonlyMap<string, { count: number; lastUsed?: number }>\n groupsState: GroupsResponse | null\n sourcesState: SourcesResponse | null\n sourceCheck: Readonly<Record<string, SourceCheckResult>>\n checkingSource: string | null\n syncingSource: string | null\n loading: boolean\n onBack: () => void\n /** Check one source repo for upstream updates. */\n onCheck: (repo: string) => void\n /** Request syncing the skill (overwrites local edits; opens a confirm). */\n onSync: (repo: string, skills: string[]) => void\n /** Request following the upstream deletion (moves into the trash). */\n onFollowDelete: (repo: string, skills: string[]) => void\n}\n\nexport function SkillDetailView(props: SkillDetailViewProps): JSX.Element {\n const { detail, hubConfig, uses, groupsState, sourcesState, sourceCheck, checkingSource, syncingSource, loading, onBack, onCheck, onSync, onFollowDelete } = props\n const detailSource = sourcesState?.sources.find((source) => source.skills.includes(detail.name))\n const detailCheck = detailSource !== undefined ? sourceCheck[detailSource.repo] : undefined\n return (\n <div className={css.panel}>\n <div className={css.detailHead}>\n <button type='button' className={css.back} onClick={onBack}>{tt('detail.back')}</button>\n <span className={css.detailName}>\n {detail.name}\n {/* 单一状态圆点:模型可调 → 蓝;否则用户可调 → 绿。与聊天 / 菜单同规则。 */}\n {detail.invocation.modelInvocable\n ? <span className={css.dot + ' ' + css.dotModel} style={dotStyle(hubConfig?.dotModelColor)} title={tt('legend.model')} />\n : detail.invocation.userInvocable\n ? <span className={css.dot + ' ' + css.dotUser} style={dotStyle(hubConfig?.dotUserColor)} title={tt('legend.user')} />\n : null}\n </span>\n </div>\n <div className={css.detailMeta}>\n <div className={css.detailMetaLine}>{tt('detail.provider')}: {detail.provider}</div>\n {detail.addedAt !== undefined ? <div className={css.detailMetaLine}>{tt('detail.addedAt')}: {formatDateTime(detail.addedAt)}</div> : null}\n {detail.updatedAt !== undefined ? <div className={css.detailMetaLine}>{tt('detail.updatedAt')}: {formatDateTime(detail.updatedAt)}</div> : null}\n {detail.path !== undefined ? <div className={css.detailMetaLine}>{tt('detail.path')}: {detail.path}</div> : null}\n {detail.whenToUse !== undefined ? <div className={css.detailMetaLine}>{tt('detail.whenToUse')}: {detail.whenToUse}</div> : null}\n {(() => {\n const stat = uses.get(detail.name)\n if (stat === undefined || stat.count === 0) return null\n const at = stat.lastUsed !== undefined ? ' · ' + new Date(stat.lastUsed).toLocaleString() : ''\n return <div className={css.detailMetaLine}>{tt('detail.uses')}: {stat.count}{at}</div>\n })()}\n {(() => {\n const tags = (groupsState?.tags ?? []).filter((tag) => tag.skillNames.includes(detail.name)).map((tag) => tag.name)\n return tags.length > 0 ? <div className={css.detailMetaLine}>{tt('detail.groups')}: {tags.join(', ')}</div> : null\n })()}\n </div>\n {detailSource !== undefined ? (\n <div className={css.sourceCard}>\n <div className={css.sourceCardTitle}>\n <a className={css.sourceLink} href={'https://github.com/' + detailSource.repo} target='_blank' rel='noreferrer'>{detailSource.repo}</a>\n {detailSource.ref !== undefined ? <span className={css.badge + ' ' + css.badgeSource}>{detailSource.ref}</span> : null}\n <SourceStatusBadge check={detailCheck} />\n </div>\n <div className={css.detailMetaLine}>\n {tt('source.commit')}: {detailSource.commitSha === '' ? tt('source.unverified') : shortSha(detailSource.commitSha)}\n </div>\n <div className={css.buttons + ' ' + css.actionsTop}>\n <button type='button' className={css.opBtn} disabled={checkingSource !== null} onClick={() => { onCheck(detailSource.repo) }}>\n {checkingSource === detailSource.repo ? tt('source.checking') : tt('source.check')}\n </button>\n <button type='button' className={css.opBtn} disabled={syncingSource !== null} onClick={() => { onSync(detailSource.repo, [detail.name]) }}>\n {syncingSource === detailSource.repo ? tt('source.syncing') : tt('source.sync')}\n </button>\n {detailCheck?.deleted.includes(detail.name) === true\n ? <button type='button' className={css.opBtn + ' ' + css.opDanger} onClick={() => { onFollowDelete(detailSource.repo, [detail.name]) }}>{tt('source.followDelete')}</button>\n : null}\n </div>\n </div>\n ) : (\n <p className={css.hintLine}>{tt('source.private')}</p>\n )}\n {loading ? <div className={css.muted}>{tt('detail.loading')}</div> : null}\n <pre className={css.detailContent}>{detail.content}</pre>\n </div>\n )\n}\n","/**\n * Full-page tag (scene) editor: rename / delete header, member checkbox\n * lists (enabled + disabled skills), and the save-members action. Pure\n * presentation — the draft state lives in the panel and arrives as props.\n */\n\nimport type { JSX } from 'react'\nimport type { CatalogResponse, SkillTag } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\n\nexport interface TagEditorViewProps {\n tag: SkillTag\n /** Current name draft (panel-owned). */\n editName: string\n /** Current member-checkbox draft (panel-owned). */\n membersDraft: ReadonlySet<string>\n /** Current member-list search text (panel-owned). */\n editSearch: string\n catalog: CatalogResponse | null\n tagBusy: boolean\n onBack: () => void\n onEditName: (value: string) => void\n onEditSearch: (value: string) => void\n onToggleMember: (name: string, checked: boolean) => void\n /** Rename with the current draft (disabled while blank). */\n onRename: () => void\n /** Delete this tag (hidden for the default scene). */\n onDelete: () => void\n /** Persist the current member draft and leave the editor. */\n onSaveMembers: () => void\n}\n\nexport function TagEditorView(props: TagEditorViewProps): JSX.Element {\n const { tag, editName, membersDraft, editSearch, catalog, tagBusy, onBack, onEditName, onEditSearch, onToggleMember, onRename, onDelete, onSaveMembers } = props\n const editQuery = editSearch.trim().toLocaleLowerCase()\n const editSkills = (catalog?.skills ?? []).filter((skill) => editQuery.length === 0 || skill.name.toLocaleLowerCase().includes(editQuery) || skill.description.toLocaleLowerCase().includes(editQuery))\n const editDisabled = (catalog?.disabled ?? []).filter((record) => editQuery.length === 0 || record.name.toLocaleLowerCase().includes(editQuery) || record.description.toLocaleLowerCase().includes(editQuery))\n return (\n <div className={css.panel}>\n <div className={css.detailHead}>\n <button type='button' className={css.back} onClick={onBack}>{tt('detail.back')}</button>\n <input\n className={css.input + ' ' + css.grow}\n value={editName}\n onChange={(event) => { onEditName(event.target.value) }}\n placeholder={tt('groups.namePlaceholder')}\n />\n <button type='button' className={css.opBtn} disabled={tagBusy || editName.trim() === ''} onClick={onRename}>{tt('groups.rename')}</button>\n {tag.default !== true\n ? <button type='button' className={css.opBtn} disabled={tagBusy} onClick={onDelete}>{tt('groups.delete')}</button>\n : null}\n </div>\n <p className={css.hintLine}>{tt('groups.membersHint')}</p>\n <input className={css.search} value={editSearch} onChange={(event) => { onEditSearch(event.target.value) }} placeholder={tt('panel.search')} />\n <div className={css.section}>\n {editSkills.map((skill) => (\n <label key={skill.name} className={css.row}>\n <input\n type='checkbox'\n checked={membersDraft.has(skill.name)}\n onChange={(event) => { onToggleMember(skill.name, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{skill.name}</div>\n <div className={css.rowDesc}>{skill.description}</div>\n </div>\n </label>\n ))}\n {editDisabled.map((record) => (\n <label key={record.name} className={css.row}>\n <input\n type='checkbox'\n checked={membersDraft.has(record.name)}\n onChange={(event) => { onToggleMember(record.name, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{record.name}</div>\n <div className={css.rowDesc}>{record.description} · {tt('panel.disabled')}</div>\n </div>\n </label>\n ))}\n </div>\n <div className={css.buttons}>\n <button type='button' className={css.button + ' ' + css.primary} disabled={tagBusy} onClick={onSaveMembers}>{tt('groups.saveMembers')}</button>\n </div>\n </div>\n )\n}\n","/**\n * One enabled skill row: name + invocation dots + usage meta, delete and\n * disable actions. Shared by the flat list and both grouped views.\n */\n\nimport type { JSX, KeyboardEvent } from 'react'\nimport type { CatalogSkill } from '../../protocol.ts'\nimport { IconTrashOutline16 } from '../icons.tsx'\nimport { tt } from '../helpers.ts'\nimport { dotStyle, relativeTimeText } from './format.ts'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function SkillRow(props: { skill: CatalogSkill; hub: SkillHubState }): JSX.Element {\n const { skill, hub } = props\n const stat = hub.uses.get(skill.name)\n const count = stat?.count ?? 0\n const lastUsed = stat?.lastUsed\n /** 单一状态圆点:模型可调 → 蓝;否则用户可调 → 绿。与聊天 / 菜单同规则。 */\n const dot = skill.invocation.modelInvocable\n ? <span className={css.dot + ' ' + css.dotModel} style={dotStyle(hub.hubConfig?.dotModelColor)} title={tt('legend.model')} />\n : skill.invocation.userInvocable\n ? <span className={css.dot + ' ' + css.dotUser} style={dotStyle(hub.hubConfig?.dotUserColor)} title={tt('legend.user')} />\n : null\n /** 键盘打开详情:Enter 或空格。仅当焦点在行本身(而非行内按钮)时生效。 */\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {\n if (event.target !== event.currentTarget) return\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n void hub.openDetail(skill.name)\n }\n }\n return (\n <div\n className={css.row}\n role='button'\n tabIndex={0}\n aria-label={tt('row.open', { name: skill.name })}\n onClick={() => { void hub.openDetail(skill.name) }}\n onKeyDown={onKeyDown}\n >\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <span className={css.rowNameText}>{skill.name}</span>\n {count > 0 && hub.hubConfig?.showUseCount !== false ? <span className={css.useCount}>{count}</span> : null}\n {dot}\n {lastUsed !== undefined && hub.hubConfig?.showUseTime !== false ? <span className={css.useTime}>{relativeTimeText(lastUsed)}</span> : null}\n </div>\n <div className={css.rowDesc}>{skill.description}</div>\n </div>\n {skill.writable\n ? <>\n <button\n type='button'\n role='switch'\n aria-checked={true}\n aria-label={tt('row.disable')}\n className={css.switch + ' ' + css.switchOn}\n disabled={hub.busyNames.has(skill.name)}\n onClick={(event) => { event.stopPropagation(); void hub.toggle(skill, false) }}\n ><span className={css.switchThumb} /></button>\n {hub.editMode ? <button\n type='button'\n className={css.opBtn + ' ' + css.opDanger + ' ' + css.iconBtn}\n disabled={hub.busyNames.has(skill.name) || hub.tagBusy}\n title={tt('row.delete')}\n aria-label={tt('row.delete')}\n onClick={(event) => { event.stopPropagation(); hub.requestDeleteSkill(skill.name) }}\n ><IconTrashOutline16 size={14} /></button> : null}\n </>\n : <span className={css.badge + ' ' + css.badgeReadonly}>{tt('row.readonly')}</span>}\n </div>\n )\n}\n","/**\n * One disabled skill row (name + description + root badge + enable switch).\n * Shared by the source-group lists, the scene-group lists, and the bottom\n * disabled section.\n */\n\nimport type { JSX } from 'react'\nimport type { DisabledSkill, WritableRoot } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport type { HubKey } from '../locales.ts'\nimport css from './panel.module.css'\n\n/** Source badge label for a disabled record, derived from its writable root. */\nfunction disabledSourceLabel(root: WritableRoot): string {\n return tt(('badge.source.' + root) as HubKey)\n}\n\nexport function DisabledRow(props: { record: DisabledSkill; busy: boolean; onEnable: () => void }): JSX.Element {\n const { record, busy, onEnable } = props\n return (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>{record.name}</div>\n <div className={css.rowDesc}>{record.description}</div>\n </div>\n <span className={css.badges}>\n <span className={css.badge + ' ' + css.badgeSource}>{disabledSourceLabel(record.root)}</span>\n </span>\n <button type='button' role='switch' aria-checked={false} aria-label={tt('row.enable')} className={css.switch} disabled={busy} onClick={onEnable}><span className={css.switchThumb} /></button>\n </div>\n )\n}\n","/**\n * Group-header usage summary: total invocation count chip + the group's most\n * recent last-used time. Honours the showGroupSummary config switch.\n */\n\nimport type { JSX } from 'react'\nimport { relativeTimeText } from './format.ts'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function GroupSummary(props: { members: readonly string[]; hub: SkillHubState }): JSX.Element {\n const { members, hub } = props\n let total = 0\n let latest: number | undefined\n for (const name of members) {\n const stat = hub.uses.get(name)\n if (stat === undefined) continue\n total += stat.count\n if (stat.lastUsed !== undefined && (latest === undefined || stat.lastUsed > latest)) latest = stat.lastUsed\n }\n return (\n <span className={css.groupTitleInner}>\n {hub.hubConfig?.showGroupSummary !== false && total > 0 ? <span className={css.useCount}>{total}</span> : null}\n {hub.hubConfig?.showGroupSummary !== false && latest !== undefined ? <span className={css.useTime + ' ' + css.groupTime}>{relativeTimeText(latest)}</span> : null}\n </span>\n )\n}\n","/**\n * Sources tab: the flat skill list or the grouped view — a project-level\n * three-tier tree (workspaces from workspace.json, each optionally split by\n * .dsh/.agents), one card per upstream collection with check/sync/\n * follow-delete actions and the tri-state switch, plus the uncategorized\n * \"personal\" card (project skills never count as personal).\n */\n\nimport { useState, type JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { filterBySource, groupSwitchView, isProjectSource, PRIVATE_SOURCE } from '../grouping.ts'\nimport { SourceStatusBadge } from './SourceStatusBadge.tsx'\nimport { SkillRow } from './SkillRow.tsx'\nimport { DisabledRow } from './DisabledRow.tsx'\nimport { GroupSummary } from './GroupSummary.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\n/** 项目级三级树:项目级 → 具体工作区(可折叠、可细分)→ .dsh/.agents。 */\nfunction ProjectTree(props: { hub: SkillHubState }): JSX.Element | null {\n const { hub } = props\n const { sorted, sourceFilter, origins, collapsedGroups, subdividedProjects, toggleGroupCollapse, toggleSubdivide } = hub\n const projectSkills = filterBySource(sorted, sourceFilter, origins).filter((skill) => isProjectSource(skill.source))\n if (projectSkills.length === 0) return null\n // workspace 缺失(过渡态)时按 source 降级分组,避免空标题。\n const byProject = new Map<string, { title: string; skills: typeof projectSkills }>()\n for (const skill of projectSkills) {\n const key = skill.workspace ?? skill.source\n const entry = byProject.get(key)\n if (entry === undefined) {\n byProject.set(key, {\n title: skill.workspaceTitle ?? skill.workspace ?? tt('groups.project'),\n skills: [skill],\n })\n } else {\n entry.skills.push(skill)\n }\n }\n const topCollapsed = collapsedGroups.has('project')\n return (\n <section className={css.section}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!topCollapsed} onClick={() => { toggleGroupCollapse('project') }}>\n <span className={css.chevron + (topCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tt('groups.project')} · {byProject.size}\n </span>\n </button>\n </div>\n {!topCollapsed ? [...byProject.entries()].map(([key, proj]) => {\n const projKey = 'project:' + key\n const projCollapsed = collapsedGroups.has(projKey)\n const subdivided = subdividedProjects.has(key)\n return (\n <div key={projKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!projCollapsed} onClick={() => { toggleGroupCollapse(projKey) }}>\n <span className={css.chevron + (projCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {proj.title} · {proj.skills.length}\n <GroupSummary members={proj.skills.map((skill) => skill.name)} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <button type='button' className={css.opBtn} onClick={(event) => { event.stopPropagation(); toggleSubdivide(key) }}>\n {subdivided ? tt('groups.merge') : tt('groups.subdivide')}\n </button>\n </span>\n </div>\n {!projCollapsed ? (\n subdivided ? (\n <div className={css.projectNest}>\n {(['project-dsh', 'project-agents'] as const).map((source) => {\n const list = proj.skills.filter((skill) => skill.source === source)\n if (list.length === 0) return null\n const srcKey = projKey + ':' + source\n const srcCollapsed = collapsedGroups.has(srcKey)\n return (\n <div key={srcKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!srcCollapsed} onClick={() => { toggleGroupCollapse(srcKey) }}>\n <span className={css.chevron + (srcCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tt(('badge.source.' + source) as 'badge.source.project-dsh' | 'badge.source.project-agents')} · {list.length}\n </span>\n </button>\n </div>\n {!srcCollapsed ? list.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />) : null}\n </div>\n )\n })}\n </div>\n ) : proj.skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)\n ) : null}\n </div>\n )\n }) : null}\n </section>\n )\n}\n\nexport function SourcesView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { catalog, groupsState, skillView, sourceFilter, origins, sorted, normalized, collapsedGroups, viewNames, sourceCheck, actionNames, checkingSource, syncingSource, batchBusy, busyNames, toggleGroupCollapse, checkSources, requestSync, requestDelete, requestDeleteGroup, toggleGroup, enableDisabled } = hub\n const [topDragKey, setTopDragKey] = useState<string | null>(null)\n const [topOverKey, setTopOverKey] = useState<string | null>(null)\n\n if (skillView === 'flat') {\n return <>{filterBySource(sorted, sourceFilter, origins).map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}</>\n }\n\n // ----- 顶层分组统一拖拽(project / col:xxx / personal 全部可拖) -----\n const projectSkillsAll = filterBySource(sorted, sourceFilter, origins).filter((skill) => isProjectSource(skill.source))\n const hasProject = projectSkillsAll.length > 0\n const collections = groupsState?.collections ?? []\n const uncategorized = filterBySource(sorted, sourceFilter, origins).filter((skill) => origins[skill.name] === undefined && !isProjectSource(skill.source))\n const personalDisabledAll = (catalog?.disabled ?? []).filter((record) => origins[record.name] === undefined)\n .filter((record) => normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized))\n .filter((record) => sourceFilter === 'all' || sourceFilter === PRIVATE_SOURCE)\n const allPersonalNamesAll = [...uncategorized.map((s) => s.name), ...personalDisabledAll.map((r) => r.name)]\n const hasPersonal = allPersonalNamesAll.length > 0\n const defaultTopKeys: string[] = [\n ...(hasProject ? ['project'] : []),\n ...collections.map((c) => 'col:' + c.name),\n ...(hasPersonal ? ['uncategorized-source'] : []),\n ]\n const storedTopOrder = groupsState?.sourceGroupOrder ?? []\n const topOrderedKeys = (() => {\n if (storedTopOrder.length === 0) return defaultTopKeys\n const set = new Set(storedTopOrder)\n const result = storedTopOrder.filter((k) => defaultTopKeys.includes(k))\n for (const k of defaultTopKeys) if (!set.has(k)) result.push(k)\n // 兼容旧 collectionOrder:若 storedTopOrder 为空但旧 order 有值,已在 defaultTopKeys 中体现 collection 顺序\n if (result.length === 0) return defaultTopKeys\n return result\n })()\n const handleTopDrop = (targetKey: string): void => {\n if (topDragKey === null || topDragKey === targetKey) return\n const from = topOrderedKeys.indexOf(topDragKey)\n const to = topOrderedKeys.indexOf(targetKey)\n if (from === -1 || to === -1) return\n const next = [...topOrderedKeys]\n const [moved] = next.splice(from, 1)\n next.splice(to, 0, moved)\n void hub.reorderSourceGroups(next)\n }\n // 兼容旧逻辑:若用户拖的是 collection 且未使用顶层排序,回退到 collectionReorder(保留旧数据兼容)\n const handleCollectionDropLegacy = (targetName: string): void => {\n // 仅当顶层排序未启用时(storedTopOrder 为空)才用旧接口\n if ((groupsState?.sourceGroupOrder?.length ?? 0) > 0) { handleTopDrop('col:' + targetName); return }\n const dragCol = topDragKey !== null && topDragKey.startsWith('col:') ? topDragKey.slice(4) : null\n if (dragCol === null || dragCol === targetName || groupsState === null) return\n const names = groupsState.collections.map((c) => c.name)\n const from = names.indexOf(dragCol)\n const to = names.indexOf(targetName)\n if (from === -1 || to === -1) return\n const next = [...names]\n const [moved] = next.splice(from, 1)\n next.splice(to, 0, moved)\n void hub.reorderCollections(next)\n }\n\n // 空状态:没有任何分组时提示\n const isEmptyTop = !hasProject && collections.length === 0 && !hasPersonal\n return (\n <>\n {isEmptyTop ? <div className={css.empty}>{tt('groups.noCollections')}</div> : null}\n {topOrderedKeys.map((topKey) => {\n // Project 顶层卡片(可拖)\n if (topKey === 'project' && hasProject) {\n const topCollapsed = collapsedGroups.has('project')\n const isDragging = topDragKey === 'project'\n const isOver = topOverKey === 'project' && topDragKey !== 'project'\n // 按 workspace 聚合,与 ProjectTree 逻辑一致\n const byProject = new Map<string, { title: string; skills: typeof projectSkillsAll }>()\n for (const skill of projectSkillsAll) {\n const key = skill.workspace ?? skill.source\n const entry = byProject.get(key)\n if (entry === undefined) byProject.set(key, { title: skill.workspaceTitle ?? skill.workspace ?? tt('groups.project'), skills: [skill] })\n else entry.skills.push(skill)\n }\n return (\n <section\n key=\"project\"\n className={css.section + (isDragging ? ' ' + css.dragging : '') + (isOver ? ' ' + css.dragOver : '')}\n draggable\n onDragStart={(e) => { setTopDragKey('project'); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', 'project') }}\n onDragOver={(e) => { e.preventDefault(); if (topOverKey !== 'project') setTopOverKey('project') }}\n onDragLeave={() => { if (topOverKey === 'project') setTopOverKey(null) }}\n onDrop={(e) => { e.preventDefault(); handleTopDrop('project'); setTopOverKey(null) }}\n onDragEnd={() => { setTopDragKey(null); setTopOverKey(null) }}\n >\n <div className={css.groupHead}>\n <span className={css.dragHandle} aria-hidden title=\"拖拽调整顺序\">⋮⋮</span>\n <button type='button' className={css.disclosure} aria-expanded={!topCollapsed} onClick={() => { toggleGroupCollapse('project') }}>\n <span className={css.chevron + (topCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>{tt('groups.project')} · {byProject.size}</span>\n </button>\n </div>\n {!topCollapsed ? [...byProject.entries()].map(([key, proj]) => {\n const projKey = 'project:' + key\n const projCollapsed = collapsedGroups.has(projKey)\n const subdivided = hub.subdividedProjects.has(key)\n return (\n <div key={projKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!projCollapsed} onClick={() => { toggleGroupCollapse(projKey) }}>\n <span className={css.chevron + (projCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>{proj.title} · {proj.skills.length}<GroupSummary members={proj.skills.map((s) => s.name)} hub={hub} /></span>\n </button>\n <span className={css.groupOps}>\n <button type='button' className={css.opBtn} onClick={(event) => { event.stopPropagation(); hub.toggleSubdivide(key) }}>{subdivided ? tt('groups.merge') : tt('groups.subdivide')}</button>\n </span>\n </div>\n {!projCollapsed ? (\n subdivided ? (\n <div className={css.projectNest}>\n {(['project-dsh', 'project-agents'] as const).map((source) => {\n const list = proj.skills.filter((skill) => skill.source === source)\n if (list.length === 0) return null\n const srcKey = projKey + ':' + source\n const srcCollapsed = collapsedGroups.has(srcKey)\n return (\n <div key={srcKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!srcCollapsed} onClick={() => { toggleGroupCollapse(srcKey) }}>\n <span className={css.chevron + (srcCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>{tt(('badge.source.' + source) as 'badge.source.project-dsh' | 'badge.source.project-agents')} · {list.length}</span>\n </button>\n </div>\n {!srcCollapsed ? list.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />) : null}\n </div>\n )\n })}\n </div>\n ) : proj.skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)\n ) : null}\n </div>\n )\n }) : null}\n </section>\n )\n }\n // Collection 卡片(可拖,归属顶层排序)\n if (topKey.startsWith('col:')) {\n const colName = topKey.slice(4)\n const collection = collections.find((c) => c.name === colName)\n if (collection === undefined) return null\n const skills = filterBySource(sorted, sourceFilter, origins).filter((skill) => collection.skillNames.includes(skill.name))\n const disabledMembers = (catalog?.disabled ?? []).filter((record) =>\n collection.skillNames.includes(record.name)\n && (normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized))\n && (sourceFilter === 'all' || (origins[record.name] ?? PRIVATE_SOURCE) === sourceFilter))\n const collapsed = collapsedGroups.has('col:' + collection.name)\n const view = groupSwitchView(collection.skillNames, viewNames)\n const check = sourceCheck[collection.name]\n const hasWritable = collection.skillNames.some((name) => actionNames.has(name))\n const isDragging = topDragKey === topKey\n const isOver = topOverKey === topKey && topDragKey !== topKey\n return (\n <section\n key={'col:' + collection.name}\n className={css.section + (isDragging ? ' ' + css.dragging : '') + (isOver ? ' ' + css.dragOver : '')}\n draggable\n onDragStart={(e) => { setTopDragKey(topKey); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', topKey) }}\n onDragOver={(e) => { e.preventDefault(); if (topOverKey !== topKey) setTopOverKey(topKey) }}\n onDragLeave={() => { if (topOverKey === topKey) setTopOverKey(null) }}\n onDrop={(e) => { e.preventDefault(); handleTopDrop(topKey); setTopOverKey(null) }}\n onDragEnd={() => { setTopDragKey(null); setTopOverKey(null) }}\n >\n <div className={css.groupHead}>\n <span className={css.dragHandle} aria-hidden title=\"拖拽调整顺序\">⋮⋮</span>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('col:' + collection.name) }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n <a className={css.sourceLink} href={'https://github.com/' + collection.name} target='_blank' rel='noreferrer' onClick={(event) => { event.stopPropagation() }}>{collection.name}</a>\n {' · ' + collection.skillNames.length}\n <GroupSummary members={collection.skillNames} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <SourceStatusBadge\n check={check}\n checking={checkingSource === collection.name}\n onCheck={() => { void checkSources(collection.name) }}\n />\n {check !== undefined && check.changed && check.updated.length > 0\n ? <button type='button' className={css.opBtn} disabled={syncingSource !== null} onClick={(event) => { event.stopPropagation(); requestSync(collection.name, check.updated) }}>\n {syncingSource === collection.name ? tt('source.syncing') : tt('source.sync')}\n </button>\n : null}\n {check !== undefined && check.deleted.length > 0\n ? <button type='button' className={css.opBtn + ' ' + css.opDanger} onClick={(event) => { event.stopPropagation(); requestDelete(collection.name, check.deleted) }}>{tt('source.followDelete')}</button>\n : null}\n <button type='button' role='switch' aria-checked={view.state !== 'off'} aria-label={collection.name}\n className={css.switch + (view.state === 'on' ? ' ' + css.switchOn : view.state === 'mixed' ? ' ' + css.switchMixed : '')}\n disabled={batchBusy || collection.skillNames.length === 0 || (view.state !== 'off' && !hasWritable)}\n title={view.state !== 'off' && !hasWritable ? tt('groups.noWritable') : undefined}\n onClick={(event) => { event.stopPropagation(); toggleGroup('col:' + collection.name, collection.name, view.state) }}>\n <span className={css.switchThumb} />\n </button>\n {hub.editMode ? <button\n type='button'\n className={css.opBtn + ' ' + css.opDanger}\n title={tt('source.deleteGroupHint', { count: collection.skillNames.length })}\n onClick={(event) => { event.stopPropagation(); requestDeleteGroup(collection.name, collection.skillNames) }}\n >\n {tt('source.deleteGroup')}\n </button> : null}\n </span>\n </div>\n {!collapsed ? (\n <>\n {skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}\n {disabledMembers.map((record) => (\n <DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />\n ))}\n </>\n ) : null}\n </section>\n )\n }\n // Personal 顶层卡片(可拖)\n if (topKey === 'uncategorized-source' && hasPersonal) {\n const uncategorized = filterBySource(sorted, sourceFilter, origins).filter((skill) => origins[skill.name] === undefined && !isProjectSource(skill.source))\n const personalDisabled = (catalog?.disabled ?? []).filter((record) => origins[record.name] === undefined)\n .filter((record) => normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized))\n .filter((record) => sourceFilter === 'all' || sourceFilter === PRIVATE_SOURCE)\n const allPersonalNames = [...uncategorized.map((s) => s.name), ...personalDisabled.map((r) => r.name)]\n if (allPersonalNames.length === 0) return null\n const collapsed = collapsedGroups.has('uncategorized-source')\n const isDragging = topDragKey === 'uncategorized-source'\n const isOver = topOverKey === 'uncategorized-source' && topDragKey !== 'uncategorized-source'\n return (\n <section\n key=\"uncategorized-source\"\n className={css.section + (isDragging ? ' ' + css.dragging : '') + (isOver ? ' ' + css.dragOver : '')}\n draggable\n onDragStart={(e) => { setTopDragKey('uncategorized-source'); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', 'uncategorized-source') }}\n onDragOver={(e) => { e.preventDefault(); if (topOverKey !== 'uncategorized-source') setTopOverKey('uncategorized-source') }}\n onDragLeave={() => { if (topOverKey === 'uncategorized-source') setTopOverKey(null) }}\n onDrop={(e) => { e.preventDefault(); handleTopDrop('uncategorized-source'); setTopOverKey(null) }}\n onDragEnd={() => { setTopDragKey(null); setTopOverKey(null) }}\n >\n <div className={css.groupHead}>\n <span className={css.dragHandle} aria-hidden title=\"拖拽调整顺序\">⋮⋮</span>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('uncategorized-source') }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>{tt('groups.personal')} · {allPersonalNames.length}<GroupSummary members={allPersonalNames} hub={hub} /></span>\n </button>\n <span className={css.groupOps}>\n {hub.editMode ? <button type='button' className={css.opBtn + ' ' + css.opDanger} title={tt('source.deleteGroupHint', { count: allPersonalNames.length })} onClick={(event) => { event.stopPropagation(); requestDeleteGroup(tt('groups.personal'), allPersonalNames) }}>{tt('source.deleteGroup')}</button> : null}\n </span>\n </div>\n {!collapsed ? (\n <>\n {uncategorized.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}\n {personalDisabled.map((record) => (<DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />))}\n </>\n ) : null}\n </section>\n )\n }\n return null\n })}\n </>\n )\n}\n","/**\n * Scenes tab: user tag groups (one card per scene with the tri-state switch\n * and edit entry) plus the new-scene form. Scenes are the user's own\n * enable/disable units (e.g. a Godot scene vs a Java scene); upstream repos\n * are managed in the sources tab.\n */\n\nimport { useState, type JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { groupSwitchView } from '../grouping.ts'\nimport { SkillRow } from './SkillRow.tsx'\nimport { DisabledRow } from './DisabledRow.tsx'\nimport { GroupSummary } from './GroupSummary.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function ScenesView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { catalog, groupsState, sorted, normalized, collapsedGroups, viewNames, actionNames, batchBusy, busyNames, newTagName, setNewTagName, tagBusy, createTag, toggleGroupCollapse, toggleGroup, setEditingTag, setEditName, setMembersDraft, setEditSearch, enableDisabled } = hub\n const [dragId, setDragId] = useState<string | null>(null)\n const [overId, setOverId] = useState<string | null>(null)\n const handleDrop = (targetId: string): void => {\n if (dragId === null || dragId === targetId || groupsState === null) return\n const ids = groupsState.tags.map((t) => t.id)\n const from = ids.indexOf(dragId)\n const to = ids.indexOf(targetId)\n if (from === -1 || to === -1) return\n const next = [...ids]\n const [moved] = next.splice(from, 1)\n next.splice(to, 0, moved)\n void hub.reorderTags(next)\n }\n return (\n <>\n <form className={css.form} onSubmit={(event) => { void createTag(event) }}>\n <div className={css.buttons}>\n <input\n className={css.input + ' ' + css.grow}\n value={newTagName}\n onChange={(event) => { setNewTagName(event.target.value) }}\n placeholder={tt('groups.namePlaceholder')}\n />\n <button type='submit' className={css.button + ' ' + css.primary} disabled={tagBusy || newTagName.trim() === ''}>{tt('groups.new')}</button>\n </div>\n </form>\n\n {groupsState !== null && groupsState.tags.length === 0 ? <div className={css.empty}>{tt('groups.empty')}</div> : null}\n {groupsState?.tags.map((tag) => {\n const skills = sorted.filter((skill) => tag.skillNames.includes(skill.name))\n const disabledMembers = (catalog?.disabled ?? []).filter((record) => tag.skillNames.includes(record.name) && (normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized)))\n const collapsed = collapsedGroups.has('tag:' + tag.id)\n const view = groupSwitchView(tag.skillNames, viewNames)\n const hasWritable = tag.skillNames.some((name) => actionNames.has(name))\n const isDragging = dragId === tag.id\n const isOver = overId === tag.id && dragId !== tag.id\n return (\n <section\n key={'tag:' + tag.id}\n className={css.section + (isDragging ? ' ' + css.dragging : '') + (isOver ? ' ' + css.dragOver : '')}\n draggable\n onDragStart={(e) => { setDragId(tag.id); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', tag.id) }}\n onDragOver={(e) => { e.preventDefault(); if (overId !== tag.id) setOverId(tag.id) }}\n onDragLeave={() => { if (overId === tag.id) setOverId(null) }}\n onDrop={(e) => { e.preventDefault(); handleDrop(tag.id); setOverId(null) }}\n onDragEnd={() => { setDragId(null); setOverId(null) }}\n >\n <div className={css.groupHead}>\n <span className={css.dragHandle} aria-hidden title=\"拖拽调整顺序\">⋮⋮</span>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('tag:' + tag.id) }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tag.name} · {tag.skillNames.length}\n <GroupSummary members={tag.skillNames} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <button type='button' role='switch' aria-checked={view.state !== 'off'} aria-label={tag.name}\n className={css.switch + (view.state === 'on' ? ' ' + css.switchOn : view.state === 'mixed' ? ' ' + css.switchMixed : '')}\n disabled={batchBusy || tag.skillNames.length === 0 || (view.state !== 'off' && !hasWritable)}\n title={view.state !== 'off' && !hasWritable ? tt('groups.noWritable') : undefined}\n onClick={(event) => { event.stopPropagation(); toggleGroup('tag:' + tag.id, tag.name, view.state) }}>\n <span className={css.switchThumb} />\n </button>\n <button type='button' className={css.opBtn} onClick={() => { setEditingTag(tag); setEditName(tag.name); setMembersDraft(new Set(tag.skillNames)); setEditSearch('') }}>{tt('groups.edit')}</button>\n </span>\n </div>\n {!collapsed ? (\n <>\n {skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}\n {disabledMembers.map((record) => (\n <DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />\n ))}\n </>\n ) : null}\n </section>\n )\n })}\n </>\n )\n}\n","/**\n * Built-in market catalog: well-known skill repos shown on the market tab so\n * users can browse and install without knowing repo URLs.\n * Only the repo slug lives here; adding goes through the normal\n * market-source route and records upstream tracking like any manual source.\n */\n\nimport type { HubKey } from './locales.ts'\n\nexport interface MarketCatalogEntry {\n repo: string\n /** locales.ts key for the one-line description. */\n descriptionKey: HubKey\n}\n\n/** 默认市场目录:精选技能仓库(顺序即展示顺序)。 */\nexport const MARKET_CATALOG: readonly MarketCatalogEntry[] = [\n { repo: 'anthropics/skills', descriptionKey: 'market.catalog.anthropics' },\n { repo: 'obra/superpowers', descriptionKey: 'market.catalog.superpowers' },\n { repo: 'mattpocock/skills', descriptionKey: 'market.catalog.mattpocock' },\n { repo: 'nexu-io/open-design', descriptionKey: 'market.catalog.openDesign' },\n]\n","/**\n * Shared dialog family for the panel: one overlay shell plus the specific\n * dialogs (group-close conflict, sync/delete confirm, branch picker, and\n * market sync selection). Every dialog closes on outside click and keeps\n * the same role/aria shell; the panel owns all dialog state.\n */\n\nimport { useEffect, type JSX, type ReactNode } from 'react'\nimport type { CollectionGroup, SkillTag } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport { groupNamesOf } from '../grouping.ts'\nimport css from './panel.module.css'\n\n/** A group-close conflict waiting for the user's decision. */\nexport interface ConflictDialogState {\n /** Group key: 'tag:<id>' or 'col:<name>'. */\n key: string\n name: string\n /** Conflicting skill names (enabled here and in other groups). */\n conflicts: string[]\n}\n\n/** A destructive/sync confirmation waiting for the user's decision. */\nexport interface ConfirmDialogState {\n kind: 'sync' | 'delete'\n repo: string\n /** Skills the action applies to. */\n skills: string[]\n}\n\n/** Branch picker shown when a repo has no release and no pinned ref. */\nexport interface BranchChoiceState {\n repo: string\n branches: string[]\n selected: string\n}\n\n/** Post-sync skill update dialog: which tracked skills to refresh. */\nexport interface MarketSyncDialogState {\n repo: string\n ref: string\n skills: string[]\n selected: ReadonlySet<string>\n}\n\n/** Overlay + centered alert-dialog shell; outside click or Escape cancels. */\nfunction DialogShell(props: { onClose: () => void; children: ReactNode }): JSX.Element {\n useEffect(() => {\n const onKey = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') props.onClose()\n }\n window.addEventListener('keydown', onKey)\n return () => { window.removeEventListener('keydown', onKey) }\n })\n return (\n <div className={css.dialogOverlay} onClick={props.onClose}>\n <div className={css.dialog} role='alertdialog' aria-modal='true' onClick={(event) => { event.stopPropagation() }}>\n {props.children}\n </div>\n </div>\n )\n}\n\n/** Simple confirm dialog: title + text + optional skill list + cancel/confirm. */\nexport function ConfirmDialog(props: {\n title: string\n text: string\n /** Optional skill names listed between the text and the buttons. */\n items?: readonly string[]\n confirmLabel: string\n /** Danger-styled confirm button (destructive actions). */\n danger?: boolean\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { title, text, items, confirmLabel, danger, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{title}</h3>\n <p className={css.dialogText}>{text}</p>\n {items !== undefined ? (\n <ul className={css.dialogList}>\n {items.map((name) => <li key={name}><span className={css.rowNameText}>{name}</span></li>)}\n </ul>\n ) : null}\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('form.cancel')}</button>\n <button type='button' className={css.button + (danger === true ? ' ' + css.danger : ' ' + css.primary)} onClick={onConfirm}>\n {confirmLabel}\n </button>\n </div>\n </DialogShell>\n )\n}\n\n/** Group-close conflict: which skills stay on, and which other groups also enable them. */\nexport function ConflictDialog(props: {\n dialog: ConflictDialogState\n tags: readonly SkillTag[]\n collections: readonly CollectionGroup[]\n onClose: () => void\n onKeepOn: () => void\n onCloseAll: () => void\n}): JSX.Element {\n const { dialog, tags, collections, onClose, onKeepOn, onCloseAll } = props\n return (\n <DialogShell onClose={onClose}>\n <h3 className={css.dialogTitle}>{tt('groups.conflictTitle')}</h3>\n <p className={css.dialogText}>{tt('groups.conflictText')}</p>\n <ul className={css.dialogList}>\n {dialog.conflicts.map((name) => (\n <li key={name}>\n <span className={css.rowNameText}>{name}</span>\n {' — ' + groupNamesOf(name, [...tags], [...collections]).join(', ')}\n </li>\n ))}\n </ul>\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onKeepOn}>{tt('groups.keepOn')}</button>\n <button type='button' className={css.button + ' ' + css.primary} onClick={onCloseAll}>{tt('groups.closeAll')}</button>\n </div>\n </DialogShell>\n )\n}\n\n/** Branch picker for a repo without releases (pins the ref, then rescans). */\nexport function BranchChoiceDialog(props: {\n choice: BranchChoiceState\n busy: boolean\n onSelect: (branch: string) => void\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { choice, busy, onSelect, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{tt('market.branchTitle')}</h3>\n <p className={css.dialogText}>{tt('market.branchHint')}</p>\n <select className={css.select + ' ' + css.dialogSelect} value={choice.selected}\n onChange={(event) => { onSelect(event.target.value) }}>\n {choice.branches.map((branch) => <option key={branch} value={branch}>{branch}</option>)}\n </select>\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('form.cancel')}</button>\n <button type='button' className={css.button + ' ' + css.primary} disabled={busy} onClick={onConfirm}>{tt('market.branchConfirm')}</button>\n </div>\n </DialogShell>\n )\n}\n\n/** Post-sync selection: which tracked skills to batch-update to the new version. */\nexport function MarketSyncDialog(props: {\n dialog: MarketSyncDialogState\n busy: boolean\n onToggle: (name: string, checked: boolean) => void\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { dialog, busy, onToggle, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{tt('market.syncTitle')}</h3>\n <p className={css.dialogText}>{tt('market.syncText', { ref: dialog.ref })}</p>\n {dialog.skills.length === 0 ? (\n <p className={css.dialogText}>{tt('market.syncNone')}</p>\n ) : (\n <div className={css.dialogList}>\n {dialog.skills.map((name) => (\n <label key={name} className={css.dialogRow}>\n <input type='checkbox' checked={dialog.selected.has(name)}\n onChange={(event) => { onToggle(name, event.target.checked) }} />\n <span className={css.rowNameText}>{name}</span>\n </label>\n ))}\n </div>\n )}\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('market.syncCancel')}</button>\n <button type='button' className={css.button + ' ' + css.primary} disabled={busy || dialog.skills.length === 0} onClick={onConfirm}>\n {busy ? tt('source.syncing') : tt('source.sync')}\n </button>\n </div>\n </DialogShell>\n )\n}\n","/**\n * Market tab: one unified market list — built-in catalog entries (add\n * button while not yet added) and the user's market sources (full state\n * badges + actions once added, plus custom sources), with check-all and\n * update-all actions and the repo scan result with the importable checklist.\n */\n\nimport { Fragment, useEffect, useMemo, useState, type JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { MARKET_CATALOG } from '../market-catalog.ts'\nimport type { MarketSourceRecord, RepoSkillEntry } from '../../protocol.ts'\nimport { ConfirmDialog } from './dialogs.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\n/** Compact byte size for repo preview rows. */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return bytes + ' B'\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'\n return (bytes / 1024 / 1024).toFixed(1) + ' MB'\n}\nfunction formatSpeed(bps?: number): string {\n if (bps === undefined || bps <= 0) return ''\n if (bps < 1024) return bps + ' B/s'\n if (bps < 1024 * 1024) return (bps / 1024).toFixed(1) + ' KB/s'\n return (bps / 1024 / 1024).toFixed(1) + ' MB/s'\n}\n\nexport function MarketView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { marketState, marketCheck, sourceCheck, sourcesState, repoDiscoverState, scanningRepo, repoSelected, setRepoSelected, repoImporting, repoResult, newSourceName, setNewSourceName, syncingMarket, tagBusy, checkingSource, addSource, addMarketSource, removeMarketSource, scanRepo, checkMarket, checkSources, syncMarketSource, toggleRepoSelected, importRepo, cancelImport, updateAllDialog, setUpdateAllDialog, updateAll } = hub\n /** 有可更新技能的来源(全部更新按钮与确认列表共用)。 */\n const updatableRepos = Object.entries(sourceCheck).filter(([, check]) => check.changed && check.updated.length > 0)\n\n // 276 列表本地状态:搜索 / 过滤 / 分页(精简:扁平列表,无 A-Z 分组)\n const [repoSearch, setRepoSearch] = useState('')\n const [repoFilter, setRepoFilter] = useState<string>('all')\n const [visibleCount, setVisibleCount] = useState(50)\n useEffect(() => { setVisibleCount(50) }, [repoDiscoverState, repoSearch, repoFilter])\n\n /** 一个已添加来源的完整行:状态徽章 + 操作按钮。B 方案:扫描主按钮 + 智能更新按钮(检查/更新二合一)+ 溢出移除 */\n const sourceRow = (record: MarketSourceRecord): JSX.Element => {\n const releaseCheck = marketCheck[record.repo]\n const skillCheck = sourceCheck[record.repo]\n const installedCount = sourcesState?.sources.find((source) => source.repo === record.repo)?.skills.length ?? 0\n const scanning = scanningRepo === record.repo\n const syncing = syncingMarket === record.repo\n const checking = checkingSource === record.repo\n const hasSkillUpdate = skillCheck?.changed === true && skillCheck.updated.length > 0\n const hasReleaseUpdate = releaseCheck?.updateAvailable === true\n const hasUpdate = hasSkillUpdate || hasReleaseUpdate\n const isChecked = releaseCheck !== undefined || skillCheck !== undefined\n // 智能按钮三态:未检查→检查更新,未检查完/有更新→更新 N 个,已检查无更新→已是最新\n let updateLabel: string\n let updateDisabled = false\n let updateDanger = false\n let updateAction: () => void = () => {}\n if (syncing) {\n updateLabel = tt('market.syncing')\n updateDisabled = true\n } else if (checking) {\n updateLabel = tt('market.checking')\n updateDisabled = true\n } else if (!isChecked) {\n updateLabel = tt('market.checkUpdate')\n updateAction = () => { void checkSources(record.repo); void checkMarket() }\n } else if (hasUpdate) {\n const count = hasSkillUpdate ? skillCheck!.updated.length : 1\n updateLabel = count > 1 || hasSkillUpdate ? tt('market.updateCount', { count }) : tt('market.update')\n updateDanger = true\n updateAction = () => { void syncMarketSource(record.repo) }\n } else {\n updateLabel = tt('market.upToDate')\n updateDisabled = true\n }\n return (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <a className={css.sourceLink} href={'https://github.com/' + record.repo} target='_blank' rel='noreferrer'>{record.repo}</a>\n {record.ref !== undefined ? <span className={css.badge + ' ' + css.badgeSource}>{record.ref}</span> : null}\n {installedCount > 0 ? <span className={css.badge + ' ' + css.badgeCount}>{tt('market.installed', { count: installedCount })}</span> : null}\n {hasSkillUpdate\n ? <span className={css.badge + ' ' + css.statusUpdated}>{tt('market.updatable', { count: skillCheck!.updated.length })}</span>\n : null}\n {skillCheck !== undefined && skillCheck.deleted.length > 0\n ? <span className={css.badge + ' ' + css.statusError}>{tt('market.deletedUpstream', { count: skillCheck.deleted.length })}</span>\n : null}\n {hasReleaseUpdate\n ? <span className={css.badge + ' ' + css.statusUpdated}>{releaseCheck!.latestTag !== undefined ? tt('market.newRelease', { version: releaseCheck!.latestTag }) : tt('market.updated')}</span>\n : null}\n </div>\n </div>\n <button type='button' className={css.button + ' ' + css.primary} style={{ padding:'4px 10px', fontSize:12 }} disabled={scanning} onClick={() => { void scanRepo(record.repo) }}>\n {scanning ? tt('market.scanning') : tt('market.scan')}\n </button>\n <button\n type='button'\n className={css.opBtn + (updateDanger ? ' ' + css.opDanger : '')}\n disabled={updateDisabled}\n title={hasUpdate ? '将同步到上游最新版并提示可更新的本地技能' : undefined}\n onClick={updateAction}\n >\n {updateLabel}\n </button>\n <button\n type='button'\n className={css.opBtn}\n disabled={tagBusy}\n title={tt('market.removeHint')}\n aria-label={tt('market.deleteSource')}\n onClick={() => { void removeMarketSource(record.repo) }}\n style={{ padding:'4px 8px', minWidth:28 }}\n >×</button>\n </div>\n )\n }\n\n // 统一列表:内置目录(未添加 → 描述+添加按钮;已添加 → 完整行)在前,\n // 自定义市场源(不在内置目录里)随后。同一个仓库不会出现两次。\n const rows: Array<{ key: string; element: JSX.Element }> = []\n for (const entry of MARKET_CATALOG) {\n const record = marketState.repos.find((item) => item.repo === entry.repo)\n if (record !== undefined) {\n rows.push({ key: entry.repo, element: sourceRow(record) })\n } else {\n const busy = scanningRepo !== null || tagBusy\n rows.push({\n key: entry.repo,\n element: (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <a className={css.sourceLink} href={'https://github.com/' + entry.repo} target='_blank' rel='noreferrer'>{entry.repo}</a>\n </div>\n <div className={css.rowDesc}>{tt(entry.descriptionKey)}</div>\n </div>\n <button type='button' className={css.opBtn} disabled={busy} onClick={() => { void addSource(entry.repo) }}>{tt('market.add')}</button>\n </div>\n ),\n })\n }\n }\n for (const record of marketState.repos) {\n if (MARKET_CATALOG.some((entry) => entry.repo === record.repo)) continue\n rows.push({ key: record.repo, element: sourceRow(record) })\n }\n const unaddedCatalog = MARKET_CATALOG.filter((entry) => !marketState.repos.some((record) => record.repo === entry.repo))\n\n return (\n <>\n <section className={css.section}>\n <div className={css.sectionTitle + ' ' + css.sectionHeadRow}>\n <span className={css.sectionTitleFill}>{tt('market.title')}</span>\n <button type='button' className={css.opBtn} onClick={() => { void checkSources(); void checkMarket() }}>{tt('market.checkAll')}</button>\n <button\n type='button'\n className={css.opBtn + (updatableRepos.length > 0 ? ' ' + css.opDanger : '')}\n disabled={updatableRepos.length === 0 || tagBusy}\n onClick={() => { setUpdateAllDialog(true) }}\n >{tt('market.updateAll')}</button>\n </div>\n <div className={css.buttons + ' ' + css.actionsPadded}>\n <input\n className={css.input + ' ' + css.grow}\n value={newSourceName}\n onChange={(event) => { setNewSourceName(event.target.value) }}\n onKeyDown={(event) => { if (event.key === 'Enter') { event.preventDefault(); void addMarketSource() } }}\n placeholder={tt('market.addPlaceholder')}\n />\n <button type='button' className={css.button + ' ' + css.primary} disabled={newSourceName.trim() === ''} onClick={() => { void addMarketSource() }}>{tt('market.addSource')}</button>\n </div>\n {unaddedCatalog.length > 0 ? <p className={css.hintLine + ' ' + css.hintPadded}>{tt('market.catalogHint')}</p> : null}\n\n {marketState.status === 'loading' ? <div className={css.empty}>{tt('panel.loading')}</div> : null}\n {marketState.status !== 'loading' && rows.length === 0 ? <div className={css.empty}>{tt('market.noSources')}</div> : null}\n {marketState.status !== 'loading' ? rows.map((row) => <Fragment key={row.key}>{row.element}</Fragment>) : null}\n </section>\n {/* 扫描结果归属卡片:用同一 section 卡片包裹扫描中/错误/就绪,标题直接点明所属仓库,消除割裂感 */}\n {(repoDiscoverState.status !== 'idle' || repoResult !== null) ? (\n <section className={css.section} style={{ borderLeft: '3px solid var(--hub-model, #2f81f7)', background: 'rgba(47,129,247,0.04)' }}>\n <div className={css.sectionTitle + ' ' + css.sectionHeadRow} style={{ margin: '10px 14px 6px' }}>\n <span className={css.sectionTitleFill} style={{ display:'flex', alignItems:'center', gap:6 }}>\n <span style={{ width:7, height:7, borderRadius:'50%', background:'var(--hub-model, #2f81f7)', display:'inline-block' }} />\n 扫描结果\n <span style={{ fontWeight:400, opacity:.75 }}>\n — {repoDiscoverState.status === 'ready' ? repoDiscoverState.data.repo : repoDiscoverState.status === 'error' ? (scanningRepo ?? '') : (scanningRepo ?? '')}\n {repoDiscoverState.status === 'ready' && repoDiscoverState.data.ref !== null ? <span style={{ opacity:.5, marginLeft:6 }}>ref {repoDiscoverState.data.ref}</span> : null}\n </span>\n </span>\n <button type='button' className={css.opBtn} onClick={() => { hub.clearScan() }}>关闭</button>\n </div>\n <div style={{ padding:'0 12px 12px' }}>\n {repoDiscoverState.status === 'scanning' ? <div className={css.empty} style={{ padding:'12px 0' }}>{tt('market.scanning')}</div> : null}\n {repoDiscoverState.status === 'error' ? <div className={css.errorBanner}>{repoDiscoverState.message}</div> : null}\n {repoDiscoverState.status === 'ready' ? (() => {\n const entries = repoDiscoverState.data.entries\n // 导入后 catalog 已包含新技能,但 scan 快照的 existing 仍为 false,需用实时 catalog + 本次导入结果兜底,避免已导入仍可选\n const installedNames = new Set<string>([\n ...((hub.catalog?.skills ?? []).map((s) => s.name)),\n ...((hub.catalog?.disabled ?? []).map((d) => d.name)),\n ...((repoResult?.imported ?? []).map((r) => r.name)),\n ...((repoResult?.skipped ?? []).map((r) => r.name)),\n ])\n const isExisting = (entry: RepoSkillEntry): boolean => entry.existing || installedNames.has(entry.name)\n const selected = entries.filter((entry) => repoSelected.has(entry.path) && !isExisting(entry))\n const selectedBytes = selected.reduce((s, e) => s + e.totalBytes, 0)\n // 过滤 + 搜索(276 场景核心)\n const filtered = entries.filter((entry) => {\n if (repoFilter !== 'all' && entry.root !== repoFilter) return false\n if (repoSearch.trim() !== '' && !entry.name.toLowerCase().includes(repoSearch.trim().toLowerCase())) return false\n return true\n }).sort((a, b) => a.name.localeCompare(b.name))\n const paged = filtered.slice(0, visibleCount)\n return (\n <>\n <p className={css.hintLine + ' ' + css.hintInline}>{tt('repo.ready', { count: entries.length })} · {repoDiscoverState.data.ref !== null ? `ref ${repoDiscoverState.data.ref}` : ''}</p>\n {entries.length === 0 ? <div className={css.empty}>{tt('repo.empty')}</div> : (\n <>\n {/* 搜索 + 过滤 + 统计 — 精简 */}\n {(() => {\n // 动态根:按已知顺序 skills/design-templates 优先,其余按字母序\n const order = new Map<string, number>([['skills', 0], ['design-templates', 1]])\n const roots = [...new Set(entries.map((e) => e.root))].sort((a, b) => {\n const ao = order.get(a) ?? 99\n const bo = order.get(b) ?? 99\n return ao !== bo ? ao - bo : a.localeCompare(b)\n })\n const counts = new Map<string, number>()\n for (const e of entries) counts.set(e.root, (counts.get(e.root) ?? 0) + 1)\n return (\n <div style={{ display:'flex', gap:8, marginBottom:8, flexWrap:'wrap' }}>\n <input\n className={css.input}\n style={{ flex:1, minWidth:140 }}\n value={repoSearch}\n onChange={(e) => setRepoSearch(e.target.value)}\n placeholder=\"搜索技能名…\"\n />\n <button type='button' className={css.button + (repoFilter === 'all' ? ' ' + css.primary : '')} style={{ padding:'6px 10px', fontSize:12 }} onClick={() => setRepoFilter('all')}>全部 {entries.length}</button>\n {roots.map((root) => (\n <button key={root} type='button' className={css.button + (repoFilter === root ? ' ' + css.primary : '')} style={{ padding:'6px 10px', fontSize:12 }} onClick={() => setRepoFilter(root)}>{root} {counts.get(root) ?? 0}</button>\n ))}\n </div>\n )\n })()}\n <div className={css.hintLine} style={{ display:'flex', justifyContent:'space-between', flexWrap:'wrap', gap:8 }}>\n <span>已选 {selected.length}/{entries.length} · {formatBytes(selectedBytes)} · 显示 {paged.length}/{filtered.length}(过滤后)</span>\n <span style={{ display:'flex', gap:6 }}>\n <button type='button' className={css.button} style={{ padding:'4px 8px', fontSize:11 }} onClick={() => { setRepoSelected(new Set(filtered.filter((e)=>!isExisting(e)).slice(0, visibleCount).map((e)=>e.path))) }}>全选当前显示</button>\n <button type='button' className={css.button} style={{ padding:'4px 8px', fontSize:11 }} onClick={() => { setRepoSelected(new Set(entries.filter((e)=>!isExisting(e)).map((e)=>e.path))) }}>全选全部 {entries.filter(e=>!isExisting(e)).length}</button>\n <button type='button' className={css.button} style={{ padding:'4px 8px', fontSize:11 }} onClick={() => { setRepoSelected(new Set()) }}>{tt('repo.clearAll')}</button>\n </span>\n </div>\n\n {/* 扁平虚拟滚动容器 — 主题自适应,CSS Modules */}\n <div className={css.scanList}>\n {paged.length === 0 ? <div className={css.empty} style={{ padding:20 }}>无匹配技能</div> : paged.map((entry) => {\n const existing = isExisting(entry)\n return (\n <label key={entry.path} className={css.row + (existing ? ' ' + css.rowMuted : '')}>\n <input\n type='checkbox'\n checked={repoSelected.has(entry.path)}\n disabled={existing}\n onChange={(event) => { toggleRepoSelected(entry.path, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{entry.name}</div>\n <div className={css.rowDesc}>{entry.dir} · {tt('repo.files', { count: entry.fileCount, size: formatBytes(entry.totalBytes) })}</div>\n </div>\n {existing\n ? <span className={css.badge + ' ' + css.badgeReadonly}>{tt('repo.existing')}</span>\n : <span className={css.badge + ' ' + css.badgeSource}>{entry.origin}</span>}\n </label>\n )})}\n </div>\n {visibleCount < filtered.length ? (\n <div style={{ textAlign:'center', marginTop:8 }}>\n <button type='button' className={css.button} onClick={() => setVisibleCount((n) => n + 50)}>加载更多 50 (剩余 {filtered.length - visibleCount})</button>\n </div>\n ) : null}\n\n <div className={css.buttons + ' ' + css.actionsTop}>\n <button type='button' className={css.button + ' ' + css.primary} disabled={selected.length === 0 || repoImporting} onClick={() => { void importRepo() }}>{repoImporting ? tt('repo.importing') : `${tt('repo.import', { count: selected.length })} · ${formatBytes(selectedBytes)}`}</button>\n {repoImporting ? <button type='button' className={css.button} onClick={() => { void cancelImport() }}>{tt('repo.cancel')}</button> : null}\n </div>\n {repoResult !== null && repoResult.status === 'running' ? (() => {\n const pct = repoResult.totalBytes > 0 ? Math.min(100, Math.round(repoResult.downloadedBytes / repoResult.totalBytes * 100)) : (repoResult.total > 0 ? Math.round(repoResult.done / repoResult.total * 100) : 0)\n const speed = formatSpeed(repoResult.bytesPerSecond)\n return (\n <div className={css.formSuccess + ' ' + css.actionsTop}>\n <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:6 }}>\n <div className={css.scanProgressTrack}>\n <div className={css.scanProgressFill} style={{ width: `${pct}%` }} />\n </div>\n <span style={{ fontSize:11, opacity:.75, minWidth:32, textAlign:'right' }}>{pct}%</span>\n </div>\n <div className={css.hintLine}>\n {formatBytes(repoResult.downloadedBytes)} / {formatBytes(repoResult.totalBytes)}\n {speed !== '' ? ` · ${speed}` : ''} · {repoResult.done}/{repoResult.total} 个技能\n </div>\n <div className={css.hintLine} style={{marginTop:4}}>\n {repoResult.current !== undefined ? tt('repo.importingCurrent', { name: repoResult.current, done: repoResult.done + 1, total: repoResult.total }) : tt('repo.importing')}\n {repoResult.currentFile !== undefined ? ` · ${repoResult.currentFile}` : ''}\n </div>\n {repoResult.failed.length > 0 ? <div className={css.errorBanner} style={{marginTop:6}}>{repoResult.failed.map(f => `${f.name}: ${f.error}`).join('; ')}</div> : null}\n </div>\n )\n })() : null}\n </>\n )}\n </>\n )\n })() : null}\n {repoResult !== null && repoResult.status !== 'running' ? (\n <div className={repoResult.status === 'cancelled' ? css.errorBanner + ' ' + css.actionsTop : css.formSuccess + ' ' + css.actionsTop}>\n {repoResult.status === 'cancelled' ? tt('repo.cancelled', { imported: repoResult.imported.length, total: repoResult.total }) : `${tt('repo.imported', { count: repoResult.imported.length })} · ${tt('repo.skippedExisting', { count: repoResult.skipped.length })} · ${tt('repo.failed', { count: repoResult.failed.length })}`}\n {repoResult.failed.length > 0 ? <div style={{marginTop:6}}>{repoResult.failed.map(f => `${f.name}: ${f.error}`).join('; ')}</div> : null}\n {repoResult.status === 'error' && repoResult.error ? <div style={{marginTop:6}}>{repoResult.error}</div> : null}\n </div>\n ) : null}\n </div>\n </section>\n ) : null}\n\n {updateAllDialog ? (\n <ConfirmDialog\n title={tt('market.updateAllConfirmTitle')}\n text={tt('market.updateAllConfirmText')}\n items={updatableRepos.map(([repo, check]) => tt('market.updateAllItem', { repo, count: check.updated.length }))}\n confirmLabel={tt('market.updateAll')}\n danger\n onCancel={() => { setUpdateAllDialog(false) }}\n onConfirm={() => { void updateAll() }}\n />\n ) : null}\n </>\n )\n}\n","/**\n * useSkillHub — the panel's state owner. Everything the skill hub panel\n * knows (catalog, groups, sources, market, dialogs, drafts) plus every\n * async flow lives here; the panel itself only renders. All hooks run\n * unconditionally at the top, so the panel may early-return for the detail\n * and tag-editor views without violating the rules of hooks.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState, type FormEvent } from 'react'\nimport type {\n CatalogResponse,\n CatalogSkill,\n DisabledSkill,\n GroupsResponse,\n HubConfig,\n MarketCheckResponse,\n MarketSourceRecord,\n RepoDiscoverResponse,\n RepoImportProgressResponse,\n RepoImportResponse,\n SkillDetail,\n SkillTag,\n SourceCheckResult,\n SourcesResponse,\n UpdateCheckResponse,\n WritableRoot,\n} from '../../protocol.ts'\nimport type { SkillHubApi } from '../api.ts'\nimport { errorMessage, tt } from '../helpers.ts'\nimport { conflictsOnClose, isProjectSource, PRIVATE_SOURCE, sortSkills, type SortKey, type GroupSwitchState } from '../grouping.ts'\nimport type { BranchChoiceState, ConfirmDialogState, ConflictDialogState, MarketSyncDialogState } from './dialogs.tsx'\n\n/** Catalog poll interval while the panel is mounted (the provider watcher feeds this). */\nconst POLL_MS = 5000\n/** Relaxed poll for slower-changing data (stats, groups, sources, config). */\nconst SLOW_POLL_MS = 60_000\n\n/** localStorage key of the last daily auto-check timestamp (survives sessions). */\nconst AUTO_CHECK_KEY = 'skill-hub.last-auto-check'\n/** Daily auto-check interval: at most one network round per day. */\nconst AUTO_CHECK_INTERVAL_MS = 24 * 60 * 60_000\n\n/** Whether the daily auto-check should run now (first visit or ≥24h since the last). */\nfunction shouldAutoCheck(): boolean {\n try {\n const raw = localStorage.getItem(AUTO_CHECK_KEY)\n const last = raw === null ? NaN : Number(raw)\n if (!Number.isFinite(last)) return true\n return Date.now() - last >= AUTO_CHECK_INTERVAL_MS\n } catch {\n // 无 localStorage(隐私模式等):每次打开都尝试,服务端 5 分钟节流兜底。\n return true\n }\n}\n\n/** Record that the daily auto-check ran. */\nfunction markAutoChecked(): void {\n try {\n localStorage.setItem(AUTO_CHECK_KEY, String(Date.now()))\n } catch {\n // 无 localStorage:不记录,下次打开仍会尝试(服务端节流兜底)。\n }\n}\n\n/** One-shot self-update check state. */\ntype UpdateState =\n | { status: 'idle' }\n | { status: 'checking' }\n | { status: 'ready'; data: UpdateCheckResponse }\n | { status: 'error'; message: string }\n\n/** Repo scanner/import state (drives the market source preview). */\ntype RepoDiscoverState =\n | { status: 'idle' }\n | { status: 'scanning' }\n | { status: 'ready'; data: RepoDiscoverResponse }\n | { status: 'error'; message: string }\n\n/** Market sources list state. */\ntype MarketState = { status: 'loading' | 'ready' | 'error'; repos: MarketSourceRecord[] }\n\n/** One market source's update-check outcome. */\ntype MarketCheckResult = MarketCheckResponse['results'][number]\n\n/** The hook's result: the panel's complete state + action surface. */\nexport type SkillHubState = ReturnType<typeof useSkillHub>\n\nexport function useSkillHub(api: SkillHubApi) {\n const [catalog, setCatalog] = useState<CatalogResponse | null>(null)\n const [loading, setLoading] = useState(true)\n const [loadError, setLoadError] = useState<string | null>(null)\n /** Green success banner (create finished); shown outside the closing form. */\n const [successBanner, setSuccessBanner] = useState<string | null>(null)\n const [updateState, setUpdateState] = useState<UpdateState>({ status: 'idle' })\n const [repoDiscoverState, setRepoDiscoverState] = useState<RepoDiscoverState>({ status: 'idle' })\n /** Market repo currently being scanned (null when idle); per-row busy state. */\n const [scanningRepo, setScanningRepo] = useState<string | null>(null)\n const [repoSelected, setRepoSelected] = useState<ReadonlySet<string>>(new Set())\n const [repoImporting, setRepoImporting] = useState(false)\n const [repoResult, setRepoResult] = useState<RepoImportProgressResponse | null>(null)\n const [importJobId, setImportJobId] = useState<string | null>(null)\n const pollAbortRef = useRef<AbortController | null>(null)\n const [search, setSearch] = useState('')\n /** 工作区(项目)路径;空 = 只看用户级技能。 */\n const [workspace, setWorkspace] = useState('')\n const [detail, setDetail] = useState<SkillDetail | null>(null)\n const [detailLoading, setDetailLoading] = useState(false)\n const [busyNames, setBusyNames] = useState<ReadonlySet<string>>(new Set())\n const [batchBusy, setBatchBusy] = useState(false)\n const [showForm, setShowForm] = useState(false)\n const [formName, setFormName] = useState('')\n const [formDesc, setFormDesc] = useState('')\n const [formRoot, setFormRoot] = useState<WritableRoot>('user-dsh')\n const [formBusy, setFormBusy] = useState(false)\n const [formMessage, setFormMessage] = useState<{ kind: 'error' | 'success'; text: string } | null>(null)\n const [uses, setUses] = useState<ReadonlyMap<string, { count: number; lastUsed?: number }>>(new Map())\n const [hubConfig, setHubConfig] = useState<HubConfig | null>(null)\n const [tab, setTab] = useState<'sources' | 'scenes' | 'market'>('sources')\n const [skillView, setSkillView] = useState<'flat' | 'groups'>('groups')\n const [sourceFilter, setSourceFilter] = useState('all')\n const [sortKey, setSortKey] = useState<SortKey>('name')\n const [marketState, setMarketState] = useState<MarketState>({ status: 'loading', repos: [] })\n const [marketCheck, setMarketCheck] = useState<Readonly<Record<string, MarketCheckResult>>>({})\n const [branchChoice, setBranchChoice] = useState<BranchChoiceState | null>(null)\n const [branchBusy, setBranchBusy] = useState(false)\n const [marketSyncDialog, setMarketSyncDialog] = useState<MarketSyncDialogState | null>(null)\n const [syncingMarket, setSyncingMarket] = useState<string | null>(null)\n const [syncBusy, setSyncBusy] = useState(false)\n const [newSourceName, setNewSourceName] = useState('')\n const [groupsState, setGroupsState] = useState<GroupsResponse | null>(null)\n const [sourcesState, setSourcesState] = useState<SourcesResponse | null>(null)\n const [sourceCheck, setSourceCheck] = useState<Readonly<Record<string, SourceCheckResult>>>({})\n const [checkingSource, setCheckingSource] = useState<string | null>(null)\n const [syncingSource, setSyncingSource] = useState<string | null>(null)\n const [conflictDialog, setConflictDialog] = useState<ConflictDialogState | null>(null)\n const [confirmDialog, setConfirmDialog] = useState<ConfirmDialogState | null>(null)\n const [deleteSkillDialog, setDeleteSkillDialog] = useState<string | null>(null)\n const [deleteGroupDialog, setDeleteGroupDialog] = useState<{ name: string; skillNames: string[] } | null>(null)\n const [confirmClearTrash, setConfirmClearTrash] = useState(false)\n /** 「全部更新」确认对话框(市场 tab)。 */\n const [updateAllDialog, setUpdateAllDialog] = useState(false)\n const [editingTag, setEditingTag] = useState<SkillTag | null>(null)\n const [editName, setEditName] = useState('')\n const [membersDraft, setMembersDraft] = useState<ReadonlySet<string>>(new Set())\n const [newTagName, setNewTagName] = useState('')\n const [tagBusy, setTagBusy] = useState(false)\n const [editSearch, setEditSearch] = useState('')\n /** 分组视图里收起的分组(key 为 tag:<id>、col:<name> 或 project 树键)。 */\n const [collapsedGroups, setCollapsedGroups] = useState<ReadonlySet<string>>(new Set())\n /** 项目级三级树里已细分(按 .dsh/.agents)的项目键。 */\n const [subdividedProjects, setSubdividedProjects] = useState<ReadonlySet<string>>(new Set())\n const [showLegend, setShowLegend] = useState(false)\n const [editMode, setEditMode] = useState(false)\n\n const toggleGroupCollapse = useCallback((key: string): void => {\n setCollapsedGroups((previous) => {\n const next = new Set(previous)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [])\n\n const toggleSubdivide = useCallback((key: string): void => {\n setSubdividedProjects((previous) => {\n const next = new Set(previous)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [])\n\n const load = useCallback(async (): Promise<void> => {\n try {\n const next = await api.catalog(workspace !== '' ? { cwd: workspace } : undefined)\n setCatalog(next)\n setLoadError(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setLoading(false)\n }\n }, [api, workspace])\n\n const loadUses = useCallback(async (): Promise<void> => {\n try {\n const result = await api.stats()\n if (result.available) setUses(new Map(result.stats.map((stat) => [stat.name, { count: stat.count, ...(stat.lastUsed !== undefined ? { lastUsed: stat.lastUsed } : {}) }])))\n } catch {\n // Invocation counts are best-effort; a stats failure must not disturb the catalog.\n }\n }, [api])\n\n const loadConfig = useCallback(async (): Promise<void> => {\n try {\n setHubConfig((await api.config()).config)\n } catch {\n // Dot colors are cosmetic; a config failure falls back to the defaults.\n }\n }, [api])\n\n /** Check the hub's own GitHub release once, and again on demand. */\n const checkUpdate = useCallback(async (): Promise<void> => {\n setUpdateState({ status: 'checking' })\n try {\n setUpdateState({ status: 'ready', data: await api.updateCheck() })\n } catch (error) {\n setUpdateState({ status: 'error', message: errorMessage(error) })\n }\n }, [api])\n\n /** 加载用户 tag 分组 + 系统集合组 + origin 映射。 */\n const loadGroups = useCallback(async (): Promise<void> => {\n try {\n setGroupsState(await api.groups())\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 加载来源记录 + 回收站。 */\n const loadSources = useCallback(async (): Promise<void> => {\n try {\n setSourcesState(await api.sources())\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 加载市场源列表。 */\n const loadMarket = useCallback(async (): Promise<void> => {\n try {\n const next = await api.market()\n setMarketState({ status: 'ready', repos: next.repos })\n } catch (error) {\n setMarketState({ status: 'error', repos: [] })\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 把最新的 tag 列表合并进 groups 状态(tags 以外的字段保持原样)。 */\n const applyTags = useCallback((tags: SkillTag[]): void => {\n setGroupsState((previous) => previous === null\n ? { ok: true, tags, collections: [], origins: {} }\n : { ...previous, tags })\n }, [])\n\n // 初始全量加载 + 双速轮询:目录是「活视图」(文件变化要 5 秒内可见),\n // 统计/分组/来源/配置变化慢,60 秒一次足够;写操作本身会触发即时刷新。\n // 更新检查、来源检查、市场检查全部改为手动按钮触发,打开面板不再自动\n // 打三路 GitHub 请求。\n useEffect(() => {\n void load()\n void loadUses()\n void loadGroups()\n void loadSources()\n void loadConfig()\n const fast = window.setInterval(() => { void load() }, POLL_MS)\n const slow = window.setInterval(() => { void loadUses(); void loadGroups(); void loadSources(); void loadConfig() }, SLOW_POLL_MS)\n return () => { window.clearInterval(fast); window.clearInterval(slow) }\n }, [load, loadUses, loadGroups, loadSources, loadConfig])\n\n const openDetail = useCallback(async (name: string): Promise<void> => {\n setDetailLoading(true)\n setLoadError(null)\n try {\n setDetail(await api.skill(name, workspace !== '' ? { cwd: workspace } : undefined))\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setDetailLoading(false)\n }\n }, [api, workspace])\n\n const toggle = useCallback(async (skill: CatalogSkill, enabled: boolean): Promise<void> => {\n setBusyNames((previous) => new Set(previous).add(skill.name))\n setLoadError(null)\n try {\n const next = await api.toggle(skill.name, enabled)\n setCatalog(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBusyNames((previous) => {\n const next = new Set(previous)\n next.delete(skill.name)\n return next\n })\n }\n }, [api])\n\n const enableDisabled = useCallback(async (record: DisabledSkill): Promise<void> => {\n setBusyNames((previous) => new Set(previous).add(record.name))\n setLoadError(null)\n try {\n const next = await api.toggle(record.name, true)\n setCatalog(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBusyNames((previous) => {\n const next = new Set(previous)\n next.delete(record.name)\n return next\n })\n }\n }, [api])\n\n /** Toggle an explicit name set in one write (enables disabled members too). */\n const batchToggleNames = useCallback(async (names: string[], enabled: boolean): Promise<void> => {\n if (names.length === 0) return\n setBatchBusy(true)\n setLoadError(null)\n try {\n const next = await api.toggleBatch(names, enabled)\n setCatalog(next.catalog)\n if (next.failures.length > 0) {\n setLoadError('toggle-batch: ' + next.failures.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBatchBusy(false)\n }\n }, [api])\n\n // -------------------------------------------------------- group switches\n\n /** 所有分组:key → 成员名(tag 与来源集合)。 */\n const groupMap = useCallback((): Map<string, string[]> => {\n const map = new Map<string, string[]>()\n for (const tag of groupsState?.tags ?? []) map.set('tag:' + tag.id, tag.skillNames)\n for (const collection of groupsState?.collections ?? []) map.set('col:' + collection.name, collection.skillNames)\n return map\n }, [groupsState])\n\n /** 当前启用且可写的技能名(组开关只作用于它们)。 */\n const actionNames = useMemo(() => new Set((catalog?.skills ?? []).filter((skill) => skill.writable).map((skill) => skill.name)), [catalog])\n\n /** 当前启用的全部技能名(含只读,用于派生开关状态)。 */\n const viewNames = useMemo(() => new Set((catalog?.skills ?? []).map((skill) => skill.name)), [catalog])\n\n /**\n * Toggle a whole group via its tri-state switch. Closing with members that\n * are enabled in other groups opens the conflict dialog instead.\n */\n const toggleGroup = useCallback((key: string, name: string, view: GroupSwitchState): void => {\n const members = groupMap().get(key) ?? []\n if (members.length === 0) return\n if (view === 'off') {\n void batchToggleNames(members, true)\n return\n }\n const others = [...groupMap().entries()].filter(([otherKey]) => otherKey !== key).map(([, memberNames]) => ({ members: memberNames }))\n const conflicts = conflictsOnClose(members, actionNames, others)\n if (conflicts.length > 0) {\n setConflictDialog({ key, name, conflicts })\n } else {\n void batchToggleNames(members.filter((member) => actionNames.has(member)), false)\n }\n }, [groupMap, actionNames, batchToggleNames])\n\n /** Resolve the open conflict dialog. */\n const resolveConflict = useCallback(async (closeAll: boolean): Promise<void> => {\n const dialog = conflictDialog\n if (dialog === null) return\n setConflictDialog(null)\n const members = groupMap().get(dialog.key) ?? []\n if (closeAll) {\n await batchToggleNames(members.filter((member) => actionNames.has(member)), false)\n } else {\n await batchToggleNames(\n members.filter((member) => actionNames.has(member) && !dialog.conflicts.includes(member)),\n false,\n )\n }\n }, [conflictDialog, groupMap, actionNames, batchToggleNames])\n\n /** Dismiss a confirm dialog and run the pending source action. */\n const runConfirmed = useCallback(async (): Promise<void> => {\n const dialog = confirmDialog\n if (dialog === null) return\n setConfirmDialog(null)\n if (dialog.kind === 'sync') {\n setSyncingSource(dialog.repo)\n setLoadError(null)\n try {\n const result = await api.syncSource(dialog.repo, dialog.skills)\n await Promise.all([load(), loadGroups(), loadSources()])\n if (result.failed.length > 0) {\n setLoadError('sync: ' + result.failed.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncingSource(null)\n }\n } else {\n setLoadError(null)\n try {\n await api.confirmDeleteSource(dialog.repo, dialog.skills)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }\n }, [confirmDialog, api, load, loadGroups, loadSources])\n\n // ---------------------------------------------------------- source ops\n\n /** 检查全部来源的上游更新(服务端 5 分钟节流)。 */\n const checkSources = useCallback(async (repo?: string): Promise<void> => {\n setCheckingSource(repo ?? 'all')\n setLoadError(null)\n try {\n const result = await api.checkSources(repo)\n const next: Record<string, SourceCheckResult> = { ...sourceCheck }\n for (const item of result.results) next[item.repo] = item\n setSourceCheck(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setCheckingSource(null)\n }\n }, [api, sourceCheck])\n\n /** 请求同步某个来源的所选技能(弹确认,因为会覆盖本地修改)。 */\n const requestSync = useCallback((repo: string, skills: string[]): void => {\n setConfirmDialog({ kind: 'sync', repo, skills })\n }, [])\n\n /** 请求跟进上游删除(弹确认,移入回收站)。 */\n const requestDelete = useCallback((repo: string, skills: string[]): void => {\n setConfirmDialog({ kind: 'delete', repo, skills })\n }, [])\n\n /** 从回收站恢复一个技能。 */\n const restoreTrash = useCallback(async (name: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n await api.restoreSource(name)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, load, loadGroups, loadSources])\n\n /** 确认后永久删除回收站里的全部技能。 */\n const clearTrash = useCallback(async (): Promise<void> => {\n setConfirmClearTrash(false)\n setTagBusy(true)\n setLoadError(null)\n try {\n const result = await api.clearTrash()\n if (result.failed.length > 0) {\n setLoadError('clear trash: ' + result.failed.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n await Promise.all([load(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, load, loadSources])\n\n /** 打开单个技能的删除确认(移入回收站,可恢复)。 */\n const requestDeleteSkill = useCallback((name: string): void => {\n setDeleteSkillDialog(name)\n }, [])\n\n /** 执行删除确认后的回收站迁移。 */\n const runDeleteSkill = useCallback(async (): Promise<void> => {\n const name = deleteSkillDialog\n if (name === null) return\n setDeleteSkillDialog(null)\n setTagBusy(true)\n setLoadError(null)\n try {\n await api.deleteSkill(name)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, deleteSkillDialog, load, loadGroups, loadSources])\n\n /** 打开整组删除确认(来源分组一键删除)。 */\n const requestDeleteGroup = useCallback((name: string, skillNames: string[]): void => {\n setDeleteGroupDialog({ name, skillNames })\n }, [])\n\n /** 执行整组删除(逐个移入回收站,跳过只读)。 */\n const runDeleteGroup = useCallback(async (): Promise<void> => {\n const dialog = deleteGroupDialog\n if (dialog === null) return\n setDeleteGroupDialog(null)\n setTagBusy(true)\n setLoadError(null)\n const failures: string[] = []\n let done = 0\n for (const name of dialog.skillNames) {\n try {\n await api.deleteSkill(name)\n done += 1\n } catch (error) {\n // 只读/不存在的跳过并记录\n failures.push(name + ': ' + errorMessage(error))\n }\n }\n await Promise.all([load(), loadGroups(), loadSources()])\n setTagBusy(false)\n if (failures.length > 0) {\n setLoadError(`删除整组 \"${dialog.name}\":成功 ${done} 个,失败 ${failures.length} 个:` + failures.join('; '))\n } else if (done > 0) {\n setSuccessBanner(`已删除整组 \"${dialog.name}\":${done} 个技能已移入回收站`)\n }\n }, [api, deleteGroupDialog, load, loadGroups, loadSources])\n\n /** 新建一个空 tag 分组。 */\n const createTag = useCallback(async (event: FormEvent): Promise<void> => {\n event.preventDefault()\n const name = newTagName.trim()\n if (name === '') return\n setTagBusy(true)\n setLoadError(null)\n try {\n applyTags(await api.saveTag({ name }))\n setNewTagName('')\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags, newTagName])\n\n /** 删除一个 tag 分组(不影响技能文件)。 */\n const deleteTag = useCallback(async (id: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n applyTags(await api.deleteTag(id))\n setEditingTag(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags])\n\n /** 重命名 tag,或保存成员勾选后回到列表。 */\n const saveTag = useCallback(async (id: string, name: string, memberNames: string[] | null): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const safeName = name.trim()\n let tags: SkillTag[] | null = null\n if (safeName !== '') tags = await api.saveTag({ id, name: safeName })\n if (memberNames !== null) tags = await api.setTagMembers(id, memberNames)\n if (tags === null) return\n applyTags(tags)\n setEditingTag(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags])\n\n /** 拖拽重排场景分组 */\n const reorderTags = useCallback(async (orderedIds: string[]): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const tags = await api.reorderTags(orderedIds)\n applyTags(tags)\n } catch (error) {\n const msg = errorMessage(error)\n if (msg.includes('404') || msg.toLowerCase().includes('not found')) {\n // 旧宿主无此路由:本地重排\n const byId = new Map(groupsState?.tags.map((t) => [t.id, t] as const) ?? [])\n const reordered = orderedIds.map((id) => byId.get(id)).filter((t): t is NonNullable<typeof t> => t !== undefined)\n if (reordered.length === orderedIds.length) {\n applyTags(reordered as typeof groupsState extends { tags: infer T } ? T : never)\n setSuccessBanner('已临时调整顺序(本地生效,重启宿主后持久化)')\n } else {\n setLoadError(msg)\n }\n } else {\n setLoadError(msg)\n }\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags, groupsState])\n\n /** 拖拽重排来源集合 */\n const reorderCollections = useCallback(async (orderedNames: string[]): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const collections = await api.reorderCollections(orderedNames)\n setGroupsState((prev) => prev === null ? prev : { ...prev, collections })\n void loadGroups()\n } catch (error) {\n const msg = errorMessage(error)\n // 404 说明宿主仍在跑旧版(需重启后才有新路由),降级为本地即时生效\n if (msg.includes('404') || msg.toLowerCase().includes('not found')) {\n setGroupsState((prev) => {\n if (prev === null) return prev\n const map = new Map(prev.collections.map((c) => [c.name, c] as const))\n const reordered = orderedNames.map((n) => map.get(n)).filter((c): c is NonNullable<typeof c> => c !== undefined)\n // 补上未在 orderedNames 中的集合(新出现的)\n for (const c of prev.collections) if (!reordered.some((r) => r.name === c.name)) reordered.push(c)\n return { ...prev, collections: reordered }\n })\n setSuccessBanner('已临时调整顺序(本地生效,重启宿主后持久化)')\n } else {\n setLoadError(msg)\n }\n } finally {\n setTagBusy(false)\n }\n }, [api, loadGroups])\n\n /** 拖拽重排来源顶层分组(project / col:xxx / personal 全量可拖) */\n const reorderSourceGroups = useCallback(async (orderedKeys: string[]): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n await api.reorderSourceGroups(orderedKeys)\n await loadGroups()\n } catch (error) {\n const msg = errorMessage(error)\n if (msg.includes('404') || msg.toLowerCase().includes('not found')) {\n // 旧宿主无此路由:本地重排顶层顺序,提示重启后持久化\n setGroupsState((prev) => {\n if (prev === null) return prev\n // 本地重排 collections 以匹配 topOrderedKeys 中的 col:xxx 顺序\n const colOrder = orderedKeys.filter((k) => k.startsWith('col:')).map((k) => k.slice(4))\n const map = new Map(prev.collections.map((c) => [c.name, c] as const))\n const reordered = colOrder.map((n) => map.get(n)).filter((c): c is NonNullable<typeof c> => c !== undefined)\n for (const c of prev.collections) if (!reordered.some((r) => r.name === c.name)) reordered.push(c)\n return { ...prev, collections: reordered, sourceGroupOrder: orderedKeys }\n })\n setSuccessBanner('已临时调整顺序(本地生效,重启宿主后持久化)')\n } else {\n setLoadError(msg)\n }\n } finally {\n setTagBusy(false)\n }\n }, [api, loadGroups])\n\n // -------------------------------------------------------------- market\n\n /** 添加一个市场源(内置市场目录与手动输入共用),并立即扫描它。 */\n const addSource = useCallback(async (input: string): Promise<void> => {\n const value = input.trim()\n if (value === '') return\n setLoadError(null)\n try {\n const result = await api.addMarketSource(value)\n setMarketState({ status: 'ready', repos: result.repos })\n setNewSourceName('')\n setRepoResult(null)\n setRepoSelected(new Set())\n // 用服务端归一化后的 slug 扫描(URL/owner@repo 输入都能对上记录)。\n const slug = result.repos[result.repos.length - 1].repo\n setScanningRepo(slug)\n setRepoDiscoverState({ status: 'scanning' })\n try {\n const data = await api.repoDiscover(slug)\n setRepoDiscoverState({ status: 'ready', data })\n } catch (error) {\n setRepoDiscoverState({ status: 'error', message: errorMessage(error) })\n } finally {\n setScanningRepo(null)\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 手动输入框的添加动作。 */\n const addMarketSource = useCallback(async (): Promise<void> => {\n await addSource(newSourceName)\n }, [addSource, newSourceName])\n\n /** 删除一个市场源(不影响已装技能)。 */\n const removeMarketSource = useCallback(async (repo: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const result = await api.removeMarketSource(repo)\n setMarketState({ status: 'ready', repos: result.repos })\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api])\n\n /** 扫描一个市场源(或手动输入)的仓库。 */\n const scanRepo = useCallback(async (input: string): Promise<void> => {\n const value = input.trim()\n if (value === '') return\n setRepoResult(null)\n setRepoSelected(new Set())\n setScanningRepo(value)\n setRepoDiscoverState({ status: 'scanning' })\n setLoadError(null)\n try {\n const data = await api.repoDiscover(value)\n if (data.ref === null) {\n // 无 release 且未定版:让用户选分支(默认第一项,通常是 main)。\n setBranchChoice({ repo: data.repo, branches: data.branches ?? [], selected: (data.branches ?? [])[0] ?? 'main' })\n setRepoDiscoverState({ status: 'idle' })\n return\n }\n setRepoDiscoverState({ status: 'ready', data })\n } catch (error) {\n setRepoDiscoverState({ status: 'error', message: errorMessage(error) })\n } finally {\n setScanningRepo(null)\n }\n }, [api])\n\n /** 确认分支选择:持久化 ref 后重新扫描。 */\n const confirmBranchChoice = useCallback(async (): Promise<void> => {\n if (branchChoice === null) return\n setBranchBusy(true)\n setLoadError(null)\n try {\n await api.setMarketSourceRef(branchChoice.repo, branchChoice.selected)\n setBranchChoice(null)\n await scanRepo(branchChoice.repo)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBranchBusy(false)\n }\n }, [api, branchChoice, scanRepo])\n\n /** Toggle one repo preview row. */\n const toggleRepoSelected = useCallback((path: string, checked: boolean): void => {\n setRepoSelected((previous) => {\n const next = new Set(previous)\n if (checked) next.add(path)\n else next.delete(path)\n return next\n })\n }, [])\n\n /** Import every checked, non-existing repo skill (B方案:job+轮询+进度). */\n const importRepo = useCallback(async (): Promise<void> => {\n if (repoDiscoverState.status !== 'ready') return\n setRepoImporting(true)\n setRepoResult(null)\n setImportJobId(null)\n setLoadError(null)\n let finalProgress: RepoImportProgressResponse | null = null\n try {\n const created = await api.repoImport(repoDiscoverState.data.repo, [...repoSelected], repoDiscoverState.data.ref ?? undefined)\n setImportJobId(created.jobId)\n // 初始占位,让进度卡片立刻出现(带真实 totalBytes)\n setRepoResult({ ok: true, jobId: created.jobId, status: 'running', total: created.total, done: 0, totalBytes: created.totalBytes, downloadedBytes: 0, imported: [], skipped: [], failed: [] })\n // 轮询直到 done/cancelled/error(800ms 起步 + 退避,避免 276 技能 900 次请求)\n pollAbortRef.current?.abort()\n pollAbortRef.current = new AbortController()\n const signal = pollAbortRef.current.signal\n let attempt = 0\n for (;;) {\n if (signal.aborted) break\n const delay = Math.min(2000, 800 + attempt * 200)\n await new Promise((r) => setTimeout(r, delay))\n if (signal.aborted) break\n try {\n const progress = await api.repoImportProgress(created.jobId)\n setRepoResult(progress)\n finalProgress = progress\n if (progress.status !== 'running') {\n break\n }\n attempt = 0\n } catch (pollError) {\n // 轮询失败退避重试\n const msg = errorMessage(pollError)\n if (msg.includes('not found')) break\n attempt += 1\n if (attempt > 8) break\n }\n }\n await Promise.all([load(), loadMarket(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n // 导入完成后把已导入/已跳过的项从勾选中移除,并把扫描快照里的 existing 置为 true,避免“仍可勾选已导入”的错觉\n if (finalProgress !== null && (finalProgress.imported.length > 0 || finalProgress.skipped.length > 0)) {\n const doneNames = new Set([...finalProgress.imported.map((r) => r.name), ...finalProgress.skipped.map((r) => r.name)])\n const donePaths = new Set(\n repoDiscoverState.data.entries.filter((e) => doneNames.has(e.name)).map((e) => e.path),\n )\n setRepoSelected((prev) => {\n const next = new Set(prev)\n for (const p of donePaths) next.delete(p)\n return next\n })\n setRepoDiscoverState((prev) => {\n if (prev.status !== 'ready') return prev\n return {\n ...prev,\n data: {\n ...prev.data,\n entries: prev.data.entries.map((e) => doneNames.has(e.name) ? { ...e, existing: true } : e),\n },\n }\n })\n }\n setRepoImporting(false)\n }\n }, [api, repoDiscoverState, repoSelected, load, loadMarket, loadGroups, loadSources])\n\n // 卸载时中断轮询,避免泄露\n useEffect(() => {\n return () => { pollAbortRef.current?.abort() }\n }, [])\n\n /** 取消正在进行的导入(选项2:唯有取消才停) */\n const cancelImport = useCallback(async (): Promise<void> => {\n if (importJobId === null) return\n pollAbortRef.current?.abort()\n try {\n const res = await api.repoImportCancel(importJobId)\n // 立刻刷新一次进度\n try {\n const progress = await api.repoImportProgress(importJobId)\n setRepoResult(progress)\n } catch {\n setRepoResult((prev) => prev !== null ? { ...prev, status: res.status as 'cancelled' } : prev)\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setRepoImporting(false)\n }\n }, [api, importJobId])\n\n /** 清空扫描结果(关闭归属卡片) */\n const clearScan = useCallback((): void => {\n setRepoDiscoverState({ status: 'idle' })\n setScanningRepo(null)\n setRepoResult(null)\n setRepoSelected(new Set())\n setImportJobId(null)\n pollAbortRef.current?.abort()\n }, [])\n\n /** 检查所有市场源的上游更新(服务端节流)。 */\n const checkMarket = useCallback(async (): Promise<void> => {\n try {\n const result = await api.marketCheck()\n const next: Record<string, MarketCheckResult> = {}\n for (const item of result.results) next[item.repo] = item\n setMarketCheck(next)\n } catch {\n // 检查失败不打扰市场列表本身。\n }\n }, [api])\n\n /** 市场源同步:版本对齐后询问是否批量更新本地技能。 */\n const syncMarketSource = useCallback(async (repo: string): Promise<void> => {\n setSyncingMarket(repo)\n setLoadError(null)\n try {\n const result = await api.marketSync(repo)\n setMarketSyncDialog({ repo: result.repo, ref: result.ref, skills: result.skills, selected: new Set(result.skills) })\n await loadMarket()\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncingMarket(null)\n }\n }, [api, loadMarket])\n\n /** 批量更新本地技能到市场源当前版本(复用来源同步路径)。 */\n const confirmMarketSync = useCallback(async (): Promise<void> => {\n if (marketSyncDialog === null) return\n const selected = [...marketSyncDialog.selected]\n setSyncBusy(true)\n setLoadError(null)\n try {\n if (selected.length > 0) {\n const result = await api.syncSource(marketSyncDialog.repo, selected)\n if (result.failed.length > 0) setLoadError(result.failed.map((item) => item.name + ': ' + item.error).join('\\n'))\n }\n setMarketSyncDialog(null)\n await Promise.all([load(), loadGroups(), loadSources()])\n void checkMarket()\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncBusy(false)\n }\n }, [api, marketSyncDialog, load, loadGroups, loadSources, checkMarket])\n\n /**\n * 一键全部更新:把每个「有可更新技能」的来源逐个同步到上游最新版本\n * (复用来源同步路径,覆盖本地修改),随后刷新并重新检查。\n */\n const updateAll = useCallback(async (): Promise<void> => {\n setUpdateAllDialog(false)\n setBatchBusy(true)\n setLoadError(null)\n const failures: string[] = []\n let done = 0\n try {\n for (const [repo, check] of Object.entries(sourceCheck)) {\n if (!check.changed || check.updated.length === 0) continue\n try {\n const result = await api.syncSource(repo, check.updated)\n done += 1\n if (result.failed.length > 0) {\n failures.push(tt('market.updateAllItem', { repo, count: result.failed.length }) + ': ' + result.failed.map((item) => item.name + ': ' + item.error).join('; '))\n }\n } catch (error) {\n failures.push(repo + ': ' + errorMessage(error))\n }\n }\n await Promise.all([load(), loadGroups(), loadSources()])\n await checkSources()\n void checkMarket()\n if (failures.length > 0) setLoadError(failures.join('\\n'))\n else if (done > 0) setSuccessBanner(tt('market.updateAllDone', { count: done }))\n } finally {\n setBatchBusy(false)\n }\n }, [api, sourceCheck, checkSources, checkMarket, load, loadGroups, loadSources])\n\n // ------------------------------------------------- daily auto-check\n // 打开面板时每天最多自动检查一次(自身更新 + 全部来源 + 全部市场源),\n // 时间戳存 localStorage 跨会话生效;手动按钮随时可用,不受节流限制。\n useEffect(() => {\n if (!shouldAutoCheck()) return\n markAutoChecked()\n void checkUpdate()\n void checkSources()\n void checkMarket()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // ---------------------------------------------------------------- create\n\n const create = useCallback(async (event: FormEvent): Promise<void> => {\n event.preventDefault()\n setFormBusy(true)\n setFormMessage(null)\n setSuccessBanner(null)\n try {\n const result = await api.create({ name: formName, description: formDesc, root: formRoot })\n // The form closes on success, so the confirmation lives in the green\n // banner outside it (a success message inside the closing form is\n // never visible).\n setSuccessBanner(tt('form.success') + result.path)\n setFormName('')\n setFormDesc('')\n setShowForm(false)\n await load()\n } catch (error) {\n setFormMessage({ kind: 'error', text: tt('form.error') + errorMessage(error) })\n } finally {\n setFormBusy(false)\n }\n }, [api, formName, formDesc, formRoot, load])\n\n // ------------------------------------------------------------- derived\n\n const normalized = search.trim().toLocaleLowerCase()\n /** skillName → origin repo(无来源记录的技能不在此映射中,筛选中视为 private)。 */\n const origins = groupsState?.origins ?? {}\n /** 来源筛选选项:来源记录中的仓库(排序)+ 末尾的「个人」;没有技能的仓库不列。 */\n const sourceOptions = useMemo(() => {\n const skills = catalog?.skills ?? []\n const repos = [...new Set(skills.map((skill) => origins[skill.name]).filter((repo): repo is string => repo !== undefined))].sort()\n // 项目级技能(有 workspace 归属)不算「个人」。\n const hasPrivate = skills.some((skill) => origins[skill.name] === undefined && !isProjectSource(skill.source))\n return [...repos, ...(hasPrivate ? [PRIVATE_SOURCE] : [])]\n }, [catalog, origins])\n const filtered = useMemo(() => (catalog?.skills ?? []).filter((skill) =>\n normalized.length === 0 || skill.name.toLocaleLowerCase().includes(normalized) || skill.description.toLocaleLowerCase().includes(normalized),\n ), [catalog, normalized])\n /** 排序后的技能列表(所有视图共用;调用次数未知按 0 处理)。 */\n const sorted = useMemo(() => sortSkills(filtered, sortKey, (name) => uses.get(name)?.count), [filtered, sortKey, uses])\n\n return {\n // state\n catalog, loading, loadError, successBanner, updateState, repoDiscoverState, scanningRepo, repoSelected, repoImporting, repoResult, importJobId,\n search, workspace, detail, detailLoading, busyNames, batchBusy, showForm, formName, formDesc, formRoot, formBusy, formMessage,\n uses, hubConfig, tab, skillView, sourceFilter, sortKey, marketState, marketCheck, branchChoice, branchBusy,\n marketSyncDialog, syncingMarket, syncBusy, newSourceName, groupsState, sourcesState, sourceCheck, checkingSource, syncingSource,\n conflictDialog, confirmDialog, deleteSkillDialog, deleteGroupDialog, confirmClearTrash, updateAllDialog, editingTag, editName, membersDraft, newTagName, tagBusy,\n editSearch, collapsedGroups, subdividedProjects, showLegend, editMode,\n // derived\n actionNames, viewNames, normalized, origins, sourceOptions, filtered, sorted,\n // actions + setters\n setLoadError, setSuccessBanner, setSearch, setWorkspace, setDetail, setShowForm, setFormName, setFormDesc, setFormRoot, setFormMessage,\n setRepoSelected, setTab, setSkillView,\n setSourceFilter, setSortKey, setBranchChoice, setMarketSyncDialog, setNewSourceName, setConflictDialog, setConfirmDialog,\n setDeleteSkillDialog, setDeleteGroupDialog, setConfirmClearTrash, setUpdateAllDialog, setEditingTag, setEditName, setMembersDraft, setNewTagName, setEditSearch, setShowLegend, setEditMode,\n toggleGroupCollapse, toggleSubdivide, checkUpdate, loadMarket, openDetail, toggle, enableDisabled, batchToggleNames, toggleGroup, resolveConflict,\n runConfirmed, checkSources, requestSync, requestDelete, restoreTrash, clearTrash, requestDeleteSkill, runDeleteSkill, requestDeleteGroup, runDeleteGroup, createTag,\n deleteTag, saveTag, reorderTags, reorderCollections, reorderSourceGroups, addSource, addMarketSource, removeMarketSource, scanRepo, confirmBranchChoice, toggleRepoSelected, importRepo, cancelImport, clearScan,\n checkMarket, syncMarketSource, confirmMarketSync, updateAll, create,\n }\n}\n","/**\n * The skill hub panel: catalog grouped by tags + source collections, search\n * and filter in one row, per-group tri-state switches with conflict dialogs,\n * upstream source tracking (check / sync / follow upstream deletion into a\n * restorable trash), market sources, disabled re-enable,\n * detail inspection, and the new-skill scaffold form.\n *\n * Thin shell: state and flows live in useSkillHub, the tab contents live in\n * SourcesView / ScenesView / MarketView, and the dialog family lives in\n * dialogs.tsx. This component owns only the shared chrome (header, banners,\n * filter bar, shared sections) and the view routing — and holds no hooks,\n * so the detail / tag-editor early returns are safe.\n */\n\nimport { useState } from 'react'\nimport type { WritableRoot } from '../../protocol.ts'\nimport { IconSkillOutline16 } from '../icons.tsx'\nimport type { SkillHubApi } from '../api.ts'\nimport { tt } from '../helpers.ts'\nimport { PRIVATE_SOURCE, type SortKey } from '../grouping.ts'\nimport { dotStyle, relativeTimeText } from './format.ts'\nimport { SkillDetailView } from './SkillDetailView.tsx'\nimport { TagEditorView } from './TagEditorView.tsx'\nimport { SourcesView } from './SourcesView.tsx'\nimport { ScenesView } from './ScenesView.tsx'\nimport { MarketView } from './MarketView.tsx'\nimport { BranchChoiceDialog, ConfirmDialog, ConflictDialog, MarketSyncDialog } from './dialogs.tsx'\nimport { useSkillHub } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport interface SkillHubPanelProps {\n api: SkillHubApi\n}\n\nexport function SkillHubPanel(props: SkillHubPanelProps): React.JSX.Element {\n const hub = useSkillHub(props.api)\n /** 工作区输入草稿:回车才应用,避免每次按键都触发目录重拉。 */\n const [workspaceDraft, setWorkspaceDraft] = useState('')\n const {\n catalog, loading, loadError, successBanner, updateState, detail, detailLoading, showForm, formName, formDesc,\n formRoot, formBusy, formMessage, hubConfig, tab, skillView, sourceFilter, sortKey, search,\n workspace, setWorkspace,\n sourcesState, tagBusy, busyNames, normalized, origins, sourceOptions, filtered,\n conflictDialog, confirmDialog, deleteSkillDialog, deleteGroupDialog, confirmClearTrash, branchChoice, branchBusy, marketSyncDialog,\n syncBusy, editingTag, editName, membersDraft, editSearch, uses, groupsState, sourceCheck, checkingSource, syncingSource,\n showLegend, editMode,\n setLoadError, setSuccessBanner, setDetail, setShowForm, setFormName, setFormDesc, setFormRoot, setFormMessage, setTab,\n setSkillView, setSourceFilter, setSortKey, setSearch, setConflictDialog, setConfirmDialog, setDeleteSkillDialog, setDeleteGroupDialog,\n setConfirmClearTrash, setBranchChoice, setMarketSyncDialog, setEditingTag, setEditName, setMembersDraft, setEditSearch,\n setShowLegend, setEditMode,\n checkUpdate, loadMarket, checkSources, requestSync, requestDelete, restoreTrash, clearTrash, runDeleteSkill, runDeleteGroup,\n runConfirmed, resolveConflict, confirmBranchChoice, confirmMarketSync, create, saveTag, deleteTag, enableDisabled,\n } = hub\n\n // -------------------------------------------------------------- detail\n\n if (detail !== null) {\n return (\n <SkillDetailView\n detail={detail}\n hubConfig={hubConfig}\n uses={uses}\n groupsState={groupsState}\n sourcesState={sourcesState}\n sourceCheck={sourceCheck}\n checkingSource={checkingSource}\n syncingSource={syncingSource}\n loading={detailLoading}\n onBack={() => { setDetail(null) }}\n onCheck={(repo) => { void checkSources(repo) }}\n onSync={requestSync}\n onFollowDelete={requestDelete}\n />\n )\n }\n\n if (editingTag !== null) {\n return (\n <TagEditorView\n tag={editingTag}\n editName={editName}\n membersDraft={membersDraft}\n editSearch={editSearch}\n catalog={catalog}\n tagBusy={tagBusy}\n onBack={() => { setEditingTag(null) }}\n onEditName={setEditName}\n onEditSearch={setEditSearch}\n onToggleMember={(name, checked) => {\n setMembersDraft((previous) => {\n const next = new Set(previous)\n if (checked) next.add(name)\n else next.delete(name)\n return next\n })\n }}\n onRename={() => { void saveTag(editingTag.id, editName, null) }}\n onDelete={() => { void deleteTag(editingTag.id) }}\n onSaveMembers={() => { void saveTag(editingTag.id, editName, [...membersDraft]) }}\n />\n )\n }\n\n /** 检查结果的悬停提示:收敛到「检查更新」按钮上,不再占面板顶部横幅。 */\n const updateTitle = ((): string | undefined => {\n if (updateState.status === 'checking') return tt('update.checking')\n if (updateState.status === 'error') return tt('update.error', { error: updateState.message })\n if (updateState.status === 'ready') {\n const data = updateState.data\n if (data.error !== undefined) return tt('update.error', { error: data.error })\n if (data.updateAvailable) return tt('update.available', { version: data.latestVersion ?? '', current: data.currentVersion })\n if (data.latestVersion === null) return tt('update.unavailable')\n return tt('update.upToDate', { version: data.latestVersion })\n }\n return undefined\n })()\n\n return (\n <div className={css.panel}>\n <div className={css.header}>\n <h2 className={css.title}><IconSkillOutline16 size={16} className={css.titleIcon} /> {tt('panel.title')}{catalog !== null ? <span className={css.pluginVersion}>v{catalog.pluginVersion}</span> : null}</h2>\n {catalog !== null\n ? <span className={css.headerCount}>\n {tt('panel.count', { count: catalog.skills.length + catalog.disabled.length })}\n {catalog.disabled.length > 0 ? ' · ' + tt('panel.disabledCount', { count: catalog.disabled.length }) : null}\n </span>\n : null}\n {catalog !== null && !catalog.complete ? <span className={css.hint}>{tt('panel.incomplete')}</span> : null}\n <span className={css.actions}>\n <button type='button' className={css.button} disabled={updateState.status === 'checking'} title={updateTitle} onClick={() => { void checkUpdate() }}>{updateState.status === 'checking' ? tt('update.checking') : tt('update.check')}</button>\n {updateState.status === 'ready' && updateState.data.updateAvailable && updateState.data.url !== null\n ? <a className={css.updateLink} href={updateState.data.url} target='_blank' rel='noreferrer'>{tt('update.newVersion', { version: updateState.data.latestVersion ?? '' })}</a>\n : null}\n </span>\n </div>\n <div className={css.subbar}>\n <span className={css.segmented}>\n <button type='button' className={css.segBtn + (tab === 'sources' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('sources') }}>{tt('view.sources')}</button>\n <button type='button' className={css.segBtn + (tab === 'scenes' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('scenes') }}>{tt('view.scenes')}</button>\n <button type='button' className={css.segBtn + (tab === 'market' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('market'); void loadMarket() }}>{tt('view.market')}</button>\n </span>\n <span className={css.workspaceBox}>\n <input\n className={css.search + ' ' + css.workspaceInput}\n value={workspaceDraft}\n placeholder={workspace !== '' ? workspace : tt('panel.workspacePlaceholder')}\n title={tt('panel.workspaceHint')}\n onChange={(event) => { setWorkspaceDraft(event.target.value) }}\n onKeyDown={(event) => { if (event.key === 'Enter') setWorkspace((event.target as HTMLInputElement).value.trim()) }}\n />\n {workspace !== ''\n ? <button type='button' className={css.opBtn} title={tt('panel.workspaceClear')} onClick={() => { setWorkspace(''); setWorkspaceDraft('') }}>✕</button>\n : null}\n </span>\n <button type='button' className={css.legendToggle + (showLegend ? ' ' + css.legendToggleActive : '')} onClick={() => { setShowLegend((value) => !value) }} title={tt('legend.hint')}>?</button>\n <span className={css.actions}>\n <button type='button' className={css.button + ' ' + css.primary} onClick={() => { setShowForm((value) => !value) }}>{tt('panel.new')}</button>\n </span>\n </div>\n\n {showForm ? (\n <form className={css.form} onSubmit={(event) => { void create(event) }}>\n <p className={css.hintLine}>{tt('form.capabilityHint')}</p>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.name')}</label>\n <input className={css.input} value={formName} onChange={(event) => { setFormName(event.target.value) }} placeholder='code-review' />\n </div>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.desc')}</label>\n <input className={css.input} value={formDesc} onChange={(event) => { setFormDesc(event.target.value) }} placeholder={tt('form.descPlaceholder')} />\n </div>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.root')}</label>\n <select className={css.select} value={formRoot} onChange={(event) => { setFormRoot(event.target.value as WritableRoot) }}>\n <option value='user-dsh'>~/.dsh/skills</option>\n <option value='user-agents'>~/.agents/skills</option>\n </select>\n </div>\n {formMessage !== null ? <div className={formMessage.kind === 'error' ? css.formError : css.formSuccess}>{formMessage.text}</div> : null}\n <div className={css.buttons}>\n <button type='submit' className={css.button + ' ' + css.primary} disabled={formBusy}>{formBusy ? tt('form.busy') : tt('form.submit')}</button>\n <button type='button' className={css.button} onClick={() => { setShowForm(false); setFormMessage(null) }}>{tt('form.cancel')}</button>\n </div>\n </form>\n ) : null}\n\n {loadError !== null ? (\n <div className={css.errorBanner}>\n <span>{loadError}</span>\n <button type='button' className={css.button} onClick={() => { setLoadError(null) }}>{tt('err.dismiss')}</button>\n </div>\n ) : null}\n\n {successBanner !== null ? (\n <div className={css.successBanner}>\n <span>{successBanner}</span>\n <button type='button' className={css.button} onClick={() => { setSuccessBanner(null) }}>{tt('err.dismiss')}</button>\n </div>\n ) : null}\n\n {showLegend ? (\n <div className={css.legend}>\n <span className={css.legendItem}><span className={css.dot + ' ' + css.dotModel} style={dotStyle(hubConfig?.dotModelColor)} />{tt('legend.model')}</span>\n <span className={css.legendItem}><span className={css.dot + ' ' + css.dotUser} style={dotStyle(hubConfig?.dotUserColor)} />{tt('legend.user')}</span>\n <span className={css.legendHint}>{tt('legend.hint')}</span>\n </div>\n ) : null}\n\n {loading ? <div className={css.empty}>{tt('panel.loading')}</div> : null}\n\n {detailLoading ? <div className={css.empty}>{tt('detail.loading')}</div> : null}\n\n {tab === 'market' ? (\n <MarketView hub={hub} />\n ) : catalog !== null ? (\n <>\n <div className={css.filterBar}>\n {tab === 'sources' ? (\n <>\n <span className={css.segmented}>\n <button type='button' className={css.segBtn + (skillView === 'flat' ? ' ' + css.segBtnActive : '')} onClick={() => { setSkillView('flat') }}>{tt('view.flat')}</button>\n <button type='button' className={css.segBtn + (skillView === 'groups' ? ' ' + css.segBtnActive : '')} onClick={() => { setSkillView('groups') }}>{tt('view.grouped')}</button>\n </span>\n <select className={css.select} value={sourceFilter} onChange={(event) => { setSourceFilter(event.target.value) }}>\n <option value='all'>{tt('filter.allSources')}</option>\n {sourceOptions.map((source) => (\n <option key={source} value={source}>{source === PRIVATE_SOURCE ? tt('filter.private') : source}</option>\n ))}\n </select>\n </>\n ) : null}\n <select className={css.select} value={sortKey} onChange={(event) => { setSortKey(event.target.value as SortKey) }}>\n <option value='name'>{tt('sort.name')}</option>\n <option value='added'>{tt('sort.added')}</option>\n <option value='uses'>{tt('sort.uses')}</option>\n </select>\n <input className={css.search} value={search} onChange={(event) => { setSearch(event.target.value) }} placeholder={tt('panel.search')} />\n <button type='button' className={css.button + (editMode ? ' ' + css.primary : '')} style={{ marginLeft:'auto' }} onClick={() => setEditMode((v) => !v)}>{editMode ? '完成' : '编辑'}</button>\n </div>\n\n {filtered.length === 0 && search.trim() !== '' ? <div className={css.empty}>{tt('panel.empty')}</div> : null}\n {filtered.length === 0 && search.trim() === '' && catalog.skills.length === 0 && catalog.disabled.length === 0 && catalog.diagnostics.length === 0\n ? <div className={css.empty}>{tt('panel.emptyAll')}</div>\n : null}\n\n {tab === 'sources' ? <SourcesView hub={hub} /> : <ScenesView hub={hub} />}\n\n {sourcesState !== null && sourcesState.trash.length > 0 ? (\n <section className={css.section}>\n <div className={css.sectionTitle + ' ' + css.sectionHeadRow}>\n <span className={css.sectionTitleFill}>{tt('source.trash')}</span>\n <button type='button' className={css.opBtn + ' ' + css.opDanger} disabled={tagBusy} onClick={() => { setConfirmClearTrash(true) }}>{tt('source.clearTrash')}</button>\n </div>\n {sourcesState.trash.map((entry) => (\n <div key={entry.name} className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>{entry.name}</div>\n <div className={css.rowDesc}>{relativeTimeText(entry.movedAt)}</div>\n </div>\n <button type='button' className={css.opBtn} disabled={tagBusy} onClick={() => { void restoreTrash(entry.name) }}>{tt('source.restore')}</button>\n </div>\n ))}\n </section>\n ) : null}\n\n {catalog.diagnostics.length > 0 ? (\n <section className={css.section}>\n <div className={css.sectionTitle}>{tt('panel.diagnostics')}</div>\n {catalog.diagnostics.map((entry) => (\n <div key={entry.path} className={css.diagRow}>\n <div className={css.diagPath}>{entry.path}</div>\n <div className={css.diagReason}>{entry.reason}</div>\n </div>\n ))}\n </section>\n ) : null}\n </>\n ) : null}\n\n {conflictDialog !== null ? (\n <ConflictDialog\n dialog={conflictDialog}\n tags={groupsState?.tags ?? []}\n collections={groupsState?.collections ?? []}\n onClose={() => { setConflictDialog(null) }}\n onKeepOn={() => { void resolveConflict(false) }}\n onCloseAll={() => { void resolveConflict(true) }}\n />\n ) : null}\n\n {confirmDialog !== null ? (\n <ConfirmDialog\n title={confirmDialog.kind === 'sync' ? tt('source.syncConfirmTitle') : tt('source.deleteConfirmTitle')}\n text={confirmDialog.kind === 'sync' ? tt('source.syncConfirmText') : tt('source.deleteConfirmText')}\n items={confirmDialog.skills}\n confirmLabel={confirmDialog.kind === 'sync' ? tt('source.sync') : tt('source.followDelete')}\n danger={confirmDialog.kind === 'delete'}\n onCancel={() => { setConfirmDialog(null) }}\n onConfirm={() => { void runConfirmed() }}\n />\n ) : null}\n\n {branchChoice !== null ? (\n <BranchChoiceDialog\n choice={branchChoice}\n busy={branchBusy}\n onSelect={(selected) => { setBranchChoice({ ...branchChoice, selected }) }}\n onCancel={() => { setBranchChoice(null) }}\n onConfirm={() => { void confirmBranchChoice() }}\n />\n ) : null}\n\n {marketSyncDialog !== null ? (\n <MarketSyncDialog\n dialog={marketSyncDialog}\n busy={syncBusy}\n onToggle={(name, checked) => {\n const next = new Set(marketSyncDialog.selected)\n if (checked) next.add(name)\n else next.delete(name)\n setMarketSyncDialog({ ...marketSyncDialog, selected: next })\n }}\n onCancel={() => { setMarketSyncDialog(null) }}\n onConfirm={() => { void confirmMarketSync() }}\n />\n ) : null}\n\n {deleteSkillDialog !== null ? (\n <ConfirmDialog\n title={tt('delete.confirmTitle')}\n text={tt('delete.confirmText', { name: deleteSkillDialog })}\n confirmLabel={tt('delete.confirm')}\n danger\n onCancel={() => { setDeleteSkillDialog(null) }}\n onConfirm={() => { void runDeleteSkill() }}\n />\n ) : null}\n\n {deleteGroupDialog !== null ? (\n <ConfirmDialog\n title={tt('source.deleteGroupTitle')}\n text={tt('source.deleteGroupText', { name: deleteGroupDialog.name, count: deleteGroupDialog.skillNames.length })}\n items={deleteGroupDialog.skillNames}\n confirmLabel={tt('source.deleteGroup')}\n danger\n onCancel={() => { setDeleteGroupDialog(null) }}\n onConfirm={() => { void runDeleteGroup() }}\n />\n ) : null}\n\n {confirmClearTrash ? (\n <ConfirmDialog\n title={tt('source.clearTrashConfirmTitle')}\n text={tt('source.clearTrashConfirmText')}\n confirmLabel={tt('source.clearTrashConfirm')}\n danger\n onCancel={() => { setConfirmClearTrash(false) }}\n onConfirm={() => { void clearTrash() }}\n />\n ) : null}\n </div>\n )\n}\n","/**\n * Browser-half entry for the dsh-skill-hub plugin — runs inside the dsh\n * web GUI.\n *\n * Registers the dsh-skill-hub locale dictionaries and mounts two Settings\n * surfaces, both through official slots (no DOM injection):\n * - a plugin-management card in the `settings.plugin.item` slot (Settings →\n * 插件 → 可配置插件列表), keyed by the hub's settings namespace and bound\n * through the official settings transport (dsh rc.7 serves every\n * registered namespace to the web client, and the tab dispatches cards by\n * namespace) — the family-bucket card pattern (PluginSettingsCard +\n * CardForm vendored from dsh-task-board);\n * - a top-level Settings section (Settings → 技能) hosting the skill hub\n * panel: catalog, search, enable/disable, diagnostics, new-skill form.\n *\n * Failure policy: mounting problems are logged, never thrown — the web\n * shell fails the whole boot when a plugin apply throws, and an external\n * plugin must not take the GUI down.\n *\n * Export discipline (packages/client rule): the /client surface carries\n * what cordis loading needs plus types only — all value exports stay\n * internal.\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the settings-scope service merge and the settings.section slot.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the LocaleNamespaceMap merge table.\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\n// Type-only: pulls the settings-plugins SlotMap merge (settings.plugin.item).\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\n// Type-only: pulls the Context merge for ctx.inputTriggers (slash-dots wiring).\nimport type {} from '@deepseek-ai/dsh-client-ui-input-trigger/client'\n// Type-only: pulls the connection/reset event.\nimport type {} from '@deepseek-ai/dsh-client-connection/client'\n\n// 0.1.2-alpha.2: slots service moved to ui-renderer; provide local augmentation for build.\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n slots: any\n }\n}\nimport type { HubSettingsValue } from '../protocol.ts'\nimport { SkillHubApi } from './api.ts'\nimport { en, zh, type HubKey } from './locales.ts'\nimport { applySettingsNavIcon } from './settings-nav-icon.ts'\nimport { setupSkillSlashDots } from './slash-dots.tsx'\nimport { SkillHubSettingsCard, SkillHubSettingsCardController } from './SkillHubSettingsCard.tsx'\nimport { SkillHubPanel } from './panel/SkillHubPanel.tsx'\n\n/** Locale namespace this plugin owns. */\nconst NS = 'dsh-skill-hub'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** dsh-skill-hub surface copy. */\n 'dsh-skill-hub': HubKey\n }\n}\n\n/**\n * Required services (fiber inject waiting — the runtime must be up first).\n * `connection`/`remote` are the settings transport's own prerequisites\n * (`ctx.settingsScope.bind` resolves them on the caller's fiber), and\n * `settingsScope` is the namespace-scope binder itself; mirror the official\n * settings-plugins inject list.\n */\nexport const inject = ['slots', 'locale', 'connection', 'remote', 'settingsScope', 'inputTriggers']\n\n/** Type-only surface (export discipline: no value exports beyond the plugin contract). */\nexport type { SkillHubPanelProps } from './panel/SkillHubPanel.tsx'\nexport type { SkillHubSettingsState } from './SkillHubSettingsCard.tsx'\nexport type { HubKey } from './locales.ts'\n\n/**\n * Mount the settings card and the skill hub section.\n * @param ctx - client root context (slots, locale).\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-skill-hub: dictionaries')\n const t = ctx.locale.bind(NS)\n const api = new SkillHubApi()\n\n // The card edits the hub's settings namespace through the official\n // settings transport — the configurable-plugins tab only dispatches cards\n // whose key the Host serves, and the Host serves every registered namespace\n // since rc.7, so this is what makes the card appear (and stay in sync).\n const settingsCard = new SkillHubSettingsCardController(\n ctx.settingsScope.bind<HubSettingsValue>({ namespace: NS }),\n )\n\n // Chat `/` menu skill dots: wrap the core skill source so every candidate\n // row carries the invocation dot, colored from the same settings the panel\n // legend uses (dotModelColor / dotUserColor). Own scope = independent reader;\n // fails silent, never takes the GUI down.\n ctx.effect(\n () => setupSkillSlashDots(ctx, api, ctx.settingsScope.bind<HubSettingsValue>({ namespace: NS })),\n 'dsh-skill-hub: slash dots',\n )\n\n // Plugin-management card: Settings → 插件 → 可配置插件列表.\n // rc.7's slot contract declares this keyed slot with options `key`\n // (the settings namespace the card edits), so registration is fully typed.\n ctx.effect(\n () => ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n key: NS,\n locale: NS,\n inject: () => settingsCard.inject(),\n }, SkillHubSettingsCard)),\n 'dsh-skill-hub: settings card',\n )\n\n // Top-level Settings section: the skill management page.\n ctx.effect(\n () => ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'skill-hub',\n order: 12,\n label: () => t('entry.label'),\n locale: NS,\n inject: () => ({}),\n }, () => <SkillHubPanel api={api} />)),\n 'dsh-skill-hub: settings section',\n )\n\n // Host shell has no section-icon registration; keep the nav gear swapped for the skill icon.\n ctx.effect(() => applySettingsNavIcon(), 'dsh-skill-hub: settings nav icon')\n}\n"],"x_google_ignoreList":[10,11,12,13],"mappings":";;;;;;;;;;;;;;;;EAQA,MAAa,gBAAgB;GAC3B,SAAS;GACT,OAAO;GACP,aAAa;GACb,QAAQ;GACR,aAAa;GACb,QAAQ;GACR,OAAO;GACP,QAAQ;GACR,QAAQ;GACR,cAAc;GACd,oBAAoB;GACpB,iBAAiB;GACjB,aAAa;GACb,YAAY;GACZ,MAAM;GACN,YAAY;GACZ,oBAAoB;GACpB,kBAAkB;GAClB,QAAQ;GACR,QAAQ;GACR,KAAK;GACL,WAAW;GACX,YAAY;GACZ,YAAY;GACZ,mBAAmB;GACnB,oBAAoB;GACpB,SAAS;GACT,aAAa;GACb,YAAY;GACZ,cAAc;GACd,eAAe;GACf,kBAAkB;EACpB;;;;;;;;ECUA,IAAa,mBAAb,cAAsC,MAAM;GAC1C,YAAY,SAAiB;IAC3B,MAAM,OAAO;IACb,KAAK,OAAO;GACd;EACF;;EAGA,eAAe,SAAY,UAAgC;GACzD,IAAI;GACJ,IAAI;IACF,OAAO,MAAM,SAAS,KAAK;GAC7B,QAAQ;IACN,MAAM,IAAI,iBAAiB,UAAU,SAAS,SAAS,yBAAyB;GAClF;GACA,IAAI,CAAC,SAAS,IAIZ,MAAM,IAAI,iBAHM,OAAO,SAAS,YAAY,SAAS,QAAQ,OAAQ,KAA6B,UAAU,WACvG,KAA2B,QAC5B,UAAU,SAAS,MACW;GAEpC,OAAO;EACT;;;;;;EAOA,eAAe,iBAAiB,OAA0B,MAAoB,KAAK,KAA2B;GAC5G,MAAM,aAAa,IAAI,gBAAgB;GACvC,MAAM,QAAQ,iBAAiB,WAAW,MAAM,GAAG,EAAE;GACrD,IAAI;IACF,OAAO,MAAM,MAAM,OAAO;KAAE,GAAG;KAAM,QAAQ,WAAW;IAAO,CAAC;GAClE,UAAU;IACR,aAAa,KAAK;GACpB;EACF;;EAGA,IAAa,cAAb,MAAyB;;GAEvB,QAAQ,SAAsD;IAE5D,OAAO,iBADK,SAAS,QAAQ,KAAA,KAAa,QAAQ,QAAQ,KAAK,cAAc,UAAU,UAAU,mBAAmB,QAAQ,GAAG,IAAI,cAAc,OACtH,CAAC,CAAC,MAAM,aAAa,SAA0B,QAAQ,CAAC;GACrF;;GAGA,MAAM,MAAM,MAAc,SAAkD;IAC1E,MAAM,MAAM,SAAS,QAAQ,KAAA,KAAa,QAAQ,QAAQ,KAAK,UAAU,mBAAmB,QAAQ,GAAG,IAAI;IAI3G,QAAO,MADY,SAA8B,MAD1B,iBADX,cAAc,QAAQ,WAAW,mBAAmB,IAAI,IAAI,GAC7B,CACc,EAAA,CAC7C;GACd;;GAGA,MAAM,YAAY,MAA4C;IAM5D,OAAO,SAA8B,MALd,iBAAiB,cAAc,aAAa;KACjE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,KAAK,CAA8B;IAC5D,CAAC,CAC4C;GAC/C;;GAGA,MAAM,OAAO,MAAc,SAA4C;IAOrE,QAAO,MADY,SAAkD,MAL9C,iBAAiB,cAAc,QAAQ;KAC5D,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU;MAAE;MAAM;KAAQ,CAAkD;IACzF,CAAC,CAC4E,EAAA,CACjE;GACd;GAEA,MAAM,OAAO,SAAiD;IAM5D,OAAO,SAAyB,MALT,iBAAiB,cAAc,QAAQ;KAC5D,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CACuC;GAC1C;GAEA,MAAM,QAAgC;IAEpC,OAAO,SAAwB,MADR,iBAAiB,cAAc,KAAK,CACpB;GACzC;;GAGA,MAAM,YAAY,OAAiB,SAAgD;IACjF,MAAM,UAA8B;KAAE;KAAO;IAAQ;IAMrD,OAAO,SAA8B,MALd,iBAAiB,cAAc,aAAa;KACjE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC4C;GAC/C;;GAGA,MAAM,SAAyC;IAE7C,OAAO,SAAgC,MADhB,iBAAiB,cAAc,MAAM,CACb;GACjD;;GAGA,MAAM,gBAAgB,MAA8C;IAMlE,OAAO,SAA+B,MALf,iBAAiB,cAAc,cAAc;KAClE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,KAAK,CAA+B;IAC7D,CAAC,CAC6C;GAChD;;GAGA,MAAM,mBAAmB,MAA8C;IAMrE,OAAO,SAA+B,MALf,iBAAiB,cAAc,oBAAoB;KACxE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,KAAK,CAA+B;IAC7D,CAAC,CAC6C;GAChD;;GAGA,MAAM,cAA4C;IAEhD,OAAO,SAA8B,MADd,iBAAiB,cAAc,WAAW,CACpB;GAC/C;;GAGA,MAAM,WAAW,MAA2C;IAM1D,OAAO,SAA6B,MALb,iBAAiB,cAAc,YAAY;KAChE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,KAAK,CAAC;IAC/B,CAAC,CAC2C;GAC9C;;GAGA,MAAM,mBAAmB,MAAc,KAA6C;IAMlF,OAAO,SAA+B,MALf,iBAAiB,cAAc,iBAAiB;KACrE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU;MAAE;MAAM;KAAI,CAAkC;IACrE,CAAC,CAC6C;GAChD;;GAGA,MAAM,cAA4C;IAEhD,OAAO,SAA8B,MADd,iBAAiB,cAAc,MAAM,CACf;GAC/C;;GAGA,MAAM,aAAa,MAA6C;IAG9D,OAAO,SAA+B,MADf,iBADX,cAAc,OAAO,WAAW,mBAAmB,IAAI,CACxB,CACG;GAChD;;GAGA,MAAM,WAAW,MAAc,OAAiB,KAA2C;IACzF,MAAM,UAA6B;KAAE;KAAM;KAAO,GAAI,QAAQ,KAAA,KAAa,QAAQ,KAAK,EAAE,IAAI,IAAI,CAAC;IAAG;IAMtG,OAAO,SAA6B,MALb,iBAAiB,cAAc,YAAY;KAChE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC2C;GAC9C;;GAGA,MAAM,mBAAmB,OAAoD;IAG3E,OAAO,SAAqC,MADrB,iBADX,cAAc,qBAAqB,YAAY,mBAAmB,KAAK,CACxC,CACS;GACtD;;GAGA,MAAM,iBAAiB,OAAkD;IAMvE,OAAO,SAAmC,MALnB,iBAAiB,cAAc,kBAAkB;KACtE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,MAAM,CAAC;IAChC,CAAC,CACiD;GACpD;;GAGA,MAAM,SAAkC;IAEtC,OAAO,SAAyB,MADT,iBAAiB,cAAc,MAAM,CACpB;GAC1C;;GAGA,MAAM,WAAW,OAA+C;IAM9D,OAAO,SAAyB,MALT,iBAAiB,cAAc,QAAQ;KAC5D,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,KAAK;IAC5B,CAAC,CACuC;GAC1C;;GAGA,MAAM,SAA2D;IAE/D,OAAO,SAAkD,MADlC,iBAAiB,cAAc,MAAM,CACK;GACnE;;GAGA,MAAM,QAAQ,SAAgG;IAO5G,QAAO,MADY,SAAmD,MAL/C,iBAAiB,cAAc,KAAK;KACzD,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC6E,EAAA,CAClE;GACd;;GAGA,MAAM,UAAU,IAA0D;IAOxE,QAAO,MADY,SAAqD,MALjD,iBAAiB,cAAc,WAAW;KAC/D,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,GAAG,CAAqD;IACjF,CAAC,CAC+E,EAAA,CACpE;GACd;;GAGA,MAAM,cAAc,IAAY,YAAoE;IAOlG,QAAO,MADY,SAAsD,MALlD,iBAAiB,cAAc,YAAY;KAChE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU;MAAE;MAAI;KAAW,CAAsD;IAC9F,CAAC,CACgF,EAAA,CACrE;GACd;;GAGA,MAAM,YAAY,YAA2C;IAO3D,QAAO,MADY,SAA6B,MALzB,iBAAiB,cAAc,YAAY;KAChE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,WAAW,CAA6B;IACjE,CAAC,CACuD,EAAA,CAC5C;GACd;;GAGA,MAAM,mBAAmB,cAAoD;IAO3E,QAAO,MADY,SAAoC,MALhC,iBAAiB,cAAc,mBAAmB;KACvE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,aAAa,CAAoC;IAC1E,CAAC,CAC8D,EAAA,CACnD;GACd;;GAGA,MAAM,oBAAoB,aAA0C;IAOlE,QAAO,MADY,SAAqC,MALjC,iBAAiB,cAAc,oBAAoB;KACxE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,EAAE,YAAY,CAAqC;IAC1E,CAAC,CAC+D,EAAA,CACpD;GACd;;GAGA,MAAM,UAAoC;IAExC,OAAO,SAA0B,MADV,iBAAiB,cAAc,OAAO,CACpB;GAC3C;;GAGA,MAAM,aAAa,MAA6C;IAC9D,MAAM,UAA8B,SAAS,KAAA,IAAY,EAAE,KAAK,IAAI,CAAC;IAMrE,OAAO,SAA8B,MALd,iBAAiB,cAAc,aAAa;KACjE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC4C;GAC/C;;GAGA,MAAM,WAAW,MAAc,QAAgD;IAC7E,MAAM,UAA6B,WAAW,KAAA,IAAY;KAAE;KAAM;IAAO,IAAI,EAAE,KAAK;IAMpF,OAAO,SAA6B,MALb,iBAAiB,cAAc,YAAY;KAChE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC2C;GAC9C;;GAGA,MAAM,oBAAoB,MAAc,QAAiD;IACvF,MAAM,UAA+B;KAAE;KAAM;IAAO;IAMpD,OAAO,SAA+B,MALf,iBAAiB,cAAc,cAAc;KAClE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC6C;GAChD;;GAGA,MAAM,cAAc,MAA8C;IAChE,MAAM,UAAgC,EAAE,KAAK;IAM7C,OAAO,SAAgC,MALhB,iBAAiB,cAAc,eAAe;KACnE,QAAQ;KACR,SAAS,EAAE,gBAAgB,mBAAmB;KAC9C,MAAM,KAAK,UAAU,OAAO;IAC9B,CAAC,CAC8C;GACjD;;GAGA,MAAM,aAAgD;IAEpD,OAAO,SAAmC,MADnB,iBAAiB,cAAc,kBAAkB,EAAE,QAAQ,OAAO,CAAC,CACxC;GACpD;EACF;;;;;;;;EC/XA,MAAa,KAAK;GAChB,eAAe;GACf,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,aAAa;GACb,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,uBAAuB;GACvB,aAAa;GACb,gBAAgB;GAChB,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,qBAAqB;GACrB,eAAe;GACf,kBAAkB;GAClB,iBAAiB;GACjB,oBAAoB;GACpB,8BAA8B;GAC9B,uBAAuB;GACvB,wBAAwB;GACxB,yBAAyB;GACzB,oBAAoB;GACpB,oBAAoB;GACpB,gBAAgB;GAChB,sBAAsB;GACtB,6BAA6B;GAC7B,8BAA8B;GAC9B,6BAA6B;GAC7B,6BAA6B;GAC7B,cAAc;GACd,oBAAoB;GACpB,oBAAoB;GACpB,0BAA0B;GAC1B,mBAAmB;GACnB,oBAAoB;GACpB,gCAAgC;GAChC,+BAA+B;GAC/B,wBAAwB;GACxB,wBAAwB;GACxB,uBAAuB;GACvB,eAAe;GACf,mBAAmB;GACnB,gBAAgB;GAChB,sBAAsB;GACtB,mBAAmB;GACnB,mBAAmB;GACnB,iBAAiB;GACjB,sBAAsB;GACtB,eAAe;GACf,kBAAkB;GAClB,kBAAkB;GAClB,qBAAqB;GACrB,sBAAsB;GACtB,qBAAqB;GACrB,wBAAwB;GACxB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,qBAAqB;GACrB,qBAAqB;GACrB,cAAc;GACd,cAAc;GACd,kBAAkB;GAClB,iBAAiB;GACjB,eAAe;GACf,kBAAkB;GAClB,iBAAiB;GACjB,cAAc;GACd,iBAAiB;GACjB,wBAAwB;GACxB,eAAe;GACf,eAAe;GACf,kBAAkB;GAClB,yBAAyB;GACzB,oBAAoB;GACpB,6BAA6B;GAC7B,qBAAqB;GACrB,gBAAgB;GAChB,mBAAmB;GACnB,mBAAmB;GACnB,oBAAoB;GACpB,qBAAqB;GACrB,sBAAsB;GACtB,gBAAgB;GAChB,sBAAsB;GACtB,qBAAqB;GACrB,wBAAwB;GACxB,gBAAgB;GAChB,iBAAiB;GACjB,kBAAkB;GAClB,qBAAqB;GACrB,iBAAiB;GACjB,eAAe;GACf,cAAc;GACd,0BAA0B;GAC1B,eAAe;GACf,iBAAiB;GACjB,iBAAiB;GACjB,sBAAsB;GACtB,sBAAsB;GACtB,gBAAgB;GAChB,wBAAwB;GACxB,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;GACpB,gBAAgB;GAChB,qBAAqB;GACrB,mBAAmB;GACnB,iBAAiB;GACjB,wBAAwB;GACxB,uBAAuB;GACvB,qBAAqB;GACrB,kBAAkB;GAClB,aAAa;GACb,cAAc;GACd,aAAa;GACb,gBAAgB;GAChB,mBAAmB;GACnB,iBAAiB;GACjB,gBAAgB;GAChB,iBAAiB;GACjB,4BAA4B;GAC5B,+BAA+B;GAC/B,uBAAuB;GACvB,wBAAwB;GACxB,yBAAyB;GACzB,4BAA4B;GAC5B,wBAAwB;GACxB,gBAAgB;GAChB,eAAe;GACf,cAAc;GACd,cAAc;GACd,YAAY;GACZ,uBAAuB;GACvB,sBAAsB;GACtB,kBAAkB;GAClB,eAAe;GACf,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;GACpB,eAAe;GACf,oBAAoB;GACpB,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,kBAAkB;GAClB,iBAAiB;GACjB,qBAAqB;GACrB,gBAAgB;GAChB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,kBAAkB;GAClB,kBAAkB;GAClB,gBAAgB;GAChB,oBAAoB;GACpB,eAAe;GACf,kBAAkB;GAClB,2BAA2B;GAC3B,0BAA0B;GAC1B,uBAAuB;GACvB,6BAA6B;GAC7B,4BAA4B;GAC5B,sBAAsB;GACtB,0BAA0B;GAC1B,2BAA2B;GAC3B,0BAA0B;GAC1B,gBAAgB;GAChB,kBAAkB;GAClB,qBAAqB;GACrB,iCAAiC;GACjC,gCAAgC;GAChC,4BAA4B;GAC5B,uBAAuB;GACvB,wBAAwB;GACxB,aAAa;GACb,aAAa;GACb,aAAa;GACb,eAAe;GACf,eAAe;GACf,aAAa;GACb,gBAAgB;GAChB,cAAc;GACd,eAAe;GACf,kBAAkB;GAClB,wBAAwB;GACxB,oBAAoB;GACpB,wBAAwB;GACxB,4BAA4B;GAC5B,gCAAgC;GAChC,0BAA0B;GAC1B,8BAA8B;GAC9B,yBAAyB;GACzB,6BAA6B;GAC7B,yBAAyB;GACzB,6BAA6B;GAC7B,wBAAwB;GACxB,4BAA4B;GAC5B,6BAA6B;GAC7B,iCAAiC;GACjC,4BAA4B;GAC5B,gCAAgC;GAChC,6BAA6B;GAC7B,iCAAiC;GACjC,oBAAoB;GACpB,eAAe;GACf,gBAAgB;GAChB,uBAAuB;GACvB,kBAAkB;GAClB,oBAAoB;GACpB,iBAAiB;GACjB,mBAAmB;GACnB,oBAAoB;GACpB,uBAAuB;GACvB,qBAAqB;GACrB,uBAAuB;GACvB,qBAAqB;GACrB,mBAAmB;EACrB;EAEA,MAAa,KAA6B;GACxC,eAAe;GACf,iBAAiB;GACjB,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,aAAa;GACb,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,uBAAuB;GACvB,aAAa;GACb,gBAAgB;GAChB,gBAAgB;GAChB,eAAe;GACf,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,qBAAqB;GACrB,eAAe;GACf,kBAAkB;GAClB,iBAAiB;GACjB,oBAAoB;GACpB,8BAA8B;GAC9B,uBAAuB;GACvB,wBAAwB;GACxB,yBAAyB;GACzB,oBAAoB;GACpB,oBAAoB;GACpB,gBAAgB;GAChB,sBAAsB;GACtB,6BAA6B;GAC7B,8BAA8B;GAC9B,6BAA6B;GAC7B,6BAA6B;GAC7B,cAAc;GACd,oBAAoB;GACpB,oBAAoB;GACpB,0BAA0B;GAC1B,mBAAmB;GACnB,oBAAoB;GACpB,gCAAgC;GAChC,+BAA+B;GAC/B,wBAAwB;GACxB,wBAAwB;GACxB,uBAAuB;GACvB,eAAe;GACf,mBAAmB;GACnB,gBAAgB;GAChB,sBAAsB;GACtB,mBAAmB;GACnB,mBAAmB;GACnB,iBAAiB;GACjB,sBAAsB;GACtB,eAAe;GACf,kBAAkB;GAClB,kBAAkB;GAClB,qBAAqB;GACrB,sBAAsB;GACtB,qBAAqB;GACrB,wBAAwB;GACxB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,qBAAqB;GACrB,qBAAqB;GACrB,cAAc;GACd,cAAc;GACd,kBAAkB;GAClB,iBAAiB;GACjB,eAAe;GACf,kBAAkB;GAClB,iBAAiB;GACjB,cAAc;GACd,iBAAiB;GACjB,wBAAwB;GACxB,eAAe;GACf,eAAe;GACf,kBAAkB;GAClB,yBAAyB;GACzB,oBAAoB;GACpB,6BAA6B;GAC7B,qBAAqB;GACrB,gBAAgB;GAChB,mBAAmB;GACnB,mBAAmB;GACnB,oBAAoB;GACpB,qBAAqB;GACrB,sBAAsB;GACtB,gBAAgB;GAChB,sBAAsB;GACtB,qBAAqB;GACrB,wBAAwB;GACxB,gBAAgB;GAChB,iBAAiB;GACjB,kBAAkB;GAClB,qBAAqB;GACrB,iBAAiB;GACjB,eAAe;GACf,cAAc;GACd,0BAA0B;GAC1B,eAAe;GACf,iBAAiB;GACjB,iBAAiB;GACjB,sBAAsB;GACtB,sBAAsB;GACtB,gBAAgB;GAChB,wBAAwB;GACxB,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;GACpB,gBAAgB;GAChB,qBAAqB;GACrB,mBAAmB;GACnB,iBAAiB;GACjB,wBAAwB;GACxB,uBAAuB;GACvB,qBAAqB;GACrB,kBAAkB;GAClB,aAAa;GACb,cAAc;GACd,aAAa;GACb,gBAAgB;GAChB,mBAAmB;GACnB,iBAAiB;GACjB,gBAAgB;GAChB,iBAAiB;GACjB,4BAA4B;GAC5B,+BAA+B;GAC/B,uBAAuB;GACvB,wBAAwB;GACxB,yBAAyB;GACzB,4BAA4B;GAC5B,wBAAwB;GACxB,gBAAgB;GAChB,eAAe;GACf,cAAc;GACd,cAAc;GACd,YAAY;GACZ,uBAAuB;GACvB,sBAAsB;GACtB,kBAAkB;GAClB,eAAe;GACf,mBAAmB;GACnB,kBAAkB;GAClB,oBAAoB;GACpB,eAAe;GACf,oBAAoB;GACpB,eAAe;GACf,iBAAiB;GACjB,kBAAkB;GAClB,kBAAkB;GAClB,iBAAiB;GACjB,qBAAqB;GACrB,gBAAgB;GAChB,oBAAoB;GACpB,mBAAmB;GACnB,mBAAmB;GACnB,kBAAkB;GAClB,kBAAkB;GAClB,gBAAgB;GAChB,oBAAoB;GACpB,eAAe;GACf,kBAAkB;GAClB,2BAA2B;GAC3B,0BAA0B;GAC1B,uBAAuB;GACvB,6BAA6B;GAC7B,4BAA4B;GAC5B,sBAAsB;GACtB,0BAA0B;GAC1B,2BAA2B;GAC3B,0BAA0B;GAC1B,gBAAgB;GAChB,kBAAkB;GAClB,qBAAqB;GACrB,iCAAiC;GACjC,gCAAgC;GAChC,4BAA4B;GAC5B,uBAAuB;GACvB,wBAAwB;GACxB,aAAa;GACb,aAAa;GACb,aAAa;GACb,eAAe;GACf,eAAe;GACf,aAAa;GACb,gBAAgB;GAChB,cAAc;GACd,eAAe;GACf,kBAAkB;GAClB,wBAAwB;GACxB,oBAAoB;GACpB,wBAAwB;GACxB,4BAA4B;GAC5B,gCAAgC;GAChC,0BAA0B;GAC1B,8BAA8B;GAC9B,yBAAyB;GACzB,6BAA6B;GAC7B,yBAAyB;GACzB,6BAA6B;GAC7B,wBAAwB;GACxB,4BAA4B;GAC5B,6BAA6B;GAC7B,iCAAiC;GACjC,4BAA4B;GAC5B,gCAAgC;GAChC,6BAA6B;GAC7B,iCAAiC;GACjC,oBAAoB;GACpB,eAAe;GACf,gBAAgB;GAChB,uBAAuB;GACvB,kBAAkB;GAClB,oBAAoB;GACpB,iBAAiB;GACjB,mBAAmB;GACnB,oBAAoB;GACpB,uBAAuB;GACvB,qBAAqB;GACrB,uBAAuB;GACvB,qBAAqB;GACrB,mBAAmB;EACrB;;EASA,SAAgB,EAAE,MAA8B,KAAa,QAAkC;GAC7F,IAAI,OAAO,KAAK,QAAQ;GACxB,IAAI,WAAW,KAAA,GACb,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,GAC/C,OAAO,KAAK,WAAW,MAAM,OAAO,KAAK,OAAO,KAAK,CAAC;GAG1D,OAAO;EACT;;;;;;;;;ECldA,MAAM,uBAAuB,CAAC,MAAM,QAAQ;EAE5C,MAAM,iBAAiB;EAEvB,IAAI,eAAqC;EAEzC,SAAS,YAA2B;GAClC,IAAI,iBAAiB,MACnB,eAAe,IAAI,UAAU,CAAC,CAAC,gBAAgB,gBAAgB,eAAe,CAAC,CAAC;GAElF,OAAO,aAAa,UAAU,IAAI;EACpC;EAEA,SAAS,eAAqB;GAC5B,MAAM,SAAS,SAAS,cAAc,mBAAiB;GACvD,IAAI,WAAW,MAAM;GACrB,KAAK,MAAM,UAAU,OAAO,iBAAoC,QAAQ,GAAG;IACzE,MAAM,QAAQ,OAAO,cAAc,MAAM;IACzC,IAAI,UAAU,QAAQ,CAAC,qBAAqB,SAAS,MAAM,aAAa,KAAK,KAAK,EAAE,GAAG;IACvF,IAAI,OAAO,cAAc,8BAA8B,MAAM,MAAM;IACnE,MAAM,UAAU,OAAO,cAAc,KAAK;IAC1C,MAAM,OAAO,UAAU;IACvB,IAAI,YAAY,MAAM,QAAQ,YAAY,IAAI;SACzC,OAAO,aAAa,MAAM,OAAO,UAAU;GAClD;EACF;;EAGA,SAAgB,uBAAmC;GACjD,IAAI,OAAO,aAAa,eAAe,OAAO,qBAAqB,aAAa,aAAa,CAAC;GAC9F,aAAa;GACb,MAAM,WAAW,IAAI,uBAAuB;IAAE,aAAa;GAAE,CAAC;GAC9D,SAAS,QAAQ,SAAS,MAAM;IAAE,WAAW;IAAM,SAAS;GAAK,CAAC;GAClE,aAAa;IAAE,SAAS,WAAW;GAAE;EACvC;;;;;;;;ECPA,SAAgB,gBAAgB,SAA4B,cAAoD;GAC9G,MAAM,UAAoB,CAAC;GAC3B,MAAM,WAAqB,CAAC;GAC5B,KAAK,MAAM,QAAQ,SACjB,IAAI,aAAa,IAAI,IAAI,GAAG,QAAQ,KAAK,IAAI;QACxC,SAAS,KAAK,IAAI;GAGzB,OAAO;IAAE,OADuB,SAAS,WAAW,IAAI,OAAO,QAAQ,WAAW,IAAI,QAAQ;IAC9E;IAAS;GAAS;EACpC;;EAGA,SAAgB,aAAa,MAAc,MAA2B,aAAmD;GACvH,MAAM,QAAkB,CAAC;GACzB,KAAK,MAAM,OAAO,MAAM,IAAI,IAAI,WAAW,SAAS,IAAI,GAAG,MAAM,KAAK,IAAI,IAAI;GAC9E,KAAK,MAAM,cAAc,aAAa,IAAI,WAAW,WAAW,SAAS,IAAI,GAAG,MAAM,KAAK,WAAW,IAAI;GAC1G,OAAO;EACT;;;;;EAMA,SAAgB,iBACd,SACA,cACA,aACU;GACV,OAAO,QAAQ,QAAQ,SAAS;IAC9B,IAAI,CAAC,aAAa,IAAI,IAAI,GAAG,OAAO;IACpC,OAAO,YAAY,MAAM,UAAU,MAAM,QAAQ,SAAS,IAAI,CAAC;GACjE,CAAC;EACH;;EAGA,MAAa,iBAAiB;;EAG9B,SAAgB,gBAAgB,QAAyB;GACvD,OAAO,WAAW,iBAAiB,WAAW;EAChD;;;;;;;;EASA,SAAgB,eAAe,QAAiC,QAAgB,SAA2D;GACzI,IAAI,WAAW,OAAO,OAAO,CAAC,GAAG,MAAM;GACvC,OAAO,OAAO,QAAQ,UAAU;IAC9B,IAAI,gBAAgB,MAAM,MAAM,GAAG,OAAO;IAC1C,QAAQ,QAAQ,MAAM,SAAA,eAA6B;GACrD,CAAC;EACH;;;;;;EAUA,SAAgB,WAAW,QAAiC,KAAc,SAAgE;GACxI,MAAM,OAAO,CAAC,GAAG,MAAM;GACvB,IAAI,QAAQ,QACV,KAAK,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;QAC3C,IAAI,QAAQ,SACjB,KAAK,MAAM,GAAG,OAAO,EAAE,WAAW,cAAc,EAAE,WAAW,UAAU;QAClE,IAAI,QAAQ,QACjB,KAAK,MAAM,GAAG,OAAO,UAAU,EAAE,IAAI,KAAK,MAAM,UAAU,EAAE,IAAI,KAAK,EAAE;GAEzE,OAAO;EACT;;EASA,SAAgB,mBAAmB,IAAY,MAAM,KAAK,IAAI,GAAiB;GAC7E,MAAM,OAAO,KAAK,IAAI,GAAG,MAAM,EAAE;GACjC,MAAM,UAAU,KAAK,MAAM,OAAO,GAAM;GACxC,IAAI,UAAU,GAAG,OAAO,EAAE,KAAK,eAAe;GAC9C,IAAI,UAAU,IAAI,OAAO;IAAE,KAAK;IAAmB,OAAO;GAAQ;GAClE,MAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;GACrC,IAAI,QAAQ,IAAI,OAAO;IAAE,KAAK;IAAiB,OAAO;GAAM;GAC5D,MAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;GAClC,IAAI,OAAO,GAAG,OAAO;IAAE,KAAK;IAAgB,OAAO;GAAK;GACxD,OAAO;IAAE,KAAK;IAAiB,OAAO,KAAK,MAAM,OAAO,CAAC;GAAE;EAC7D;;;;;;;;ECzHA,SAAgB,aAAqC;GAEnD,QADa,OAAO,aAAa,cAAc,SAAS,gBAAgB,OAAO,KAAA,CACnE,YAAY,CAAC,CAAC,WAAW,IAAI,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,GAAG;EACnE;;EAGA,SAAgB,GAAG,KAAa,QAAkC;GAChE,OAAO,EAAE,WAAW,GAAG,KAAK,MAAM;EACpC;;EAGA,SAAgB,aAAa,OAAwB;GACnD,IAAI,iBAAiB,OAAO,OAAO,MAAM;GACzC,OAAO,OAAO,KAAK;EACrB;;;;;ECLA,MAAa,0BAA0B;;;EAGvC,MAAa,yBAAyB;;EAGtC,SAAgB,SAAS,OAAsD;GAC7E,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;GAChC,OAAO;IAAE,YAAY;IAAO,aAAa;GAAM;EACjD;;EAGA,SAAgB,iBAAiB,IAAoB;GACnD,MAAM,KAAK,mBAAmB,EAAE;GAChC,OAAO,GAAG,GAAG,KAAK,GAAG,UAAU,KAAA,IAAY,EAAE,OAAO,GAAG,MAAM,IAAI,KAAA,CAAS;EAC5E;;EAGA,SAAgB,eAAe,IAAoB;GACjD,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,eAAe;EACrC;;EAGA,SAAgB,SAAS,KAAqB;GAC5C,OAAO,IAAI,SAAS,IAAI,IAAI,MAAM,GAAG,CAAC,IAAI;EAC5C;;;;ECRA,MAAM,eAAe;GAAE,SAAS;GAAK,MAAM;EAAQ;;EAGnD,MAAM,eAAe;;;;;;;;EAcrB,SAAgB,gBAAgB,SAAsE;GACpG,MAAM,OAAQ,QAAsC;GACpD,IAAI,MAAM,YAAY,KAAA,GAAW,OAAO,KAAA;GACxC,OAAO,KAAK,QAAQ,MAAM,WAAW,OAAO,YAAY,aAAa,WAAW,OAAO,SAAS,aAAa,IAAI;EACnH;;EAGA,IAAI;;;;;EAMJ,SAAgB,kBAAwB;GACtC,aAAa,KAAA;EACf;;;;;;;;;EAUA,eAAe,kBAAkB,KAAiD;GAChF,MAAM,MAAM,KAAK,IAAI;GACrB,MAAM,SAAS;GACf,IAAI,WAAW,KAAA,KAAa,MAAM,OAAO,KAAK,cAC5C,OAAO,YAAY,yBAAS,IAAI,IAAI,IAAI,OAAO;GAEjD,IAAI;IACF,MAAM,UAAU,MAAM,IAAI,QAAQ;IAClC,MAAM,MAAM,IAAI,IAAqB,QAAQ,OAAO,KAAK,UAAU,CAAC,MAAM,MAAM,MAAM,WAAW,cAAc,CAAC,CAAC;IACjH,aAAa;KAAE,IAAI;KAAK;IAAI;IAC5B,OAAO;GACT,SAAS,OAAO;IACd,QAAQ,MAAM,kDAAkD,KAAK;IACrE,aAAa;KAAE,IAAI;KAAK,QAAQ;IAAK;IACrC,uBAAO,IAAI,IAAI;GACjB;EACF;;;;;;;EAQA,SAAS,QAAQ,OAA8C;GAC7D,QAAA,GAAA,MAAA,cAAA,CAAqB,QAAQ;IAC3B,eAAe;IACf,OAAO;KACL,SAAS;KACT,OAAO;KACP,QAAQ;KACR,cAAc;KACd,YAAY;KACZ,MAAM;IACR;GACF,CAAC;EACH;;;;;;;;;;;;;;EAeA,SAAS,iBAAiB,aAAmC,YAAoB,WAAyB;GACxG,IAAI,OAAO,aAAa,eAAe,OAAO,0BAA0B,aAAa;GACrF,MAAM,YAAkB;IACtB,MAAM,UAAU,SAAS,iBAAiB,mBAAiB;IAC3D,KAAK,MAAM,OAAO,SAAS;KAEzB,IAAI,IAAI,cAAc,kBAAkB,MAAM,MAAM;KAEpD,MAAM,SAAS,IAAI,cAAc,uBAAqB;KACtD,IAAI,WAAW,MAAM;KACrB,MAAM,QAAQ,OAAO,eAAe,GAAA,CAAI,KAAK;KAC7C,IAAI,KAAK,WAAW,GAAG;KACvB,IAAI,CAAC,YAAY,IAAI,IAAI,KAAK,OAAO,gBAAgB,MAAM;KAC3D,MAAM,QAAS,YAAY,IAAI,IAAI,KAAK,OAAQ,aAAa;KAC7D,MAAM,MAAM,SAAS,cAAc,MAAM;KACzC,IAAI,aAAa,kBAAkB,EAAE;KACrC,IAAI,aAAa,eAAe,MAAM;KACtC,IAAI,MAAM,UAAU;KACpB,IAAI,MAAM,QAAQ;KAClB,IAAI,MAAM,SAAS;KACnB,IAAI,MAAM,eAAe;KACzB,IAAI,MAAM,aAAa;KACvB,IAAI,MAAM,OAAO;KAEjB,MAAM,SAAS,IAAI,cAAc,uBAAqB;KACtD,IAAI,WAAW,QAAQ,OAAO,gBAAgB,MAC5C,OAAO,eAAe,aAAa,KAAK,OAAO,WAAW;UAE1D,OAAO,eAAe,aAAa,KAAK,MAAM;IAElD;GACF;GAEA,4BAA4B,WAAW,KAAK,CAAC,CAAC;EAChD;EAEA,SAAgB,gBAAgB,QAA4B,KAAkB,OAAoD;GAChI,MAAM,WAAW,OAAO;GACxB,OAAO,aAAa,OAAO,SAAS,QAAQ;IAC1C,MAAM,QAAQ,MAAM,SAAS,SAAS,GAAG;IACzC,IAAI,IAAI,OAAO,SAAS,OAAO;IAI/B,MAAM,YAAY,QAAQ,QAAQ,OAAO,QAAQ,YAAY,aAAc;IAC3E,MAAM,cAAc,MAAM,kBAAkB,GAAG;IAC/C,IAAI,IAAI,OAAO,SAAS,OAAO;IAC/B,MAAM,WAAW,MAAM,YAAY;IACnC,MAAM,aAAa,SAAS,OAAO,iBAAA;IACnC,MAAM,YAAY,SAAS,OAAO,gBAAA;IAClC,IAAI,WAAW;KAEb,iBAAiB,aAAa,YAAY,SAAS;KACnD,OAAO;IACT;IAEA,OAAO,MAAM,KAAK,UAAU;KAC1B,GAAG;KACH,MAAM,QAAS,YAAY,IAAI,KAAK,IAAI,KAAK,OAAQ,aAAa,SAAS;IAC7E,EAAE;GACJ;GACA,aAAa;IACX,OAAO,aAAa;GACtB;EACF;;;;;;;;;;;;EAaA,SAAgB,oBACd,KACA,KACA,OACY;GACZ,MAAM,gBAAgB,IAAI,IAAI,eAAe;GAC7C,IAAI,kBAAkB,KAAA,GAAW,aAAa,CAAC;GAE/C,IAAI,WAAW;GACf,IAAI;GACJ,IAAI,WAAW;GAIf,MAAM,gBAAsB;IAC1B,IAAI,UAAU;IACd,MAAM,SAAS,gBAAgB,aAAa;IAC5C,IAAI,WAAW,KAAA,GAAW;KACxB,IAAI,WAAW,IAAI;MACjB,YAAY;MACZ,WAAW,SAAS,GAAG;KACzB;KACA;IACF;IACA,UAAU,gBAAgB,QAAQ,KAAK,KAAK;GAC9C;GACA,QAAQ;GAER,MAAM,mBAAyB;IAC7B,gBAAgB;GAClB;GAEA,MAAM,WAAW,IAAI,GAAG,oBAAoB,UAAU;GAEtD,aAAa;IACX,WAAW;IACX,SAAS;IACT,UAAU;IACV,UAAU,KAAA;GACZ;EACF;;;;EC5NA,SAAgB,yBAAyB,EAAE,OAAO,IAAI,aAAqC;GACzF,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,OAAO;IAAM,QAAQ;IAAiB;IAAW,SAAQ;IAAY,MAAK;IAAO,OAAM;cAC1F,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,GAAE;KACF,MAAK;IACN,CAAA;GACE,CAAA;EAET;;EAGA,SAAgB,mBAAmB,EAAE,OAAO,IAAI,aAAqC;GACnF,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,OAAO;IAAM,QAAQ;IAAiB;IAAW,SAAQ;IAAY,MAAK;IAAO,OAAM;cAC1F,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,GAAE;KACF,MAAK;IACN,CAAA;GACE,CAAA;EAET;;EAGA,SAAgB,mBAAmB,EAAE,OAAO,IAAI,aAAqC;GACnF,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,OAAO;IAAM,QAAQ;IAAiB;IAAW,SAAQ;IAAY,MAAK;IAAO,OAAM;cAA5F,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,GAAE;KACF,MAAK;IACN,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KACE,GAAE;KACF,MAAK;IACN,CAAA,CACE;;EAET;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ECxBA,SAAgB,mBAAmB,OAAqD;GACtF,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,SAAA,CAAoB,KAAK;GACtC,MAAM,EAAE,UAAU;GAClB,IAAI,CAAC,MAAM,WAAW,OAAO;GAC7B,MAAM,QAAQ,MAAM,EAAE,MAAM,QAAQ;GACpC,MAAM,UAAU,CAAC,MAAM,SAAS,MAAM,WAAW,MAAM;GAEvD,MAAM,SACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;IACE,MAAK;IACL,WAAWA,iCAAI;IACf,iBAAe;IACf,cAAY,MAAM,EAAE,OAAO,sBAAsB,iBAAiB,IAAI,OAAO;IAC7E,eAAe;KAAE,QAAQ,CAAC,IAAI;IAAE;cALlC;KAOE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAWA,iCAAI;gBAArB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWA,iCAAI;iBAArB,CAA4B,OAAO,MAAM,YAAY,KAAA,IAAY,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,iCAAI;kBAArB,CAAiC,KAAE,MAAM,OAAc;YAAI,IAAW;UACvI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,iCAAI;iBAAc,MAAM,EAAE,MAAM,cAAc;MAAQ,CAAA,CACnE;;KACL,MAAM,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,iCAAI;gBAAU,MAAM,EAAE,kBAAkB;KAAQ,CAAA,IAAI;KACpF,iBAAA,GAAA,kBAAA,IAAA,CAAC,0BAAD,EAA0B,WAAW,OAAOA,iCAAI,cAAcA,iCAAI,QAAU,CAAA;IACtE;;GAGV,IAAI,CAAC,MAAM,SACT,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;IAAI,WAAWA,iCAAI,QAAQ,OAAO,MAAMA,iCAAI,WAAW;cAAvD,CACG,QACA,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,iCAAI;eAAM,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAI;MAAY,MAAK;gBAAU,MAAM,EAAE,qBAAqB;KAAK,CAAA;IAAM,CAAA,IAAI,IACzH;;GAIR,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;IAAI,WAAWA,iCAAI,QAAQ,OAAO,MAAMA,iCAAI,WAAW;cAAvD,CACG,QACA,OACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,iCAAI;eAApB;MACG,CAAC,MAAM,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,iCAAI;OAAU,MAAK;iBAAU,MAAM,EAAE,mBAAmB;MAAK,CAAA,IAAI;MACjG,MAAM;MACP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,iCAAI;iBAApB;QACG,MAAM,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,iCAAI;SAAQ,MAAK;mBAAU,MAAM,EAAE,qBAAqB;QAAK,CAAA,IAAI;QAC/F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,iCAAI;SAAS,UAAU,CAAC,MAAM,SAAS,MAAM;SAAQ,SAAS,MAAM;mBAClG,MAAM,EAAE,kBAAkB;QACrB,CAAA;QACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,iCAAI;SAAM,UAAU;SAAS,SAAS,MAAM;mBAC1E,MAAM,EAAE,CAAC,MAAM,SAAS,kBAAkB,iBAAiB;QACtD,CAAA;OACL;;KACF;SACH,IACF;;EAER;EA6DA,SAAgB,YAAY,OAAuC;GACjE,MAAM,UAAU,MAAM,SAAS;GAC/B,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWA,iCAAI;cAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,iCAAI;eAApB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,iCAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,iCAAI;iBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,iCAAI;kBAAQ,MAAM;OAAY,CAAA,GAC9C,MAAM,aACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,iCAAI;kBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,iCAAI;mBAAQ,MAAM;QAAsB,CAAA,GACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,iCAAI;SAAO,UAAU,MAAM;SAAU,SAAS,MAAM;mBAClF,MAAM;QACD,CAAA,CACJ;YACJ,IACD;UACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,iCAAI;iBAAO,MAAM;MAAQ,CAAA,CACpC;SACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MACE,MAAK;MACL,WAAW,UAAUA,iCAAI,WAAWA,iCAAI;MACxC,MAAK;MACL,gBAAc;MACd,cAAY,MAAM;MAClB,UAAU,MAAM;MAChB,eAAe;OAAE,MAAM,OAAO,OAAO,CAAC,OAAO,CAAC;MAAE;gBAEhD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,iCAAI,YAAc,CAAA;KAC7B,CAAA,CACL;;GACF,CAAA;EAET;EAoBA,SAAgB,WAAW,OAAsC;GAC/D,MAAM,QAAQ,kBAAkB,KAAK,MAAM,IAAI,IAAI,MAAM,OAAO,MAAM;GACtE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,iCAAI;cAApB;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,iCAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OAAO,WAAWA,iCAAI;OAAO,SAAS,MAAM;iBAAK,MAAM;MAAa,CAAA,GACnE,MAAM,aACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWA,iCAAI;iBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,iCAAI;kBAAQ,MAAM;OAAsB,CAAA,GACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,iCAAI;QAAO,UAAU,MAAM;QAAU,SAAS,MAAM;kBAClF,MAAM;OACD,CAAA,CACJ;WACJ,IACD;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,iCAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OACE,IAAI,MAAM;OACV,MAAK;OACL,WAAWA,iCAAI;OACR;OACP,UAAU,MAAM;OAChB,WAAW,UAAU;QAAE,MAAM,OAAO,MAAM,OAAO,KAAK;OAAE;MACzD,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OACE,MAAK;OACL,WAAWA,iCAAI,QAAQ,MAAMA,iCAAI;OACjC,OAAO,MAAM;OACb,UAAU,MAAM;OAChB,aAAa,MAAM;OACnB,WAAW,UAAU;QAAE,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC;OAAE;MAChE,CAAA,CACE;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAI;gBAAO,MAAM;KAAQ,CAAA;IACpC;;EAET;EAoBA,SAAgB,YAAY,OAAuC;GACjE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWA,iCAAI;cAApB;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,iCAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OAAO,WAAWA,iCAAI;OAAO,SAAS,MAAM;iBAAK,MAAM;MAAa,CAAA,GACnE,MAAM,aACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWA,iCAAI;iBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,iCAAI;kBAAQ,MAAM;OAAsB,CAAA,GACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,iCAAI;QAAO,UAAU,MAAM;QAAU,SAAS,MAAM;kBAClF,MAAM;OACD,CAAA,CACJ;WACJ,IACD;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;MACE,IAAI,MAAM;MACV,MAAK;MACL,WAAU;MACV,WAAWA,iCAAI;MACf,OAAO,MAAM;MACb,UAAU,MAAM;MAChB,aAAa,MAAM;MACnB,gBAAc,MAAM,YAAY;MAChC,WAAW,UAAU;OAAE,MAAM,OAAO,MAAM,OAAO,KAAK;MAAE;KACzD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,iCAAI;gBAAO,MAAM;KAAQ,CAAA;IACpC;;EAET;;;EC/RA,MAAM,mBAAmB,gBAAgB;GACvC,IAAI;GACJ,MAAM,4BAA4B,IAAI,IAAI;GAC1C,MAAM,YAAY,SAAS,YAAY;IACrC,MAAM,YAAY,OAAO,YAAY,aAAa,QAAQ,KAAK,IAAI;IACnE,IAAI,CAAC,OAAO,GAAG,WAAW,KAAK,GAAG;KAChC,MAAM,gBAAgB;KACtB,SAAS,WAAW,OAAO,UAAU,OAAO,cAAc,YAAY,cAAc,QAAQ,YAAY,OAAO,OAAO,CAAC,GAAG,OAAO,SAAS;KAC1I,UAAU,SAAS,aAAa,SAAS,OAAO,aAAa,CAAC;IAChE;GACF;GACA,MAAM,iBAAiB;GACvB,MAAM,aAAa,aAAa;IAC9B,UAAU,IAAI,QAAQ;IACtB,aAAa,UAAU,OAAO,QAAQ;GACxC;GACA,MAAM,gBAAgB;IAMpB,UAAU,MAAM;GAClB;GACA,MAAM,MAAM;IAAE;IAAU;IAAU;IAAW;GAAQ;GACrD,QAAQ,YAAY,UAAU,UAAU,GAAG;GAC3C,OAAO;EACT;EACA,MAAM,eAAe,gBAAgB,cAAc,gBAAgB,WAAW,IAAI;;;ECsMlF,MAAM,6BAA6B,QAAQ,KAAK,KAAK,QAAQ;GAC3D,MAAM,gBAAgB,IAAI;GAC1B,IAAI,aAAa,UAAU,aAAa,YAAY;IAClD,IAAI,WAAW;IACf,IAAI,aAAa;KACf,MAAM,cAAc,WAAW,OAAO,KAAK,IAAI,QAAQ,eAAe,OAAO;KAC7E,IAAI,eAAe,SAAS,IAAI,SAAS,CAAC;KAC1C,YAAY,UAAU;MACpB,MAAM,YAAY,SAAS,KAAK;MAChC,IAAI,CAAC,WAAW,cAAc,SAAS,GAAG;OACxC,MAAM,gBAAgB;OACtB,YAAY,eAAe,WAAW,aAAa;MACrD;KACF;KACA,IAAI,WAAW,OAAO,KAAK,IAAI,QAAQ,iBACrC,YAAY,cAAc,YAAY;IAE1C;IACA,OAAO,cAAc,QAAQ;GAC/B;GAEA,OADqB,GAAG,KAAK,KAAK,GAChB;EACpB;EACA,MAAM,wBAAwB;;;ECxP9B,IAAI,UAAU,OAAO,IAAI,eAAe;EACxC,IAAI,YAAY,OAAO,IAAI,iBAAiB;EAC5C,IAAI,cAAc,OAAO,IAAI,aAAa;EAkC1C,SAAS,IAAI,OAAO,GAAG,MAAM;GAM3B,MAAM,IAAI,MACR,8BAA8B,MAAM,wCACtC;EACF;EAGA,IAAI,iBAAiB,OAAO;EAC5B,SAAS,QAAQ,OAAO;GACtB,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM;EAC5B;EACA,SAAS,YAAY,OAAO;GAC1B,IAAI,CAAC,OACH,OAAO;GACT,OAAO,cAAc,KAAK,KAAK,MAAM,QAAQ,KAAK,KAAK,CAAC,CAAC,MAAM,cAAc,CAAC,CAAC,MAAM,cAAc,cAAc,MAAM,KAAK,KAAK,MAAM,KAAK;EAC9I;EACA,IAAI,mBAAmB,OAAO,UAAU,YAAY,SAAS;EAC7D,IAAI,oCAAoC,IAAI,QAAQ;EACpD,SAAS,cAAc,OAAO;GAC5B,IAAI,CAAC,SAAS,OAAO,UAAU,UAC7B,OAAO;GACT,MAAM,QAAQ,OAAO,eAAe,KAAK;GACzC,IAAI,UAAU,QAAQ,UAAU,OAAO,WACrC,OAAO;GACT,MAAM,OAAO,OAAO,eAAe,KAAK,OAAO,aAAa,KAAK,MAAM;GACvE,IAAI,SAAS,QACX,OAAO;GACT,IAAI,OAAO,SAAS,YAClB,OAAO;GACT,IAAI,aAAa,kBAAkB,IAAI,IAAI;GAC3C,IAAI,eAAe,KAAK,GAAG;IACzB,aAAa,SAAS,SAAS,KAAK,IAAI;IACxC,kBAAkB,IAAI,MAAM,UAAU;GACxC;GACA,OAAO,eAAe;EACxB;EAMA,SAAS,KAAK,KAAK,MAAM,SAAS,MAAM;GACtC,IAAI,YAAY,GAAG,MAAM,GAEvB,CADa,SAAS,QAAQ,QAAQ,GAAG,IAAI,OAAO,KAAK,GAAG,EAAA,CACvD,SAAS,QAAQ;IACpB,KAAK,KAAK,IAAI,MAAM,GAAG;GACzB,CAAC;QAED,IAAI,SAAS,OAAO,UAAU,KAAK,OAAO,OAAO,GAAG,CAAC;EAEzD;EACA,SAAS,YAAY,OAAO;GAC1B,MAAM,QAAQ,MAAM;GACpB,OAAO,QAAQ,MAAM,QAAQ,MAAM,QAAQ,KAAK,IAAI,IAAgB,MAAM,KAAK,IAAI,IAAc,MAAM,KAAK,IAAI,IAAc;EAChI;EACA,SAAS,IAAI,OAAO,MAAM;GACxB,OAAO,YAAY,KAAK,MAAM,IAAc,MAAM,IAAI,IAAI,IAAI,OAAO,UAAU,eAAe,KAAK,OAAO,IAAI;EAChH;EAIA,SAAS,IAAI,OAAO,gBAAgB,OAAO;GACzC,MAAM,IAAI,YAAY,KAAK;GAC3B,IAAI,MAAM,GACR,MAAM,IAAI,gBAAgB,KAAK;QAC5B,IAAI,MAAM,GACb,MAAM,IAAI,KAAK;QAEf,MAAM,kBAAkB;EAC5B;EACA,SAAS,GAAG,GAAG,GAAG;GAChB,IAAI,MAAM,GACR,OAAO,MAAM,KAAK,IAAI,MAAM,IAAI;QAEhC,OAAO,MAAM,KAAK,MAAM;EAE5B;EACA,SAAS,MAAM,QAAQ;GACrB,OAAO,kBAAkB;EAC3B;EACA,SAAS,MAAM,QAAQ;GACrB,OAAO,kBAAkB;EAC3B;EACA,SAAS,OAAO,OAAO;GACrB,OAAO,MAAM,SAAS,MAAM;EAC9B;EACA,SAAS,YAAY,MAAM,QAAQ;GACjC,IAAI,MAAM,IAAI,GACZ,OAAO,IAAI,IAAI,IAAI;GAErB,IAAI,MAAM,IAAI,GACZ,OAAO,IAAI,IAAI,IAAI;GAErB,IAAI,MAAM,QAAQ,IAAI,GACpB,OAAO,MAAM,UAAU,MAAM,KAAK,IAAI;GACxC,MAAM,UAAU,cAAc,IAAI;GAClC,IAAI,WAAW,QAAQ,WAAW,gBAAgB,CAAC,SAAS;IAC1D,MAAM,cAAc,OAAO,0BAA0B,IAAI;IACzD,OAAO,YAAY;IACnB,IAAI,OAAO,QAAQ,QAAQ,WAAW;IACtC,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;KACpC,MAAM,MAAM,KAAK;KACjB,MAAM,OAAO,YAAY;KACzB,IAAI,KAAK,aAAa,OAAO;MAC3B,KAAK,WAAW;MAChB,KAAK,eAAe;KACtB;KACA,IAAI,KAAK,OAAO,KAAK,KACnB,YAAY,OAAO;MACjB,cAAc;MACd,UAAU;MAEV,YAAY,KAAK;MACjB,OAAO,KAAK;KACd;IACJ;IACA,OAAO,OAAO,OAAO,eAAe,IAAI,GAAG,WAAW;GACxD,OAAO;IACL,MAAM,QAAQ,eAAe,IAAI;IACjC,IAAI,UAAU,QAAQ,SACpB,OAAO,EAAE,GAAG,KAAK;IAEnB,MAAM,MAAM,OAAO,OAAO,KAAK;IAC/B,OAAO,OAAO,OAAO,KAAK,IAAI;GAChC;EACF;EACA,SAAS,OAAO,KAAK,OAAO,OAAO;GACjC,IAAI,SAAS,GAAG,KAAK,QAAQ,GAAG,KAAK,CAAC,YAAY,GAAG,GACnD,OAAO;GACT,IAAI,YAAY,GAAG,IAAI,GACrB,OAAO,iBAAiB,KAAK;IAC3B,KAAK;IACL,KAAK;IACL,OAAO;IACP,QAAQ;GACV,CAAC;GAEH,OAAO,OAAO,GAAG;GACjB,IAAI,MACF,OAAO,OAAO,GAAG,CAAC,CAAC,SAAS,UAAU,OAAO,OAAO,IAAI,CAAC;GAC3D,OAAO;EACT;EACA,SAAS,8BAA8B;GACrC,IAAI,CAAC;EACP;EACA,IAAI,2BAA2B,EAC7B,OAAO,4BACT;EACA,SAAS,SAAS,KAAK;GACrB,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UACjC,OAAO;GACT,OAAO,OAAO,SAAS,GAAG;EAC5B;EAGA,IAAI,UAAU,CAAC;EACf,SAAS,UAAU,WAAW;GAC5B,MAAM,SAAS,QAAQ;GACvB,IAAI,CAAC,QACH,IAAI,GAAG,SAAS;GAElB,OAAO;EACT;EAOA,IAAI;EACJ,SAAS,kBAAkB;GACzB,OAAO;EACT;EACA,SAAS,YAAY,SAAS,QAAQ;GACpC,OAAO;IACL,SAAS,CAAC;IACV;IACA;IAGA,gBAAgB;IAChB,oBAAoB;GACtB;EACF;EACA,SAAS,kBAAkB,OAAO,eAAe;GAC/C,IAAI,eAAe;IACjB,UAAU,SAAS;IACnB,MAAM,WAAW,CAAC;IAClB,MAAM,kBAAkB,CAAC;IACzB,MAAM,iBAAiB;GACzB;EACF;EACA,SAAS,YAAY,OAAO;GAC1B,WAAW,KAAK;GAChB,MAAM,QAAQ,QAAQ,WAAW;GACjC,MAAM,UAAU;EAClB;EACA,SAAS,WAAW,OAAO;GACzB,IAAI,UAAU,cACZ,eAAe,MAAM;EAEzB;EACA,SAAS,WAAW,QAAQ;GAC1B,OAAO,eAAe,YAAY,cAAc,MAAM;EACxD;EACA,SAAS,YAAY,OAAO;GAC1B,MAAM,QAAQ,MAAM;GACpB,IAAI,MAAM,UAAU,KAAkB,MAAM,UAAU,GACpD,MAAM,QAAQ;QAEd,MAAM,WAAW;EACrB;EAGA,SAAS,cAAc,QAAQ,OAAO;GACpC,MAAM,qBAAqB,MAAM,QAAQ;GACzC,MAAM,YAAY,MAAM,QAAQ;GAEhC,IADmB,WAAW,KAAK,KAAK,WAAW,WACnC;IACd,IAAI,UAAU,YAAY,CAAC,WAAW;KACpC,YAAY,KAAK;KACjB,IAAI,CAAC;IACP;IACA,IAAI,YAAY,MAAM,GAAG;KACvB,SAAS,SAAS,OAAO,MAAM;KAC/B,IAAI,CAAC,MAAM,SACT,YAAY,OAAO,MAAM;IAC7B;IACA,IAAI,MAAM,UACR,UAAU,SAAS,CAAC,CAAC,4BACnB,UAAU,YAAY,CAAC,OACvB,QACA,MAAM,UACN,MAAM,eACR;GAEJ,OACE,SAAS,SAAS,OAAO,WAAW,CAAC,CAAC;GAExC,YAAY,KAAK;GACjB,IAAI,MAAM,UACR,MAAM,eAAe,MAAM,UAAU,MAAM,eAAe;GAE5D,OAAO,WAAW,UAAU,SAAS,KAAK;EAC5C;EACA,SAAS,SAAS,WAAW,OAAO,MAAM;GACxC,IAAI,SAAS,KAAK,GAChB,OAAO;GACT,MAAM,qBAAqB,UAAU,OAAO,yBAAyB;GACrE,MAAM,QAAQ,MAAM;GACpB,IAAI,CAAC,OAAO;IACV,KACE,QACC,KAAK,eAAe,iBAAiB,WAAW,OAAO,OAAO,KAAK,YAAY,IAAI,GACpF,kBACF;IACA,OAAO;GACT;GACA,IAAI,MAAM,WAAW,WACnB,OAAO;GACT,IAAI,CAAC,MAAM,WAAW;IACpB,YAAY,WAAW,MAAM,OAAO,IAAI;IACxC,OAAO,MAAM;GACf;GACA,IAAI,CAAC,MAAM,YAAY;IACrB,MAAM,aAAa;IACnB,MAAM,OAAO;IACb,MAAM,SAAS,MAAM;IACrB,IAAI,aAAa;IACjB,IAAI,SAAS;IACb,IAAI,MAAM,UAAU,GAAa;KAC/B,aAAa,IAAI,IAAI,MAAM;KAC3B,OAAO,MAAM;KACb,SAAS;IACX;IACA,KACE,aACC,KAAK,eAAe,iBACnB,WACA,OACA,QACA,KACA,YACA,MACA,MACF,GACA,kBACF;IACA,YAAY,WAAW,QAAQ,KAAK;IACpC,IAAI,QAAQ,UAAU,UACpB,UAAU,SAAS,CAAC,CAAC,iBACnB,OACA,MACA,UAAU,UACV,UAAU,eACZ;GAEJ;GACA,OAAO,MAAM;EACf;EACA,SAAS,iBAAiB,WAAW,aAAa,cAAc,MAAM,YAAY,UAAU,aAAa;GACvG,IAAI,cAAc,MAChB;GAEF,IAAI,OAAO,eAAe,YAAY,CAAC,aACrC;GAEF,MAAM,gBAAgB,SAAS,UAAU;GACzC,IAAI,iBAAiB,CAAC,aACpB;GAIF,IAAI,QAAQ,UAAU,GAAG;IAGvB,MAAM,MAAM,SAAS,WAAW,YAFnB,YAAY,eAAe,YAAY,UAAU,KAC9D,CAAC,IAAI,YAAY,WAAW,IAAI,IAAI,SAAS,OAAO,IAAI,IAAI,KAAK,CACjB;IAChD,IAAI,cAAc,MAAM,GAAG;IAC3B,IAAI,QAAQ,GAAG,GACb,UAAU,iBAAiB;SAE3B;GACJ,OAAO,IAAI,aACT,aAAa,IAAI,UAAU;GAE7B,IAAI,YAAY,UAAU,KAAK,CAAC,eAAe;IAC7C,IAAI,CAAC,UAAU,OAAO,eAAe,UAAU,qBAAqB,GAClE;IAEF,IAAI,eAAe,YAAY,SAAS,YAAY,MAAM,UAAU,cAAc,eAChF;IAEF,SAAS,WAAW,UAAU;IAC9B,KAAK,CAAC,eAAe,CAAC,YAAY,OAAO,YAAY,OAAO,SAAS,aAAa,MAAM,YAAY,IAAI,aAAa,IAAI,IAAI,IAAI,OAAO,UAAU,qBAAqB,KAAK,cAAc,IAAI,IAC5L,YAAY,WAAW,UAAU;GACrC;EACF;EACA,SAAS,YAAY,OAAO,OAAO,OAAO,OAAO;GAC/C,IAAI,CAAC,MAAM,WAAW,MAAM,OAAO,eAAe,MAAM,gBACtD,OAAO,OAAO,IAAI;EAEtB;EAGA,SAAS,iBAAiB,MAAM,QAAQ;GACtC,MAAM,UAAU,MAAM,QAAQ,IAAI;GAClC,MAAM,QAAQ;IACZ,OAAO,UAAU,IAAgB;IAEjC,QAAQ,SAAS,OAAO,SAAS,gBAAgB;IAEjD,WAAW;IAEX,YAAY;IAEZ,WAAW,CAAC;IAEZ,SAAS;IAET,OAAO;IAEP,QAAQ;IAGR,OAAO;IAEP,SAAS;IACT,WAAW;GACb;GACA,IAAI,SAAS;GACb,IAAI,QAAQ;GACZ,IAAI,SAAS;IACX,SAAS,CAAC,KAAK;IACf,QAAQ;GACV;GACA,MAAM,EAAE,QAAQ,UAAU,MAAM,UAAU,QAAQ,KAAK;GACvD,MAAM,SAAS;GACf,MAAM,UAAU;GAChB,OAAO;EACT;EACA,IAAI,cAAc;GAChB,IAAI,OAAO,MAAM;IACf,IAAI,SAAS,aACX,OAAO;IACT,MAAM,SAAS,OAAO,KAAK;IAC3B,IAAI,CAAC,IAAI,QAAQ,IAAI,GACnB,OAAO,kBAAkB,OAAO,QAAQ,IAAI;IAE9C,MAAM,QAAQ,OAAO;IACrB,IAAI,MAAM,cAAc,CAAC,YAAY,KAAK,GACxC,OAAO;IAET,IAAI,UAAU,KAAK,MAAM,OAAO,IAAI,GAAG;KACrC,YAAY,KAAK;KACjB,OAAO,MAAM,MAAM,QAAQ,YAAY,OAAO,KAAK;IACrD;IACA,OAAO;GACT;GACA,IAAI,OAAO,MAAM;IACf,OAAO,QAAQ,OAAO,KAAK;GAC7B;GACA,QAAQ,OAAO;IACb,OAAO,QAAQ,QAAQ,OAAO,KAAK,CAAC;GACtC;GACA,IAAI,OAAO,MAAM,OAAO;IACtB,MAAM,OAAO,uBAAuB,OAAO,KAAK,GAAG,IAAI;IACvD,IAAI,MAAM,KAAK;KACb,KAAK,IAAI,KAAK,MAAM,QAAQ,KAAK;KACjC,OAAO;IACT;IACA,IAAI,CAAC,MAAM,WAAW;KACpB,MAAM,WAAW,KAAK,OAAO,KAAK,GAAG,IAAI;KACzC,MAAM,eAAe,WAAW;KAChC,IAAI,gBAAgB,aAAa,UAAU,OAAO;MAChD,MAAM,MAAM,QAAQ;MACpB,MAAM,UAAU,QAAQ;MACxB,OAAO;KACT;KACA,IAAI,GAAG,OAAO,QAAQ,MAAM,UAAU,KAAK,KAAK,IAAI,MAAM,OAAO,IAAI,IACnE,OAAO;KACT,YAAY,KAAK;KACjB,YAAY,KAAK;IACnB;IACA,IAAI,MAAM,MAAM,UAAU,UACzB,UAAU,KAAK,KAAK,QAAQ,MAAM,UACnC,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM,MAAM,MAAM,KAAK,GACnD,OAAO;IACT,MAAM,MAAM,QAAQ;IACpB,MAAM,UAAU,QAAQ;IACxB,OAAO;GACT;GACA,eAAe,OAAO,MAAM;IAC1B,IAAI,KAAK,MAAM,OAAO,IAAI,MAAM,KAAK,KAAK,QAAQ,MAAM,OAAO;KAC7D,MAAM,UAAU,QAAQ;KACxB,YAAY,KAAK;KACjB,YAAY,KAAK;IACnB,OACE,OAAO,MAAM,UAAU;IAEzB,IAAI,MAAM,OACR,OAAO,MAAM,MAAM;IAErB,OAAO;GACT;GAGA,yBAAyB,OAAO,MAAM;IACpC,MAAM,QAAQ,OAAO,KAAK;IAC1B,MAAM,OAAO,QAAQ,yBAAyB,OAAO,IAAI;IACzD,IAAI,CAAC,MACH,OAAO;IACT,OAAO;KACL,UAAU;KACV,cAAc,MAAM,UAAU,KAAiB,SAAS;KACxD,YAAY,KAAK;KACjB,OAAO,MAAM;IACf;GACF;GACA,iBAAiB;IACf,IAAI,EAAE;GACR;GACA,eAAe,OAAO;IACpB,OAAO,eAAe,MAAM,KAAK;GACnC;GACA,iBAAiB;IACf,IAAI,EAAE;GACR;EACF;EACA,IAAI,aAAa,CAAC;EAClB,KAAK,cAAc,KAAK,OAAO;GAC7B,WAAW,OAAO,WAAW;IAC3B,UAAU,KAAK,UAAU,EAAE,CAAC;IAC5B,OAAO,GAAG,MAAM,MAAM,SAAS;GACjC;EACF,CAAC;EACD,WAAW,iBAAiB,SAAS,OAAO,MAAM;GAGhD,OAAO,WAAW,IAAI,KAAK,MAAM,OAAO,MAAM,KAAK,CAAC;EACtD;EACA,WAAW,MAAM,SAAS,OAAO,MAAM,OAAO;GAG5C,OAAO,YAAY,IAAI,KAAK,MAAM,MAAM,IAAI,MAAM,OAAO,MAAM,EAAE;EACnE;EACA,SAAS,KAAK,OAAO,MAAM;GACzB,MAAM,QAAQ,MAAM;GAEpB,QADe,QAAQ,OAAO,KAAK,IAAI,MAAA,CACzB;EAChB;EACA,SAAS,kBAAkB,OAAO,QAAQ,MAAM;GAC9C,MAAM,OAAO,uBAAuB,QAAQ,IAAI;GAChD,OAAO,OAAO,WAAW,OAAO,KAAK,QAGnC,KAAK,KAAK,KAAK,MAAM,MAAM,IACzB,KAAK;EACX;EACA,SAAS,uBAAuB,QAAQ,MAAM;GAC5C,IAAI,EAAE,QAAQ,SACZ,OAAO,KAAK;GACd,IAAI,QAAQ,eAAe,MAAM;GACjC,OAAO,OAAO;IACZ,MAAM,OAAO,OAAO,yBAAyB,OAAO,IAAI;IACxD,IAAI,MACF,OAAO;IACT,QAAQ,eAAe,KAAK;GAC9B;EAEF;EACA,SAAS,YAAY,OAAO;GAC1B,IAAI,CAAC,MAAM,WAAW;IACpB,MAAM,YAAY;IAClB,IAAI,MAAM,SACR,YAAY,MAAM,OAAO;GAE7B;EACF;EACA,SAAS,YAAY,OAAO;GAC1B,IAAI,CAAC,MAAM,OACT,MAAM,QAAQ,YACZ,MAAM,OACN,MAAM,OAAO,OAAO,qBACtB;EAEJ;EAGA,IAAI,SAAS,MAAM;GACjB,YAAY,QAAQ;IAClB,KAAK,cAAc;IACnB,KAAK,wBAAwB;IAC7B,KAAK,sBAAsB;;;;;;;;;;;;;;;;;;;;IAoB3B,KAAK,WAAW,MAAM,QAAQ,kBAAkB;KAC9C,IAAI,OAAO,SAAS,cAAc,OAAO,WAAW,YAAY;MAC9D,MAAM,cAAc;MACpB,SAAS;MACT,MAAM,OAAO;MACb,OAAO,SAAS,eAAe,QAAQ,aAAa,GAAG,MAAM;OAC3D,OAAO,KAAK,QAAQ,QAAQ,UAAU,OAAO,KAAK,MAAM,OAAO,GAAG,IAAI,CAAC;MACzE;KACF;KACA,IAAI,OAAO,WAAW,YACpB,IAAI,CAAC;KACP,IAAI,kBAAkB,KAAK,KAAK,OAAO,kBAAkB,YACvD,IAAI,CAAC;KACP,IAAI;KACJ,IAAI,YAAY,IAAI,GAAG;MACrB,MAAM,QAAQ,WAAW,IAAI;MAC7B,MAAM,QAAQ,YAAY,MAAM,KAAK,CAAC;MACtC,IAAI,WAAW;MACf,IAAI;OACF,SAAS,OAAO,KAAK;OACrB,WAAW;MACb,UAAU;OACR,IAAI,UACF,YAAY,KAAK;YAEjB,WAAW,KAAK;MACpB;MACA,kBAAkB,OAAO,aAAa;MACtC,OAAO,cAAc,QAAQ,KAAK;KACpC,OAAO,IAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;MAC5C,SAAS,OAAO,IAAI;MACpB,IAAI,WAAW,KAAK,GAClB,SAAS;MACX,IAAI,WAAW,SACb,SAAS,KAAK;MAChB,IAAI,KAAK,aACP,OAAO,QAAQ,IAAI;MACrB,IAAI,eAAe;OACjB,MAAM,IAAI,CAAC;OACX,MAAM,KAAK,CAAC;OACZ,UAAU,SAAS,CAAC,CAAC,4BAA4B,MAAM,QAAQ,GAAG,EAAE;OACpE,cAAc,GAAG,EAAE;MACrB;MACA,OAAO;KACT,OACE,IAAI,GAAG,IAAI;IACf;IACA,KAAK,sBAAsB,MAAM,WAAW;KAC1C,IAAI,OAAO,SAAS,YAClB,QAAQ,OAAO,GAAG,SAAS,KAAK,mBAAmB,QAAQ,UAAU,KAAK,OAAO,GAAG,IAAI,CAAC;KAE3F,IAAI,SAAS;KAKb,OAAO;MAJQ,KAAK,QAAQ,MAAM,SAAS,GAAG,OAAO;OACnD,UAAU;OACV,iBAAiB;MACnB,CACa;MAAG;MAAS;KAAc;IACzC;IACA,IAAI,OAAO,QAAQ,eAAe,WAChC,KAAK,cAAc,OAAO,UAAU;IACtC,IAAI,OAAO,QAAQ,yBAAyB,WAC1C,KAAK,wBAAwB,OAAO,oBAAoB;IAC1D,IAAI,OAAO,QAAQ,uBAAuB,WACxC,KAAK,sBAAsB,OAAO,kBAAkB;GACxD;GACA,YAAY,MAAM;IAChB,IAAI,CAAC,YAAY,IAAI,GACnB,IAAI,CAAC;IACP,IAAI,QAAQ,IAAI,GACd,OAAO,QAAQ,IAAI;IACrB,MAAM,QAAQ,WAAW,IAAI;IAC7B,MAAM,QAAQ,YAAY,MAAM,KAAK,CAAC;IACtC,MAAM,YAAY,CAAC,YAAY;IAC/B,WAAW,KAAK;IAChB,OAAO;GACT;GACA,YAAY,OAAO,eAAe;IAChC,MAAM,QAAQ,SAAS,MAAM;IAC7B,IAAI,CAAC,SAAS,CAAC,MAAM,WACnB,IAAI,CAAC;IACP,MAAM,EAAE,QAAQ,UAAU;IAC1B,kBAAkB,OAAO,aAAa;IACtC,OAAO,cAAc,KAAK,GAAG,KAAK;GACpC;;;;;;GAMA,cAAc,OAAO;IACnB,KAAK,cAAc;GACrB;;;;;;GAMA,wBAAwB,OAAO;IAC7B,KAAK,wBAAwB;GAC/B;;;;;;;GAOA,sBAAsB,OAAO;IAC3B,KAAK,sBAAsB;GAC7B;GACA,2BAA2B;IACzB,OAAO,KAAK;GACd;GACA,aAAa,MAAM,SAAS;IAC1B,IAAI;IACJ,KAAK,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;KACxC,MAAM,QAAQ,QAAQ;KACtB,IAAI,MAAM,KAAK,WAAW,KAAK,MAAM,OAAO,WAAW;MACrD,OAAO,MAAM;MACb;KACF;IACF;IACA,IAAI,IAAI,IACN,UAAU,QAAQ,MAAM,IAAI,CAAC;IAE/B,MAAM,mBAAmB,UAAU,SAAS,CAAC,CAAC;IAC9C,IAAI,QAAQ,IAAI,GACd,OAAO,iBAAiB,MAAM,OAAO;IAEvC,OAAO,KAAK,QACV,OACC,UAAU,iBAAiB,OAAO,OAAO,CAC5C;GACF;EACF;EACA,SAAS,YAAY,OAAO,QAAQ;GAClC,MAAM,QAAQ,MAAM,KAAK,IAAI,UAAU,QAAQ,CAAC,CAAC,UAAU,OAAO,MAAM,IAAI,MAAM,KAAK,IAAI,UAAU,QAAQ,CAAC,CAAC,UAAU,OAAO,MAAM,IAAI,iBAAiB,OAAO,MAAM;GAExK,CADc,SAAS,OAAO,SAAS,gBAAgB,EAAA,CACjD,QAAQ,KAAK,KAAK;GACxB,OAAO;EACT;EAGA,SAAS,QAAQ,OAAO;GACtB,IAAI,CAAC,QAAQ,KAAK,GAChB,IAAI,IAAI,KAAK;GACf,OAAO,YAAY,KAAK;EAC1B;EACA,SAAS,YAAY,OAAO;GAC1B,IAAI,CAAC,YAAY,KAAK,KAAK,SAAS,KAAK,GACvC,OAAO;GACT,MAAM,QAAQ,MAAM;GACpB,IAAI;GACJ,IAAI,SAAS;GACb,IAAI,OAAO;IACT,IAAI,CAAC,MAAM,WACT,OAAO,MAAM;IACf,MAAM,aAAa;IACnB,OAAO,YAAY,OAAO,MAAM,OAAO,OAAO,qBAAqB;IACnE,SAAS,MAAM,OAAO,OAAO,yBAAyB;GACxD,OACE,OAAO,YAAY,OAAO,IAAI;GAEhC,KACE,OACC,KAAK,eAAe;IACnB,IAAI,MAAM,KAAK,YAAY,UAAU,CAAC;GACxC,GACA,MACF;GACA,IAAI,OACF,MAAM,aAAa;GAErB,OAAO;EACT;EA0eA,IAAI,UAAU,IADE,OACF,CAAA,CAAM;;;;;;;;;;;;;;;;;;ECrtCpB,SAAS,kBAAkB,WAAW,OAAO,GAAG,MAAM;GACrD,KAAK,MAAM,YAAY,CAAC,GAAG,SAAS,GAAG,IAAI;IAC1C,SAAS,GAAG,IAAI;GACjB,SAAS,OAAO;IACf,QAAQ,MAAM,GAAG,MAAM,sBAAsB,KAAK;GACnD;EACD;;EAYA,SAAS,SAAS,QAAQ;GACzB,MAAM,WAAW,OAAO,0BAA0B,cAAc,OAAO;IACtE,4BAA4B;KAC3B,GAAG;IACJ,CAAC;GACF,KAAK,OAAO;IACX,eAAe,EAAE;GAClB;GACA,IAAI,YAAY;GAChB,aAAa;IACZ,IAAI,WAAW;IACf,YAAY;IACZ,eAAe;KACd,YAAY;KACZ,OAAO;IACR,CAAC;GACF;EACD;;;;;;;;;;;;;;EAcA,SAAS,oBAAoB,MAAM,MAAM;GACxC,MAAM,eAAe,4BAA4B,IAAI;GACrD,MAAM,MAAM,YAAY,CAAC,CAAC,YAAY;GACtC,IAAI,MAAM,SAAS,kBAAkB,KAAK,KAAK,QAAQ,IAAI;GAC3D,IAAI,aAAa,OAAO,IAAI,gBAAgB;IAC3C,kBAAkB,CAAC,EAAE,GAAG,gBAAgB;GACzC,CAAC;GACD,IAAI,MAAM,UAAU,OAAO;IAC1B,MAAM,4BAA4B,IAAI,IAAI;IAC1C,MAAM,QAAQ,eAAe;KAC5B,kBAAkB,WAAW,gBAAgB;IAC9C,CAAC;IACD,IAAI,UAAU,KAAK;IACnB,aAAa,OAAO;KACnB,UAAU,IAAI,EAAE;KAChB,aAAa;MACZ,UAAU,OAAO,EAAE;KACpB;IACD;GACD;GACA,OAAO;IACN,mBAAmB,IAAI,SAAS;IAChC,YAAY,OAAO,UAAU,EAAE;IAC/B,SAAS,YAAY;KACpB,IAAI,SAAS,QAAQ,IAAI,SAAS,IAAI,UAAU;MAC/C,QAAQ,KAAK;KACd,CAAC,GAAG,IAAI;IACT;IACA,MAAM,SAAS;KACd,IAAI,SAAS,UAAU,IAAI,GAAG,IAAI;IACnC;GACD;EACD;;;;;;;;;EASA,SAAS,kBAAkB,KAAK,MAAM;GACrC,IAAI,OAAO,iBAAiB,aAAa;GACzC,IAAI;IACH,MAAM,MAAM,aAAa,QAAQ,IAAI;IACrC,IAAI,QAAQ,MAAM,IAAI,SAAS,UAAU,KAAK,MAAM,GAAG,CAAC,GAAG,IAAI;GAChE,SAAS,OAAO;IACf,QAAQ,MAAM,mBAAmB,KAAK,wBAAwB,KAAK;GACpE;GACA,IAAI,WAAW,UAAU;IACxB,IAAI;KACH,aAAa,QAAQ,MAAM,KAAK,UAAU,KAAK,CAAC;IACjD,SAAS,OAAO;KACf,QAAQ,MAAM,mBAAmB,KAAK,wBAAwB,KAAK;IACpE;GACD,CAAC;EACF;;EAEA,SAAS,UAAU,OAAO;GACzB,OAAO,OAAO,OAAO,IAAI;EAC1B;;;;;;;;;;;;;;ECrGA,SAAgB,aAAa,OAA0B;GACrD,OAAO;IACL;IACA,SAAS,UAAW,OAAO,UAAU,YAAY,OAAO,KAAK,IAAI;IACjE,QAAQ,SAAS;KACf,IAAI,SAAS,QAAQ,OAAO;MAAE,MAAM;MAAO,OAAO;KAAK;KACvD,IAAI,SAAS,SAAS,OAAO;MAAE,MAAM;MAAO,OAAO;KAAM;IAE3D;GACF;EACF;;EAGA,SAAgB,WAAW,OAA0B;GACnD,OAAO;IACL;IACA,SAAS,UAAW,OAAO,UAAU,YAAY,kBAAkB,KAAK,KAAK,IAAI,QAAQ;IACzF,QAAQ,SAAS;KACf,IAAI,kBAAkB,KAAK,IAAI,GAAG,OAAO;MAAE,MAAM;MAAO,OAAO;KAAK;IAEtE;GACF;EACF;;;;;EAMA,SAAgB,YAAY,OAAe,UAA6D,CAAC,GAAc;GACrH,MAAM,MAAM,QAAQ,OAAO,OAAO;GAClC,MAAM,MAAM,QAAQ,OAAO,OAAO;GAClC,MAAM,UAAU,QAAQ,WAAW;GACnC,OAAO;IACL;IACA,SAAS,UAAW,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,OAAO,KAAK,IAAI;IAC1F,QAAQ,SAAS;KACf,MAAM,UAAU,KAAK,KAAK;KAC1B,IAAI,CAAC,kBAAkB,KAAK,OAAO,GAAG,OAAO,KAAA;KAC7C,MAAM,SAAS,UAAU,KAAK,MAAM,OAAO,OAAO,CAAC,IAAI,OAAO,OAAO;KACrE,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,SAAS,OAAO,SAAS,KAAK,OAAO,KAAA;KACrE,OAAO;MAAE,MAAM;MAAO,OAAO;KAAO;IACtC;GACF;EACF;;EA6BA,IAAa,WAAb,MAAsB;GACpB;GACA,wBAAyB,IAAI,IAAuB;GACpD,yBAA0B,IAAI,IAAwB;GACtD,4BAA6B,IAAI,IAAgB;GACjD,SAAiB;GACjB,SAAiB;;GAGjB,YAAY,OAAkB,OAAoB;IAChD,KAAK,QAAQ;IACb,KAAK,MAAM,QAAQ,OAAO,KAAK,MAAM,IAAI,KAAK,OAAO,IAAI;IACzD,MAAM,gBAAgB;KAAE,KAAK,QAAQ;IAAE,CAAC;GAC1C;;GAGA,KAAQ,SAAkB;IACxB,MAAM,QAAQ,oBAAoB,QAAQ,CAAC;IAC3C,KAAK,UAAU,UAAU;KAAE,MAAM,IAAI,QAAQ,CAAC;IAAE,CAAC;IACjD,OAAO;GACT;;GAGA,QAAmB;IACjB,MAAM,WAAW,KAAK,MAAM,YAAY;IACxC,MAAM,OAAO,KAAK,KAAK;IACvB,OAAO;KACL,WAAW,SAAS,WAAW;KAC/B,SAAS,SAAS,WAAW;KAC7B,UAAU,SAAS;KACnB,OAAO,KAAK,SAAS;KACrB,SAAS,KAAK,MAAM,SAAS,KAAK,QAAQ,KAAA,CAAS;KACnD,QAAQ,KAAK;KACb,QAAQ,KAAK;IACf;GACF;;GAGA,MAAM,OAA2B;IAC/B,MAAM,OAAO,KAAK,OAAO,KAAK;IAC9B,MAAM,SAAS,KAAK,OAAO,IAAI,KAAK;IACpC,IAAI,WAAW,KAAA,GACb,OAAO;KAAE,MAAM,KAAK,OAAO,KAAK,aAAa,KAAK,CAAC;KAAG,YAAY,KAAK,OAAO,KAAK;KAAG,SAAS;IAAM;IAEvG,MAAM,QAAQ,OAAO,QAAQ,EAAE,MAAM,QAAiB,IAAI,KAAK,MAAM,OAAO,IAAI;IAChF,OAAO;KAAE,MAAM,OAAO;KAAM,YAAY,OAAO,SAAS;KAAO,SAAS,UAAU,KAAA;IAAU;GAC9F;;GAGA,UAAU;IACR,OAAO;KACL,OAAO,OAAe,SAAiB;MAAE,KAAK,MAAM,OAAO;OAAE;OAAM,OAAO;MAAM,CAAC;KAAE;KACnF,aAAa,UAAkB;MAC7B,KAAK,MAAM,OAAO;OAAE,MAAM,KAAK,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK,UAAU,KAAK,CAAC;OAAG,OAAO;MAAK,CAAC;KAC3F;KACA,YAAY;MAAE,KAAU,KAAK;KAAE;KAC/B,eAAe;MACb,IAAI,KAAK,OAAO,SAAS,KAAK,CAAC,KAAK,QAAQ;MAC5C,KAAK,OAAO,MAAM;MAClB,KAAK,SAAS;MACd,KAAK,QAAQ;KACf;IACF;GACF;;GAGA,MAAM,OAAsB;IAC1B,MAAM,OAAO,KAAK,KAAK;IACvB,MAAM,SAAS,KAAK,SAAS,SAAU,KAAK,QAAQ,KAAA,IAAY,CAAC,IAAI,CAAC,KAAK,GAAG,CAAE;IAChF,IAAI,KAAK,WAAW,KAAK,KAAK,UAAU,OAAO,WAAW,KAAK,QAAQ;IACvE,KAAK,SAAS;IACd,KAAK,SAAS;IACd,KAAK,QAAQ;IACb,IAAI,SAAS;IACb,KAAK,MAAM,SAAS,QAAQ,SAAU,MAAM,MAAM,KAAM;IACxD,IAAI,QAAQ,KAAK,OAAO,MAAM;IAC9B,KAAK,SAAS;IACd,KAAK,SAAS,CAAC;IACf,KAAK,QAAQ;GACf;;GAGA,OAA4E;IAC1E,MAAM,OAA4E,CAAC;IACnF,KAAK,MAAM,CAAC,OAAO,WAAW,KAAK,QAAQ;KACzC,MAAM,OAAO,KAAK,OAAO,KAAK;KAC9B,IAAI,OAAO,OAAO;MAChB,IAAI,KAAK,OAAO,KAAK,GAAG,KAAK,KAAK;OAAE;OAAO,WAAW,KAAK,MAAM,KAAK;MAAE,CAAC;MACzE;KACF;KACA,IAAI,OAAO,SAAS,KAAK,OAAO,KAAK,aAAa,KAAK,CAAC,GAAG;KAC3D,MAAM,QAAQ,KAAK,MAAM,OAAO,IAAI;KACpC,IAAI,UAAU,KAAA,GAAW,KAAK,KAAK;MAAE;MAAO,KAAK,KAAA;KAAU,CAAC;UACvD,IAAI,MAAM,SAAS,SAAS,KAAK,KAAK;MAAE;MAAO,WAAW,KAAK,MAAM,KAAK;KAAE,CAAC;UAC7E,KAAK,KAAK;MAAE;MAAO,WAAW,KAAK,MAAM,OAAO,MAAM,KAAK;KAAE,CAAC;IACrE;IACA,OAAO;GACT;GAEA,MAAc,MAAM,OAAiC;IACnD,MAAM,KAAK,MAAM,MAAM,KAAK;IAC5B,OAAO,CAAC,KAAK,OAAO,KAAK;GAC3B;GAEA,MAAc,MAAM,OAAe,OAAkC;IACnE,MAAM,KAAK,MAAM,IAAI,OAAO,KAAK;IACjC,OAAO,KAAK,UAAU,CAAC,GAAG,WAAW;GACvC;GAEA,aAA0D;IACxD,MAAM,OAAO,KAAK,MAAM,YAAY,CAAC,CAAC;IACtC,OAAO,OAAO,SAAS,YAAY,SAAS,OAAO,OAAkC,KAAA;GACvF;GAEA,MAAc,OAAe,MAAwB;IACnD,KAAK,OAAO,IAAI,OAAO,IAAI;IAC3B,KAAK,SAAS;IACd,KAAK,QAAQ;GACf;GAEA,OAAe,OAA0B;IACvC,MAAM,OAAO,KAAK,MAAM,IAAI,KAAK;IACjC,IAAI,SAAS,KAAA,GAAW,MAAM,IAAI,MAAM,gCAAgC,KAAK;IAC7E,OAAO;GACT;GAEA,aAAqB,OAAwB;IAC3C,OAAO,KAAK,MAAM,YAAY,CAAC,CAAC,QAAQ;GAC1C;GAEA,UAAkB,OAAwB;IACxC,MAAM,OAAO,KAAK,MAAM,YAAY,CAAC,CAAC;IACtC,OAAO,OAAO,SAAS,YAAY,SAAS,OAAQ,KAAiC,SAAS,KAAA;GAChG;GAEA,YAAyD;IACvD,OAAO,KAAK,WAAW;GACzB;GAEA,OAAe,OAAwB;IACrC,MAAM,OAAO,KAAK,WAAW;IAC7B,OAAO,SAAS,KAAA,KAAa,OAAO,OAAO,MAAM,KAAK;GACxD;GAEA,UAAwB;IACtB,KAAK,MAAM,YAAY,KAAK,WAAW,SAAS;GAClD;EACF;;;;;;;;;;;ECtMA,IAAa,iCAAb,MAA4C;GAC1C;GACA;;GAGA,YAAY,OAAkB;IAC5B,KAAK,OAAO,IAAI,SAAS,OAAO;KAAC,aAAa,SAAS;KAAG,aAAa,iBAAiB;KAAG,WAAW,eAAe;KAAG,WAAW,cAAc;KAAG,aAAa,cAAc;KAAG,aAAa,aAAa;KAAG,aAAa,kBAAkB;KAAG,YAAY,mBAAmB;MAAE,KAAK;MAAG,KAAK;KAAK,CAAC;KAAG,YAAY,oBAAoB;MAAE,KAAK;MAAG,KAAK;KAAK,CAAC;IAAC,CAAC;IAC/V,KAAK,QAAQ,KAAK,KAAK,WAAW,KAAK,WAAW,CAAC;GACrD;GAEA,aAA4C;IAC1C,OAAO;KACL,GAAG,KAAK,KAAK,MAAM;KACnB,SAAS,KAAK,KAAK,MAAM,SAAS;KAClC,iBAAiB,KAAK,KAAK,MAAM,iBAAiB;KAClD,eAAe,KAAK,KAAK,MAAM,eAAe;KAC9C,cAAc,KAAK,KAAK,MAAM,cAAc;KAC5C,cAAc,KAAK,KAAK,MAAM,cAAc;KAC5C,aAAa,KAAK,KAAK,MAAM,aAAa;KAC1C,kBAAkB,KAAK,KAAK,MAAM,kBAAkB;KACpD,iBAAiB,KAAK,KAAK,MAAM,iBAAiB;KAClD,kBAAkB,KAAK,KAAK,MAAM,kBAAkB;IACtD;GACF;;;;;GAMA,SAAmC;IACjC,OAAO;KACL,OAAO,EAAE,sBAAsB,KAAK,MAAM;KAC1C,GAAG,KAAK,KAAK,QAAQ;IACvB;GACF;EACF;;;;;;EAOA,SAAgB,qBAAqB,OAAgD;GACnF,MAAM,EAAE,MAAM;GACd,MAAM,QAAQ,MAAM,yBAAyB,aAAa,QAAQ;GAElE,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,SAAA,CAA2C,KAAA,CAAS;GACpE,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,YAAY;IAChB,IAAS,YAAY,CAAC,CAAC,OAAO,CAAC,CAC5B,MAAM,QAAQ;KAAE,IAAI,CAAC,aAAa,IAAI,IAAI,WAAW,IAAI,aAAa;IAAE,CAAC,CAAC,CAC1E,YAAY,CAAwB,CAAC;IACxC,aAAa;KAAE,YAAY;IAAK;GAClC,GAAG,CAAC,CAAC;GACL,MAAM,WAAW,CAAC,MAAM;GACxB,MAAM,aAAa;IACjB,iBAAiB,EAAE,qBAAqB;IACxC,YAAY,EAAE,gBAAgB;IAC9B;GACF;GACA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,oBAAD;IACK;IACH,UAAS;IACT,gBAAe;IACN;IACF;IACP,QAAQ,MAAM;IACd,WAAW,MAAM;cAPnB;KASE,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,OAAO,EAAE,kBAAkB;MAC3B,MAAM,EAAE,sBAAsB;MAC9B,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,WAAW,IAAI;MAAE;MAChD,eAAe;OAAE,MAAM,WAAW,SAAS;MAAE;KAC9C,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,OAAO,EAAE,0BAA0B;MACnC,MAAM,EAAE,8BAA8B;MACtC,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,mBAAmB,IAAI;MAAE;MACxD,eAAe;OAAE,MAAM,WAAW,iBAAiB;MAAE;KACtD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;MACE,IAAG;MACH,OAAO,EAAE,wBAAwB;MACjC,MAAM,EAAE,4BAA4B;MACpC,cAAc,EAAE,kBAAkB;MAClC,cAAc;MACd,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,iBAAiB,IAAI;MAAE;MACtD,eAAe;OAAE,MAAM,WAAW,eAAe;MAAE;KACpD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD;MACE,IAAG;MACH,OAAO,EAAE,uBAAuB;MAChC,MAAM,EAAE,2BAA2B;MACnC,cAAc,EAAE,kBAAkB;MAClC,cAAc;MACd,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,gBAAgB,IAAI;MAAE;MACrD,eAAe;OAAE,MAAM,WAAW,cAAc;MAAE;KACnD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,OAAO,EAAE,uBAAuB;MAChC,MAAM,EAAE,2BAA2B;MACnC,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,gBAAgB,IAAI;MAAE;MACrD,eAAe;OAAE,MAAM,WAAW,cAAc;MAAE;KACnD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,OAAO,EAAE,sBAAsB;MAC/B,MAAM,EAAE,0BAA0B;MAClC,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,eAAe,IAAI;MAAE;MACpD,eAAe;OAAE,MAAM,WAAW,aAAa;MAAE;KAClD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,OAAO,EAAE,2BAA2B;MACpC,MAAM,EAAE,+BAA+B;MACvC,GAAI;MACJ,GAAI,MAAM;MACV,SAAS,SAAS;OAAE,MAAM,KAAK,oBAAoB,IAAI;MAAE;MACzD,eAAe;OAAE,MAAM,WAAW,kBAAkB;MAAE;KACvD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,IAAG;MACH,OAAO,EAAE,0BAA0B;MACnC,MAAM,EAAE,8BAA8B;MACtC,cAAc,EAAE,kBAAkB;MAClC,GAAI;MACJ,MAAM,MAAM,gBAAgB;MAC5B,YAAY,MAAM,gBAAgB;MAClC,SAAS,MAAM,gBAAgB;MAC/B,SAAS,SAAS;OAAE,MAAM,KAAK,mBAAmB,IAAI;MAAE;MACxD,eAAe;OAAE,MAAM,WAAW,iBAAiB;MAAE;KACtD,CAAA;KACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;MACE,IAAG;MACH,OAAO,EAAE,2BAA2B;MACpC,MAAM,EAAE,+BAA+B;MACvC,cAAc,EAAE,kBAAkB;MAClC,GAAI;MACJ,MAAM,MAAM,iBAAiB;MAC7B,YAAY,MAAM,iBAAiB;MACnC,SAAS,MAAM,iBAAiB;MAChC,SAAS,SAAS;OAAE,MAAM,KAAK,oBAAoB,IAAI;MAAE;MACzD,eAAe;OAAE,MAAM,WAAW,kBAAkB;MAAE;KACvD,CAAA;IACiB;;EAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EChMA,SAAgB,kBAAkB,OAMX;GACrB,MAAM,EAAE,OAAO,UAAU,YAAY;GACrC,IAAI,aAAa,MACf,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWC,yBAAI;cAAc,GAAG,iBAAiB;GAAQ,CAAA;GAExE,IAAI,UAAU,KAAA,GAAW;IACvB,IAAI,YAAY,KAAA,GAAW,OAAO;IAClC,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KAAQ,MAAK;KAAS,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;KAAc,OAAO,GAAG,kBAAkB;KAAG,SAAS;eAChH,GAAG,cAAc;IACZ,CAAA;GAEZ;GACA,MAAM,gBAAoC;IACxC,IAAI,MAAM,UAAU,KAAA,GAClB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;eAAc,GAAG,cAAc;IAAQ,CAAA;IAE7F,IAAI,MAAM,cAAc,MACtB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI;eAAc,GAAG,kBAAkB;IAAQ,CAAA;IAEzE,IAAI,MAAM,eAAe,MACvB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI;eAAc,GAAG,mBAAmB;IAAQ,CAAA;IAE1E,IAAI,MAAM,SACR,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI;eAArB,CACG,MAAM,QAAQ,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;gBAAgB,GAAG,kBAAkB,EAAE,OAAO,MAAM,QAAQ,OAAO,CAAC;KAAQ,CAAA,IAAI,MACxJ,MAAM,QAAQ,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;gBAAc,GAAG,kBAAkB,EAAE,OAAO,MAAM,QAAQ,OAAO,CAAC;KAAQ,CAAA,IAAI,IACnJ;;IAGV,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;eAAW,GAAG,iBAAiB;IAAQ,CAAA;GAC7F,EAAA,CAAG;GACH,IAAI,YAAY,KAAA,GAAW,OAAO;GAClC,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IAAQ,MAAK;IAAS,WAAWA,yBAAI;IAAY,OAAO,GAAG,kBAAkB;IAAG,SAAS;cACtF;GACK,CAAA;EAEZ;;;EC1BA,SAAgB,gBAAgB,OAA0C;GACxE,MAAM,EAAE,QAAQ,WAAW,MAAM,aAAa,cAAc,aAAa,gBAAgB,eAAe,SAAS,QAAQ,SAAS,QAAQ,mBAAmB;GAC7J,MAAM,eAAe,cAAc,QAAQ,MAAM,WAAW,OAAO,OAAO,SAAS,OAAO,IAAI,CAAC;GAC/F,MAAM,cAAc,iBAAiB,KAAA,IAAY,YAAY,aAAa,QAAQ,KAAA;GAClF,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,yBAAI;cAApB;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAM,SAAS;iBAAS,GAAG,aAAa;MAAU,CAAA,GACvF,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWA,yBAAI;iBAArB,CACG,OAAO,MAEP,OAAO,WAAW,iBACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;QAAU,OAAO,SAAS,WAAW,aAAa;QAAG,OAAO,GAAG,cAAc;OAAI,CAAA,IACtH,OAAO,WAAW,gBAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;QAAS,OAAO,SAAS,WAAW,YAAY;QAAG,OAAO,GAAG,aAAa;OAAI,CAAA,IACnH,IACF;QACH;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SAAqC,GAAG,iBAAiB;SAAE;SAAG,OAAO;QAAc;;OAClF,OAAO,YAAY,KAAA,IAAY,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SAAqC,GAAG,gBAAgB;SAAE;SAAG,eAAe,OAAO,OAAO;QAAO;YAAI;OACpI,OAAO,cAAc,KAAA,IAAY,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SAAqC,GAAG,kBAAkB;SAAE;SAAG,eAAe,OAAO,SAAS;QAAO;YAAI;OAC1I,OAAO,SAAS,KAAA,IAAY,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SAAqC,GAAG,aAAa;SAAE;SAAG,OAAO;QAAU;YAAI;OAC3G,OAAO,cAAc,KAAA,IAAY,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SAAqC,GAAG,kBAAkB;SAAE;SAAG,OAAO;QAAe;YAAI;cACnH;QACN,MAAM,OAAO,KAAK,IAAI,OAAO,IAAI;QACjC,IAAI,SAAS,KAAA,KAAa,KAAK,UAAU,GAAG,OAAO;QACnD,MAAM,KAAK,KAAK,aAAa,KAAA,IAAY,QAAQ,IAAI,KAAK,KAAK,QAAQ,CAAC,CAAC,eAAe,IAAI;QAC5F,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAApB;UAAqC,GAAG,aAAa;UAAE;UAAG,KAAK;UAAO;SAAQ;;OACvF,EAAA,CAAG;cACK;QACN,MAAM,QAAQ,aAAa,QAAQ,CAAC,EAAA,CAAG,QAAQ,QAAQ,IAAI,WAAW,SAAS,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,IAAI;QAClH,OAAO,KAAK,SAAS,IAAI,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAApB;UAAqC,GAAG,eAAe;UAAE;UAAG,KAAK,KAAK,IAAI;SAAO;aAAI;OAChH,EAAA,CAAG;MACA;;KACJ,iBAAiB,KAAA,IAChB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;UAAG,WAAWA,yBAAI;UAAY,MAAM,wBAAwB,aAAa;UAAM,QAAO;UAAS,KAAI;oBAAc,aAAa;SAAQ,CAAA;SACrI,aAAa,QAAQ,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAc,aAAa;SAAU,CAAA,IAAI;SAClH,iBAAA,GAAA,kBAAA,IAAA,CAAC,mBAAD,EAAmB,OAAO,YAAc,CAAA;QACrC;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SACG,GAAG,eAAe;SAAE;SAAG,aAAa,cAAc,KAAK,GAAG,mBAAmB,IAAI,SAAS,aAAa,SAAS;QAC9G;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI,UAAU,MAAMA,yBAAI;kBAAxC;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI;UAAO,UAAU,mBAAmB;UAAM,eAAe;WAAE,QAAQ,aAAa,IAAI;UAAE;oBACxH,mBAAmB,aAAa,OAAO,GAAG,iBAAiB,IAAI,GAAG,cAAc;SAC3E,CAAA;SACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI;UAAO,UAAU,kBAAkB;UAAM,eAAe;WAAE,OAAO,aAAa,MAAM,CAAC,OAAO,IAAI,CAAC;UAAE;oBACrI,kBAAkB,aAAa,OAAO,GAAG,gBAAgB,IAAI,GAAG,aAAa;SACxE,CAAA;SACP,aAAa,QAAQ,SAAS,OAAO,IAAI,MAAM,OAC5C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;UAAU,eAAe;WAAE,eAAe,aAAa,MAAM,CAAC,OAAO,IAAI,CAAC;UAAE;oBAAI,GAAG,qBAAqB;SAAU,CAAA,IACzK;QACD;;MACF;UAEL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAW,GAAG,gBAAgB;KAAK,CAAA;KAEtD,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAQ,GAAG,gBAAgB;KAAO,CAAA,IAAI;KACrE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAgB,OAAO;KAAa,CAAA;IACrD;;EAET;;;ECjEA,SAAgB,cAAc,OAAwC;GACpE,MAAM,EAAE,KAAK,UAAU,cAAc,YAAY,SAAS,SAAS,QAAQ,YAAY,cAAc,gBAAgB,UAAU,UAAU,kBAAkB;GAC3J,MAAM,YAAY,WAAW,KAAK,CAAC,CAAC,kBAAkB;GACtD,MAAM,cAAc,SAAS,UAAU,CAAC,EAAA,CAAG,QAAQ,UAAU,UAAU,WAAW,KAAK,MAAM,KAAK,kBAAkB,CAAC,CAAC,SAAS,SAAS,KAAK,MAAM,YAAY,kBAAkB,CAAC,CAAC,SAAS,SAAS,CAAC;GACtM,MAAM,gBAAgB,SAAS,YAAY,CAAC,EAAA,CAAG,QAAQ,WAAW,UAAU,WAAW,KAAK,OAAO,KAAK,kBAAkB,CAAC,CAAC,SAAS,SAAS,KAAK,OAAO,YAAY,kBAAkB,CAAC,CAAC,SAAS,SAAS,CAAC;GAC7M,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,yBAAI;cAApB;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAM,SAAS;kBAAS,GAAG,aAAa;OAAU,CAAA;OACvF,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;QACjC,OAAO;QACP,WAAW,UAAU;SAAE,WAAW,MAAM,OAAO,KAAK;QAAE;QACtD,aAAa,GAAG,wBAAwB;OACzC,CAAA;OACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAO,UAAU,WAAW,SAAS,KAAK,MAAM;QAAI,SAAS;kBAAW,GAAG,eAAe;OAAU,CAAA;OACxI,IAAI,YAAY,OACb,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAO,UAAU;QAAS,SAAS;kBAAW,GAAG,eAAe;OAAU,CAAA,IAC/G;MACD;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAW,GAAG,oBAAoB;KAAK,CAAA;KACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;MAAO,WAAWA,yBAAI;MAAQ,OAAO;MAAY,WAAW,UAAU;OAAE,aAAa,MAAM,OAAO,KAAK;MAAE;MAAG,aAAa,GAAG,cAAc;KAAI,CAAA;KAC9I,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACG,WAAW,KAAK,UACf,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;OAAwB,WAAWA,yBAAI;iBAAvC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,MAAK;QACL,SAAS,aAAa,IAAI,MAAM,IAAI;QACpC,WAAW,UAAU;SAAE,eAAe,MAAM,MAAM,MAAM,OAAO,OAAO;QAAE;OACzE,CAAA,GACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAU,MAAM;QAAU,CAAA,GAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAU,MAAM;QAAiB,CAAA,CAClD;SACA;SAVK,MAAM,IAUX,CACR,GACA,aAAa,KAAK,WACjB,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;OAAyB,WAAWA,yBAAI;iBAAxC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,MAAK;QACL,SAAS,aAAa,IAAI,OAAO,IAAI;QACrC,WAAW,UAAU;SAAE,eAAe,OAAO,MAAM,MAAM,OAAO,OAAO;QAAE;OAC1E,CAAA,GACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAU,OAAO;QAAU,CAAA,GAC/C,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAApB;UAA8B,OAAO;UAAY;UAAI,GAAG,gBAAgB;SAAO;UAC5E;SACA;SAVK,OAAO,IAUZ,CACR,CACE;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,UAAU;OAAS,SAAS;iBAAgB,GAAG,oBAAoB;MAAU,CAAA;KAC3I,CAAA;IACF;;EAET;;;EC3EA,SAAgB,SAAS,OAAiE;GACxF,MAAM,EAAE,OAAO,QAAQ;GACvB,MAAM,OAAO,IAAI,KAAK,IAAI,MAAM,IAAI;GACpC,MAAM,QAAQ,MAAM,SAAS;GAC7B,MAAM,WAAW,MAAM;;GAEvB,MAAM,MAAM,MAAM,WAAW,iBACzB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWC,yBAAI,MAAM,MAAMA,yBAAI;IAAU,OAAO,SAAS,IAAI,WAAW,aAAa;IAAG,OAAO,GAAG,cAAc;GAAI,CAAA,IAC1H,MAAM,WAAW,gBACf,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;IAAM,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;IAAS,OAAO,SAAS,IAAI,WAAW,YAAY;IAAG,OAAO,GAAG,aAAa;GAAI,CAAA,IACvH;;GAEN,MAAM,aAAa,UAA+C;IAChE,IAAI,MAAM,WAAW,MAAM,eAAe;IAC1C,IAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;KAC9C,MAAM,eAAe;KACrB,IAAS,WAAW,MAAM,IAAI;IAChC;GACF;GACA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IACE,WAAWA,yBAAI;IACf,MAAK;IACL,UAAU;IACV,cAAY,GAAG,YAAY,EAAE,MAAM,MAAM,KAAK,CAAC;IAC/C,eAAe;KAAE,IAAS,WAAW,MAAM,IAAI;IAAE;IACtC;cANb,CAQE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWA,yBAAI;eAApB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAc,MAAM;OAAW,CAAA;OACnD,QAAQ,KAAK,IAAI,WAAW,iBAAiB,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAW;OAAY,CAAA,IAAI;OACrG;OACA,aAAa,KAAA,KAAa,IAAI,WAAW,gBAAgB,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAU,iBAAiB,QAAQ;OAAQ,CAAA,IAAI;MACnI;SACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAU,MAAM;KAAiB,CAAA,CAClD;QACJ,MAAM,WACH,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,MAAK;KACL,gBAAc;KACd,cAAY,GAAG,aAAa;KAC5B,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;KAClC,UAAU,IAAI,UAAU,IAAI,MAAM,IAAI;KACtC,UAAU,UAAU;MAAE,MAAM,gBAAgB;MAAG,IAAS,OAAO,OAAO,KAAK;KAAE;eAC9E,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,YAAc,CAAA;IAAS,CAAA,GAC5C,IAAI,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACd,MAAK;KACL,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI,WAAW,MAAMA,yBAAI;KACtD,UAAU,IAAI,UAAU,IAAI,MAAM,IAAI,KAAK,IAAI;KAC/C,OAAO,GAAG,YAAY;KACtB,cAAY,GAAG,YAAY;KAC3B,UAAU,UAAU;MAAE,MAAM,gBAAgB;MAAG,IAAI,mBAAmB,MAAM,IAAI;KAAE;eACnF,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD,EAAoB,MAAM,GAAK,CAAA;IAAS,CAAA,IAAI,IAC7C,EAAA,CAAA,IACF,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;eAAgB,GAAG,cAAc;IAAQ,CAAA,CACjF;;EAET;;;;EC5DA,SAAS,oBAAoB,MAA4B;GACvD,OAAO,GAAI,kBAAkB,IAAe;EAC9C;EAEA,SAAgB,YAAY,OAAoF;GAC9G,MAAM,EAAE,QAAQ,MAAM,aAAa;GACnC,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWC,yBAAI,MAAM,MAAMA,yBAAI;cAApC;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAU,OAAO;MAAU,CAAA,GAC/C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAU,OAAO;MAAiB,CAAA,CACnD;;KACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;MAAM,WAAWA,yBAAI;gBACnB,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;iBAAc,oBAAoB,OAAO,IAAI;MAAQ,CAAA;KACxF,CAAA;KACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MAAQ,MAAK;MAAS,MAAK;MAAS,gBAAc;MAAO,cAAY,GAAG,YAAY;MAAG,WAAWA,yBAAI;MAAQ,UAAU;MAAM,SAAS;gBAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,YAAc,CAAA;KAAS,CAAA;IAC1L;;EAET;;;ECrBA,SAAgB,aAAa,OAAwE;GACnG,MAAM,EAAE,SAAS,QAAQ;GACzB,IAAI,QAAQ;GACZ,IAAI;GACJ,KAAK,MAAM,QAAQ,SAAS;IAC1B,MAAM,OAAO,IAAI,KAAK,IAAI,IAAI;IAC9B,IAAI,SAAS,KAAA,GAAW;IACxB,SAAS,KAAK;IACd,IAAI,KAAK,aAAa,KAAA,MAAc,WAAW,KAAA,KAAa,KAAK,WAAW,SAAS,SAAS,KAAK;GACrG;GACA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;IAAM,WAAWC,yBAAI;cAArB,CACG,IAAI,WAAW,qBAAqB,SAAS,QAAQ,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI;eAAW;IAAY,CAAA,IAAI,MACzG,IAAI,WAAW,qBAAqB,SAAS,WAAW,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWA,yBAAI,UAAU,MAAMA,yBAAI;eAAY,iBAAiB,MAAM;IAAQ,CAAA,IAAI,IACzJ;;EAEV;;;;;;;;;;EC2EA,SAAgB,YAAY,OAA4C;GACtE,MAAM,EAAE,QAAQ;GAChB,MAAM,EAAE,SAAS,aAAa,WAAW,cAAc,SAAS,QAAQ,YAAY,iBAAiB,WAAW,aAAa,aAAa,gBAAgB,eAAe,WAAW,WAAW,qBAAqB,cAAc,aAAa,eAAe,oBAAoB,aAAa,mBAAmB;GAClT,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAAyC,IAAI;GAChE,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAAyC,IAAI;GAEhE,IAAI,cAAc,QAChB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAA,kBAAA,UAAA,EAAA,UAAG,eAAe,QAAQ,cAAc,OAAO,CAAC,CAAC,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;IAAkC;IAAY;GAAM,GAArC,MAAM,IAA+B,CAAC,EAAI,CAAA;GAIlI,MAAM,mBAAmB,eAAe,QAAQ,cAAc,OAAO,CAAC,CAAC,QAAQ,UAAU,gBAAgB,MAAM,MAAM,CAAC;GACtH,MAAM,aAAa,iBAAiB,SAAS;GAC7C,MAAM,cAAc,aAAa,eAAe,CAAC;GACjD,MAAM,gBAAgB,eAAe,QAAQ,cAAc,OAAO,CAAC,CAAC,QAAQ,UAAU,QAAQ,MAAM,UAAU,KAAA,KAAa,CAAC,gBAAgB,MAAM,MAAM,CAAC;GACzJ,MAAM,uBAAuB,SAAS,YAAY,CAAC,EAAA,CAAG,QAAQ,WAAW,QAAQ,OAAO,UAAU,KAAA,CAAS,CAAC,CACzG,QAAQ,WAAW,WAAW,WAAW,KAAK,OAAO,KAAK,kBAAkB,CAAC,CAAC,SAAS,UAAU,KAAK,OAAO,YAAY,kBAAkB,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAClK,QAAQ,WAAW,iBAAiB,SAAS,iBAAA,SAA+B;GAE/E,MAAM,cAAc,CADS,GAAG,cAAc,KAAK,MAAM,EAAE,IAAI,GAAG,GAAG,oBAAoB,KAAK,MAAM,EAAE,IAAI,CACpE,CAAC,CAAC,SAAS;GACjD,MAAM,iBAA2B;IAC/B,GAAI,aAAa,CAAC,SAAS,IAAI,CAAC;IAChC,GAAG,YAAY,KAAK,MAAM,SAAS,EAAE,IAAI;IACzC,GAAI,cAAc,CAAC,sBAAsB,IAAI,CAAC;GAChD;GACA,MAAM,iBAAiB,aAAa,oBAAoB,CAAC;GACzD,MAAM,wBAAwB;IAC5B,IAAI,eAAe,WAAW,GAAG,OAAO;IACxC,MAAM,MAAM,IAAI,IAAI,cAAc;IAClC,MAAM,SAAS,eAAe,QAAQ,MAAM,eAAe,SAAS,CAAC,CAAC;IACtE,KAAK,MAAM,KAAK,gBAAgB,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,CAAC;IAE9D,IAAI,OAAO,WAAW,GAAG,OAAO;IAChC,OAAO;GACT,EAAA,CAAG;GACH,MAAM,iBAAiB,cAA4B;IACjD,IAAI,eAAe,QAAQ,eAAe,WAAW;IACrD,MAAM,OAAO,eAAe,QAAQ,UAAU;IAC9C,MAAM,KAAK,eAAe,QAAQ,SAAS;IAC3C,IAAI,SAAS,MAAM,OAAO,IAAI;IAC9B,MAAM,OAAO,CAAC,GAAG,cAAc;IAC/B,MAAM,CAAC,SAAS,KAAK,OAAO,MAAM,CAAC;IACnC,KAAK,OAAO,IAAI,GAAG,KAAK;IACxB,IAAS,oBAAoB,IAAI;GACnC;GAmBA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CAFiB,CAAC,cAAc,YAAY,WAAW,KAAK,CAAC,cAG7C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWC,yBAAI;cAAQ,GAAG,sBAAsB;GAAO,CAAA,IAAI,MAC7E,eAAe,KAAK,WAAW;IAE9B,IAAI,WAAW,aAAa,YAAY;KACtC,MAAM,eAAe,gBAAgB,IAAI,SAAS;KAClD,MAAM,aAAa,eAAe;KAClC,MAAM,SAAS,eAAe,aAAa,eAAe;KAE1D,MAAM,4BAAY,IAAI,IAAgE;KACtF,KAAK,MAAM,SAAS,kBAAkB;MACpC,MAAM,MAAM,MAAM,aAAa,MAAM;MACrC,MAAM,QAAQ,UAAU,IAAI,GAAG;MAC/B,IAAI,UAAU,KAAA,GAAW,UAAU,IAAI,KAAK;OAAE,OAAO,MAAM,kBAAkB,MAAM,aAAa,GAAG,gBAAgB;OAAG,QAAQ,CAAC,KAAK;MAAE,CAAC;WAClI,MAAM,OAAO,KAAK,KAAK;KAC9B;KACA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;MAEE,WAAWA,yBAAI,WAAW,aAAa,MAAMA,yBAAI,WAAW,OAAO,SAAS,MAAMA,yBAAI,WAAW;MACjG,WAAA;MACA,cAAc,MAAM;OAAE,cAAc,SAAS;OAAG,EAAE,aAAa,gBAAgB;OAAQ,EAAE,aAAa,QAAQ,cAAc,SAAS;MAAE;MACvI,aAAa,MAAM;OAAE,EAAE,eAAe;OAAG,IAAI,eAAe,WAAW,cAAc,SAAS;MAAE;MAChG,mBAAmB;OAAE,IAAI,eAAe,WAAW,cAAc,IAAI;MAAE;MACvE,SAAS,MAAM;OAAE,EAAE,eAAe;OAAG,cAAc,SAAS;OAAG,cAAc,IAAI;MAAE;MACnF,iBAAiB;OAAE,cAAc,IAAI;OAAG,cAAc,IAAI;MAAE;gBAR9D,CAUE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;QAAY,eAAA;QAAY,OAAM;kBAAS;OAAQ,CAAA,GACpE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAY,iBAAe,CAAC;QAAc,eAAe;SAAE,oBAAoB,SAAS;QAAE;kBAA/H,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,eAAe,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GAClF,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAArB;UAAkC,GAAG,gBAAgB;UAAE;UAAI,UAAU;SAAW;UAC1E;SACL;UACJ,CAAC,eAAe,CAAC,GAAG,UAAU,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,UAAU;OAC7D,MAAM,UAAU,aAAa;OAC7B,MAAM,gBAAgB,gBAAgB,IAAI,OAAO;OACjD,MAAM,aAAa,IAAI,mBAAmB,IAAI,GAAG;OACjD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAmB,WAAWA,yBAAI;kBAAlC,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAApB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI;UAAY,iBAAe,CAAC;UAAe,eAAe;WAAE,oBAAoB,OAAO;UAAE;oBAA9H,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,gBAAgB,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GACnF,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;WAAM,WAAWA,yBAAI;qBAArB;YAAkC,KAAK;YAAM;YAAI,KAAK,OAAO;YAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;aAAc,SAAS,KAAK,OAAO,KAAK,MAAM,EAAE,IAAI;aAAQ;YAAM,CAAA;WAAO;YACvI;aACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI;oBACnB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,WAAWA,yBAAI;WAAO,UAAU,UAAU;YAAE,MAAM,gBAAgB;YAAG,IAAI,gBAAgB,GAAG;WAAE;qBAAI,aAAa,GAAG,cAAc,IAAI,GAAG,kBAAkB;UAAU,CAAA;SACrL,CAAA,CACH;YACJ,CAAC,gBACA,aACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAChB,CAAC,eAAe,gBAAgB,CAAC,CAAW,KAAK,WAAW;UAC5D,MAAM,OAAO,KAAK,OAAO,QAAQ,UAAU,MAAM,WAAW,MAAM;UAClE,IAAI,KAAK,WAAW,GAAG,OAAO;UAC9B,MAAM,SAAS,UAAU,MAAM;UAC/B,MAAM,eAAe,gBAAgB,IAAI,MAAM;UAC/C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAkB,WAAWA,yBAAI;qBAAjC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;YAAK,WAAWA,yBAAI;sBAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;aAAQ,MAAK;aAAS,WAAWA,yBAAI;aAAY,iBAAe,CAAC;aAAc,eAAe;cAAE,oBAAoB,MAAM;aAAE;uBAA5H,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,eAAe,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GAClF,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;cAAM,WAAWA,yBAAI;wBAArB;eAAkC,GAAI,kBAAkB,MAAqE;eAAE;eAAI,KAAK;cAAa;eAC/I;;WACL,CAAA,GACJ,CAAC,eAAe,KAAK,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;YAAkC;YAAY;WAAM,GAArC,MAAM,IAA+B,CAAC,IAAI,IAC3F;aARK,MAQL;SAET,CAAC;QACE,CAAA,IACH,KAAK,OAAO,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAkC;SAAY;QAAM,GAArC,MAAM,IAA+B,CAAC,IAClF,IACD;UAjCK,OAiCL;MAET,CAAC,IAAI,IACE;QAzDH,SAyDG;IAEb;IAEA,IAAI,OAAO,WAAW,MAAM,GAAG;KAC7B,MAAM,UAAU,OAAO,MAAM,CAAC;KAC9B,MAAM,aAAa,YAAY,MAAM,MAAM,EAAE,SAAS,OAAO;KAC7D,IAAI,eAAe,KAAA,GAAW,OAAO;KACvC,MAAM,SAAS,eAAe,QAAQ,cAAc,OAAO,CAAC,CAAC,QAAQ,UAAU,WAAW,WAAW,SAAS,MAAM,IAAI,CAAC;KACzH,MAAM,mBAAmB,SAAS,YAAY,CAAC,EAAA,CAAG,QAAQ,WACxD,WAAW,WAAW,SAAS,OAAO,IAAI,MACtC,WAAW,WAAW,KAAK,OAAO,KAAK,kBAAkB,CAAC,CAAC,SAAS,UAAU,KAAK,OAAO,YAAY,kBAAkB,CAAC,CAAC,SAAS,UAAU,OAC7I,iBAAiB,UAAU,QAAQ,OAAO,SAAA,eAA6B,aAAa;KAC1F,MAAM,YAAY,gBAAgB,IAAI,SAAS,WAAW,IAAI;KAC9D,MAAM,OAAO,gBAAgB,WAAW,YAAY,SAAS;KAC7D,MAAM,QAAQ,YAAY,WAAW;KACrC,MAAM,cAAc,WAAW,WAAW,MAAM,SAAS,YAAY,IAAI,IAAI,CAAC;KAC9E,MAAM,aAAa,eAAe;KAClC,MAAM,SAAS,eAAe,UAAU,eAAe;KACvD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;MAEE,WAAWA,yBAAI,WAAW,aAAa,MAAMA,yBAAI,WAAW,OAAO,SAAS,MAAMA,yBAAI,WAAW;MACjG,WAAA;MACA,cAAc,MAAM;OAAE,cAAc,MAAM;OAAG,EAAE,aAAa,gBAAgB;OAAQ,EAAE,aAAa,QAAQ,cAAc,MAAM;MAAE;MACjI,aAAa,MAAM;OAAE,EAAE,eAAe;OAAG,IAAI,eAAe,QAAQ,cAAc,MAAM;MAAE;MAC1F,mBAAmB;OAAE,IAAI,eAAe,QAAQ,cAAc,IAAI;MAAE;MACpE,SAAS,MAAM;OAAE,EAAE,eAAe;OAAG,cAAc,MAAM;OAAG,cAAc,IAAI;MAAE;MAChF,iBAAiB;OAAE,cAAc,IAAI;OAAG,cAAc,IAAI;MAAE;gBAR9D,CAUE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAApB;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;SAAY,eAAA;SAAY,OAAM;mBAAS;QAAQ,CAAA;QACpE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAY,iBAAe,CAAC;SAAW,eAAe;UAAE,oBAAoB,SAAS,WAAW,IAAI;SAAE;mBAA3I,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,YAAY,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GAC/E,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI;oBAArB;WACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;YAAG,WAAWA,yBAAI;YAAY,MAAM,wBAAwB,WAAW;YAAM,QAAO;YAAS,KAAI;YAAa,UAAU,UAAU;aAAE,MAAM,gBAAgB;YAAE;sBAAI,WAAW;WAAQ,CAAA;WAClL,QAAQ,WAAW,WAAW;WAC/B,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;YAAc,SAAS,WAAW;YAAiB;WAAM,CAAA;UACrD;WACA;;QACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAArB;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,mBAAD;WACS;WACP,UAAU,mBAAmB,WAAW;WACxC,eAAe;YAAE,aAAkB,WAAW,IAAI;WAAE;UACrD,CAAA;UACA,UAAU,KAAA,KAAa,MAAM,WAAW,MAAM,QAAQ,SAAS,IAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,WAAWA,yBAAI;WAAO,UAAU,kBAAkB;WAAM,UAAU,UAAU;YAAE,MAAM,gBAAgB;YAAG,YAAY,WAAW,MAAM,MAAM,OAAO;WAAE;qBACtK,kBAAkB,WAAW,OAAO,GAAG,gBAAgB,IAAI,GAAG,aAAa;UACtE,CAAA,IACR;UACH,UAAU,KAAA,KAAa,MAAM,QAAQ,SAAS,IAC3C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;WAAU,UAAU,UAAU;YAAE,MAAM,gBAAgB;YAAG,cAAc,WAAW,MAAM,MAAM,OAAO;WAAE;qBAAI,GAAG,qBAAqB;UAAU,CAAA,IACpM;UACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,MAAK;WAAS,gBAAc,KAAK,UAAU;WAAO,cAAY,WAAW;WAC7F,WAAWA,yBAAI,UAAU,KAAK,UAAU,OAAO,MAAMA,yBAAI,WAAW,KAAK,UAAU,UAAU,MAAMA,yBAAI,cAAc;WACrH,UAAU,aAAa,WAAW,WAAW,WAAW,KAAM,KAAK,UAAU,SAAS,CAAC;WACvF,OAAO,KAAK,UAAU,SAAS,CAAC,cAAc,GAAG,mBAAmB,IAAI,KAAA;WACxE,UAAU,UAAU;YAAE,MAAM,gBAAgB;YAAG,YAAY,SAAS,WAAW,MAAM,WAAW,MAAM,KAAK,KAAK;WAAE;qBAClH,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,YAAc,CAAA;UAC7B,CAAA;UACP,IAAI,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WACd,MAAK;WACL,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;WACjC,OAAO,GAAG,0BAA0B,EAAE,OAAO,WAAW,WAAW,OAAO,CAAC;WAC3E,UAAU,UAAU;YAAE,MAAM,gBAAgB;YAAG,mBAAmB,WAAW,MAAM,WAAW,UAAU;WAAE;qBAEzG,GAAG,oBAAoB;UAClB,CAAA,IAAI;SACR;;OACH;UACJ,CAAC,YACA,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACG,OAAO,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAkC;OAAY;MAAM,GAArC,MAAM,IAA+B,CAAC,GAC3E,gBAAgB,KAAK,WACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;OAAuC;OAAQ,MAAM,UAAU,IAAI,OAAO,IAAI;OAAG,gBAAgB;QAAE,eAAoB,MAAM;OAAE;MAAI,GAAjH,OAAO,IAA0G,CACpI,CACD,EAAA,CAAA,IACA,IACG;QA1DF,SAAS,WAAW,IA0DlB;IAEX;IAEA,IAAI,WAAW,0BAA0B,aAAa;KACpD,MAAM,gBAAgB,eAAe,QAAQ,cAAc,OAAO,CAAC,CAAC,QAAQ,UAAU,QAAQ,MAAM,UAAU,KAAA,KAAa,CAAC,gBAAgB,MAAM,MAAM,CAAC;KACzJ,MAAM,oBAAoB,SAAS,YAAY,CAAC,EAAA,CAAG,QAAQ,WAAW,QAAQ,OAAO,UAAU,KAAA,CAAS,CAAC,CACtG,QAAQ,WAAW,WAAW,WAAW,KAAK,OAAO,KAAK,kBAAkB,CAAC,CAAC,SAAS,UAAU,KAAK,OAAO,YAAY,kBAAkB,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAClK,QAAQ,WAAW,iBAAiB,SAAS,iBAAA,SAA+B;KAC/E,MAAM,mBAAmB,CAAC,GAAG,cAAc,KAAK,MAAM,EAAE,IAAI,GAAG,GAAG,iBAAiB,KAAK,MAAM,EAAE,IAAI,CAAC;KACrG,IAAI,iBAAiB,WAAW,GAAG,OAAO;KAC1C,MAAM,YAAY,gBAAgB,IAAI,sBAAsB;KAC5D,MAAM,aAAa,eAAe;KAClC,MAAM,SAAS,eAAe,0BAA0B,eAAe;KACvE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;MAEE,WAAWA,yBAAI,WAAW,aAAa,MAAMA,yBAAI,WAAW,OAAO,SAAS,MAAMA,yBAAI,WAAW;MACjG,WAAA;MACA,cAAc,MAAM;OAAE,cAAc,sBAAsB;OAAG,EAAE,aAAa,gBAAgB;OAAQ,EAAE,aAAa,QAAQ,cAAc,sBAAsB;MAAE;MACjK,aAAa,MAAM;OAAE,EAAE,eAAe;OAAG,IAAI,eAAe,wBAAwB,cAAc,sBAAsB;MAAE;MAC1H,mBAAmB;OAAE,IAAI,eAAe,wBAAwB,cAAc,IAAI;MAAE;MACpF,SAAS,MAAM;OAAE,EAAE,eAAe;OAAG,cAAc,sBAAsB;OAAG,cAAc,IAAI;MAAE;MAChG,iBAAiB;OAAE,cAAc,IAAI;OAAG,cAAc,IAAI;MAAE;gBAR9D,CAUE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAApB;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;SAAY,eAAA;SAAY,OAAM;mBAAS;QAAQ,CAAA;QACpE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAY,iBAAe,CAAC;SAAW,eAAe;UAAE,oBAAoB,sBAAsB;SAAE;mBAAzI,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,YAAY,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GAC/E,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI;oBAArB;WAAkC,GAAG,iBAAiB;WAAE;WAAI,iBAAiB;WAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;YAAc,SAAS;YAAuB;WAAM,CAAA;UAAO;WACzI;;QACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAClB,IAAI,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;UAAU,OAAO,GAAG,0BAA0B,EAAE,OAAO,iBAAiB,OAAO,CAAC;UAAG,UAAU,UAAU;WAAE,MAAM,gBAAgB;WAAG,mBAAmB,GAAG,iBAAiB,GAAG,gBAAgB;UAAE;oBAAI,GAAG,oBAAoB;SAAU,CAAA,IAAI;QAC1S,CAAA;OACH;UACJ,CAAC,YACA,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACG,cAAc,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAkC;OAAY;MAAM,GAArC,MAAM,IAA+B,CAAC,GAClF,iBAAiB,KAAK,WAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;OAAuC;OAAQ,MAAM,UAAU,IAAI,OAAO,IAAI;OAAG,gBAAgB;QAAE,eAAoB,MAAM;OAAE;MAAI,GAAjH,OAAO,IAA0G,CAAE,CACxK,EAAA,CAAA,IACA,IACG;QAzBH,sBAyBG;IAEb;IACA,OAAO;GACT,CAAC,CACD,EAAA,CAAA;EAEN;;;;;;;;;EC/VA,SAAgB,WAAW,OAA4C;GACrE,MAAM,EAAE,QAAQ;GAChB,MAAM,EAAE,SAAS,aAAa,QAAQ,YAAY,iBAAiB,WAAW,aAAa,WAAW,WAAW,YAAY,eAAe,SAAS,WAAW,qBAAqB,aAAa,eAAe,aAAa,iBAAiB,eAAe,mBAAmB;GACjR,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,SAAA,CAAqC,IAAI;GACxD,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,SAAA,CAAqC,IAAI;GACxD,MAAM,cAAc,aAA2B;IAC7C,IAAI,WAAW,QAAQ,WAAW,YAAY,gBAAgB,MAAM;IACpE,MAAM,MAAM,YAAY,KAAK,KAAK,MAAM,EAAE,EAAE;IAC5C,MAAM,OAAO,IAAI,QAAQ,MAAM;IAC/B,MAAM,KAAK,IAAI,QAAQ,QAAQ;IAC/B,IAAI,SAAS,MAAM,OAAO,IAAI;IAC9B,MAAM,OAAO,CAAC,GAAG,GAAG;IACpB,MAAM,CAAC,SAAS,KAAK,OAAO,MAAM,CAAC;IACnC,KAAK,OAAO,IAAI,GAAG,KAAK;IACxB,IAAS,YAAY,IAAI;GAC3B;GACA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;IACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;KAAM,WAAWC,yBAAI;KAAM,WAAW,UAAU;MAAE,UAAe,KAAK;KAAE;eACtE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;OACE,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;OACjC,OAAO;OACP,WAAW,UAAU;QAAE,cAAc,MAAM,OAAO,KAAK;OAAE;OACzD,aAAa,GAAG,wBAAwB;MACzC,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,UAAU,WAAW,WAAW,KAAK,MAAM;iBAAK,GAAG,YAAY;MAAU,CAAA,CACvI;;IACD,CAAA;IAEL,gBAAgB,QAAQ,YAAY,KAAK,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,yBAAI;eAAQ,GAAG,cAAc;IAAO,CAAA,IAAI;IAChH,aAAa,KAAK,KAAK,QAAQ;KAC9B,MAAM,SAAS,OAAO,QAAQ,UAAU,IAAI,WAAW,SAAS,MAAM,IAAI,CAAC;KAC3E,MAAM,mBAAmB,SAAS,YAAY,CAAC,EAAA,CAAG,QAAQ,WAAW,IAAI,WAAW,SAAS,OAAO,IAAI,MAAM,WAAW,WAAW,KAAK,OAAO,KAAK,kBAAkB,CAAC,CAAC,SAAS,UAAU,KAAK,OAAO,YAAY,kBAAkB,CAAC,CAAC,SAAS,UAAU,EAAE;KAC7P,MAAM,YAAY,gBAAgB,IAAI,SAAS,IAAI,EAAE;KACrD,MAAM,OAAO,gBAAgB,IAAI,YAAY,SAAS;KACtD,MAAM,cAAc,IAAI,WAAW,MAAM,SAAS,YAAY,IAAI,IAAI,CAAC;KACvE,MAAM,aAAa,WAAW,IAAI;KAClC,MAAM,SAAS,WAAW,IAAI,MAAM,WAAW,IAAI;KACnD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;MAEE,WAAWA,yBAAI,WAAW,aAAa,MAAMA,yBAAI,WAAW,OAAO,SAAS,MAAMA,yBAAI,WAAW;MACjG,WAAA;MACA,cAAc,MAAM;OAAE,UAAU,IAAI,EAAE;OAAG,EAAE,aAAa,gBAAgB;OAAQ,EAAE,aAAa,QAAQ,cAAc,IAAI,EAAE;MAAE;MAC7H,aAAa,MAAM;OAAE,EAAE,eAAe;OAAG,IAAI,WAAW,IAAI,IAAI,UAAU,IAAI,EAAE;MAAE;MAClF,mBAAmB;OAAE,IAAI,WAAW,IAAI,IAAI,UAAU,IAAI;MAAE;MAC5D,SAAS,MAAM;OAAE,EAAE,eAAe;OAAG,WAAW,IAAI,EAAE;OAAG,UAAU,IAAI;MAAE;MACzE,iBAAiB;OAAE,UAAU,IAAI;OAAG,UAAU,IAAI;MAAE;gBARtD,CAUE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAApB;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;SAAY,eAAA;SAAY,OAAM;mBAAS;QAAQ,CAAA;QACpE,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAY,iBAAe,CAAC;SAAW,eAAe;UAAE,oBAAoB,SAAS,IAAI,EAAE;SAAE;mBAAlI,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,WAAW,YAAY,MAAMA,yBAAI,mBAAmB,IAAM,CAAA,GAC/E,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI;oBAArB;WACG,IAAI;WAAK;WAAI,IAAI,WAAW;WAC7B,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAD;YAAc,SAAS,IAAI;YAAiB;WAAM,CAAA;UAC9C;WACA;;QACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,MAAK;UAAS,gBAAc,KAAK,UAAU;UAAO,cAAY,IAAI;UACtF,WAAWA,yBAAI,UAAU,KAAK,UAAU,OAAO,MAAMA,yBAAI,WAAW,KAAK,UAAU,UAAU,MAAMA,yBAAI,cAAc;UACrH,UAAU,aAAa,IAAI,WAAW,WAAW,KAAM,KAAK,UAAU,SAAS,CAAC;UAChF,OAAO,KAAK,UAAU,SAAS,CAAC,cAAc,GAAG,mBAAmB,IAAI,KAAA;UACxE,UAAU,UAAU;WAAE,MAAM,gBAAgB;WAAG,YAAY,SAAS,IAAI,IAAI,IAAI,MAAM,KAAK,KAAK;UAAE;oBAClG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,WAAWA,yBAAI,YAAc,CAAA;SAC7B,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI;UAAO,eAAe;WAAE,cAAc,GAAG;WAAG,YAAY,IAAI,IAAI;WAAG,gBAAgB,IAAI,IAAI,IAAI,UAAU,CAAC;WAAG,cAAc,EAAE;UAAE;oBAAI,GAAG,aAAa;SAAU,CAAA,CAC9L;;OACH;UACJ,CAAC,YACA,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACG,OAAO,KAAK,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAkC;OAAY;MAAM,GAArC,MAAM,IAA+B,CAAC,GAC3E,gBAAgB,KAAK,WACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD;OAAuC;OAAQ,MAAM,UAAU,IAAI,OAAO,IAAI;OAAG,gBAAgB;QAAE,eAAoB,MAAM;OAAE;MAAI,GAAjH,OAAO,IAA0G,CACpI,CACD,EAAA,CAAA,IACA,IACG;QArCF,SAAS,IAAI,EAqCX;IAEb,CAAC;GACD,EAAA,CAAA;EAEN;;;;ECnFA,MAAa,iBAAgD;GAC3D;IAAE,MAAM;IAAqB,gBAAgB;GAA4B;GACzE;IAAE,MAAM;IAAoB,gBAAgB;GAA6B;GACzE;IAAE,MAAM;IAAqB,gBAAgB;GAA4B;GACzE;IAAE,MAAM;IAAuB,gBAAgB;GAA4B;EAC7E;;;;;;;;;;ECyBA,SAAS,YAAY,OAAkE;GACrF,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,MAAM,SAAS,UAA+B;KAC5C,IAAI,MAAM,QAAQ,UAAU,MAAM,QAAQ;IAC5C;IACA,OAAO,iBAAiB,WAAW,KAAK;IACxC,aAAa;KAAE,OAAO,oBAAoB,WAAW,KAAK;IAAE;GAC9D,CAAC;GACD,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;IAAK,WAAWC,yBAAI;IAAe,SAAS,MAAM;cAChD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;KAAK,WAAWA,yBAAI;KAAQ,MAAK;KAAc,cAAW;KAAO,UAAU,UAAU;MAAE,MAAM,gBAAgB;KAAE;eAC5G,MAAM;IACJ,CAAA;GACF,CAAA;EAET;;EAGA,SAAgB,cAAc,OAUd;GACd,MAAM,EAAE,OAAO,MAAM,OAAO,cAAc,QAAQ,UAAU,cAAc;GAC1E,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,aAAD;IAAa,SAAS;cAAtB;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAAc;KAAU,CAAA;KAC3C,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAa;KAAQ,CAAA;KACtC,UAAU,KAAA,IACT,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAChB,MAAM,KAAK,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD,EAAA,UAAe,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,yBAAI;iBAAc;MAAW,CAAA,EAAK,GAAzD,IAAyD,CAAC;KACtF,CAAA,IACF;KACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,SAAS;iBAAW,GAAG,aAAa;MAAU,CAAA,GAC3F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,UAAU,WAAW,OAAO,MAAMA,yBAAI,SAAS,MAAMA,yBAAI;OAAU,SAAS;iBAC9G;MACK,CAAA,CACL;;IACM;;EAEjB;;EAGA,SAAgB,eAAe,OAOf;GACd,MAAM,EAAE,QAAQ,MAAM,aAAa,SAAS,UAAU,eAAe;GACrE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,aAAD;IAAsB;cAAtB;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAAc,GAAG,sBAAsB;KAAM,CAAA;KAChE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAa,GAAG,qBAAqB;KAAK,CAAA;KAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAChB,OAAO,UAAU,KAAK,SACrB,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;OAAM,WAAWA,yBAAI;iBAAc;MAAW,CAAA,GAC7C,QAAQ,aAAa,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAChE,EAAA,GAHK,IAGL,CACL;KACC,CAAA;KACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,SAAS;iBAAW,GAAG,eAAe;MAAU,CAAA,GAC7F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,SAAS;iBAAa,GAAG,iBAAiB;MAAU,CAAA,CAClH;;IACM;;EAEjB;;EAGA,SAAgB,mBAAmB,OAMnB;GACd,MAAM,EAAE,QAAQ,MAAM,UAAU,UAAU,cAAc;GACxD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,aAAD;IAAa,SAAS;cAAtB;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAAc,GAAG,oBAAoB;KAAM,CAAA;KAC9D,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAa,GAAG,mBAAmB;KAAK,CAAA;KAC1D,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;MAAQ,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;MAAc,OAAO,OAAO;MACpE,WAAW,UAAU;OAAE,SAAS,MAAM,OAAO,KAAK;MAAE;gBACnD,OAAO,SAAS,KAAK,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAqB,OAAO;iBAAS;MAAe,GAAvC,MAAuC,CAAC;KAChF,CAAA;KACR,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,SAAS;iBAAW,GAAG,aAAa;MAAU,CAAA,GAC3F,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,UAAU;OAAM,SAAS;iBAAY,GAAG,sBAAsB;MAAU,CAAA,CACtI;;IACM;;EAEjB;;EAGA,SAAgB,iBAAiB,OAMjB;GACd,MAAM,EAAE,QAAQ,MAAM,UAAU,UAAU,cAAc;GACxD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,aAAD;IAAa,SAAS;cAAtB;KACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;MAAI,WAAWA,yBAAI;gBAAc,GAAG,kBAAkB;KAAM,CAAA;KAC5D,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAa,GAAG,mBAAmB,EAAE,KAAK,OAAO,IAAI,CAAC;KAAK,CAAA;KAC5E,OAAO,OAAO,WAAW,IACxB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;MAAG,WAAWA,yBAAI;gBAAa,GAAG,iBAAiB;KAAK,CAAA,IAExD,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBACjB,OAAO,OAAO,KAAK,SAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;OAAkB,WAAWA,yBAAI;iBAAjC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QAAO,MAAK;QAAW,SAAS,OAAO,SAAS,IAAI,IAAI;QACtD,WAAW,UAAU;SAAE,SAAS,MAAM,MAAM,OAAO,OAAO;QAAE;OAAI,CAAA,GAClE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAc;OAAW,CAAA,CACzC;SAJK,IAIL,CACR;KACE,CAAA;KAEP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,SAAS;iBAAW,GAAG,mBAAmB;MAAU,CAAA,GACjG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,UAAU,QAAQ,OAAO,OAAO,WAAW;OAAG,SAAS;iBACrH,OAAO,GAAG,gBAAgB,IAAI,GAAG,aAAa;MACzC,CAAA,CACL;;IACM;;EAEjB;;;;;;;;;;ECxKA,SAAS,YAAY,OAAuB;GAC1C,IAAI,QAAQ,MAAM,OAAO,QAAQ;GACjC,IAAI,QAAQ,OAAO,MAAM,QAAQ,QAAQ,KAAA,CAAM,QAAQ,CAAC,IAAI;GAC5D,QAAQ,QAAQ,OAAO,KAAA,CAAM,QAAQ,CAAC,IAAI;EAC5C;EACA,SAAS,YAAY,KAAsB;GACzC,IAAI,QAAQ,KAAA,KAAa,OAAO,GAAG,OAAO;GAC1C,IAAI,MAAM,MAAM,OAAO,MAAM;GAC7B,IAAI,MAAM,OAAO,MAAM,QAAQ,MAAM,KAAA,CAAM,QAAQ,CAAC,IAAI;GACxD,QAAQ,MAAM,OAAO,KAAA,CAAM,QAAQ,CAAC,IAAI;EAC1C;EAEA,SAAgB,WAAW,OAA4C;GACrE,MAAM,EAAE,QAAQ;GAChB,MAAM,EAAE,aAAa,aAAa,aAAa,cAAc,mBAAmB,cAAc,cAAc,iBAAiB,eAAe,YAAY,eAAe,kBAAkB,eAAe,SAAS,gBAAgB,WAAW,iBAAiB,oBAAoB,UAAU,aAAa,cAAc,kBAAkB,oBAAoB,YAAY,cAAc,iBAAiB,oBAAoB,cAAc;;GAEza,MAAM,iBAAiB,OAAO,QAAQ,WAAW,CAAC,CAAC,QAAQ,GAAG,WAAW,MAAM,WAAW,MAAM,QAAQ,SAAS,CAAC;GAGlH,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA0B,EAAE;GAC/C,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAAkC,KAAK;GAC1D,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAA4B,EAAE;GACnD,CAAA,GAAA,MAAA,UAAA,OAAgB;IAAE,gBAAgB,EAAE;GAAE,GAAG;IAAC;IAAmB;IAAY;GAAU,CAAC;;GAGpF,MAAM,aAAa,WAA4C;IAC7D,MAAM,eAAe,YAAY,OAAO;IACxC,MAAM,aAAa,YAAY,OAAO;IACtC,MAAM,iBAAiB,cAAc,QAAQ,MAAM,WAAW,OAAO,SAAS,OAAO,IAAI,CAAC,EAAE,OAAO,UAAU;IAC7G,MAAM,WAAW,iBAAiB,OAAO;IACzC,MAAM,UAAU,kBAAkB,OAAO;IACzC,MAAM,WAAW,mBAAmB,OAAO;IAC3C,MAAM,iBAAiB,YAAY,YAAY,QAAQ,WAAW,QAAQ,SAAS;IACnF,MAAM,mBAAmB,cAAc,oBAAoB;IAC3D,MAAM,YAAY,kBAAkB;IACpC,MAAM,YAAY,iBAAiB,KAAA,KAAa,eAAe,KAAA;IAE/D,IAAI;IACJ,IAAI,iBAAiB;IACrB,IAAI,eAAe;IACnB,IAAI,qBAAiC,CAAC;IACtC,IAAI,SAAS;KACX,cAAc,GAAG,gBAAgB;KACjC,iBAAiB;IACnB,OAAO,IAAI,UAAU;KACnB,cAAc,GAAG,iBAAiB;KAClC,iBAAiB;IACnB,OAAO,IAAI,CAAC,WAAW;KACrB,cAAc,GAAG,oBAAoB;KACrC,qBAAqB;MAAE,aAAkB,OAAO,IAAI;MAAG,YAAiB;KAAE;IAC5E,OAAO,IAAI,WAAW;KACpB,MAAM,QAAQ,iBAAiB,WAAY,QAAQ,SAAS;KAC5D,cAAc,QAAQ,KAAK,iBAAiB,GAAG,sBAAsB,EAAE,MAAM,CAAC,IAAI,GAAG,eAAe;KACpG,eAAe;KACf,qBAAqB;MAAE,iBAAsB,OAAO,IAAI;KAAE;IAC5D,OAAO;KACL,cAAc,GAAG,iBAAiB;KAClC,iBAAiB;IACnB;IACA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;KAAK,WAAWC,yBAAI,MAAM,MAAMA,yBAAI;eAApC;MACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAClB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;UAAG,WAAWA,yBAAI;UAAY,MAAM,wBAAwB,OAAO;UAAM,QAAO;UAAS,KAAI;oBAAc,OAAO;SAAQ,CAAA;SACzH,OAAO,QAAQ,KAAA,IAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAc,OAAO;SAAU,CAAA,IAAI;SACrG,iBAAiB,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAa,GAAG,oBAAoB,EAAE,OAAO,eAAe,CAAC;SAAQ,CAAA,IAAI;SACrI,iBACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAgB,GAAG,oBAAoB,EAAE,OAAO,WAAY,QAAQ,OAAO,CAAC;SAAQ,CAAA,IAC3H;SACH,eAAe,KAAA,KAAa,WAAW,QAAQ,SAAS,IACrD,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAc,GAAG,0BAA0B,EAAE,OAAO,WAAW,QAAQ,OAAO,CAAC;SAAQ,CAAA,IAC9H;SACH,mBACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;oBAAgB,aAAc,cAAc,KAAA,IAAY,GAAG,qBAAqB,EAAE,SAAS,aAAc,UAAU,CAAC,IAAI,GAAG,gBAAgB;SAAQ,CAAA,IAC1L;QACD;;MACF,CAAA;MACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;OAAS,OAAO;QAAE,SAAQ;QAAY,UAAS;OAAG;OAAG,UAAU;OAAU,eAAe;QAAE,SAAc,OAAO,IAAI;OAAE;iBAC1K,WAAW,GAAG,iBAAiB,IAAI,GAAG,aAAa;MAC9C,CAAA;MACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,MAAK;OACL,WAAWA,yBAAI,SAAS,eAAe,MAAMA,yBAAI,WAAW;OAC5D,UAAU;OACV,OAAO,YAAY,yBAAyB,KAAA;OAC5C,SAAS;iBAER;MACK,CAAA;MACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OACE,MAAK;OACL,WAAWA,yBAAI;OACf,UAAU;OACV,OAAO,GAAG,mBAAmB;OAC7B,cAAY,GAAG,qBAAqB;OACpC,eAAe;QAAE,mBAAwB,OAAO,IAAI;OAAE;OACtD,OAAO;QAAE,SAAQ;QAAW,UAAS;OAAG;iBACzC;MAAS,CAAA;KACP;;GAET;GAIA,MAAM,OAAqD,CAAC;GAC5D,KAAK,MAAM,SAAS,gBAAgB;IAClC,MAAM,SAAS,YAAY,MAAM,MAAM,SAAS,KAAK,SAAS,MAAM,IAAI;IACxE,IAAI,WAAW,KAAA,GACb,KAAK,KAAK;KAAE,KAAK,MAAM;KAAM,SAAS,UAAU,MAAM;IAAE,CAAC;SACpD;KACL,MAAM,OAAO,iBAAiB,QAAQ;KACtC,KAAK,KAAK;MACR,KAAK,MAAM;MACX,SACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;iBAApC,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;UAAG,WAAWA,yBAAI;UAAY,MAAM,wBAAwB,MAAM;UAAM,QAAO;UAAS,KAAI;oBAAc,MAAM;SAAQ,CAAA;QACrH,CAAA,GACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAU,GAAG,MAAM,cAAc;QAAO,CAAA,CACzD;WACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI;QAAO,UAAU;QAAM,eAAe;SAAE,UAAe,MAAM,IAAI;QAAE;kBAAI,GAAG,YAAY;OAAU,CAAA,CAClI;;KAET,CAAC;IACH;GACF;GACA,KAAK,MAAM,UAAU,YAAY,OAAO;IACtC,IAAI,eAAe,MAAM,UAAU,MAAM,SAAS,OAAO,IAAI,GAAG;IAChE,KAAK,KAAK;KAAE,KAAK,OAAO;KAAM,SAAS,UAAU,MAAM;IAAE,CAAC;GAC5D;GACA,MAAM,iBAAiB,eAAe,QAAQ,UAAU,CAAC,YAAY,MAAM,MAAM,WAAW,OAAO,SAAS,MAAM,IAAI,CAAC;GAEvH,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;IACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;KAAS,WAAWA,yBAAI;eAAxB;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI,eAAe,MAAMA,yBAAI;iBAA7C;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAAmB,GAAG,cAAc;QAAQ,CAAA;QACjE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAO,eAAe;UAAE,aAAkB;UAAG,YAAiB;SAAE;mBAAI,GAAG,iBAAiB;QAAU,CAAA;QACvI,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SACE,MAAK;SACL,WAAWA,yBAAI,SAAS,eAAe,SAAS,IAAI,MAAMA,yBAAI,WAAW;SACzE,UAAU,eAAe,WAAW,KAAK;SACzC,eAAe;UAAE,mBAAmB,IAAI;SAAE;mBAC1C,GAAG,kBAAkB;QAAU,CAAA;OAC9B;;MACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI,UAAU,MAAMA,yBAAI;iBAAxC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;QACE,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;QACjC,OAAO;QACP,WAAW,UAAU;SAAE,iBAAiB,MAAM,OAAO,KAAK;QAAE;QAC5D,YAAY,UAAU;SAAE,IAAI,MAAM,QAAQ,SAAS;UAAE,MAAM,eAAe;UAAG,gBAAqB;SAAE;QAAE;QACtG,aAAa,GAAG,uBAAuB;OACxC,CAAA,GACD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;QAAS,UAAU,cAAc,KAAK,MAAM;QAAI,eAAe;SAAE,gBAAqB;QAAE;kBAAI,GAAG,kBAAkB;OAAU,CAAA,CAChL;;MACJ,eAAe,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;OAAG,WAAWA,yBAAI,WAAW,MAAMA,yBAAI;iBAAa,GAAG,oBAAoB;MAAK,CAAA,IAAI;MAEhH,YAAY,WAAW,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAQ,GAAG,eAAe;MAAO,CAAA,IAAI;MAC5F,YAAY,WAAW,aAAa,KAAK,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAQ,GAAG,kBAAkB;MAAO,CAAA,IAAI;MACpH,YAAY,WAAW,YAAY,KAAK,KAAK,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAACC,MAAAA,UAAD,EAAA,UAAyB,IAAI,QAAkB,GAAhC,IAAI,GAA4B,CAAC,IAAI;KACnG;;IAEP,kBAAkB,WAAW,UAAU,eAAe,OACtD,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;KAAS,WAAWD,yBAAI;KAAS,OAAO;MAAE,YAAY;MAAuC,YAAY;KAAwB;eAAjI,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI,eAAe,MAAMA,yBAAI;MAAgB,OAAO,EAAE,QAAQ,gBAAgB;gBAA9F,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;OAAM,WAAWA,yBAAI;OAAkB,OAAO;QAAE,SAAQ;QAAQ,YAAW;QAAU,KAAI;OAAE;iBAA3F;QACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAM,OAAO;SAAE,OAAM;SAAG,QAAO;SAAG,cAAa;SAAO,YAAW;SAA6B,SAAQ;QAAe,EAAI,CAAA;QAAC;QAE1H,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SAAM,OAAO;UAAE,YAAW;UAAK,SAAQ;SAAI;mBAA3C;UAA8C;UACzC,kBAAkB,WAAW,UAAU,kBAAkB,KAAK,OAAO,kBAAkB,WAAW,UAAW,gBAAgB,KAAO,gBAAgB;UACtJ,kBAAkB,WAAW,WAAW,kBAAkB,KAAK,QAAQ,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;WAAM,OAAO;YAAE,SAAQ;YAAI,YAAW;WAAE;qBAAxC,CAA2C,QAAK,kBAAkB,KAAK,GAAU;eAAI;SAChK;;OACF;UACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAO,eAAe;QAAE,IAAI,UAAU;OAAE;iBAAG;MAAU,CAAA,CACvF;SACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,OAAO,EAAE,SAAQ,cAAc;gBAApC;OACG,kBAAkB,WAAW,aAAa,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;QAAO,OAAO,EAAE,SAAQ,SAAS;kBAAI,GAAG,iBAAiB;OAAO,CAAA,IAAI;OAClI,kBAAkB,WAAW,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAAc,kBAAkB;OAAa,CAAA,IAAI;OAC5G,kBAAkB,WAAW,iBAAiB;QACnD,MAAM,UAAU,kBAAkB,KAAK;QAEvC,MAAM,iCAAiB,IAAI,IAAY;SACrC,IAAK,IAAI,SAAS,UAAU,CAAC,EAAA,CAAG,KAAK,MAAM,EAAE,IAAI;SACjD,IAAK,IAAI,SAAS,YAAY,CAAC,EAAA,CAAG,KAAK,MAAM,EAAE,IAAI;SACnD,IAAK,YAAY,YAAY,CAAC,EAAA,CAAG,KAAK,MAAM,EAAE,IAAI;SAClD,IAAK,YAAY,WAAW,CAAC,EAAA,CAAG,KAAK,MAAM,EAAE,IAAI;QACnD,CAAC;QACD,MAAM,cAAc,UAAmC,MAAM,YAAY,eAAe,IAAI,MAAM,IAAI;QACtG,MAAM,WAAW,QAAQ,QAAQ,UAAU,aAAa,IAAI,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,CAAC;QAC7F,MAAM,gBAAgB,SAAS,QAAQ,GAAG,MAAM,IAAI,EAAE,YAAY,CAAC;QAEnE,MAAM,WAAW,QAAQ,QAAQ,UAAU;SACzC,IAAI,eAAe,SAAS,MAAM,SAAS,YAAY,OAAO;SAC9D,IAAI,WAAW,KAAK,MAAM,MAAM,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,SAAS,WAAW,KAAK,CAAC,CAAC,YAAY,CAAC,GAAG,OAAO;SAC5G,OAAO;QACT,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;QAC9C,MAAM,QAAQ,SAAS,MAAM,GAAG,YAAY;QAC5C,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,KAAD;SAAG,WAAWA,yBAAI,WAAW,MAAMA,yBAAI;mBAAvC;UAAoD,GAAG,cAAc,EAAE,OAAO,QAAQ,OAAO,CAAC;UAAE;UAAI,kBAAkB,KAAK,QAAQ,OAAO,OAAO,kBAAkB,KAAK,QAAQ;SAAM;YACrL,QAAQ,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAQ,GAAG,YAAY;QAAO,CAAA,IACxE,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;gBAEU;UAEN,MAAM,wBAAQ,IAAI,IAAoB,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC;UAC9E,MAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM;WACpE,MAAM,KAAK,MAAM,IAAI,CAAC,KAAK;WAC3B,MAAM,KAAK,MAAM,IAAI,CAAC,KAAK;WAC3B,OAAO,OAAO,KAAK,KAAK,KAAK,EAAE,cAAc,CAAC;UAChD,CAAC;UACD,MAAM,yBAAS,IAAI,IAAoB;UACvC,KAAK,MAAM,KAAK,SAAS,OAAO,IAAI,EAAE,OAAO,OAAO,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC;UACzE,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,OAAO;YAAE,SAAQ;YAAQ,KAAI;YAAG,cAAa;YAAG,UAAS;WAAO;qBAArE;YACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;aACE,WAAWA,yBAAI;aACf,OAAO;cAAE,MAAK;cAAG,UAAS;aAAI;aAC9B,OAAO;aACP,WAAW,MAAM,cAAc,EAAE,OAAO,KAAK;aAC7C,aAAY;YACb,CAAA;YACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;aAAQ,MAAK;aAAS,WAAWA,yBAAI,UAAU,eAAe,QAAQ,MAAMA,yBAAI,UAAU;aAAK,OAAO;cAAE,SAAQ;cAAY,UAAS;aAAG;aAAG,eAAe,cAAc,KAAK;uBAA7K,CAAgL,OAAI,QAAQ,MAAe;;YAC1M,MAAM,KAAK,SACV,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;aAAmB,MAAK;aAAS,WAAWA,yBAAI,UAAU,eAAe,OAAO,MAAMA,yBAAI,UAAU;aAAK,OAAO;cAAE,SAAQ;cAAY,UAAS;aAAG;aAAG,eAAe,cAAc,IAAI;uBAAtL;cAA0L;cAAK;cAAE,OAAO,IAAI,IAAI,KAAK;aAAU;eAAlN,IAAkN,CAChO;WACE;;SAET,EAAA,CAAG;SACH,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,yBAAI;UAAU,OAAO;WAAE,SAAQ;WAAQ,gBAAe;WAAiB,UAAS;WAAQ,KAAI;UAAE;oBAA9G,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD,EAAA,UAAA;WAAM;WAAI,SAAS;WAAO;WAAE,QAAQ;WAAO;WAAI,YAAY,aAAa;WAAE;WAAO,MAAM;WAAO;WAAE,SAAS;WAAO;UAAW,EAAA,CAAA,GAC3H,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;WAAM,OAAO;YAAE,SAAQ;YAAQ,KAAI;WAAE;qBAArC;YACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aAAQ,MAAK;aAAS,WAAWA,yBAAI;aAAQ,OAAO;cAAE,SAAQ;cAAW,UAAS;aAAG;aAAG,eAAe;cAAE,gBAAgB,IAAI,IAAI,SAAS,QAAQ,MAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,KAAK,MAAI,EAAE,IAAI,CAAC,CAAC;aAAE;uBAAG;YAAc,CAAA;YACjO,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;aAAQ,MAAK;aAAS,WAAWA,yBAAI;aAAQ,OAAO;cAAE,SAAQ;cAAW,UAAS;aAAG;aAAG,eAAe;cAAE,gBAAgB,IAAI,IAAI,QAAQ,QAAQ,MAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,MAAI,EAAE,IAAI,CAAC,CAAC;aAAE;uBAAxL,CAA2L,SAAM,QAAQ,QAAO,MAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAe;;YAClP,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;aAAQ,MAAK;aAAS,WAAWA,yBAAI;aAAQ,OAAO;cAAE,SAAQ;cAAW,UAAS;aAAG;aAAG,eAAe;cAAE,gCAAgB,IAAI,IAAI,CAAC;aAAE;uBAAI,GAAG,eAAe;YAAU,CAAA;WAChK;YACH;;SAGL,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWA,yBAAI;oBACjB,MAAM,WAAW,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;WAAK,WAAWA,yBAAI;WAAO,OAAO,EAAE,SAAQ,GAAG;qBAAG;UAAU,CAAA,IAAI,MAAM,KAAK,UAAU;WACzG,MAAM,WAAW,WAAW,KAAK;WACjC,OACA,iBAAA,GAAA,kBAAA,KAAA,CAAC,SAAD;YAAwB,WAAWA,yBAAI,OAAO,WAAW,MAAMA,yBAAI,WAAW;sBAA9E;aACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;cACE,MAAK;cACL,SAAS,aAAa,IAAI,MAAM,IAAI;cACpC,UAAU;cACV,WAAW,UAAU;eAAE,mBAAmB,MAAM,MAAM,MAAM,OAAO,OAAO;cAAE;aAC7E,CAAA;aACD,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;cAAK,WAAWA,yBAAI;wBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;eAAK,WAAWA,yBAAI;yBAAU,MAAM;cAAU,CAAA,GAC9C,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;eAAK,WAAWA,yBAAI;yBAApB;gBAA8B,MAAM;gBAAI;gBAAI,GAAG,cAAc;iBAAE,OAAO,MAAM;iBAAW,MAAM,YAAY,MAAM,UAAU;gBAAE,CAAC;eAAO;gBAChI;;aACJ,WACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;cAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;wBAAgB,GAAG,eAAe;aAAQ,CAAA,IACjF,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;cAAM,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;wBAAc,MAAM;aAAa,CAAA;YACvE;cAdK,MAAM,IAcX;UACR,CAAC;SACC,CAAA;SACJ,eAAe,SAAS,SACvB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,OAAO;WAAE,WAAU;WAAU,WAAU;UAAE;oBAC5C,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,WAAWA,yBAAI;WAAQ,eAAe,iBAAiB,MAAM,IAAI,EAAE;qBAAzF;YAA4F;YAAa,SAAS,SAAS;YAAa;WAAS;;SAC9I,CAAA,IACH;SAEJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;UAAK,WAAWA,yBAAI,UAAU,MAAMA,yBAAI;oBAAxC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;WAAS,UAAU,SAAS,WAAW,KAAK;WAAe,eAAe;YAAE,WAAgB;WAAE;qBAAI,gBAAgB,GAAG,gBAAgB,IAAI,GAAG,GAAG,eAAe,EAAE,OAAO,SAAS,OAAO,CAAC,EAAE,KAAK,YAAY,aAAa;UAAY,CAAA,GAC3R,gBAAgB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,MAAK;WAAS,WAAWA,yBAAI;WAAQ,eAAe;YAAE,aAAkB;WAAE;qBAAI,GAAG,aAAa;UAAU,CAAA,IAAI,IAClI;;SACJ,eAAe,QAAQ,WAAW,WAAW,mBAAmB;UAC/D,MAAM,MAAM,WAAW,aAAa,IAAI,KAAK,IAAI,KAAK,KAAK,MAAM,WAAW,kBAAkB,WAAW,aAAa,GAAG,CAAC,IAAK,WAAW,QAAQ,IAAI,KAAK,MAAM,WAAW,OAAO,WAAW,QAAQ,GAAG,IAAI;UAC7M,MAAM,QAAQ,YAAY,WAAW,cAAc;UACnD,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;WAAK,WAAWA,yBAAI,cAAc,MAAMA,yBAAI;qBAA5C;YACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;aAAK,OAAO;cAAE,SAAQ;cAAQ,YAAW;cAAU,KAAI;cAAG,cAAa;aAAE;uBAAzE,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;cAAK,WAAWA,yBAAI;wBAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;eAAK,WAAWA,yBAAI;eAAkB,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG;cAAI,CAAA;aACjE,CAAA,GACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;cAAM,OAAO;eAAE,UAAS;eAAI,SAAQ;eAAK,UAAS;eAAI,WAAU;cAAQ;wBAAxE,CAA4E,KAAI,GAAO;eACpF;;YACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;aAAK,WAAWA,yBAAI;uBAApB;cACG,YAAY,WAAW,eAAe;cAAE;cAAI,YAAY,WAAW,UAAU;cAC7E,UAAU,KAAK,MAAM,UAAU;cAAG;cAAI,WAAW;cAAK;cAAE,WAAW;cAAM;aACvE;;YACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;aAAK,WAAWA,yBAAI;aAAU,OAAO,EAAC,WAAU,EAAC;uBAAjD,CACG,WAAW,YAAY,KAAA,IAAY,GAAG,yBAAyB;cAAE,MAAM,WAAW;cAAS,MAAM,WAAW,OAAO;cAAG,OAAO,WAAW;aAAM,CAAC,IAAI,GAAG,gBAAgB,GACtK,WAAW,gBAAgB,KAAA,IAAY,MAAM,WAAW,gBAAgB,EACtE;;YACJ,WAAW,OAAO,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;aAAK,WAAWA,yBAAI;aAAa,OAAO,EAAC,WAAU,EAAC;uBAAI,WAAW,OAAO,KAAI,MAAK,GAAG,EAAE,KAAK,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI;YAAO,CAAA,IAAI;WAC7J;;SAET,EAAA,CAAG,IAAI;QACP,EAAA,CAAA,CAEJ,EAAA,CAAA;OAEN,EAAA,CAAG,IAAI;OACN,eAAe,QAAQ,WAAW,WAAW,YAC5C,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAW,WAAW,WAAW,cAAcA,yBAAI,cAAc,MAAMA,yBAAI,aAAaA,yBAAI,cAAc,MAAMA,yBAAI;kBAAzH;SACG,WAAW,WAAW,cAAc,GAAG,kBAAkB;UAAE,UAAU,WAAW,SAAS;UAAQ,OAAO,WAAW;SAAM,CAAC,IAAI,GAAG,GAAG,iBAAiB,EAAE,OAAO,WAAW,SAAS,OAAO,CAAC,EAAE,KAAK,GAAG,wBAAwB,EAAE,OAAO,WAAW,QAAQ,OAAO,CAAC,EAAE,KAAK,GAAG,eAAe,EAAE,OAAO,WAAW,OAAO,OAAO,CAAC;SAC5T,WAAW,OAAO,SAAS,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,OAAO,EAAC,WAAU,EAAC;oBAAI,WAAW,OAAO,KAAI,MAAK,GAAG,EAAE,KAAK,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,IAAI;SAAO,CAAA,IAAI;SACnI,WAAW,WAAW,WAAW,WAAW,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,OAAO,EAAC,WAAU,EAAC;oBAAI,WAAW;SAAW,CAAA,IAAI;QACxG;YACH;MACK;OACE;SACP;IAEH,kBACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;KACE,OAAO,GAAG,8BAA8B;KACxC,MAAM,GAAG,6BAA6B;KACtC,OAAO,eAAe,KAAK,CAAC,MAAM,WAAW,GAAG,wBAAwB;MAAE;MAAM,OAAO,MAAM,QAAQ;KAAO,CAAC,CAAC;KAC9G,cAAc,GAAG,kBAAkB;KACnC,QAAA;KACA,gBAAgB;MAAE,mBAAmB,KAAK;KAAE;KAC5C,iBAAiB;MAAE,UAAe;KAAE;IACrC,CAAA,IACC;GACJ,EAAA,CAAA;EAEN;;;;;;;;;;;EClTA,MAAM,UAAU;;EAEhB,MAAM,eAAe;;EAGrB,MAAM,iBAAiB;;EAEvB,MAAM,yBAAyB,OAAU;;EAGzC,SAAS,kBAA2B;GAClC,IAAI;IACF,MAAM,MAAM,aAAa,QAAQ,cAAc;IAC/C,MAAM,OAAO,QAAQ,OAAO,MAAM,OAAO,GAAG;IAC5C,IAAI,CAAC,OAAO,SAAS,IAAI,GAAG,OAAO;IACnC,OAAO,KAAK,IAAI,IAAI,QAAQ;GAC9B,QAAQ;IAEN,OAAO;GACT;EACF;;EAGA,SAAS,kBAAwB;GAC/B,IAAI;IACF,aAAa,QAAQ,gBAAgB,OAAO,KAAK,IAAI,CAAC,CAAC;GACzD,QAAQ,CAER;EACF;EAyBA,SAAgB,YAAY,KAAkB;GAC5C,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,SAAA,CAA+C,IAAI;GACnE,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,SAAA,CAAuB,IAAI;GAC3C,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,CAAwC,IAAI;;GAE9D,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA4C,IAAI;GACtE,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAAwC,EAAE,QAAQ,OAAO,CAAC;GAC9E,MAAM,CAAC,mBAAmB,yBAAA,GAAA,MAAA,SAAA,CAAoD,EAAE,QAAQ,OAAO,CAAC;;GAEhG,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAA2C,IAAI;GACpE,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,iBAAiD,IAAI,IAAI,CAAC;GAC/E,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA6B,KAAK;GACxD,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA6D,IAAI;GACpF,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAA0C,IAAI;GAClE,MAAM,gBAAA,GAAA,MAAA,OAAA,CAA8C,IAAI;GACxD,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,SAAA,CAAsB,EAAE;;GAEvC,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,CAAyB,EAAE;GAC7C,MAAM,CAAC,QAAQ,cAAA,GAAA,MAAA,SAAA,CAA0C,IAAI;GAC7D,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA6B,KAAK;GACxD,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,iBAA8C,IAAI,IAAI,CAAC;GACzE,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,CAAyB,KAAK;GAChD,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,KAAK;GAC9C,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,EAAE;GAC3C,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,EAAE;GAC3C,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAsC,UAAU;GACjE,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,KAAK;GAC9C,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAA+E,IAAI;GACvG,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,SAAA,iBAA+E,IAAI,IAAI,CAAC;GACrG,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,CAA2C,IAAI;GACjE,MAAM,CAAC,KAAK,WAAA,GAAA,MAAA,SAAA,CAAoD,SAAS;GACzE,MAAM,CAAC,WAAW,iBAAA,GAAA,MAAA,SAAA,CAA4C,QAAQ;GACtE,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAA4B,KAAK;GACtD,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,SAAA,CAAgC,MAAM;GACtD,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAAwC;IAAE,QAAQ;IAAW,OAAO,CAAC;GAAE,CAAC;GAC5F,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAAwE,CAAC,CAAC;GAC9F,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAAsD,IAAI;GAC/E,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA0B,KAAK;GAClD,MAAM,CAAC,kBAAkB,wBAAA,GAAA,MAAA,SAAA,CAA8D,IAAI;GAC3F,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA4C,IAAI;GACtE,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,KAAK;GAC9C,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA6B,EAAE;GACrD,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAAkD,IAAI;GAC1E,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,CAAoD,IAAI;GAC7E,MAAM,CAAC,aAAa,mBAAA,GAAA,MAAA,SAAA,CAAwE,CAAC,CAAC;GAC9F,MAAM,CAAC,gBAAgB,sBAAA,GAAA,MAAA,SAAA,CAA6C,IAAI;GACxE,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAA4C,IAAI;GACtE,MAAM,CAAC,gBAAgB,sBAAA,GAAA,MAAA,SAAA,CAA0D,IAAI;GACrF,MAAM,CAAC,eAAe,qBAAA,GAAA,MAAA,SAAA,CAAwD,IAAI;GAClF,MAAM,CAAC,mBAAmB,yBAAA,GAAA,MAAA,SAAA,CAAgD,IAAI;GAC9E,MAAM,CAAC,mBAAmB,yBAAA,GAAA,MAAA,SAAA,CAAgF,IAAI;GAC9G,MAAM,CAAC,mBAAmB,yBAAA,GAAA,MAAA,SAAA,CAAiC,KAAK;;GAEhE,MAAM,CAAC,iBAAiB,uBAAA,GAAA,MAAA,SAAA,CAA+B,KAAK;GAC5D,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA2C,IAAI;GAClE,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,EAAE;GAC3C,MAAM,CAAC,cAAc,oBAAA,GAAA,MAAA,SAAA,iBAAiD,IAAI,IAAI,CAAC;GAC/E,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA0B,EAAE;GAC/C,MAAM,CAAC,SAAS,eAAA,GAAA,MAAA,SAAA,CAAuB,KAAK;GAC5C,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA0B,EAAE;;GAE/C,MAAM,CAAC,iBAAiB,uBAAA,GAAA,MAAA,SAAA,iBAAoD,IAAI,IAAI,CAAC;;GAErF,MAAM,CAAC,oBAAoB,0BAAA,GAAA,MAAA,SAAA,iBAAuD,IAAI,IAAI,CAAC;GAC3F,MAAM,CAAC,YAAY,kBAAA,GAAA,MAAA,SAAA,CAA0B,KAAK;GAClD,MAAM,CAAC,UAAU,gBAAA,GAAA,MAAA,SAAA,CAAwB,KAAK;GAE9C,MAAM,uBAAA,GAAA,MAAA,YAAA,EAAmC,QAAsB;IAC7D,oBAAoB,aAAa;KAC/B,MAAM,OAAO,IAAI,IAAI,QAAQ;KAC7B,IAAI,KAAK,IAAI,GAAG,GAAG,KAAK,OAAO,GAAG;UAC7B,KAAK,IAAI,GAAG;KACjB,OAAO;IACT,CAAC;GACH,GAAG,CAAC,CAAC;GAEL,MAAM,mBAAA,GAAA,MAAA,YAAA,EAA+B,QAAsB;IACzD,uBAAuB,aAAa;KAClC,MAAM,OAAO,IAAI,IAAI,QAAQ;KAC7B,IAAI,KAAK,IAAI,GAAG,GAAG,KAAK,OAAO,GAAG;UAC7B,KAAK,IAAI,GAAG;KACjB,OAAO;IACT,CAAC;GACH,GAAG,CAAC,CAAC;GAEL,MAAM,QAAA,GAAA,MAAA,YAAA,CAAmB,YAA2B;IAClD,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,QAAQ,cAAc,KAAK,EAAE,KAAK,UAAU,IAAI,KAAA,CAAS;KAChF,WAAW,IAAI;KACf,aAAa,IAAI;IACnB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG,CAAC,KAAK,SAAS,CAAC;GAEnB,MAAM,YAAA,GAAA,MAAA,YAAA,CAAuB,YAA2B;IACtD,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,MAAM;KAC/B,IAAI,OAAO,WAAW,QAAQ,IAAI,IAAI,OAAO,MAAM,KAAK,SAAS,CAAC,KAAK,MAAM;MAAE,OAAO,KAAK;MAAO,GAAI,KAAK,aAAa,KAAA,IAAY,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;KAAG,CAAC,CAAC,CAAC,CAAC;IAC5K,QAAQ,CAER;GACF,GAAG,CAAC,GAAG,CAAC;GAER,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,YAA2B;IACxD,IAAI;KACF,cAAc,MAAM,IAAI,OAAO,EAAA,CAAG,MAAM;IAC1C,QAAQ,CAER;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,eAAA,GAAA,MAAA,YAAA,CAA0B,YAA2B;IACzD,eAAe,EAAE,QAAQ,WAAW,CAAC;IACrC,IAAI;KACF,eAAe;MAAE,QAAQ;MAAS,MAAM,MAAM,IAAI,YAAY;KAAE,CAAC;IACnE,SAAS,OAAO;KACd,eAAe;MAAE,QAAQ;MAAS,SAAS,aAAa,KAAK;KAAE,CAAC;IAClE;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,YAA2B;IACxD,IAAI;KACF,eAAe,MAAM,IAAI,OAAO,CAAC;IACnC,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,eAAA,GAAA,MAAA,YAAA,CAA0B,YAA2B;IACzD,IAAI;KACF,gBAAgB,MAAM,IAAI,QAAQ,CAAC;IACrC,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,YAA2B;IACxD,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,OAAO;KAC9B,eAAe;MAAE,QAAQ;MAAS,OAAO,KAAK;KAAM,CAAC;IACvD,SAAS,OAAO;KACd,eAAe;MAAE,QAAQ;MAAS,OAAO,CAAC;KAAE,CAAC;KAC7C,aAAa,aAAa,KAAK,CAAC;IAClC;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,aAAA,GAAA,MAAA,YAAA,EAAyB,SAA2B;IACxD,gBAAgB,aAAa,aAAa,OACtC;KAAE,IAAI;KAAM;KAAM,aAAa,CAAC;KAAG,SAAS,CAAC;IAAE,IAC/C;KAAE,GAAG;KAAU;IAAK,CAAC;GAC3B,GAAG,CAAC,CAAC;GAML,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,KAAU;IACV,SAAc;IACd,WAAgB;IAChB,YAAiB;IACjB,WAAgB;IAChB,MAAM,OAAO,OAAO,kBAAkB;KAAE,KAAU;IAAE,GAAG,OAAO;IAC9D,MAAM,OAAO,OAAO,kBAAkB;KAAE,SAAc;KAAG,WAAgB;KAAG,YAAiB;KAAG,WAAgB;IAAE,GAAG,YAAY;IACjI,aAAa;KAAE,OAAO,cAAc,IAAI;KAAG,OAAO,cAAc,IAAI;IAAE;GACxE,GAAG;IAAC;IAAM;IAAU;IAAY;IAAa;GAAU,CAAC;GAExD,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,OAAO,SAAgC;IACpE,iBAAiB,IAAI;IACrB,aAAa,IAAI;IACjB,IAAI;KACF,UAAU,MAAM,IAAI,MAAM,MAAM,cAAc,KAAK,EAAE,KAAK,UAAU,IAAI,KAAA,CAAS,CAAC;IACpF,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,iBAAiB,KAAK;IACxB;GACF,GAAG,CAAC,KAAK,SAAS,CAAC;GAEnB,MAAM,UAAA,GAAA,MAAA,YAAA,CAAqB,OAAO,OAAqB,YAAoC;IACzF,cAAc,aAAa,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,MAAM,IAAI,CAAC;IAC5D,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,OAAO,MAAM,MAAM,OAAO;KACjD,WAAW,IAAI;IACjB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,cAAc,aAAa;MACzB,MAAM,OAAO,IAAI,IAAI,QAAQ;MAC7B,KAAK,OAAO,MAAM,IAAI;MACtB,OAAO;KACT,CAAC;IACH;GACF,GAAG,CAAC,GAAG,CAAC;GAER,MAAM,kBAAA,GAAA,MAAA,YAAA,CAA6B,OAAO,WAAyC;IACjF,cAAc,aAAa,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC;IAC7D,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,OAAO,OAAO,MAAM,IAAI;KAC/C,WAAW,IAAI;IACjB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,cAAc,aAAa;MACzB,MAAM,OAAO,IAAI,IAAI,QAAQ;MAC7B,KAAK,OAAO,OAAO,IAAI;MACvB,OAAO;KACT,CAAC;IACH;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,oBAAA,GAAA,MAAA,YAAA,CAA+B,OAAO,OAAiB,YAAoC;IAC/F,IAAI,MAAM,WAAW,GAAG;IACxB,aAAa,IAAI;IACjB,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,YAAY,OAAO,OAAO;KACjD,WAAW,KAAK,OAAO;KACvB,IAAI,KAAK,SAAS,SAAS,GACzB,aAAa,mBAAmB,KAAK,SAAS,KAAK,YAAY,QAAQ,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;IAElH,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,aAAa,KAAK;IACpB;GACF,GAAG,CAAC,GAAG,CAAC;;GAKR,MAAM,YAAA,GAAA,MAAA,YAAA,OAAoD;IACxD,MAAM,sBAAM,IAAI,IAAsB;IACtC,KAAK,MAAM,OAAO,aAAa,QAAQ,CAAC,GAAG,IAAI,IAAI,SAAS,IAAI,IAAI,IAAI,UAAU;IAClF,KAAK,MAAM,cAAc,aAAa,eAAe,CAAC,GAAG,IAAI,IAAI,SAAS,WAAW,MAAM,WAAW,UAAU;IAChH,OAAO;GACT,GAAG,CAAC,WAAW,CAAC;;GAGhB,MAAM,eAAA,GAAA,MAAA,QAAA,OAA4B,IAAI,KAAK,SAAS,UAAU,CAAC,EAAA,CAAG,QAAQ,UAAU,MAAM,QAAQ,CAAC,CAAC,KAAK,UAAU,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;;GAG1I,MAAM,aAAA,GAAA,MAAA,QAAA,OAA0B,IAAI,KAAK,SAAS,UAAU,CAAC,EAAA,CAAG,KAAK,UAAU,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;;;;;GAMtG,MAAM,eAAA,GAAA,MAAA,YAAA,EAA2B,KAAa,MAAc,SAAiC;IAC3F,MAAM,UAAU,SAAS,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC;IACxC,IAAI,QAAQ,WAAW,GAAG;IAC1B,IAAI,SAAS,OAAO;KAClB,iBAAsB,SAAS,IAAI;KACnC;IACF;IACA,MAAM,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,aAAa,GAAG,CAAC,CAAC,KAAK,GAAG,kBAAkB,EAAE,SAAS,YAAY,EAAE;IACrI,MAAM,YAAY,iBAAiB,SAAS,aAAa,MAAM;IAC/D,IAAI,UAAU,SAAS,GACrB,kBAAkB;KAAE;KAAK;KAAM;IAAU,CAAC;SAE1C,iBAAsB,QAAQ,QAAQ,WAAW,YAAY,IAAI,MAAM,CAAC,GAAG,KAAK;GAEpF,GAAG;IAAC;IAAU;IAAa;GAAgB,CAAC;;GAG5C,MAAM,mBAAA,GAAA,MAAA,YAAA,CAA8B,OAAO,aAAqC;IAC9E,MAAM,SAAS;IACf,IAAI,WAAW,MAAM;IACrB,kBAAkB,IAAI;IACtB,MAAM,UAAU,SAAS,CAAC,CAAC,IAAI,OAAO,GAAG,KAAK,CAAC;IAC/C,IAAI,UACF,MAAM,iBAAiB,QAAQ,QAAQ,WAAW,YAAY,IAAI,MAAM,CAAC,GAAG,KAAK;SAEjF,MAAM,iBACJ,QAAQ,QAAQ,WAAW,YAAY,IAAI,MAAM,KAAK,CAAC,OAAO,UAAU,SAAS,MAAM,CAAC,GACxF,KACF;GAEJ,GAAG;IAAC;IAAgB;IAAU;IAAa;GAAgB,CAAC;;GAG5D,MAAM,gBAAA,GAAA,MAAA,YAAA,CAA2B,YAA2B;IAC1D,MAAM,SAAS;IACf,IAAI,WAAW,MAAM;IACrB,iBAAiB,IAAI;IACrB,IAAI,OAAO,SAAS,QAAQ;KAC1B,iBAAiB,OAAO,IAAI;KAC5B,aAAa,IAAI;KACjB,IAAI;MACF,MAAM,SAAS,MAAM,IAAI,WAAW,OAAO,MAAM,OAAO,MAAM;MAC9D,MAAM,QAAQ,IAAI;OAAC,KAAK;OAAG,WAAW;OAAG,YAAY;MAAC,CAAC;MACvD,IAAI,OAAO,OAAO,SAAS,GACzB,aAAa,WAAW,OAAO,OAAO,KAAK,YAAY,QAAQ,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;KAE1G,SAAS,OAAO;MACd,aAAa,aAAa,KAAK,CAAC;KAClC,UAAU;MACR,iBAAiB,IAAI;KACvB;IACF,OAAO;KACL,aAAa,IAAI;KACjB,IAAI;MACF,MAAM,IAAI,oBAAoB,OAAO,MAAM,OAAO,MAAM;MACxD,MAAM,QAAQ,IAAI;OAAC,KAAK;OAAG,WAAW;OAAG,YAAY;MAAC,CAAC;KACzD,SAAS,OAAO;MACd,aAAa,aAAa,KAAK,CAAC;KAClC;IACF;GACF,GAAG;IAAC;IAAe;IAAK;IAAM;IAAY;GAAW,CAAC;;GAKtD,MAAM,gBAAA,GAAA,MAAA,YAAA,CAA2B,OAAO,SAAiC;IACvE,kBAAkB,QAAQ,KAAK;IAC/B,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,aAAa,IAAI;KAC1C,MAAM,OAA0C,EAAE,GAAG,YAAY;KACjE,KAAK,MAAM,QAAQ,OAAO,SAAS,KAAK,KAAK,QAAQ;KACrD,eAAe,IAAI;IACrB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,kBAAkB,IAAI;IACxB;GACF,GAAG,CAAC,KAAK,WAAW,CAAC;;GAGrB,MAAM,eAAA,GAAA,MAAA,YAAA,EAA2B,MAAc,WAA2B;IACxE,iBAAiB;KAAE,MAAM;KAAQ;KAAM;IAAO,CAAC;GACjD,GAAG,CAAC,CAAC;;GAGL,MAAM,iBAAA,GAAA,MAAA,YAAA,EAA6B,MAAc,WAA2B;IAC1E,iBAAiB;KAAE,MAAM;KAAU;KAAM;IAAO,CAAC;GACnD,GAAG,CAAC,CAAC;;GAGL,MAAM,gBAAA,GAAA,MAAA,YAAA,CAA2B,OAAO,SAAgC;IACtE,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,IAAI,cAAc,IAAI;KAC5B,MAAM,QAAQ,IAAI;MAAC,KAAK;MAAG,WAAW;MAAG,YAAY;KAAC,CAAC;IACzD,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG;IAAC;IAAK;IAAM;IAAY;GAAW,CAAC;;GAGvC,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,YAA2B;IACxD,qBAAqB,KAAK;IAC1B,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,WAAW;KACpC,IAAI,OAAO,OAAO,SAAS,GACzB,aAAa,kBAAkB,OAAO,OAAO,KAAK,YAAY,QAAQ,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;KAE/G,MAAM,QAAQ,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC,CAAC;IAC3C,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG;IAAC;IAAK;IAAM;GAAW,CAAC;;GAG3B,MAAM,sBAAA,GAAA,MAAA,YAAA,EAAkC,SAAuB;IAC7D,qBAAqB,IAAI;GAC3B,GAAG,CAAC,CAAC;;GAGL,MAAM,kBAAA,GAAA,MAAA,YAAA,CAA6B,YAA2B;IAC5D,MAAM,OAAO;IACb,IAAI,SAAS,MAAM;IACnB,qBAAqB,IAAI;IACzB,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,IAAI,YAAY,IAAI;KAC1B,MAAM,QAAQ,IAAI;MAAC,KAAK;MAAG,WAAW;MAAG,YAAY;KAAC,CAAC;IACzD,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG;IAAC;IAAK;IAAmB;IAAM;IAAY;GAAW,CAAC;;GAG1D,MAAM,sBAAA,GAAA,MAAA,YAAA,EAAkC,MAAc,eAA+B;IACnF,qBAAqB;KAAE;KAAM;IAAW,CAAC;GAC3C,GAAG,CAAC,CAAC;;GAGL,MAAM,kBAAA,GAAA,MAAA,YAAA,CAA6B,YAA2B;IAC5D,MAAM,SAAS;IACf,IAAI,WAAW,MAAM;IACrB,qBAAqB,IAAI;IACzB,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,MAAM,WAAqB,CAAC;IAC5B,IAAI,OAAO;IACX,KAAK,MAAM,QAAQ,OAAO,YACxB,IAAI;KACF,MAAM,IAAI,YAAY,IAAI;KAC1B,QAAQ;IACV,SAAS,OAAO;KAEd,SAAS,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC;IACjD;IAEF,MAAM,QAAQ,IAAI;KAAC,KAAK;KAAG,WAAW;KAAG,YAAY;IAAC,CAAC;IACvD,WAAW,KAAK;IAChB,IAAI,SAAS,SAAS,GACpB,aAAa,SAAS,OAAO,KAAK,OAAO,KAAK,QAAQ,SAAS,OAAO,OAAO,SAAS,KAAK,IAAI,CAAC;SAC3F,IAAI,OAAO,GAChB,iBAAiB,UAAU,OAAO,KAAK,IAAI,KAAK,WAAW;GAE/D,GAAG;IAAC;IAAK;IAAmB;IAAM;IAAY;GAAW,CAAC;;GAG1D,MAAM,aAAA,GAAA,MAAA,YAAA,CAAwB,OAAO,UAAoC;IACvE,MAAM,eAAe;IACrB,MAAM,OAAO,WAAW,KAAK;IAC7B,IAAI,SAAS,IAAI;IACjB,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,UAAU,MAAM,IAAI,QAAQ,EAAE,KAAK,CAAC,CAAC;KACrC,cAAc,EAAE;IAClB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG;IAAC;IAAK;IAAW;GAAU,CAAC;;GAG/B,MAAM,aAAA,GAAA,MAAA,YAAA,CAAwB,OAAO,OAA8B;IACjE,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,UAAU,MAAM,IAAI,UAAU,EAAE,CAAC;KACjC,cAAc,IAAI;IACpB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG,CAAC,KAAK,SAAS,CAAC;;GAGnB,MAAM,WAAA,GAAA,MAAA,YAAA,CAAsB,OAAO,IAAY,MAAc,gBAAgD;IAC3G,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,WAAW,KAAK,KAAK;KAC3B,IAAI,OAA0B;KAC9B,IAAI,aAAa,IAAI,OAAO,MAAM,IAAI,QAAQ;MAAE;MAAI,MAAM;KAAS,CAAC;KACpE,IAAI,gBAAgB,MAAM,OAAO,MAAM,IAAI,cAAc,IAAI,WAAW;KACxE,IAAI,SAAS,MAAM;KACnB,UAAU,IAAI;KACd,cAAc,IAAI;IACpB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG,CAAC,KAAK,SAAS,CAAC;;GAGnB,MAAM,eAAA,GAAA,MAAA,YAAA,CAA0B,OAAO,eAAwC;IAC7E,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,YAAY,UAAU;KAC7C,UAAU,IAAI;IAChB,SAAS,OAAO;KACd,MAAM,MAAM,aAAa,KAAK;KAC9B,IAAI,IAAI,SAAS,KAAK,KAAK,IAAI,YAAY,CAAC,CAAC,SAAS,WAAW,GAAG;MAElE,MAAM,OAAO,IAAI,IAAI,aAAa,KAAK,KAAK,MAAM,CAAC,EAAE,IAAI,CAAC,CAAU,KAAK,CAAC,CAAC;MAC3E,MAAM,YAAY,WAAW,KAAK,OAAO,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,MAAkC,MAAM,KAAA,CAAS;MAChH,IAAI,UAAU,WAAW,WAAW,QAAQ;OAC1C,UAAU,SAAqE;OAC/E,iBAAiB,wBAAwB;MAC3C,OACE,aAAa,GAAG;KAEpB,OACE,aAAa,GAAG;IAEpB,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG;IAAC;IAAK;IAAW;GAAW,CAAC;;GAGhC,MAAM,sBAAA,GAAA,MAAA,YAAA,CAAiC,OAAO,iBAA0C;IACtF,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,cAAc,MAAM,IAAI,mBAAmB,YAAY;KAC7D,gBAAgB,SAAS,SAAS,OAAO,OAAO;MAAE,GAAG;MAAM;KAAY,CAAC;KACxE,WAAgB;IAClB,SAAS,OAAO;KACd,MAAM,MAAM,aAAa,KAAK;KAE9B,IAAI,IAAI,SAAS,KAAK,KAAK,IAAI,YAAY,CAAC,CAAC,SAAS,WAAW,GAAG;MAClE,gBAAgB,SAAS;OACvB,IAAI,SAAS,MAAM,OAAO;OAC1B,MAAM,MAAM,IAAI,IAAI,KAAK,YAAY,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,CAAU,CAAC;OACrE,MAAM,YAAY,aAAa,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAkC,MAAM,KAAA,CAAS;OAE/G,KAAK,MAAM,KAAK,KAAK,aAAa,IAAI,CAAC,UAAU,MAAM,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,UAAU,KAAK,CAAC;OACjG,OAAO;QAAE,GAAG;QAAM,aAAa;OAAU;MAC3C,CAAC;MACD,iBAAiB,wBAAwB;KAC3C,OACE,aAAa,GAAG;IAEpB,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG,CAAC,KAAK,UAAU,CAAC;;GAGpB,MAAM,uBAAA,GAAA,MAAA,YAAA,CAAkC,OAAO,gBAAyC;IACtF,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,IAAI,oBAAoB,WAAW;KACzC,MAAM,WAAW;IACnB,SAAS,OAAO;KACd,MAAM,MAAM,aAAa,KAAK;KAC9B,IAAI,IAAI,SAAS,KAAK,KAAK,IAAI,YAAY,CAAC,CAAC,SAAS,WAAW,GAAG;MAElE,gBAAgB,SAAS;OACvB,IAAI,SAAS,MAAM,OAAO;OAE1B,MAAM,WAAW,YAAY,QAAQ,MAAM,EAAE,WAAW,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,MAAM,CAAC,CAAC;OACtF,MAAM,MAAM,IAAI,IAAI,KAAK,YAAY,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,CAAU,CAAC;OACrE,MAAM,YAAY,SAAS,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAkC,MAAM,KAAA,CAAS;OAC3G,KAAK,MAAM,KAAK,KAAK,aAAa,IAAI,CAAC,UAAU,MAAM,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,UAAU,KAAK,CAAC;OACjG,OAAO;QAAE,GAAG;QAAM,aAAa;QAAW,kBAAkB;OAAY;MAC1E,CAAC;MACD,iBAAiB,wBAAwB;KAC3C,OACE,aAAa,GAAG;IAEpB,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG,CAAC,KAAK,UAAU,CAAC;;GAKpB,MAAM,aAAA,GAAA,MAAA,YAAA,CAAwB,OAAO,UAAiC;IACpE,MAAM,QAAQ,MAAM,KAAK;IACzB,IAAI,UAAU,IAAI;IAClB,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,gBAAgB,KAAK;KAC9C,eAAe;MAAE,QAAQ;MAAS,OAAO,OAAO;KAAM,CAAC;KACvD,iBAAiB,EAAE;KACnB,cAAc,IAAI;KAClB,gCAAgB,IAAI,IAAI,CAAC;KAEzB,MAAM,OAAO,OAAO,MAAM,OAAO,MAAM,SAAS,EAAE,CAAC;KACnD,gBAAgB,IAAI;KACpB,qBAAqB,EAAE,QAAQ,WAAW,CAAC;KAC3C,IAAI;MACF,MAAM,OAAO,MAAM,IAAI,aAAa,IAAI;MACxC,qBAAqB;OAAE,QAAQ;OAAS;MAAK,CAAC;KAChD,SAAS,OAAO;MACd,qBAAqB;OAAE,QAAQ;OAAS,SAAS,aAAa,KAAK;MAAE,CAAC;KACxE,UAAU;MACR,gBAAgB,IAAI;KACtB;IACF,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,mBAAA,GAAA,MAAA,YAAA,CAA8B,YAA2B;IAC7D,MAAM,UAAU,aAAa;GAC/B,GAAG,CAAC,WAAW,aAAa,CAAC;;GAG7B,MAAM,sBAAA,GAAA,MAAA,YAAA,CAAiC,OAAO,SAAgC;IAC5E,WAAW,IAAI;IACf,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,mBAAmB,IAAI;KAChD,eAAe;MAAE,QAAQ;MAAS,OAAO,OAAO;KAAM,CAAC;IACzD,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,WAAW,KAAK;IAClB;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,YAAA,GAAA,MAAA,YAAA,CAAuB,OAAO,UAAiC;IACnE,MAAM,QAAQ,MAAM,KAAK;IACzB,IAAI,UAAU,IAAI;IAClB,cAAc,IAAI;IAClB,gCAAgB,IAAI,IAAI,CAAC;IACzB,gBAAgB,KAAK;IACrB,qBAAqB,EAAE,QAAQ,WAAW,CAAC;IAC3C,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,OAAO,MAAM,IAAI,aAAa,KAAK;KACzC,IAAI,KAAK,QAAQ,MAAM;MAErB,gBAAgB;OAAE,MAAM,KAAK;OAAM,UAAU,KAAK,YAAY,CAAC;OAAG,WAAW,KAAK,YAAY,CAAC,EAAA,CAAG,MAAM;MAAO,CAAC;MAChH,qBAAqB,EAAE,QAAQ,OAAO,CAAC;MACvC;KACF;KACA,qBAAqB;MAAE,QAAQ;MAAS;KAAK,CAAC;IAChD,SAAS,OAAO;KACd,qBAAqB;MAAE,QAAQ;MAAS,SAAS,aAAa,KAAK;KAAE,CAAC;IACxE,UAAU;KACR,gBAAgB,IAAI;IACtB;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,uBAAA,GAAA,MAAA,YAAA,CAAkC,YAA2B;IACjE,IAAI,iBAAiB,MAAM;IAC3B,cAAc,IAAI;IAClB,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,IAAI,mBAAmB,aAAa,MAAM,aAAa,QAAQ;KACrE,gBAAgB,IAAI;KACpB,MAAM,SAAS,aAAa,IAAI;IAClC,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,cAAc,KAAK;IACrB;GACF,GAAG;IAAC;IAAK;IAAc;GAAQ,CAAC;;GAGhC,MAAM,sBAAA,GAAA,MAAA,YAAA,EAAkC,MAAc,YAA2B;IAC/E,iBAAiB,aAAa;KAC5B,MAAM,OAAO,IAAI,IAAI,QAAQ;KAC7B,IAAI,SAAS,KAAK,IAAI,IAAI;UACrB,KAAK,OAAO,IAAI;KACrB,OAAO;IACT,CAAC;GACH,GAAG,CAAC,CAAC;;GAGL,MAAM,cAAA,GAAA,MAAA,YAAA,CAAyB,YAA2B;IACxD,IAAI,kBAAkB,WAAW,SAAS;IAC1C,iBAAiB,IAAI;IACrB,cAAc,IAAI;IAClB,eAAe,IAAI;IACnB,aAAa,IAAI;IACjB,IAAI,gBAAmD;IACvD,IAAI;KACF,MAAM,UAAU,MAAM,IAAI,WAAW,kBAAkB,KAAK,MAAM,CAAC,GAAG,YAAY,GAAG,kBAAkB,KAAK,OAAO,KAAA,CAAS;KAC5H,eAAe,QAAQ,KAAK;KAE5B,cAAc;MAAE,IAAI;MAAM,OAAO,QAAQ;MAAO,QAAQ;MAAW,OAAO,QAAQ;MAAO,MAAM;MAAG,YAAY,QAAQ;MAAY,iBAAiB;MAAG,UAAU,CAAC;MAAG,SAAS,CAAC;MAAG,QAAQ,CAAC;KAAE,CAAC;KAE7L,aAAa,SAAS,MAAM;KAC5B,aAAa,UAAU,IAAI,gBAAgB;KAC3C,MAAM,SAAS,aAAa,QAAQ;KACpC,IAAI,UAAU;KACd,SAAS;MACP,IAAI,OAAO,SAAS;MACpB,MAAM,QAAQ,KAAK,IAAI,KAAM,MAAM,UAAU,GAAG;MAChD,MAAM,IAAI,SAAS,MAAM,WAAW,GAAG,KAAK,CAAC;MAC7C,IAAI,OAAO,SAAS;MACpB,IAAI;OACF,MAAM,WAAW,MAAM,IAAI,mBAAmB,QAAQ,KAAK;OAC3D,cAAc,QAAQ;OACtB,gBAAgB;OAChB,IAAI,SAAS,WAAW,WACtB;OAEF,UAAU;MACZ,SAAS,WAAW;OAGlB,IADY,aAAa,SACnB,CAAC,CAAC,SAAS,WAAW,GAAG;OAC/B,WAAW;OACX,IAAI,UAAU,GAAG;MACnB;KACF;KACA,MAAM,QAAQ,IAAI;MAAC,KAAK;MAAG,WAAW;MAAG,WAAW;MAAG,YAAY;KAAC,CAAC;IACvE,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KAER,IAAI,kBAAkB,SAAS,cAAc,SAAS,SAAS,KAAK,cAAc,QAAQ,SAAS,IAAI;MACrG,MAAM,4BAAY,IAAI,IAAI,CAAC,GAAG,cAAc,SAAS,KAAK,MAAM,EAAE,IAAI,GAAG,GAAG,cAAc,QAAQ,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC;MACrH,MAAM,YAAY,IAAI,IACpB,kBAAkB,KAAK,QAAQ,QAAQ,MAAM,UAAU,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI,CACvF;MACA,iBAAiB,SAAS;OACxB,MAAM,OAAO,IAAI,IAAI,IAAI;OACzB,KAAK,MAAM,KAAK,WAAW,KAAK,OAAO,CAAC;OACxC,OAAO;MACT,CAAC;MACD,sBAAsB,SAAS;OAC7B,IAAI,KAAK,WAAW,SAAS,OAAO;OACpC,OAAO;QACL,GAAG;QACH,MAAM;SACJ,GAAG,KAAK;SACR,SAAS,KAAK,KAAK,QAAQ,KAAK,MAAM,UAAU,IAAI,EAAE,IAAI,IAAI;UAAE,GAAG;UAAG,UAAU;SAAK,IAAI,CAAC;QAC5F;OACF;MACF,CAAC;KACH;KACA,iBAAiB,KAAK;IACxB;GACF,GAAG;IAAC;IAAK;IAAmB;IAAc;IAAM;IAAY;IAAY;GAAW,CAAC;GAGpF,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,aAAa;KAAE,aAAa,SAAS,MAAM;IAAE;GAC/C,GAAG,CAAC,CAAC;;GAGL,MAAM,gBAAA,GAAA,MAAA,YAAA,CAA2B,YAA2B;IAC1D,IAAI,gBAAgB,MAAM;IAC1B,aAAa,SAAS,MAAM;IAC5B,IAAI;KACF,MAAM,MAAM,MAAM,IAAI,iBAAiB,WAAW;KAElD,IAAI;MACF,MAAM,WAAW,MAAM,IAAI,mBAAmB,WAAW;MACzD,cAAc,QAAQ;KACxB,QAAQ;MACN,eAAe,SAAS,SAAS,OAAO;OAAE,GAAG;OAAM,QAAQ,IAAI;MAAsB,IAAI,IAAI;KAC/F;IACF,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,iBAAiB,KAAK;IACxB;GACF,GAAG,CAAC,KAAK,WAAW,CAAC;;GAGrB,MAAM,aAAA,GAAA,MAAA,YAAA,OAAoC;IACxC,qBAAqB,EAAE,QAAQ,OAAO,CAAC;IACvC,gBAAgB,IAAI;IACpB,cAAc,IAAI;IAClB,gCAAgB,IAAI,IAAI,CAAC;IACzB,eAAe,IAAI;IACnB,aAAa,SAAS,MAAM;GAC9B,GAAG,CAAC,CAAC;;GAGL,MAAM,eAAA,GAAA,MAAA,YAAA,CAA0B,YAA2B;IACzD,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,YAAY;KACrC,MAAM,OAA0C,CAAC;KACjD,KAAK,MAAM,QAAQ,OAAO,SAAS,KAAK,KAAK,QAAQ;KACrD,eAAe,IAAI;IACrB,QAAQ,CAER;GACF,GAAG,CAAC,GAAG,CAAC;;GAGR,MAAM,oBAAA,GAAA,MAAA,YAAA,CAA+B,OAAO,SAAgC;IAC1E,iBAAiB,IAAI;IACrB,aAAa,IAAI;IACjB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,WAAW,IAAI;KACxC,oBAAoB;MAAE,MAAM,OAAO;MAAM,KAAK,OAAO;MAAK,QAAQ,OAAO;MAAQ,UAAU,IAAI,IAAI,OAAO,MAAM;KAAE,CAAC;KACnH,MAAM,WAAW;IACnB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,iBAAiB,IAAI;IACvB;GACF,GAAG,CAAC,KAAK,UAAU,CAAC;;GAGpB,MAAM,qBAAA,GAAA,MAAA,YAAA,CAAgC,YAA2B;IAC/D,IAAI,qBAAqB,MAAM;IAC/B,MAAM,WAAW,CAAC,GAAG,iBAAiB,QAAQ;IAC9C,YAAY,IAAI;IAChB,aAAa,IAAI;IACjB,IAAI;KACF,IAAI,SAAS,SAAS,GAAG;MACvB,MAAM,SAAS,MAAM,IAAI,WAAW,iBAAiB,MAAM,QAAQ;MACnE,IAAI,OAAO,OAAO,SAAS,GAAG,aAAa,OAAO,OAAO,KAAK,SAAS,KAAK,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;KAClH;KACA,oBAAoB,IAAI;KACxB,MAAM,QAAQ,IAAI;MAAC,KAAK;MAAG,WAAW;MAAG,YAAY;KAAC,CAAC;KACvD,YAAiB;IACnB,SAAS,OAAO;KACd,aAAa,aAAa,KAAK,CAAC;IAClC,UAAU;KACR,YAAY,KAAK;IACnB;GACF,GAAG;IAAC;IAAK;IAAkB;IAAM;IAAY;IAAa;GAAW,CAAC;;;;;GAMtE,MAAM,aAAA,GAAA,MAAA,YAAA,CAAwB,YAA2B;IACvD,mBAAmB,KAAK;IACxB,aAAa,IAAI;IACjB,aAAa,IAAI;IACjB,MAAM,WAAqB,CAAC;IAC5B,IAAI,OAAO;IACX,IAAI;KACF,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,WAAW,GAAG;MACvD,IAAI,CAAC,MAAM,WAAW,MAAM,QAAQ,WAAW,GAAG;MAClD,IAAI;OACF,MAAM,SAAS,MAAM,IAAI,WAAW,MAAM,MAAM,OAAO;OACvD,QAAQ;OACR,IAAI,OAAO,OAAO,SAAS,GACzB,SAAS,KAAK,GAAG,wBAAwB;QAAE;QAAM,OAAO,OAAO,OAAO;OAAO,CAAC,IAAI,OAAO,OAAO,OAAO,KAAK,SAAS,KAAK,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;MAElK,SAAS,OAAO;OACd,SAAS,KAAK,OAAO,OAAO,aAAa,KAAK,CAAC;MACjD;KACF;KACA,MAAM,QAAQ,IAAI;MAAC,KAAK;MAAG,WAAW;MAAG,YAAY;KAAC,CAAC;KACvD,MAAM,aAAa;KACnB,YAAiB;KACjB,IAAI,SAAS,SAAS,GAAG,aAAa,SAAS,KAAK,IAAI,CAAC;UACpD,IAAI,OAAO,GAAG,iBAAiB,GAAG,wBAAwB,EAAE,OAAO,KAAK,CAAC,CAAC;IACjF,UAAU;KACR,aAAa,KAAK;IACpB;GACF,GAAG;IAAC;IAAK;IAAa;IAAc;IAAa;IAAM;IAAY;GAAW,CAAC;GAK/E,CAAA,GAAA,MAAA,UAAA,OAAgB;IACd,IAAI,CAAC,gBAAgB,GAAG;IACxB,gBAAgB;IAChB,YAAiB;IACjB,aAAkB;IAClB,YAAiB;GAEnB,GAAG,CAAC,CAAC;GAIL,MAAM,UAAA,GAAA,MAAA,YAAA,CAAqB,OAAO,UAAoC;IACpE,MAAM,eAAe;IACrB,YAAY,IAAI;IAChB,eAAe,IAAI;IACnB,iBAAiB,IAAI;IACrB,IAAI;KACF,MAAM,SAAS,MAAM,IAAI,OAAO;MAAE,MAAM;MAAU,aAAa;MAAU,MAAM;KAAS,CAAC;KAIzF,iBAAiB,GAAG,cAAc,IAAI,OAAO,IAAI;KACjD,YAAY,EAAE;KACd,YAAY,EAAE;KACd,YAAY,KAAK;KACjB,MAAM,KAAK;IACb,SAAS,OAAO;KACd,eAAe;MAAE,MAAM;MAAS,MAAM,GAAG,YAAY,IAAI,aAAa,KAAK;KAAE,CAAC;IAChF,UAAU;KACR,YAAY,KAAK;IACnB;GACF,GAAG;IAAC;IAAK;IAAU;IAAU;IAAU;GAAI,CAAC;GAI5C,MAAM,aAAa,OAAO,KAAK,CAAC,CAAC,kBAAkB;;GAEnD,MAAM,UAAU,aAAa,WAAW,CAAC;;GAEzC,MAAM,iBAAA,GAAA,MAAA,QAAA,OAA8B;IAClC,MAAM,SAAS,SAAS,UAAU,CAAC;IACnC,MAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,OAAO,KAAK,UAAU,QAAQ,MAAM,KAAK,CAAC,CAAC,QAAQ,SAAyB,SAAS,KAAA,CAAS,CAAC,CAAC,CAAC,CAAC,KAAK;IAEjI,MAAM,aAAa,OAAO,MAAM,UAAU,QAAQ,MAAM,UAAU,KAAA,KAAa,CAAC,gBAAgB,MAAM,MAAM,CAAC;IAC7G,OAAO,CAAC,GAAG,OAAO,GAAI,aAAa,CAAC,cAAc,IAAI,CAAC,CAAE;GAC3D,GAAG,CAAC,SAAS,OAAO,CAAC;GACrB,MAAM,YAAA,GAAA,MAAA,QAAA,QAA0B,SAAS,UAAU,CAAC,EAAA,CAAG,QAAQ,UAC7D,WAAW,WAAW,KAAK,MAAM,KAAK,kBAAkB,CAAC,CAAC,SAAS,UAAU,KAAK,MAAM,YAAY,kBAAkB,CAAC,CAAC,SAAS,UAAU,CAC7I,GAAG,CAAC,SAAS,UAAU,CAAC;GAIxB,OAAO;IAEL;IAAS;IAAS;IAAW;IAAe;IAAa;IAAmB;IAAc;IAAc;IAAe;IAAY;IACnI;IAAQ;IAAW;IAAQ;IAAe;IAAW;IAAW;IAAU;IAAU;IAAU;IAAU;IAAU;IAClH;IAAM;IAAW;IAAK;IAAW;IAAc;IAAS;IAAa;IAAa;IAAc;IAChG;IAAkB;IAAe;IAAU;IAAe;IAAa;IAAc;IAAa;IAAgB;IAClH;IAAgB;IAAe;IAAmB;IAAmB;IAAmB;IAAiB;IAAY;IAAU;IAAc;IAAY;IACzJ;IAAY;IAAiB;IAAoB;IAAY;IAE7D;IAAa;IAAW;IAAY;IAAS;IAAe;IAAU,SAAA,GAAA,MAAA,QAAA,OAX3C,WAAW,UAAU,UAAU,SAAS,KAAK,IAAI,IAAI,CAAC,EAAE,KAAK,GAAG;KAAC;KAAU;KAAS;IAAI,CAWxC;IAE3E;IAAc;IAAkB;IAAW;IAAc;IAAW;IAAa;IAAa;IAAa;IAAa;IACxH;IAAiB;IAAQ;IACzB;IAAiB;IAAY;IAAiB;IAAqB;IAAkB;IAAmB;IACxG;IAAsB;IAAsB;IAAsB;IAAoB;IAAe;IAAa;IAAiB;IAAe;IAAe;IAAe;IAChL;IAAqB;IAAiB;IAAa;IAAY;IAAY;IAAQ;IAAgB;IAAkB;IAAa;IAClI;IAAc;IAAc;IAAa;IAAe;IAAc;IAAY;IAAoB;IAAgB;IAAoB;IAAgB;IAC1J;IAAW;IAAS;IAAa;IAAoB;IAAqB;IAAW;IAAiB;IAAoB;IAAU;IAAqB;IAAoB;IAAY;IAAc;IACvM;IAAa;IAAkB;IAAmB;IAAW;GAC/D;EACF;;;;;;;;;;;;;;;;ECv9BA,SAAgB,cAAc,OAA8C;GAC1E,MAAM,MAAM,YAAY,MAAM,GAAG;;GAEjC,MAAM,CAAC,gBAAgB,sBAAA,GAAA,MAAA,SAAA,CAA8B,EAAE;GACvD,MAAM,EACJ,SAAS,SAAS,WAAW,eAAe,aAAa,QAAQ,eAAe,UAAU,UAAU,UACpG,UAAU,UAAU,aAAa,WAAW,KAAK,WAAW,cAAc,SAAS,QACnF,WAAW,cACX,cAAc,SAAS,WAAW,YAAY,SAAS,eAAe,UACtE,gBAAgB,eAAe,mBAAmB,mBAAmB,mBAAmB,cAAc,YAAY,kBAClH,UAAU,YAAY,UAAU,cAAc,YAAY,MAAM,aAAa,aAAa,gBAAgB,eAC1G,YAAY,UACZ,cAAc,kBAAkB,WAAW,aAAa,aAAa,aAAa,aAAa,gBAAgB,QAC/G,cAAc,iBAAiB,YAAY,WAAW,mBAAmB,kBAAkB,sBAAsB,sBACjH,sBAAsB,iBAAiB,qBAAqB,eAAe,aAAa,iBAAiB,eACzG,eAAe,aACf,aAAa,YAAY,cAAc,aAAa,eAAe,cAAc,YAAY,gBAAgB,gBAC7G,cAAc,iBAAiB,qBAAqB,mBAAmB,QAAQ,SAAS,WAAW,mBACjG;GAIJ,IAAI,WAAW,MACb,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAD;IACU;IACG;IACL;IACO;IACC;IACD;IACG;IACD;IACf,SAAS;IACT,cAAc;KAAE,UAAU,IAAI;IAAE;IAChC,UAAU,SAAS;KAAE,aAAkB,IAAI;IAAE;IAC7C,QAAQ;IACR,gBAAgB;GACjB,CAAA;GAIL,IAAI,eAAe,MACjB,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;IACE,KAAK;IACK;IACI;IACF;IACH;IACA;IACT,cAAc;KAAE,cAAc,IAAI;IAAE;IACpC,YAAY;IACZ,cAAc;IACd,iBAAiB,MAAM,YAAY;KACjC,iBAAiB,aAAa;MAC5B,MAAM,OAAO,IAAI,IAAI,QAAQ;MAC7B,IAAI,SAAS,KAAK,IAAI,IAAI;WACrB,KAAK,OAAO,IAAI;MACrB,OAAO;KACT,CAAC;IACH;IACA,gBAAgB;KAAE,QAAa,WAAW,IAAI,UAAU,IAAI;IAAE;IAC9D,gBAAgB;KAAE,UAAe,WAAW,EAAE;IAAE;IAChD,qBAAqB;KAAE,QAAa,WAAW,IAAI,UAAU,CAAC,GAAG,YAAY,CAAC;IAAE;GACjF,CAAA;;GAKL,MAAM,qBAAyC;IAC7C,IAAI,YAAY,WAAW,YAAY,OAAO,GAAG,iBAAiB;IAClE,IAAI,YAAY,WAAW,SAAS,OAAO,GAAG,gBAAgB,EAAE,OAAO,YAAY,QAAQ,CAAC;IAC5F,IAAI,YAAY,WAAW,SAAS;KAClC,MAAM,OAAO,YAAY;KACzB,IAAI,KAAK,UAAU,KAAA,GAAW,OAAO,GAAG,gBAAgB,EAAE,OAAO,KAAK,MAAM,CAAC;KAC7E,IAAI,KAAK,iBAAiB,OAAO,GAAG,oBAAoB;MAAE,SAAS,KAAK,iBAAiB;MAAI,SAAS,KAAK;KAAe,CAAC;KAC3H,IAAI,KAAK,kBAAkB,MAAM,OAAO,GAAG,oBAAoB;KAC/D,OAAO,GAAG,mBAAmB,EAAE,SAAS,KAAK,cAAc,CAAC;IAC9D;GAEF,EAAA,CAAG;GAEH,OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAWE,yBAAI;cAApB;KACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,MAAD;QAAI,WAAWA,yBAAI;kBAAnB;SAA0B,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD;UAAoB,MAAM;UAAI,WAAWA,yBAAI;SAAY,CAAA;SAAC;SAAE,GAAG,aAAa;SAAG,YAAY,OAAO,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;UAAM,WAAWA,yBAAI;oBAArB,CAAoC,KAAE,QAAQ,aAAoB;cAAI;QAAS;;OAC1M,YAAY,OACT,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CACG,GAAG,eAAe,EAAE,OAAO,QAAQ,OAAO,SAAS,QAAQ,SAAS,OAAO,CAAC,GAC5E,QAAQ,SAAS,SAAS,IAAI,QAAQ,GAAG,uBAAuB,EAAE,OAAO,QAAQ,SAAS,OAAO,CAAC,IAAI,IACnG;YACN;OACH,YAAY,QAAQ,CAAC,QAAQ,WAAW,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAO,GAAG,kBAAkB;OAAQ,CAAA,IAAI;OACtG,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAQ,UAAU,YAAY,WAAW;SAAY,OAAO;SAAa,eAAe;UAAE,YAAiB;SAAE;mBAAI,YAAY,WAAW,aAAa,GAAG,iBAAiB,IAAI,GAAG,cAAc;QAAU,CAAA,GAC5O,YAAY,WAAW,WAAW,YAAY,KAAK,mBAAmB,YAAY,KAAK,QAAQ,OAC5F,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;SAAG,WAAWA,yBAAI;SAAY,MAAM,YAAY,KAAK;SAAK,QAAO;SAAS,KAAI;mBAAc,GAAG,qBAAqB,EAAE,SAAS,YAAY,KAAK,iBAAiB,GAAG,CAAC;QAAK,CAAA,IAC1K,IACA;;MACH;;KACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB;SACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,UAAU,QAAQ,YAAY,MAAMA,yBAAI,eAAe;UAAK,eAAe;WAAE,OAAO,SAAS;UAAE;oBAAI,GAAG,cAAc;SAAU,CAAA;SACnK,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,UAAU,QAAQ,WAAW,MAAMA,yBAAI,eAAe;UAAK,eAAe;WAAE,OAAO,QAAQ;UAAE;oBAAI,GAAG,aAAa;SAAU,CAAA;SAChK,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,UAAU,QAAQ,WAAW,MAAMA,yBAAI,eAAe;UAAK,eAAe;WAAE,OAAO,QAAQ;WAAG,WAAgB;UAAE;oBAAI,GAAG,aAAa;SAAU,CAAA;QAC/K;;OACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SACE,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;SAClC,OAAO;SACP,aAAa,cAAc,KAAK,YAAY,GAAG,4BAA4B;SAC3E,OAAO,GAAG,qBAAqB;SAC/B,WAAW,UAAU;UAAE,kBAAkB,MAAM,OAAO,KAAK;SAAE;SAC7D,YAAY,UAAU;UAAE,IAAI,MAAM,QAAQ,SAAS,aAAc,MAAM,OAA4B,MAAM,KAAK,CAAC;SAAE;QAClH,CAAA,GACA,cAAc,KACX,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAO,OAAO,GAAG,sBAAsB;SAAG,eAAe;UAAE,aAAa,EAAE;UAAG,kBAAkB,EAAE;SAAE;mBAAG;QAAS,CAAA,IACpJ,IACA;;OACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;QAAQ,MAAK;QAAS,WAAWA,yBAAI,gBAAgB,aAAa,MAAMA,yBAAI,qBAAqB;QAAK,eAAe;SAAE,eAAe,UAAU,CAAC,KAAK;QAAE;QAAG,OAAO,GAAG,aAAa;kBAAG;OAAS,CAAA;OAC9L,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBACnB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;SAAS,eAAe;UAAE,aAAa,UAAU,CAAC,KAAK;SAAE;mBAAI,GAAG,WAAW;QAAU,CAAA;OACzI,CAAA;MACH;;KAEJ,WACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;MAAM,WAAWA,yBAAI;MAAM,WAAW,UAAU;OAAE,OAAY,KAAK;MAAE;gBAArE;OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;QAAG,WAAWA,yBAAI;kBAAW,GAAG,qBAAqB;OAAK,CAAA;OAC1D,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;mBAAY,GAAG,WAAW;QAAS,CAAA,GACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;SAAO,OAAO;SAAU,WAAW,UAAU;UAAE,YAAY,MAAM,OAAO,KAAK;SAAE;SAAG,aAAY;QAAe,CAAA,CAChI;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;mBAAY,GAAG,WAAW;QAAS,CAAA,GACzD,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;SAAO,OAAO;SAAU,WAAW,UAAU;UAAE,YAAY,MAAM,OAAO,KAAK;SAAE;SAAG,aAAa,GAAG,sBAAsB;QAAI,CAAA,CAC/I;;OACL,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;mBAAY,GAAG,WAAW;QAAS,CAAA,GACzD,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAQ,WAAWA,yBAAI;SAAQ,OAAO;SAAU,WAAW,UAAU;UAAE,YAAY,MAAM,OAAO,KAAqB;SAAE;mBAAvH,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;oBAAW;SAAqB,CAAA,GAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;oBAAc;SAAwB,CAAA,CAC9C;UACL;;OACJ,gBAAgB,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAW,YAAY,SAAS,UAAUA,yBAAI,YAAYA,yBAAI;kBAAc,YAAY;OAAU,CAAA,IAAI;OACnI,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI,SAAS,MAAMA,yBAAI;SAAS,UAAU;mBAAW,WAAW,GAAG,WAAW,IAAI,GAAG,aAAa;QAAU,CAAA,GAC7I,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAQ,eAAe;UAAE,YAAY,KAAK;UAAG,eAAe,IAAI;SAAE;mBAAI,GAAG,aAAa;QAAU,CAAA,CAClI;;MACD;UACJ;KAEH,cAAc,OACb,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,UAAgB,CAAA,GACvB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,eAAe;QAAE,aAAa,IAAI;OAAE;iBAAI,GAAG,aAAa;MAAU,CAAA,CAC5G;UACH;KAEH,kBAAkB,OACjB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD,EAAA,UAAO,cAAoB,CAAA,GAC3B,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;OAAQ,MAAK;OAAS,WAAWA,yBAAI;OAAQ,eAAe;QAAE,iBAAiB,IAAI;OAAE;iBAAI,GAAG,aAAa;MAAU,CAAA,CAChH;UACH;KAEH,aACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAApB;OACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CAAiC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;SAAU,OAAO,SAAS,WAAW,aAAa;QAAI,CAAA,GAAE,GAAG,cAAc,CAAQ;;OACvJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAArB,CAAiC,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;SAAS,OAAO,SAAS,WAAW,YAAY;QAAI,CAAA,GAAE,GAAG,aAAa,CAAQ;;OACpJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QAAM,WAAWA,yBAAI;kBAAa,GAAG,aAAa;OAAQ,CAAA;MACvD;UACH;KAEH,UAAU,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAQ,GAAG,eAAe;KAAO,CAAA,IAAI;KAEnE,gBAAgB,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAWA,yBAAI;gBAAQ,GAAG,gBAAgB;KAAO,CAAA,IAAI;KAE1E,QAAQ,WACP,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD,EAAiB,IAAM,CAAA,IACrB,YAAY,OACd,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA;MACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAApB;QACG,QAAQ,YACP,iBAAA,GAAA,kBAAA,KAAA,CAAA,kBAAA,UAAA,EAAA,UAAA,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAArB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,UAAU,cAAc,SAAS,MAAMA,yBAAI,eAAe;UAAK,eAAe;WAAE,aAAa,MAAM;UAAE;oBAAI,GAAG,WAAW;SAAU,CAAA,GACtK,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,MAAK;UAAS,WAAWA,yBAAI,UAAU,cAAc,WAAW,MAAMA,yBAAI,eAAe;UAAK,eAAe;WAAE,aAAa,QAAQ;UAAE;oBAAI,GAAG,cAAc;SAAU,CAAA,CACzK;YACN,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAQ,WAAWA,yBAAI;SAAQ,OAAO;SAAc,WAAW,UAAU;UAAE,gBAAgB,MAAM,OAAO,KAAK;SAAE;mBAA/G,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAQ,OAAM;oBAAO,GAAG,mBAAmB;SAAU,CAAA,GACpD,cAAc,KAAK,WAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;UAAqB,OAAO;oBAAS,WAAA,YAA4B,GAAG,gBAAgB,IAAI;SAAe,GAA1F,MAA0F,CACxG,CACK;UACR,EAAA,CAAA,IACA;QACJ,iBAAA,GAAA,kBAAA,KAAA,CAAC,UAAD;SAAQ,WAAWA,yBAAI;SAAQ,OAAO;SAAS,WAAW,UAAU;UAAE,WAAW,MAAM,OAAO,KAAgB;SAAE;mBAAhH;UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;qBAAQ,GAAG,WAAW;UAAU,CAAA;UAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;qBAAS,GAAG,YAAY;UAAU,CAAA;UAChD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;WAAQ,OAAM;qBAAQ,GAAG,WAAW;UAAU,CAAA;SACxC;;QACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,SAAD;SAAO,WAAWA,yBAAI;SAAQ,OAAO;SAAQ,WAAW,UAAU;UAAE,UAAU,MAAM,OAAO,KAAK;SAAE;SAAG,aAAa,GAAG,cAAc;QAAI,CAAA;QACvI,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI,UAAU,WAAW,MAAMA,yBAAI,UAAU;SAAK,OAAO,EAAE,YAAW,OAAO;SAAG,eAAe,aAAa,MAAM,CAAC,CAAC;mBAAI,WAAW,OAAO;QAAa,CAAA;OACrL;;MAEJ,SAAS,WAAW,KAAK,OAAO,KAAK,MAAM,KAAK,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAQ,GAAG,aAAa;MAAO,CAAA,IAAI;MACvG,SAAS,WAAW,KAAK,OAAO,KAAK,MAAM,MAAM,QAAQ,OAAO,WAAW,KAAK,QAAQ,SAAS,WAAW,KAAK,QAAQ,YAAY,WAAW,IAC7I,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OAAK,WAAWA,yBAAI;iBAAQ,GAAG,gBAAgB;MAAO,CAAA,IACtD;MAEH,QAAQ,YAAY,iBAAA,GAAA,kBAAA,IAAA,CAAC,aAAD,EAAkB,IAAM,CAAA,IAAI,iBAAA,GAAA,kBAAA,IAAA,CAAC,YAAD,EAAiB,IAAM,CAAA;MAEvE,iBAAiB,QAAQ,aAAa,MAAM,SAAS,IACpD,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;OAAS,WAAWA,yBAAI;iBAAxB,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI,eAAe,MAAMA,yBAAI;kBAA7C,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;SAAM,WAAWA,yBAAI;mBAAmB,GAAG,cAAc;QAAQ,CAAA,GACjE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI,QAAQ,MAAMA,yBAAI;SAAU,UAAU;SAAS,eAAe;UAAE,qBAAqB,IAAI;SAAE;mBAAI,GAAG,mBAAmB;QAAU,CAAA,CACjK;WACJ,aAAa,MAAM,KAAK,UACvB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAsB,WAAWA,yBAAI,MAAM,MAAMA,yBAAI;kBAArD,CACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAApB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWA,yBAAI;oBAAU,MAAM;SAAU,CAAA,GAC9C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;UAAK,WAAWA,yBAAI;oBAAU,iBAAiB,MAAM,OAAO;SAAO,CAAA,CAChE;YACL,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;SAAQ,MAAK;SAAS,WAAWA,yBAAI;SAAO,UAAU;SAAS,eAAe;UAAE,aAAkB,MAAM,IAAI;SAAE;mBAAI,GAAG,gBAAgB;QAAU,CAAA,CAC5I;UANK,MAAM,IAMX,CACN,CACM;WACP;MAEH,QAAQ,YAAY,SAAS,IAC5B,iBAAA,GAAA,kBAAA,KAAA,CAAC,WAAD;OAAS,WAAWA,yBAAI;iBAAxB,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;QAAK,WAAWA,yBAAI;kBAAe,GAAG,mBAAmB;OAAO,CAAA,GAC/D,QAAQ,YAAY,KAAK,UACxB,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;QAAsB,WAAWA,yBAAI;kBAArC,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAW,MAAM;QAAU,CAAA,GAC/C,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;SAAK,WAAWA,yBAAI;mBAAa,MAAM;QAAY,CAAA,CAChD;UAHK,MAAM,IAGX,CACN,CACM;WACP;KACJ,EAAA,CAAA,IACA;KAEH,mBAAmB,OAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,gBAAD;MACE,QAAQ;MACR,MAAM,aAAa,QAAQ,CAAC;MAC5B,aAAa,aAAa,eAAe,CAAC;MAC1C,eAAe;OAAE,kBAAkB,IAAI;MAAE;MACzC,gBAAgB;OAAE,gBAAqB,KAAK;MAAE;MAC9C,kBAAkB;OAAE,gBAAqB,IAAI;MAAE;KAChD,CAAA,IACC;KAEH,kBAAkB,OACjB,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;MACE,OAAO,cAAc,SAAS,SAAS,GAAG,yBAAyB,IAAI,GAAG,2BAA2B;MACrG,MAAM,cAAc,SAAS,SAAS,GAAG,wBAAwB,IAAI,GAAG,0BAA0B;MAClG,OAAO,cAAc;MACrB,cAAc,cAAc,SAAS,SAAS,GAAG,aAAa,IAAI,GAAG,qBAAqB;MAC1F,QAAQ,cAAc,SAAS;MAC/B,gBAAgB;OAAE,iBAAiB,IAAI;MAAE;MACzC,iBAAiB;OAAE,aAAkB;MAAE;KACxC,CAAA,IACC;KAEH,iBAAiB,OAChB,iBAAA,GAAA,kBAAA,IAAA,CAAC,oBAAD;MACE,QAAQ;MACR,MAAM;MACN,WAAW,aAAa;OAAE,gBAAgB;QAAE,GAAG;QAAc;OAAS,CAAC;MAAE;MACzE,gBAAgB;OAAE,gBAAgB,IAAI;MAAE;MACxC,iBAAiB;OAAE,oBAAyB;MAAE;KAC/C,CAAA,IACC;KAEH,qBAAqB,OACpB,iBAAA,GAAA,kBAAA,IAAA,CAAC,kBAAD;MACE,QAAQ;MACR,MAAM;MACN,WAAW,MAAM,YAAY;OAC3B,MAAM,OAAO,IAAI,IAAI,iBAAiB,QAAQ;OAC9C,IAAI,SAAS,KAAK,IAAI,IAAI;YACrB,KAAK,OAAO,IAAI;OACrB,oBAAoB;QAAE,GAAG;QAAkB,UAAU;OAAK,CAAC;MAC7D;MACA,gBAAgB;OAAE,oBAAoB,IAAI;MAAE;MAC5C,iBAAiB;OAAE,kBAAuB;MAAE;KAC7C,CAAA,IACC;KAEH,sBAAsB,OACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;MACE,OAAO,GAAG,qBAAqB;MAC/B,MAAM,GAAG,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;MAC1D,cAAc,GAAG,gBAAgB;MACjC,QAAA;MACA,gBAAgB;OAAE,qBAAqB,IAAI;MAAE;MAC7C,iBAAiB;OAAE,eAAoB;MAAE;KAC1C,CAAA,IACC;KAEH,sBAAsB,OACrB,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;MACE,OAAO,GAAG,yBAAyB;MACnC,MAAM,GAAG,0BAA0B;OAAE,MAAM,kBAAkB;OAAM,OAAO,kBAAkB,WAAW;MAAO,CAAC;MAC/G,OAAO,kBAAkB;MACzB,cAAc,GAAG,oBAAoB;MACrC,QAAA;MACA,gBAAgB;OAAE,qBAAqB,IAAI;MAAE;MAC7C,iBAAiB;OAAE,eAAoB;MAAE;KAC1C,CAAA,IACC;KAEH,oBACC,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD;MACE,OAAO,GAAG,+BAA+B;MACzC,MAAM,GAAG,8BAA8B;MACvC,cAAc,GAAG,0BAA0B;MAC3C,QAAA;MACA,gBAAgB;OAAE,qBAAqB,KAAK;MAAE;MAC9C,iBAAiB;OAAE,WAAgB;MAAE;KACtC,CAAA,IACC;IACD;;EAET;;;;ECrTA,MAAM,KAAK;;;;;;;;EAgBX,MAAa,SAAS;GAAC;GAAS;GAAU;GAAc;GAAU;GAAiB;EAAe;;;;;EAWlG,SAAgB,MAAM,KAA0B;GAC9C,IAAI,aAAa,IAAI,OAAO,SAAS,IAAI;IAAE;IAAI;GAAG,CAAC,GAAG,6BAA6B;GACnF,MAAM,IAAI,IAAI,OAAO,KAAK,EAAE;GAC5B,MAAM,MAAM,IAAI,YAAY;GAM5B,MAAM,eAAe,IAAI,+BACvB,IAAI,cAAc,KAAuB,EAAE,WAAW,GAAG,CAAC,CAC5D;GAMA,IAAI,aACI,oBAAoB,KAAK,KAAK,IAAI,cAAc,KAAuB,EAAE,WAAW,GAAG,CAAC,CAAC,GAC/F,2BACF;GAKA,IAAI,aACI,IAAI,MAAM,OAAO,8BAA8B,IAAI,MAAM,SAAS;IACtE,MAAM;IACN,KAAK;IACL,QAAQ;IACR,cAAc,aAAa,OAAO;GACpC,GAAG,oBAAoB,CAAC,GACxB,8BACF;GAGA,IAAI,aACI,IAAI,MAAM,OAAO,0BAA0B,IAAI,MAAM,SAAS;IAClE,MAAM;IACN,IAAI;IACJ,OAAO;IACP,aAAa,EAAE,aAAa;IAC5B,QAAQ;IACR,eAAe,CAAC;GAClB,SAAS,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAD,EAAoB,IAAM,CAAA,CAAC,CAAC,GACrC,iCACF;GAGA,IAAI,aAAa,qBAAqB,GAAG,kCAAkC;EAC7E"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["css","css","css","css","css","css","css","css","css","css","css","Fragment","css"],"sources":["../src/protocol.ts","../src/client/api.ts","../src/client/locales.ts","../src/client/settings-nav-icon.ts","../src/client/grouping.ts","../src/client/helpers.ts","../src/client/panel/format.ts","../src/client/slash-dots.tsx","../src/client/icons.tsx","../src/client/settings-card.tsx","../node_modules/zustand/esm/vanilla.mjs","../node_modules/zustand/esm/middleware.mjs","../node_modules/immer/dist/immer.mjs","../node_modules/@deepseek-ai/dsh-client-store/lib/index.js","../src/client/settings-form.ts","../src/client/SkillHubSettingsCard.tsx","../src/client/panel/SourceStatusBadge.tsx","../src/client/panel/SkillDetailView.tsx","../src/client/panel/TagEditorView.tsx","../src/client/panel/SkillRow.tsx","../src/client/panel/DisabledRow.tsx","../src/client/panel/GroupSummary.tsx","../src/client/panel/SourcesView.tsx","../src/client/panel/ScenesView.tsx","../src/client/market-catalog.ts","../src/client/panel/dialogs.tsx","../src/client/panel/MarketView.tsx","../src/client/panel/useSkillHub.ts","../src/client/panel/SkillHubPanel.tsx","../src/client/index.tsx"],"sourcesContent":["/**\n * Shared API contract for dsh-skill-hub: the route paths and payload shapes\n * both the host half and the browser half import. The browser half must never\n * depend on host SDK packages, so registry types are re-spelled here as\n * plain JSON-safe interfaces.\n */\n\n/** Browser-facing base paths of the skill-hub API family. */\nexport const SKILL_HUB_API = {\n catalog: '/api/skill-hub/catalog',\n skill: '/api/skill-hub/skill',\n skillDelete: '/api/skill-hub/skill/delete',\n toggle: '/api/skill-hub/toggle',\n toggleBatch: '/api/skill-hub/toggle-batch',\n create: '/api/skill-hub/create',\n stats: '/api/skill-hub/stats',\n config: '/api/skill-hub/config',\n market: '/api/skill-hub/market',\n marketSource: '/api/skill-hub/market/source',\n marketSourceDelete: '/api/skill-hub/market/source/delete',\n marketSourceRef: '/api/skill-hub/market/source/ref',\n marketCheck: '/api/skill-hub/market/check',\n marketSync: '/api/skill-hub/market/source/sync',\n repo: '/api/skill-hub/repo',\n repoImport: '/api/skill-hub/repo/import',\n repoImportProgress: '/api/skill-hub/repo/import/progress',\n repoImportCancel: '/api/skill-hub/repo/import/cancel',\n update: '/api/skill-hub/update',\n groups: '/api/skill-hub/groups',\n tag: '/api/skill-hub/tag',\n tagDelete: '/api/skill-hub/tag/delete',\n tagMembers: '/api/skill-hub/tag/members',\n tagReorder: '/api/skill-hub/tag/reorder',\n collectionReorder: '/api/skill-hub/collections/reorder',\n sourceGroupReorder: '/api/skill-hub/source-groups/reorder',\n sources: '/api/skill-hub/sources',\n sourceCheck: '/api/skill-hub/sources/check',\n sourceSync: '/api/skill-hub/sources/sync',\n sourceDelete: '/api/skill-hub/sources/delete',\n sourceRestore: '/api/skill-hub/sources/restore',\n sourceTrashClear: '/api/skill-hub/sources/trash/clear',\n} as const\n\n/** User-level roots the hub may write to (matches dsh-skill-filesystem ranks 400/500). */\nexport type WritableRoot = 'user-dsh' | 'user-agents'\n\n/** Invocation policy resolved by the registry, re-spelled for the wire. */\nexport interface HubInvocation {\n /** Whether model-facing catalogs may load this skill. */\n modelInvocable: boolean\n /** Whether human-facing command catalogs may load this skill. */\n userInvocable: boolean\n}\n\n/** One enabled skill row in the catalog. */\nexport interface CatalogSkill {\n name: string\n description: string\n whenToUse?: string\n invocation: HubInvocation\n provider: string\n /** Whether the hub may toggle this skill (user-level filesystem skills only). */\n writable: boolean\n /** 技能来源标识(user-dsh/user-agents/project-dsh/project-agents/...)。 */\n source: string\n /** SKILL.md creation time (epoch ms); used for \"added\" sorting. Absent when unknown. */\n addedAt?: number\n /** SKILL.md last-modified time (epoch ms); used for \"updated\" display. Absent when unknown. */\n updatedAt?: number\n /** 项目技能的所属工作区路径(仅 project-dsh/project-agents 来源携带)。 */\n workspace?: string\n /** 工作区显示标题(来自 workspace.json;无则回退为路径)。 */\n workspaceTitle?: string\n}\n\n/** One disabled skill tracked by the hub sidecar (SKILL.md renamed away). */\nexport interface DisabledSkill {\n name: string\n description: string\n /** Absolute path of the renamed file (SKILL.md.disabled / <name>.md.disabled). */\n path: string\n root: WritableRoot\n disabledAt: number\n}\n\n/** One discovery diagnostic: a file the filesystem provider skips, with the reason. */\nexport interface DiagnosticEntry {\n path: string\n root: string\n reason: string\n}\n\n/** GET /api/skill-hub/catalog */\nexport interface CatalogResponse {\n ok: true\n /** 已安装插件自身的版本号(package.json version),面板标题旁显示。 */\n pluginVersion: string\n /** Whether discovery completed within a stable catalog revision. */\n complete: boolean\n /** Sorted winning summaries of every enabled skill (all roots + providers). */\n skills: CatalogSkill[]\n /** Skills the hub has toggled off (kept outside provider discovery). */\n disabled: DisabledSkill[]\n /** Files in the writable roots the provider ignores, with reasons. */\n diagnostics: DiagnosticEntry[]\n}\n\n/** GET /api/skill-hub/skill */\nexport interface SkillDetail {\n name: string\n description: string\n whenToUse?: string\n invocation: HubInvocation\n provider: string\n /** Absolute file path when the skill came from disk. */\n path?: string\n /** SKILL.md creation time (epoch ms); absent when the file is unreadable. */\n addedAt?: number\n /** SKILL.md last-modified time (epoch ms); absent when the file is unreadable. */\n updatedAt?: number\n /** Markdown instruction body. */\n content: string\n}\n\nexport interface SkillDetailResponse {\n ok: true\n skill: SkillDetail\n}\n\n/** POST /api/skill-hub/skill/delete — 把单个技能移入回收站(可恢复)。 */\nexport interface SkillDeleteRequest {\n name: string\n}\n\n/** POST /api/skill-hub/skill/delete */\nexport interface SkillDeleteResponse {\n ok: true\n name: string\n /** 移入回收站后的路径(目录或文件)。 */\n path: string\n}\n\n/** POST /api/skill-hub/toggle */\nexport interface ToggleRequest {\n /** Kebab-case skill name. */\n name: string\n /** true re-enables a hub-disabled skill; false disables an enabled one. */\n enabled: boolean\n}\n\nexport interface ToggleResponse {\n ok: true\n /** Fresh catalog after the mutation (the filesystem provider may lag a beat). */\n catalog: CatalogResponse\n}\n\n/** POST /api/skill-hub/toggle-batch — one group of skills, one write. */\nexport interface ToggleBatchRequest {\n names: string[]\n enabled: boolean\n}\n\n/** POST /api/skill-hub/toggle-batch */\nexport interface ToggleBatchResponse {\n ok: true\n catalog: CatalogResponse\n /** Per-name failures (unknown/read-only skills); empty means all landed. */\n failures: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/create */\nexport interface CreateRequest {\n /** Kebab-case skill name (validated with the official isSkillName grammar). */\n name: string\n /** Optional one-line routing description for the frontmatter. */\n description?: string\n /** Target user root; defaults to user-dsh (~/.dsh/skills). */\n root?: WritableRoot\n}\n\nexport interface CreateResponse {\n ok: true\n path: string\n root: WritableRoot\n}\n\n/** One skill's invocation stats across the local session logs. */\nexport interface SkillStat {\n /** Kebab-case skill name. */\n name: string\n /** How many sessions recorded a user-explicit invocation of this skill. */\n count: number\n /** Unix epoch ms of the most recent invocation (absent when never called). */\n lastUsed?: number\n}\n\n/** GET /api/skill-hub/stats */\nexport interface StatsResponse {\n ok: true\n /** Whether a session-log source was available (false means counts are empty). */\n available: boolean\n /** Sorted per-skill invocation counts. */\n stats: SkillStat[]\n}\n\n/**\n * Persisted incremental-scan checkpoint for the usage statistics (sidecar\n * `skillStats` field). Sessions created before `frozenBefore` are treated as\n * finalized: their per-session counts live in `frozenSessions` (only sessions\n * with at least one invocation are kept) and they are not re-read on\n * incremental scans. A daily full reconciliation rebuilds the cache and\n * advances the watermark, so a resumed old session is eventually re-counted.\n */\nexport interface SkillStatsCheckpoint {\n /** The rolling-window configuration this checkpoint was built for (0 = all history). */\n windowDays: number\n /** Watermark: every session with header.createdAt < this value is frozen. */\n frozenBefore: number\n /** Per-session counts of finalized sessions, keyed by session id. */\n frozenSessions: Record<string, { createdAt: number; counts: Record<string, { count: number; lastUsed: number }> }>\n /** Epoch ms of the last full reconciliation (drives the daily cadence). */\n lastFullReconcile: number\n}\n\n/** JSON error body shared by every route. */\nexport interface ErrorResponse {\n error: string\n}\n\n/** The skill hub's own runtime configuration, edited from the settings card. */\nexport interface HubConfig {\n /** Master switch: routes, provider, and announcement all go live with this. */\n enabled: boolean\n /** When true, a system-prompt section announces the hub to every agent. */\n announceToAgent: boolean\n /** Model-invocable dot color (#rrggbb); absent means the panel default. */\n dotModelColor?: string\n /** User-invocable dot color (#rrggbb); absent means the panel default. */\n dotUserColor?: string\n /** Show per-skill invocation count chip. Default true. */\n showUseCount?: boolean\n /** Show per-skill last-used relative time. Default true. */\n showUseTime?: boolean\n /** Show group-header usage summaries (count + last used). Default true. */\n showGroupSummary?: boolean\n /** 统计滚动窗口天数:只统计最近 N 天的使用;0 = 全部历史。默认 0。 */\n statsWindowDays?: number\n /** 自动统计扫描间隔(分钟,最小 1)。默认 5。 */\n statsScanMinutes?: number\n}\n\n/**\n * The resolved shape of the hub's settings namespace (schema defaults, then\n * the composition base, then the user layer). Kept as a type alias so the\n * browser-side settings scope snapshot is index-compatible with the card\n * form's record shape.\n */\nexport type HubSettingsValue = {\n enabled: boolean\n announceToAgent: boolean\n showUseCount: boolean\n showUseTime: boolean\n showGroupSummary: boolean\n /** Model-invocable dot color (#rrggbb); absent means the panel default. */\n dotModelColor?: string\n /** User-invocable dot color (#rrggbb); absent means the panel default. */\n dotUserColor?: string\n /** 统计滚动窗口天数(0 = 全部历史)。 */\n statsWindowDays?: number\n /** 自动统计扫描间隔(分钟)。 */\n statsScanMinutes?: number\n}\n\n/**\n * Hub config defaults — the single source every layer reads: the cordis\n * schema (index.ts), the host's saved-override merge, and the routes'\n * fallback view. Changing a default here changes all three.\n */\nexport const HUB_CONFIG_DEFAULTS = {\n enabled: true,\n announceToAgent: true,\n showUseCount: true,\n showUseTime: true,\n showGroupSummary: true,\n statsWindowDays: 14,\n statsScanMinutes: 5,\n} as const\n\n/**\n * Resolve the effective hub config: saved sidecar overrides win over the\n * cordis composition entry (the web card owns runtime config), missing\n * booleans fall back to HUB_CONFIG_DEFAULTS, and dot colors pass through\n * (saved first, then base) only when set. Numeric stats knobs are clamped to\n * their sane ranges (window ≥ 0, scan interval ≥ 1 minute).\n */\nexport function resolveHubConfig(saved: Partial<HubConfig>, base: Partial<HubConfig> = {}): HubConfig {\n const dotModelColor = saved.dotModelColor !== undefined ? saved.dotModelColor : base.dotModelColor\n const dotUserColor = saved.dotUserColor !== undefined ? saved.dotUserColor : base.dotUserColor\n const windowDays = clampNumber(saved.statsWindowDays ?? base.statsWindowDays, 0) ?? HUB_CONFIG_DEFAULTS.statsWindowDays\n const scanMinutes = clampNumber(saved.statsScanMinutes ?? base.statsScanMinutes, 1) ?? HUB_CONFIG_DEFAULTS.statsScanMinutes\n return {\n enabled: saved.enabled ?? base.enabled ?? HUB_CONFIG_DEFAULTS.enabled,\n announceToAgent: saved.announceToAgent ?? base.announceToAgent ?? HUB_CONFIG_DEFAULTS.announceToAgent,\n showUseCount: saved.showUseCount ?? base.showUseCount ?? HUB_CONFIG_DEFAULTS.showUseCount,\n showUseTime: saved.showUseTime ?? base.showUseTime ?? HUB_CONFIG_DEFAULTS.showUseTime,\n showGroupSummary: saved.showGroupSummary ?? base.showGroupSummary ?? HUB_CONFIG_DEFAULTS.showGroupSummary,\n statsWindowDays: windowDays,\n statsScanMinutes: scanMinutes,\n ...(dotModelColor !== undefined ? { dotModelColor } : {}),\n ...(dotUserColor !== undefined ? { dotUserColor } : {}),\n }\n}\n\n/** Clamp a numeric override into a valid value; undefined/invalid stays undefined. */\nfunction clampNumber(value: unknown, min: number): number | undefined {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < min) return undefined\n return Math.floor(value)\n}\n\n/** HEX color validation shared by host routes and the settings card. */\nexport const HEX_COLOR_RE = /^#[0-9a-f]{6}$/i\n\n/** GET /api/skill-hub/config */\nexport interface ConfigResponse {\n ok: true\n /** 已安装插件自身的版本号(package.json version),设置卡标题旁显示。 */\n pluginVersion: string\n /** Effective configuration (saved overrides merged over the defaults). */\n config: HubConfig\n /** Raw user overrides persisted in the sidecar (absent fields inherit defaults). */\n saved: Partial<HubConfig>\n}\n\n/** POST /api/skill-hub/config — a partial patch; omitted fields keep their values. */\nexport interface ConfigRequest {\n /** Set the field; null clears the saved override so it re-inherits the default. */\n enabled?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n announceToAgent?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showUseCount?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showUseTime?: boolean | null\n /** Set the field; null clears the saved override so it re-inherits the default. */\n showGroupSummary?: boolean | null\n /** Set the dot color; null clears the saved override so it re-inherits the default. */\n dotModelColor?: string | null\n /** Set the dot color; null clears the saved override so it re-inherits the default. */\n dotUserColor?: string | null\n /** 统计滚动窗口天数(0 = 全部历史);null 清除覆盖回默认。 */\n statsWindowDays?: number | null\n /** 自动统计扫描间隔(分钟);null 清除覆盖回默认。 */\n statsScanMinutes?: number | null\n}\n\n/** One market source: a tracked upstream repo plus its pinned version. */\nexport interface MarketSourceRecord {\n /** Repo slug (owner/repo). */\n repo: string\n /** Pinned version: release tag, branch name, or custom ref. Absent = not yet pinned. */\n ref?: string\n /** Commit the pinned ref last resolved to (update-check baseline). */\n commitSha?: string\n}\n\n/** GET /api/skill-hub/market — the user's added market sources. */\nexport interface MarketSourcesResponse {\n ok: true\n /** Added market sources, in addition order. */\n repos: MarketSourceRecord[]\n}\n\n/** POST /api/skill-hub/market/source — add one repo as a market source. */\nexport interface MarketSourceRequest {\n /** owner/repo, owner/repo@ref, or a github.com URL. */\n repo: string\n}\n\n/** POST /api/skill-hub/market/source|delete */\nexport interface MarketSourceResponse {\n ok: true\n repos: MarketSourceRecord[]\n}\n\n/** POST /api/skill-hub/market/source/ref — pin a market source to an explicit ref. */\nexport interface MarketSourceRefRequest {\n repo: string\n /** Release tag or branch name chosen for the repo. */\n ref: string\n}\n\n/** GET /api/skill-hub/market/check — update check over market sources. */\nexport interface MarketCheckResponse {\n ok: true\n results: Array<{\n repo: string\n /** Pinned ref, when one is recorded. */\n ref?: string\n /** Latest release tag on the repo, when it has one. */\n latestTag?: string\n /** Whether the pinned ref (or the repo) has moved ahead. */\n updateAvailable: boolean\n /** Latest commit of the checked ref. */\n commitSha: string\n /** Throttled: the check was skipped within the interval. */\n throttled?: boolean\n error?: string\n }>\n}\n\n/** POST /api/skill-hub/market/source/sync — align a market source to its pinned ref. */\nexport interface MarketSyncResponse {\n ok: true\n repo: string\n /** The ref the source is now pinned to. */\n ref: string\n commitSha: string\n /** Local skills tracked from this repo (candidates for a batch update). */\n skills: string[]\n}\n\n/** A skill discovered in a GitHub repo under any top-level root (e.g. skills/, templates/). */\nexport interface RepoSkillEntry {\n /** Kebab-case skill name (directory basename). */\n name: string\n /** Root-relative skill directory, e.g. skills/code-review. */\n dir: string\n /** Root-relative SKILL.md path, e.g. skills/code-review/SKILL.md. */\n path: string\n /** Repo root the skill lives in. */\n root: RepoRoot\n /** Collection name recorded as origin after import. */\n origin: string\n /** Number of files in the skill directory. */\n fileCount: number\n /** Total bytes across all files in the skill directory. */\n totalBytes: number\n /** Whether a same-named skill already exists locally. */\n existing: boolean\n}\n\n/** Skill root in a GitHub repo: the top-level directory that contains skills (e.g. skills, design-templates, templates). Auto-derived from SKILL.md locations, not hard-coded. */\nexport type RepoRoot = string\n\n/** GET /api/skill-hub/repo — discover importable skills in a GitHub repo. */\nexport interface RepoDiscoverResponse {\n ok: true\n repo: string\n /**\n * Ref the discovery ran against (release tag / branch / default branch).\n * Null means the repo has no release and no pinned ref — the client must\n * ask the user to pick a branch (see `branches`) and pin it first.\n */\n ref: string | null\n /** Branch names to choose from when ref is null (default branch first). */\n branches?: string[]\n entries: RepoSkillEntry[]\n}\n\n/** POST /api/skill-hub/repo/import — install selected repo skills. */\nexport interface RepoImportRequest {\n repo: string\n /** Selected SKILL.md paths from the discover response. */\n paths: string[]\n /** The ref the discovery ran against; the import must use the same one. */\n ref?: string\n}\n\n/** POST /api/skill-hub/repo/import — now creates an async job (B方案) */\nexport interface RepoImportResponse {\n ok: true\n jobId: string\n total: number\n totalBytes: number\n}\n\n/** GET /api/skill-hub/repo/import/progress?jobId=xxx */\nexport interface RepoImportProgressResponse {\n ok: true\n jobId: string\n status: 'running' | 'done' | 'cancelled' | 'error'\n total: number\n done: number\n /** 当前正在下载的 skill 名,done < total 时有效 */\n current?: string\n /** 当前正在下载的文件路径(相对 skill dir) */\n currentFile?: string\n /** 字节级进度 */\n totalBytes: number\n downloadedBytes: number\n /** 下载速度 bytes/sec,running 时有效 */\n bytesPerSecond?: number\n imported: Array<{ name: string; origin: string; path: string }>\n skipped: Array<{ name: string; reason: 'exists' }>\n failed: Array<{ name: string; error: string }>\n /** error 状态时的原因 */\n error?: string\n}\n\n/** POST /api/skill-hub/repo/import/cancel */\nexport interface RepoImportCancelRequest {\n jobId: string\n}\nexport interface RepoImportCancelResponse {\n ok: true\n jobId: string\n status: 'cancelled' | 'done'\n}\n\n/** @deprecated 旧同步响应,保留供类型兼容,实际已由 Progress 代替 */\nexport interface RepoImportLegacyResponse {\n ok: true\n imported: Array<{ name: string; origin: string; path: string }>\n skipped: Array<{ name: string; reason: 'exists' }>\n failed: Array<{ name: string; error: string }>\n}\n\n/** GET /api/skill-hub/update — check the plugin's own latest GitHub release. */\nexport interface UpdateCheckResponse {\n ok: true\n /** Installed plugin version (from the bundled host build). */\n currentVersion: string\n /** Latest release tag, normalized without the leading v; null when unknown. */\n latestVersion: string | null\n /** True when latestVersion is strictly newer than currentVersion. */\n updateAvailable: boolean\n /** Release page URL; null when unavailable. */\n url: string | null\n /** Best-effort message when the check failed or no release exists. */\n error?: string\n}\n\n/** 用户自定义 tag 分组:纯组织视图,不改技能文件。 */\nexport interface SkillTag {\n /** 稳定 ID(新建时由宿主生成)。 */\n id: string\n /** 显示名。 */\n name: string\n /** 成员技能名(集合技能与独立技能都可加入)。 */\n skillNames: string[]\n /** 默认场景(「通用」):系统预置、不可删除、新技能自动归入。 */\n default?: boolean\n}\n\n/** 系统集合组:按 origin(来源集合标识)自动聚合。 */\nexport interface CollectionGroup {\n /** 集合名(origin 值,如 \"superpowers\" / \"anthropics/skills\")。 */\n name: string\n /** 该集合下的技能名,按名称排序。 */\n skillNames: string[]\n}\n\n/** GET /api/skill-hub/groups */\nexport interface GroupsResponse {\n ok: true\n /** 用户自定义 tag 分组(按拖拽顺序)。 */\n tags: SkillTag[]\n /** 系统集合组(按拖拽顺序,兜底按名称)。 */\n collections: CollectionGroup[]\n /** skillName → 集合名 的完整映射。 */\n origins: Record<string, string>\n /** 来源分组整体顺序(project / col:xxx / uncategorized-source),用于 SourcesView 顶层排序 */\n sourceGroupOrder?: string[]\n /** 兼容旧 collectionOrder 字段 */\n collectionOrder?: string[]\n}\n\n/** POST /api/skill-hub/tag — 新建(缺省 id)或重命名(带 id)。 */\nexport interface TagSaveRequest {\n /** 已有 tag 的 id;缺省表示新建。 */\n id?: string\n /** 显示名(去空格后非空)。 */\n name: string\n}\n\n/** POST /api/skill-hub/tag */\nexport interface TagSaveResponse {\n ok: true\n /** 变更后的全部 tag。 */\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/tag/delete */\nexport interface TagDeleteRequest {\n id: string\n}\n\n/** POST /api/skill-hub/tag/delete */\nexport interface TagDeleteResponse {\n ok: true\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/tag/members — 直接设置某 tag 的完整成员列表(幂等)。 */\nexport interface TagMembersRequest {\n id: string\n /** 目标成员技能名;后端只保留目录中存在的名字。 */\n skillNames: string[]\n}\n\n/** POST /api/skill-hub/tag/members */\nexport interface TagMembersResponse {\n ok: true\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/tag/reorder — 拖拽重排场景分组 */\nexport interface TagReorderRequest {\n /** 按新顺序排列的 tag id 列表(需包含全部 id) */\n orderedIds: string[]\n}\n/** POST /api/skill-hub/tag/reorder */\nexport interface TagReorderResponse {\n ok: true\n tags: SkillTag[]\n}\n\n/** POST /api/skill-hub/collections/reorder — 拖拽重排来源集合 */\nexport interface CollectionReorderRequest {\n /** 按新顺序排列的集合名列表(需包含全部 name) */\n orderedNames: string[]\n}\n/** POST /api/skill-hub/collections/reorder */\nexport interface CollectionReorderResponse {\n ok: true\n collections: CollectionGroup[]\n order: string[]\n}\n\n/** POST /api/skill-hub/source-groups/reorder — 拖拽重排来源顶层分组(project / collections / personal) */\nexport interface SourceGroupReorderRequest {\n /** 按新顺序排列的顶层分组 key 列表(project / col:xxx / uncategorized-source) */\n orderedKeys: string[]\n}\nexport interface SourceGroupReorderResponse {\n ok: true\n order: string[]\n}\n\n/** 来源跟踪记录:一组来自同一上游仓库根目录的技能。 */\nexport interface SourceRecord {\n /** GitHub owner/repo。 */\n repo: string\n /** 显式分支/tag;缺省表示默认分支。 */\n ref?: string\n /** 技能在仓库中的根目录。 */\n root: RepoRoot\n /** 上次导入/同步时的上游 commit SHA;空 = 尚未核对过。 */\n commitSha: string\n /** 该来源下的技能名(来源组 = 这些技能)。 */\n skills: string[]\n /** 仓库内路径 → 文件大小 的基线清单(差异检测用;缺失 = 无基线)。 */\n manifest?: Record<string, number>\n}\n\n/** 回收站条目:上游删除后跟进删除(移入 .trash)的技能。 */\nexport interface TrashEntry {\n name: string\n /** .trash 下的绝对路径。 */\n path: string\n /** 移入回收站的时间(epoch ms)。 */\n movedAt: number\n /** 移入回收站前的原始路径(目录或文件);旧版本条目没有该字段。 */\n sourcePath?: string\n /**\n * 移入回收站前的来源跟踪快照(恢复时用它把技能重新挂回来源记录,\n * 否则恢复后的技能会丢失来源归属、变成「个人技能」)。\n */\n origin?: {\n repo: string\n root: RepoRoot\n ref?: string\n commitSha: string\n }\n /** 移入回收站前所属的场景(tag)ID;恢复时重新加回这些场景。 */\n tagIds?: string[]\n}\n\n/** GET /api/skill-hub/sources */\nexport interface SourcesResponse {\n ok: true\n /** 全部来源记录(按 repo 排序)。 */\n sources: SourceRecord[]\n /** skillName → 集合名(由 sources 派生)。 */\n origins: Record<string, string>\n /** 来源集合组(按 origin 聚合)。 */\n collections: CollectionGroup[]\n /** 回收站内容。 */\n trash: TrashEntry[]\n}\n\n/** POST /api/skill-hub/sources/check — 检查指定(或全部)来源的上游更新。 */\nexport interface SourceCheckRequest {\n /** 仅检查该 repo;缺省检查全部。 */\n repo?: string\n}\n\n/** 单个来源的检查结果。 */\nexport interface SourceCheckResult {\n repo: string\n ref?: string\n /** 检查失败时的原因(如仓库不可达/限流)。 */\n error?: string\n /** 上游 commit 是否变化。 */\n changed: boolean\n /** 上游最新 commit SHA(检查成功时)。 */\n commitSha?: string\n /** 上游有更新的技能名(changed 时经 tree 差异得出)。 */\n updated: string[]\n /** 上游已删除的技能名(changed 时经 tree 差异得出)。 */\n deleted: string[]\n /** 节流跳过(距上次检查不足 5 分钟,未访问网络)。 */\n throttled?: boolean\n /** 该来源此前没有快照(迁移/旧记录),本次已回填 commit,尚未有差异基线。 */\n unverified?: boolean\n}\n\n/** POST /api/skill-hub/sources/check */\nexport interface SourceCheckResponse {\n ok: true\n results: SourceCheckResult[]\n}\n\n/** POST /api/skill-hub/sources/sync — 按上游重新下载所选技能并更新快照。 */\nexport interface SourceSyncRequest {\n repo: string\n /** 要同步的技能名;缺省同步该来源全部技能。 */\n skills?: string[]\n}\n\n/** POST /api/skill-hub/sources/sync */\nexport interface SourceSyncResponse {\n ok: true\n repo: string\n /** 同步后的上游 commit SHA。 */\n commitSha: string\n /** 成功同步的技能。 */\n synced: string[]\n /** 失败的技能。 */\n failed: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/sources/delete — 跟进上游删除,本地移入回收站。 */\nexport interface SourceDeleteRequest {\n repo: string\n /** 要删除的技能名(移入 .trash)。 */\n skills: string[]\n}\n\n/** POST /api/skill-hub/sources/delete */\nexport interface SourceDeleteResponse {\n ok: true\n /** 已移入回收站的技能。 */\n trashed: string[]\n failed: Array<{ name: string; error: string }>\n}\n\n/** POST /api/skill-hub/sources/restore — 从回收站恢复一个技能。 */\nexport interface SourceRestoreRequest {\n name: string\n}\n\n/** POST /api/skill-hub/sources/restore */\nexport interface SourceRestoreResponse {\n ok: true\n name: string\n path: string\n}\n\n/** POST /api/skill-hub/sources/trash/clear — 永久删除回收站里的全部技能。 */\nexport interface SourceTrashClearResponse {\n ok: true\n /** 已永久删除的技能名。 */\n deleted: string[]\n /** 未能删除的技能(保留在回收站中)。 */\n failed: Array<{ name: string; error: string }>\n}\n","/**\n * Browser-side API client for the /api/skill-hub route family. The only\n * data access path the panel uses — plain fetch, same origin.\n */\nimport {\n SKILL_HUB_API,\n type CatalogResponse,\n type CollectionGroup,\n type ConfigRequest,\n type ConfigResponse,\n type CreateRequest,\n type CreateResponse,\n type CollectionReorderRequest,\n type CollectionReorderResponse,\n type SourceGroupReorderRequest,\n type SourceGroupReorderResponse,\n type MarketCheckResponse,\n type MarketSourceRefRequest,\n type MarketSourceRequest,\n type MarketSourceResponse,\n type MarketSourcesResponse,\n type MarketSyncResponse,\n type RepoDiscoverResponse,\n type RepoImportCancelResponse,\n type RepoImportProgressResponse,\n type RepoImportRequest,\n type RepoImportResponse,\n type SkillDetail,\n type SkillDetailResponse,\n type SkillDeleteRequest,\n type SkillDeleteResponse,\n type SkillTag,\n type SourceCheckRequest,\n type SourceCheckResponse,\n type SourceDeleteRequest,\n type SourceDeleteResponse,\n type SourceRestoreRequest,\n type SourceRestoreResponse,\n type SourceTrashClearResponse,\n type SourcesResponse,\n type SourceSyncRequest,\n type SourceSyncResponse,\n type StatsResponse,\n type TagReorderRequest,\n type TagReorderResponse,\n type ToggleBatchRequest,\n type ToggleBatchResponse,\n type UpdateCheckResponse,\n} from '../protocol.ts'\n\n/** Error carrying the route's JSON error message. */\nexport class SkillHubApiError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'SkillHubApiError'\n }\n}\n\n/** Parse a JSON response or throw a SkillHubApiError. */\nasync function readJson<T>(response: Response): Promise<T> {\n let body: unknown\n try {\n body = await response.json()\n } catch {\n throw new SkillHubApiError('HTTP ' + response.status + ': invalid JSON response')\n }\n if (!response.ok) {\n const message = typeof body === 'object' && body !== null && typeof (body as { error?: unknown }).error === 'string'\n ? (body as { error: string }).error\n : 'HTTP ' + response.status\n throw new SkillHubApiError(message)\n }\n return body as T\n}\n\n/**\n * Fetch with a hard timeout: a hung connection (proxy, stalled keep-alive,\n * host wedged) must never leave the panel stuck on \"loading\" forever — it\n * fails fast and surfaces the error banner instead.\n */\nasync function fetchWithTimeout(input: RequestInfo | URL, init?: RequestInit, ms = 10_000): Promise<Response> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), ms)\n try {\n return await fetch(input, { ...init, signal: controller.signal })\n } finally {\n clearTimeout(timer)\n }\n}\n\n/** The browser half's only data entry point. */\nexport class SkillHubApi {\n /** Catalog lookup options (cwd selects a workspace's project skills). */\n catalog(options?: { cwd?: string }): Promise<CatalogResponse> {\n const url = options?.cwd !== undefined && options.cwd !== '' ? SKILL_HUB_API.catalog + '?cwd=' + encodeURIComponent(options.cwd) : SKILL_HUB_API.catalog\n return fetchWithTimeout(url).then((response) => readJson<CatalogResponse>(response))\n }\n\n /** One skill's detail (cwd selects a workspace's project skills). */\n async skill(name: string, options?: { cwd?: string }): Promise<SkillDetail> {\n const cwd = options?.cwd !== undefined && options.cwd !== '' ? '&cwd=' + encodeURIComponent(options.cwd) : ''\n const url = SKILL_HUB_API.skill + '?name=' + encodeURIComponent(name) + cwd\n const response = await fetchWithTimeout(url)\n const body = await readJson<SkillDetailResponse>(response)\n return body.skill\n }\n\n /** Move one writable skill into the restorable trash. */\n async deleteSkill(name: string): Promise<SkillDeleteResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.skillDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name } satisfies SkillDeleteRequest),\n })\n return readJson<SkillDeleteResponse>(response)\n }\n\n /** Toggle one skill; resolves with the fresh catalog from the route. */\n async toggle(name: string, enabled: boolean): Promise<CatalogResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.toggle, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ name, enabled } satisfies import('../protocol.ts').ToggleRequest),\n })\n const body = await readJson<import('../protocol.ts').ToggleResponse>(response)\n return body.catalog\n }\n\n async create(payload: CreateRequest): Promise<CreateResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.create, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<CreateResponse>(response)\n }\n\n async stats(): Promise<StatsResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.stats)\n return readJson<StatsResponse>(response)\n }\n\n /** Toggle a whole group in one write; resolves with the fresh catalog + failures. */\n async toggleBatch(names: string[], enabled: boolean): Promise<ToggleBatchResponse> {\n const payload: ToggleBatchRequest = { names, enabled }\n const response = await fetchWithTimeout(SKILL_HUB_API.toggleBatch, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<ToggleBatchResponse>(response)\n }\n\n /** The user's added market sources. */\n async market(): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.market)\n return readJson<MarketSourcesResponse>(response)\n }\n\n /** Add a market source repo; resolves with the fresh list. */\n async addMarketSource(repo: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSource, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo } satisfies MarketSourceRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Remove a market source repo; resolves with the fresh list. */\n async removeMarketSource(repo: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSourceDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo } satisfies MarketSourceRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Check every market source for updates (throttled server-side). */\n async marketCheck(): Promise<MarketCheckResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketCheck)\n return readJson<MarketCheckResponse>(response)\n }\n\n /** Align a market source to its pinned ref; resolves with tracked skills. */\n async marketSync(repo: string): Promise<MarketSyncResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSync, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo }),\n })\n return readJson<MarketSyncResponse>(response)\n }\n\n /** Pin a market source to an explicit ref (branch picker). */\n async setMarketSourceRef(repo: string, ref: string): Promise<MarketSourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.marketSourceRef, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ repo, ref } satisfies MarketSourceRefRequest),\n })\n return readJson<MarketSourceResponse>(response)\n }\n\n /** Check the hub's own latest GitHub release. */\n async updateCheck(): Promise<UpdateCheckResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.update)\n return readJson<UpdateCheckResponse>(response)\n }\n\n /** Discover importable skills in a GitHub repo. */\n async repoDiscover(repo: string): Promise<RepoDiscoverResponse> {\n const url = SKILL_HUB_API.repo + '?repo=' + encodeURIComponent(repo)\n const response = await fetchWithTimeout(url)\n return readJson<RepoDiscoverResponse>(response)\n }\n\n /** Install selected repo skills into the user-dsh root (records the source). Returns jobId for polling. */\n async repoImport(repo: string, paths: string[], ref?: string): Promise<RepoImportResponse> {\n const payload: RepoImportRequest = { repo, paths, ...(ref !== undefined && ref !== '' ? { ref } : {}) }\n const response = await fetchWithTimeout(SKILL_HUB_API.repoImport, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<RepoImportResponse>(response)\n }\n\n /** Poll import job progress (B方案轮询) */\n async repoImportProgress(jobId: string): Promise<RepoImportProgressResponse> {\n const url = SKILL_HUB_API.repoImportProgress + '?jobId=' + encodeURIComponent(jobId)\n const response = await fetchWithTimeout(url)\n return readJson<RepoImportProgressResponse>(response)\n }\n\n /** Cancel a running import job (选项2:唯有取消才停) */\n async repoImportCancel(jobId: string): Promise<RepoImportCancelResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.repoImportCancel, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ jobId }),\n })\n return readJson<RepoImportCancelResponse>(response)\n }\n\n /** Read the hub's runtime config (effective values + saved overrides). */\n async config(): Promise<ConfigResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.config)\n return readJson<ConfigResponse>(response)\n }\n\n /** Patch the hub's runtime config (null clears a saved override). */\n async saveConfig(patch: ConfigRequest): Promise<ConfigResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.config, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(patch),\n })\n return readJson<ConfigResponse>(response)\n }\n\n /** 用户 tag 分组 + 系统集合组 + origin 映射。 */\n async groups(): Promise<import('../protocol.ts').GroupsResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.groups)\n return readJson<import('../protocol.ts').GroupsResponse>(response)\n }\n\n /** 新建(无 id)或重命名(带 id)一个 tag 分组;返回全部 tag。 */\n async saveTag(payload: import('../protocol.ts').TagSaveRequest): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tag, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n const body = await readJson<import('../protocol.ts').TagSaveResponse>(response)\n return body.tags\n }\n\n /** 删除一个 tag 分组;返回全部 tag。 */\n async deleteTag(id: string): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tagDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id } satisfies import('../protocol.ts').TagDeleteRequest),\n })\n const body = await readJson<import('../protocol.ts').TagDeleteResponse>(response)\n return body.tags\n }\n\n /** 直接设置某 tag 的完整成员列表;返回全部 tag。 */\n async setTagMembers(id: string, skillNames: string[]): Promise<import('../protocol.ts').SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tagMembers, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ id, skillNames } satisfies import('../protocol.ts').TagMembersRequest),\n })\n const body = await readJson<import('../protocol.ts').TagMembersResponse>(response)\n return body.tags\n }\n\n /** 拖拽重排场景分组 */\n async reorderTags(orderedIds: string[]): Promise<SkillTag[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.tagReorder, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ orderedIds } satisfies TagReorderRequest),\n })\n const body = await readJson<TagReorderResponse>(response)\n return body.tags\n }\n\n /** 拖拽重排来源集合 */\n async reorderCollections(orderedNames: string[]): Promise<CollectionGroup[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.collectionReorder, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ orderedNames } satisfies CollectionReorderRequest),\n })\n const body = await readJson<CollectionReorderResponse>(response)\n return body.collections\n }\n\n /** 拖拽重排来源顶层分组(project / collections / personal) */\n async reorderSourceGroups(orderedKeys: string[]): Promise<string[]> {\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceGroupReorder, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ orderedKeys } satisfies SourceGroupReorderRequest),\n })\n const body = await readJson<SourceGroupReorderResponse>(response)\n return body.order\n }\n\n /** 来源列表 + 派生 origin 映射 + 集合组 + 回收站。 */\n async sources(): Promise<SourcesResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.sources)\n return readJson<SourcesResponse>(response)\n }\n\n /** 检查指定(或全部)来源的上游更新。 */\n async checkSources(repo?: string): Promise<SourceCheckResponse> {\n const payload: SourceCheckRequest = repo !== undefined ? { repo } : {}\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceCheck, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceCheckResponse>(response)\n }\n\n /** 同步一个来源的所选(或全部)技能到上游最新版本。 */\n async syncSource(repo: string, skills?: string[]): Promise<SourceSyncResponse> {\n const payload: SourceSyncRequest = skills !== undefined ? { repo, skills } : { repo }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceSync, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceSyncResponse>(response)\n }\n\n /** 跟进上游删除:把所选技能移入回收站。 */\n async confirmDeleteSource(repo: string, skills: string[]): Promise<SourceDeleteResponse> {\n const payload: SourceDeleteRequest = { repo, skills }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceDelete, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceDeleteResponse>(response)\n }\n\n /** 从回收站恢复一个技能。 */\n async restoreSource(name: string): Promise<SourceRestoreResponse> {\n const payload: SourceRestoreRequest = { name }\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceRestore, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n return readJson<SourceRestoreResponse>(response)\n }\n\n /** Permanently delete every skill currently in the trash. */\n async clearTrash(): Promise<SourceTrashClearResponse> {\n const response = await fetchWithTimeout(SKILL_HUB_API.sourceTrashClear, { method: 'POST' })\n return readJson<SourceTrashClearResponse>(response)\n }\n}\n","/**\n * dsh-skill-hub surface copy (zh/en). The dictionary type is re-exported\n * so the LocaleNamespaceMap module augmentation in client/index.ts can\n * reference it without a value import.\n */\n\nexport const zh = {\n 'entry.label': '技能',\n 'entry.tooltip': '技能中枢:浏览、分组与同步管理本地技能',\n 'view.sources': '来源',\n 'view.scenes': '场景',\n 'view.market': '市场',\n 'view.flat': '平铺',\n 'view.grouped': '分组',\n 'panel.title': '技能中枢',\n 'panel.count': '共 {count} 个技能',\n 'panel.disabledCount': '已禁用 {count}',\n 'panel.new': '新建技能',\n 'panel.search': '搜索技能…',\n 'legend.model': '模型可调 — Agent 可自动调用',\n 'legend.user': '用户可调 — 仅显式点名时触发',\n 'legend.hint': '每个技能最多一个圆点;无圆点 = 不可被调用。',\n 'panel.enabled': '已启用',\n 'panel.disabled': '已禁用',\n 'panel.diagnostics': '发现诊断',\n 'panel.empty': '没有匹配的技能。',\n 'panel.emptyAll': '本地还没有技能。点击「新建技能」创建第一个。',\n 'panel.loading': '读取中…',\n 'panel.incomplete': '(目录可能不完整)',\n 'panel.workspacePlaceholder': '工作区路径(回车应用)',\n 'panel.workspaceHint': '填写项目路径后,面板同时显示该项目 .dsh/skills 与 .agents/skills 下的技能(只读);留空回车恢复用户级视图。',\n 'panel.workspaceClear': '清除工作区',\n 'market.addPlaceholder': 'owner/repo 或 https://github.com/…',\n 'market.addSource': '添加源',\n 'market.noSources': '还没有市场源。从下方内置市场添加,或输入一个 GitHub 仓库。',\n 'market.title': '市场',\n 'market.catalogHint': '精选技能仓库,添加后即可扫描安装,并持续检查更新。',\n 'market.catalog.anthropics': 'Anthropic 官方技能合集(Claude Skills)',\n 'market.catalog.superpowers': 'Superpowers 社区技能合集',\n 'market.catalog.mattpocock': 'Matt Pocock 技能集',\n 'market.catalog.openDesign': '设计技能合集(design-templates)',\n 'market.add': '添加',\n 'market.installed': '已装 {count}',\n 'market.updatable': '可更新 {count}',\n 'market.deletedUpstream': '上游已删 {count}',\n 'market.checkAll': '检查全部',\n 'market.updateAll': '全部更新',\n 'market.updateAllConfirmTitle': '批量更新全部技能?',\n 'market.updateAllConfirmText': '将把以下来源的可更新技能更新到上游最新版本(覆盖本地修改):',\n 'market.updateAllItem': '{repo}({count} 个技能)',\n 'market.updateAllDone': '已更新 {count} 个来源',\n 'market.deleteSource': '移除源',\n 'market.scan': '扫描',\n 'market.scanning': '扫描中…',\n 'market.check': '检查',\n 'market.checkUpdate': '检查更新',\n 'market.checking': '检查中…',\n 'market.upToDate': '已是最新',\n 'market.update': '更新',\n 'market.updateCount': '更新 {count} 个',\n 'market.sync': '同步',\n 'market.syncing': '同步中…',\n 'market.updated': '有更新',\n 'market.newRelease': '新版本 v{version}',\n 'market.branchTitle': '选择分支',\n 'market.branchHint': '该仓库没有正式发布,选择要跟踪的分支(默认为 main):',\n 'market.branchConfirm': '确定',\n 'market.syncTitle': '同步本地技能',\n 'market.syncText': '市场源已对齐到 {ref},要同步更新以下本地技能吗?',\n 'market.syncNone': '该来源还没有导入本地技能。',\n 'market.syncCancel': '跳过',\n 'market.removeHint': '移除源不影响已安装的技能。',\n 'repo.ready': '发现 {count} 个可导入技能',\n 'repo.empty': '没有找到可导入技能。',\n 'repo.selectAll': '全选',\n 'repo.clearAll': '清空',\n 'repo.import': '导入所选 ({count})',\n 'repo.importing': '导入中…',\n 'repo.existing': '已存在',\n 'repo.files': '{count} 个文件 · {size}',\n 'repo.imported': '导入成功 {count} 个',\n 'repo.skippedExisting': '跳过已存在 {count} 个',\n 'repo.failed': '失败 {count} 个',\n 'repo.cancel': '取消',\n 'repo.cancelled': '已取消 · 已导入 {imported}/{total} 已保留,临时文件已清理',\n 'repo.importingCurrent': '正在导入: {name} ({done}/{total})',\n 'repo.root.skills': '技能 skills',\n 'repo.root.designTemplates': '模板 design-templates',\n 'repo.root.generic': '{root}',\n 'update.check': '检查更新',\n 'update.checking': '检查中…',\n 'update.upToDate': '已是最新版本 v{version}',\n 'update.available': '发现新版本 v{version}(当前 v{current})',\n 'update.newVersion': '新版本 v{version}',\n 'update.viewRelease': '查看发布',\n 'update.error': '检查更新失败:{error}',\n 'update.unavailable': '暂无可用的发布版本',\n 'group.project-dsh': '项目 .dsh/skills',\n 'group.project-agents': '项目 .agents/skills',\n 'group.custom': '自定义目录',\n 'group.runtime': '运行时',\n 'group.user-dsh': '用户 ~/.dsh/skills',\n 'group.user-agents': '用户 ~/.agents/skills',\n 'group.bundled': '内置',\n 'group.other': '其他来源',\n 'groups.new': '新建场景',\n 'groups.namePlaceholder': '场景名',\n 'groups.edit': '编辑',\n 'groups.rename': '保存名称',\n 'groups.delete': '删除场景',\n 'groups.saveMembers': '保存成员',\n 'groups.membersHint': '勾选技能加入此场景(含已禁用)。',\n 'groups.empty': '还没有场景。先新建一个,再把技能归类。',\n 'groups.noCollections': '暂无来源组。从市场导入技能后自动按来源聚合。',\n 'groups.personal': '个人',\n 'groups.project': '项目级',\n 'groups.subdivide': '细分',\n 'groups.merge': '合并',\n 'groups.noWritable': '该组没有可写技能(只读技能无法由中枢开关)',\n 'groups.closeAll': '全部关闭',\n 'groups.keepOn': '保留开启',\n 'groups.conflictTitle': '关闭此组?',\n 'groups.conflictText': '以下技能也在其他组中开启,关闭它们会影响那些组:',\n 'filter.allSources': '全部来源',\n 'filter.private': '个人',\n 'sort.name': '按名称',\n 'sort.added': '按添加时间',\n 'sort.uses': '按调用次数',\n 'time.justNow': '刚刚',\n 'time.minutesAgo': '{value} 分钟前',\n 'time.hoursAgo': '{value} 小时前',\n 'time.daysAgo': '{value} 天前',\n 'time.weeksAgo': '{value} 周前',\n 'badge.source.project-dsh': '项目 .dsh',\n 'badge.source.project-agents': '项目 .agents',\n 'badge.source.custom': '自定义',\n 'badge.source.runtime': '运行时',\n 'badge.source.user-dsh': '用户 .dsh',\n 'badge.source.user-agents': '用户 .agents',\n 'badge.source.bundled': '内置',\n 'row.readonly': '只读',\n 'row.disable': '禁用',\n 'row.enable': '启用',\n 'row.delete': '移入回收站',\n 'row.open': '查看 {name} 详情(回车)',\n 'delete.confirmTitle': '移入回收站?',\n 'delete.confirmText': '确定把「{name}」移入回收站吗?可随时恢复。',\n 'delete.confirm': '移入回收站',\n 'detail.back': '返回列表',\n 'detail.provider': '提供者',\n 'detail.addedAt': '添加时间',\n 'detail.updatedAt': '更新时间',\n 'detail.path': '路径',\n 'detail.whenToUse': '适用场景',\n 'detail.uses': '调用次数',\n 'detail.groups': '所属场景',\n 'detail.loading': '读取技能正文…',\n 'source.private': '个人技能(未绑定上游,不检查更新)',\n 'source.commit': '已同步版本',\n 'source.unverified': '尚未核对上游',\n 'source.check': '检查更新',\n 'source.checkHint': '点击检查上游更新',\n 'source.checking': '检查中…',\n 'source.upToDate': '已是最新',\n 'source.updated': '有更新 {count} 个',\n 'source.deleted': '上游已删除 {count} 个',\n 'source.error': '检查失败',\n 'source.throttled': '刚刚检查过',\n 'source.sync': '同步',\n 'source.syncing': '同步中…',\n 'source.syncConfirmTitle': '同步技能?',\n 'source.syncConfirmText': '将用上游最新版本覆盖本地对以下技能的所有修改:',\n 'source.followDelete': '跟进删除',\n 'source.deleteConfirmTitle': '跟进上游删除?',\n 'source.deleteConfirmText': '以下技能已从上游仓库移除,本地目录将移入回收站(可恢复):',\n 'source.deleteGroup': '删除整组',\n 'source.deleteGroupHint': '删除该分组下的全部 {count} 个技能',\n 'source.deleteGroupTitle': '删除整组?',\n 'source.deleteGroupText': '将把分组“{name}”下的全部 {count} 个技能移入回收站(可恢复),只读技能会跳过:',\n 'source.trash': '回收站',\n 'source.restore': '恢复',\n 'source.clearTrash': '清空回收站',\n 'source.clearTrashConfirmTitle': '清空回收站?',\n 'source.clearTrashConfirmText': '回收站里的技能会被永久删除,无法恢复。此操作不可撤销。',\n 'source.clearTrashConfirm': '永久删除',\n 'form.capabilityHint': '能力怎么选:重复方法 → 技能;外部系统 → MCP;长期资料 → 知识库。',\n 'form.descPlaceholder': '一句话说明用途(含触发词),Agent 靠它自动激活技能',\n 'form.name': '技能名(kebab-case,如 code-review)',\n 'form.desc': '描述(一句话路由说明)',\n 'form.root': '目标目录',\n 'form.submit': '创建',\n 'form.cancel': '取消',\n 'form.busy': '创建中…',\n 'form.success': '已创建:',\n 'form.error': '创建失败:',\n 'err.dismiss': '知道了',\n 'settings.title': '技能中枢',\n 'settings.description': '管理 dsh 本地技能目录:浏览、分组、来源同步与新建。',\n 'settings.enabled': '启用插件',\n 'settings.enabledHint': '关闭后技能中枢的路由、入口与公告全部下线。',\n 'settings.announceToAgent': '向 Agent 公告',\n 'settings.announceToAgentHint': '在系统提示中加入本插件说明,用户提到技能管理时 Agent 知道如何协作。',\n 'settings.dotModelColor': '模型可调圆点颜色',\n 'settings.dotModelColorHint': '技能行/聊天 / 菜单中「模型可调」蓝色圆点的颜色(#rrggbb)。',\n 'settings.dotUserColor': '用户可调圆点颜色',\n 'settings.dotUserColorHint': '技能行/聊天 / 菜单中「仅用户可调」绿色圆点的颜色(#rrggbb)。',\n 'settings.showUseCount': '显示调用次数',\n 'settings.showUseCountHint': '在技能名旁显示琥珀色调用次数。',\n 'settings.showUseTime': '显示最近调用时间',\n 'settings.showUseTimeHint': '在技能名行右侧显示相对时间(如「3 天前」)。',\n 'settings.showGroupSummary': '显示分组汇总',\n 'settings.showGroupSummaryHint': '在分组标题后汇总调用次数与最近调用时间。',\n 'settings.statsWindowDays': '统计窗口(天)',\n 'settings.statsWindowDaysHint': '只统计最近 N 天的使用次数,默认 14 天;0 = 全部历史。改动立即生效。',\n 'settings.statsScanMinutes': '自动统计间隔(分钟)',\n 'settings.statsScanMinutesHint': '后台扫描会话日志的间隔,最小 1 分钟;扫描耗时会自动拉长间隔。',\n 'settings.inherit': '继承',\n 'settings.on': '开',\n 'settings.off': '关',\n 'settings.overridden': '已覆盖',\n 'settings.reset': '恢复默认',\n 'settings.unsaved': '未保存',\n 'settings.save': '保存',\n 'settings.saving': '保存中…',\n 'settings.discard': '放弃修改',\n 'settings.saveFailed': '本部署没有接受这些值,已保留供你修改。',\n 'settings.readOnly': '本部署的设置为只读。',\n 'settings.notExposed': '本部署没有挂载该设置命名空间。',\n 'settings.collapse': '收起设置',\n 'settings.expand': '展开设置',\n} as const\n\nexport const en: Record<HubKey, string> = {\n 'entry.label': 'Skills',\n 'entry.tooltip': 'Skill hub: browse, group, and sync local skills',\n 'view.sources': 'Sources',\n 'view.scenes': 'Scenes',\n 'view.market': 'Market',\n 'view.flat': 'Flat',\n 'view.grouped': 'Grouped',\n 'panel.title': 'Skill Hub',\n 'panel.count': '{count} skills total',\n 'panel.disabledCount': '{count} disabled',\n 'panel.new': 'New Skill',\n 'panel.search': 'Search skills…',\n 'legend.model': 'Model-invocable — agents may call automatically',\n 'legend.user': 'User-invocable — explicit invocation only',\n 'legend.hint': 'At most one dot per skill; no dot = not invocable.',\n 'panel.enabled': 'Enabled',\n 'panel.disabled': 'Disabled',\n 'panel.diagnostics': 'Discovery diagnostics',\n 'panel.empty': 'No matching skills.',\n 'panel.emptyAll': 'No skills installed yet. Create the first one.',\n 'panel.loading': 'Loading…',\n 'panel.incomplete': '(catalog may be incomplete)',\n 'panel.workspacePlaceholder': 'Workspace path (Enter to apply)',\n 'panel.workspaceHint': 'Enter a project path to also show that workspace\\'s .dsh/skills and .agents/skills skills (read-only); clear + Enter to return to the user-level view.',\n 'panel.workspaceClear': 'Clear workspace',\n 'market.addPlaceholder': 'owner/repo or https://github.com/…',\n 'market.addSource': 'Add source',\n 'market.noSources': 'No market sources yet. Add one from the built-in catalog below, or enter a GitHub repo.',\n 'market.title': 'Market',\n 'market.catalogHint': 'Curated skill repos — add one to scan and install, with ongoing update checks.',\n 'market.catalog.anthropics': 'Official Anthropic skill collection (Claude Skills)',\n 'market.catalog.superpowers': 'Superpowers community skill collection',\n 'market.catalog.mattpocock': 'Matt Pocock skill collection',\n 'market.catalog.openDesign': 'Design skill collection (design-templates)',\n 'market.add': 'Add',\n 'market.installed': '{count} installed',\n 'market.updatable': '{count} updatable',\n 'market.deletedUpstream': '{count} deleted upstream',\n 'market.checkAll': 'Check all',\n 'market.updateAll': 'Update all',\n 'market.updateAllConfirmTitle': 'Update every skill?',\n 'market.updateAllConfirmText': 'The updatable skills of these sources will be overwritten with their latest upstream versions:',\n 'market.updateAllItem': '{repo} ({count} skills)',\n 'market.updateAllDone': 'Updated {count} sources',\n 'market.deleteSource': 'Remove source',\n 'market.scan': 'Scan',\n 'market.scanning': 'Scanning…',\n 'market.check': 'Check',\n 'market.checkUpdate': 'Check for updates',\n 'market.checking': 'Checking…',\n 'market.upToDate': 'Up to date',\n 'market.update': 'Update',\n 'market.updateCount': 'Update {count}',\n 'market.sync': 'Sync',\n 'market.syncing': 'Syncing…',\n 'market.updated': 'Updates available',\n 'market.newRelease': 'New release v{version}',\n 'market.branchTitle': 'Choose a branch',\n 'market.branchHint': 'This repo has no releases. Pick a branch to track (main by default):',\n 'market.branchConfirm': 'Confirm',\n 'market.syncTitle': 'Update local skills',\n 'market.syncText': 'Market source aligned to {ref}. Update these local skills?',\n 'market.syncNone': 'No local skills tracked from this repo yet.',\n 'market.syncCancel': 'Skip',\n 'market.removeHint': 'Removing a source does not affect installed skills.',\n 'repo.ready': '{count} importable skills found',\n 'repo.empty': 'No importable skills found.',\n 'repo.selectAll': 'Select all',\n 'repo.clearAll': 'Clear',\n 'repo.import': 'Import selected ({count})',\n 'repo.importing': 'Importing…',\n 'repo.existing': 'Existing',\n 'repo.files': '{count} files · {size}',\n 'repo.imported': 'Imported {count}',\n 'repo.skippedExisting': 'Skipped existing {count}',\n 'repo.failed': 'Failed {count}',\n 'repo.cancel': 'Cancel',\n 'repo.cancelled': 'Cancelled · {imported}/{total} kept, temp files cleaned',\n 'repo.importingCurrent': 'Importing: {name} ({done}/{total})',\n 'repo.root.skills': 'Skills',\n 'repo.root.designTemplates': 'Templates design-templates',\n 'repo.root.generic': '{root}',\n 'update.check': 'Check for updates',\n 'update.checking': 'Checking…',\n 'update.upToDate': 'Up to date: v{version}',\n 'update.available': 'Update available: v{version} (current v{current})',\n 'update.newVersion': 'New version v{version}',\n 'update.viewRelease': 'View release',\n 'update.error': 'Update check failed: {error}',\n 'update.unavailable': 'No release available',\n 'group.project-dsh': 'Project .dsh/skills',\n 'group.project-agents': 'Project .agents/skills',\n 'group.custom': 'Custom directories',\n 'group.runtime': 'Runtime',\n 'group.user-dsh': 'User ~/.dsh/skills',\n 'group.user-agents': 'User ~/.agents/skills',\n 'group.bundled': 'Bundled',\n 'group.other': 'Other sources',\n 'groups.new': 'New scene',\n 'groups.namePlaceholder': 'Scene name',\n 'groups.edit': 'Edit',\n 'groups.rename': 'Save name',\n 'groups.delete': 'Delete scene',\n 'groups.saveMembers': 'Save members',\n 'groups.membersHint': 'Check skills to add to this scene (disabled skills included).',\n 'groups.empty': 'No scenes yet. Create one and start categorizing skills.',\n 'groups.noCollections': 'No source groups yet. Import skills from the market to group them by source.',\n 'groups.personal': 'Personal',\n 'groups.project': 'Project',\n 'groups.subdivide': 'Split',\n 'groups.merge': 'Merge',\n 'groups.noWritable': 'No writable skills in this group (read-only skills cannot be switched from the hub)',\n 'groups.closeAll': 'Close all',\n 'groups.keepOn': 'Keep on',\n 'groups.conflictTitle': 'Close this group?',\n 'groups.conflictText': 'These skills are also enabled in other groups; closing them affects those groups:',\n 'filter.allSources': 'All sources',\n 'filter.private': 'Personal',\n 'sort.name': 'By name',\n 'sort.added': 'By added',\n 'sort.uses': 'By uses',\n 'time.justNow': 'just now',\n 'time.minutesAgo': '{value} min ago',\n 'time.hoursAgo': '{value} h ago',\n 'time.daysAgo': '{value} d ago',\n 'time.weeksAgo': '{value} w ago',\n 'badge.source.project-dsh': 'project .dsh',\n 'badge.source.project-agents': 'project .agents',\n 'badge.source.custom': 'custom',\n 'badge.source.runtime': 'runtime',\n 'badge.source.user-dsh': 'user .dsh',\n 'badge.source.user-agents': 'user .agents',\n 'badge.source.bundled': 'bundled',\n 'row.readonly': 'read-only',\n 'row.disable': 'Disable',\n 'row.enable': 'Enable',\n 'row.delete': 'Move to trash',\n 'row.open': 'View {name} details (Enter)',\n 'delete.confirmTitle': 'Move to trash?',\n 'delete.confirmText': 'Move \"{name}\" to trash? It can be restored anytime.',\n 'delete.confirm': 'Move to trash',\n 'detail.back': 'Back to list',\n 'detail.provider': 'Provider',\n 'detail.addedAt': 'Added',\n 'detail.updatedAt': 'Updated',\n 'detail.path': 'Path',\n 'detail.whenToUse': 'When to use',\n 'detail.uses': 'Uses',\n 'detail.groups': 'Groups',\n 'detail.loading': 'Loading skill body…',\n 'source.private': 'Personal skill (not bound to an upstream; no update checks)',\n 'source.commit': 'Synced commit',\n 'source.unverified': 'upstream not verified yet',\n 'source.check': 'Check for updates',\n 'source.checkHint': 'Click to check the upstream for updates',\n 'source.checking': 'Checking…',\n 'source.upToDate': 'Up to date',\n 'source.updated': '{count} updates',\n 'source.deleted': '{count} deleted upstream',\n 'source.error': 'Check failed',\n 'source.throttled': 'Checked recently',\n 'source.sync': 'Sync',\n 'source.syncing': 'Syncing…',\n 'source.syncConfirmTitle': 'Sync skills?',\n 'source.syncConfirmText': 'This overwrites local changes to these skills with the latest upstream version:',\n 'source.followDelete': 'Follow deletion',\n 'source.deleteConfirmTitle': 'Follow upstream deletion?',\n 'source.deleteConfirmText': 'These skills were removed upstream; their local directories move to trash (restorable):',\n 'source.deleteGroup': 'Delete group',\n 'source.deleteGroupHint': 'Delete all {count} skills in this group',\n 'source.deleteGroupTitle': 'Delete group?',\n 'source.deleteGroupText': 'All {count} skills in group \"{name}\" will be moved to trash (restorable); read-only skills will be skipped:',\n 'source.trash': 'Trash',\n 'source.restore': 'Restore',\n 'source.clearTrash': 'Empty trash',\n 'source.clearTrashConfirmTitle': 'Empty the trash?',\n 'source.clearTrashConfirmText': 'Skills in the trash will be permanently deleted and cannot be restored.',\n 'source.clearTrashConfirm': 'Delete permanently',\n 'form.capabilityHint': 'Choosing a capability: repeatable method → skill; external system → MCP; long-term knowledge → knowledge base.',\n 'form.descPlaceholder': 'One line on what it does (with trigger words) — agents auto-activate from this',\n 'form.name': 'Skill name (kebab-case, e.g. code-review)',\n 'form.desc': 'Description (one routing sentence)',\n 'form.root': 'Target root',\n 'form.submit': 'Create',\n 'form.cancel': 'Cancel',\n 'form.busy': 'Creating…',\n 'form.success': 'Created: ',\n 'form.error': 'Create failed: ',\n 'err.dismiss': 'Dismiss',\n 'settings.title': 'Skill Hub',\n 'settings.description': 'Manage the local dsh skill catalog: browse, group, sync, and scaffold skills.',\n 'settings.enabled': 'Enable plugin',\n 'settings.enabledHint': 'Disables the hub routes, entries, and announcement.',\n 'settings.announceToAgent': 'Announce to agent',\n 'settings.announceToAgentHint': 'Adds a system-prompt section so agents know how to collaborate when users mention skill management.',\n 'settings.dotModelColor': 'Model-invocable dot color',\n 'settings.dotModelColorHint': 'Color of the blue \"model-callable\" dot in the skill panel and the chat / menu (#rrggbb).',\n 'settings.dotUserColor': 'User-invocable dot color',\n 'settings.dotUserColorHint': 'Color of the green \"user-only\" dot in the skill panel and the chat / menu (#rrggbb).',\n 'settings.showUseCount': 'Show invocation count',\n 'settings.showUseCountHint': 'Show the amber invocation count beside each skill name.',\n 'settings.showUseTime': 'Show last-used time',\n 'settings.showUseTimeHint': 'Show relative last-used time on the name row (e.g. \"3 d ago\").',\n 'settings.showGroupSummary': 'Show group summaries',\n 'settings.showGroupSummaryHint': 'Summarize invocation count and last-used time after group titles.',\n 'settings.statsWindowDays': 'Stats window (days)',\n 'settings.statsWindowDaysHint': 'Count only usage within the last N days (default 14); 0 = full history. Changes apply immediately.',\n 'settings.statsScanMinutes': 'Auto stats interval (minutes)',\n 'settings.statsScanMinutesHint': 'How often the background session-log scan runs (min 1); heavy scans automatically stretch it.',\n 'settings.inherit': 'Inherit',\n 'settings.on': 'On',\n 'settings.off': 'Off',\n 'settings.overridden': 'Overridden',\n 'settings.reset': 'Reset to default',\n 'settings.unsaved': 'Unsaved',\n 'settings.save': 'Save',\n 'settings.saving': 'Saving…',\n 'settings.discard': 'Discard',\n 'settings.saveFailed': 'The deployment did not accept these values; they were left for you to correct.',\n 'settings.readOnly': 'This deployment stores settings read-only.',\n 'settings.notExposed': 'This deployment does not expose the settings namespace.',\n 'settings.collapse': 'Hide settings',\n 'settings.expand': 'Show settings',\n}\n\n/** Union of every translatable key (the namespace's registered dictionary type). */\nexport type HubKey = keyof typeof zh\n\n/** Template values accepted by the interpolator. */\nexport type TranslateValues = Record<string, string | number>\n\n/** Interpolate a {name} template with the given values. */\nexport function t(dict: Record<string, string>, key: HubKey, values?: TranslateValues): string {\n let text = dict[key] ?? key\n if (values !== undefined) {\n for (const [name, value] of Object.entries(values)) {\n text = text.replaceAll('{' + name + '}', String(value))\n }\n }\n return text\n}\n","/**\n * The settings shell renders section nav icons from a hard-coded id map and\n * exposes no registrant icon option, so the skill-hub section falls back to\n * the generic gear. This scoped DOM patch swaps in the official skill icon\n * whenever the settings dialog re-renders.\n */\n\nconst SKILL_SECTION_LABELS = ['技能', 'Skills']\n\nconst SKILL_ICON_SVG = `<svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-skill-hub-nav-icon=\"true\"><path d=\"M12.5113 15.4067C12.4395 15.6249 12.1308 15.6249 12.059 15.4067L11.643 14.1416C11.454 13.567 11.0033 13.1164 10.4288 12.9274L9.16369 12.5113C8.94544 12.4395 8.94544 12.1308 9.16369 12.059L10.4288 11.643C11.0033 11.454 11.454 11.0033 11.643 10.4288L12.059 9.16369C12.1308 8.94544 12.4395 8.94544 12.5113 9.16369L12.9274 10.4288C13.1164 11.0033 13.567 11.454 14.1416 11.643L15.4067 12.059C15.6249 12.1308 15.6249 12.4395 15.4067 12.5113L14.1416 12.9274C13.567 13.1164 13.1164 13.567 12.9274 14.1416L12.5113 15.4067Z\" fill=\"currentColor\"/><path d=\"M9.02246 0.546878C9.9822 0.546878 10.7564 0.545403 11.374 0.612307C12.0042 0.680586 12.5515 0.826244 13.0273 1.17188C13.3052 1.37376 13.5501 1.61868 13.752 1.89649C14.0975 2.37225 14.2432 2.91984 14.3115 3.54981C14.3784 4.16727 14.377 4.94206 14.377 5.90137V8.51367C13.9611 8.29533 13.5071 8.13985 13.0273 8.06055V5.90137C13.0273 4.9121 13.0259 4.22322 12.9688 3.69532C12.9129 3.18044 12.8098 2.89782 12.6592 2.69043C12.5406 2.52724 12.3966 2.38326 12.2334 2.26465C12.026 2.11404 11.7437 2.0109 11.2285 1.95508C10.7005 1.89789 10.0122 1.89649 9.02246 1.89649H6.55371C5.56395 1.89649 4.87569 1.89787 4.34766 1.95508C3.83242 2.01092 3.55022 2.11398 3.34278 2.26465C3.17953 2.38329 3.03564 2.52719 2.91699 2.69043C2.76642 2.89782 2.66325 3.18042 2.60742 3.69532C2.55027 4.22322 2.54883 4.9121 2.54883 5.90137V10.0986C2.54883 11.0878 2.55031 11.7768 2.60742 12.3047C2.66326 12.8196 2.76642 13.1032 2.91699 13.3105C3.03558 13.4736 3.17966 13.6178 3.34278 13.7363C3.5502 13.8869 3.83265 13.9901 4.34766 14.0459C4.87568 14.1031 5.56398 14.1035 6.55371 14.1035H8.08399C8.27443 14.6025 8.55077 15.0585 8.89551 15.4541H6.55371C5.59402 15.4541 4.81976 15.4546 4.20215 15.3877C3.57204 15.3194 3.02468 15.1738 2.54883 14.8281C2.27111 14.6263 2.02606 14.3813 1.82422 14.1035C1.47883 13.6278 1.33293 13.08 1.26465 12.4502C1.19783 11.8327 1.19922 11.0579 1.19922 10.0986V5.90137C1.19922 4.94206 1.1978 4.16727 1.26465 3.54981C1.33295 2.91984 1.47867 2.37225 1.82422 1.89649C2.02613 1.61864 2.27098 1.37379 2.54883 1.17188C3.02472 0.826181 3.57197 0.6806 4.20215 0.612307C4.81976 0.545393 5.594 0.546877 6.55371 0.546878H9.02246ZM9.19629 9.14649H4.5459V7.84571H9.19629V9.14649ZM11.0303 6.10645H4.5459V4.80567H11.0303V6.10645Z\" fill=\"currentColor\"/></svg>`\n\nlet iconTemplate: SVGSVGElement | null = null\n\nfunction skillIcon(): SVGSVGElement {\n if (iconTemplate === null) {\n iconTemplate = new DOMParser().parseFromString(SKILL_ICON_SVG, 'image/svg+xml').documentElement as unknown as SVGSVGElement\n }\n return iconTemplate.cloneNode(true) as SVGSVGElement\n}\n\nfunction patchNavIcon(): void {\n const dialog = document.querySelector('[role=\"dialog\"]')\n if (dialog === null) return\n for (const button of dialog.querySelectorAll<HTMLButtonElement>('button')) {\n const label = button.querySelector('span')\n if (label === null || !SKILL_SECTION_LABELS.includes(label.textContent?.trim() ?? '')) continue\n if (button.querySelector('svg[data-skill-hub-nav-icon]') !== null) continue\n const current = button.querySelector('svg')\n const icon = skillIcon()\n if (current !== null) current.replaceWith(icon)\n else button.insertBefore(icon, button.firstChild)\n }\n}\n\n/** Swap the settings nav gear for the skill icon and keep it in sync. */\nexport function applySettingsNavIcon(): () => void {\n if (typeof document === 'undefined' || typeof MutationObserver === 'undefined') return () => {}\n patchNavIcon()\n const observer = new MutationObserver(() => { patchNavIcon() })\n observer.observe(document.body, { childList: true, subtree: true })\n return () => { observer.disconnect() }\n}\n","/**\n * Pure grouping helpers for the skill-hub panel (no React/DOM deps, so the\n * merge/classify/filter logic stays unit-testable).\n *\n * The \"分组\" view unifies two ways a skill can belong to a group:\n * - user tags (sidecar SkillTag)\n * - origin collections (sidecar sources → backend-aggregated CollectionGroup)\n *\n * Switch semantics: a skill's enabled state is global (the file is renamed\n * once), so a group switch is derived from its members' actual states:\n * all members enabled → 'on', all disabled → 'off', otherwise 'mixed'.\n * Closing a group whose member is enabled in another group is a conflict the\n * GUI resolves with a dialog; the helpers below compute both sides.\n */\n\nimport type { CatalogSkill, CollectionGroup, SkillTag } from '../protocol.ts'\n\n/** Grouped switch state derived from member enablement. */\nexport type GroupSwitchState = 'on' | 'off' | 'mixed'\n\n/** The derived switch view of one group. */\nexport interface GroupSwitchView {\n state: GroupSwitchState\n /** Writable members currently enabled. */\n enabled: string[]\n /** Writable members currently disabled. */\n disabled: string[]\n}\n\n/**\n * Derive a group switch view from its member names and the set of currently\n * enabled skill names (catalog.skills). Members not in the enabled set count\n * as disabled (catalog.disabled or absent read-only rows).\n */\nexport function groupSwitchView(members: readonly string[], enabledNames: ReadonlySet<string>): GroupSwitchView {\n const enabled: string[] = []\n const disabled: string[] = []\n for (const name of members) {\n if (enabledNames.has(name)) enabled.push(name)\n else disabled.push(name)\n }\n const state: GroupSwitchState = disabled.length === 0 ? 'on' : enabled.length === 0 ? 'off' : 'mixed'\n return { state, enabled, disabled }\n}\n\n/** Names of every group a skill belongs to (tags + collections). */\nexport function groupNamesOf(name: string, tags: readonly SkillTag[], collections: readonly CollectionGroup[]): string[] {\n const names: string[] = []\n for (const tag of tags) if (tag.skillNames.includes(name)) names.push(tag.name)\n for (const collection of collections) if (collection.skillNames.includes(name)) names.push(collection.name)\n return names\n}\n\n/**\n * Members of a group that are currently enabled AND also belong to at least\n * one other group — the set a \"close\" action must ask about.\n */\nexport function conflictsOnClose(\n members: readonly string[],\n enabledNames: ReadonlySet<string>,\n otherGroups: ReadonlyArray<{ members: readonly string[] }>,\n): string[] {\n return members.filter((name) => {\n if (!enabledNames.has(name)) return false\n return otherGroups.some((group) => group.members.includes(name))\n })\n}\n\n/** Origin-repo filter value: skills with no source record (private skills). */\nexport const PRIVATE_SOURCE = 'private'\n\n/** 项目级技能来源(它们有 workspace 归属,不属于「个人」组)。 */\nexport function isProjectSource(source: string): boolean {\n return source === 'project-dsh' || source === 'project-agents'\n}\n\n/**\n * Apply the origin filter ('all' or a specific origin repo; skills without a\n * source record count as PRIVATE_SOURCE). The origins map is the store's\n * skillName → repo derivation, so filtering follows the tracked source\n * records instead of the filesystem root a skill happens to live under.\n * 项目级技能(有 workspace 归属)永远不算「个人」。\n */\nexport function filterBySource(skills: readonly CatalogSkill[], source: string, origins: Readonly<Record<string, string>>): CatalogSkill[] {\n if (source === 'all') return [...skills]\n return skills.filter((skill) => {\n if (isProjectSource(skill.source)) return false\n return (origins[skill.name] ?? PRIVATE_SOURCE) === source\n })\n}\n\n/** Catalog sort keys offered by the filter bar. */\nexport type SortKey = 'name' | 'added' | 'uses'\n\n/**\n * Sort a skill list in place-safe copy order: name ascending, added\n * descending (newest first, unknown addedAt last), or uses descending\n * (most-called first). Unknown values always trail.\n */\nexport function sortSkills(skills: readonly CatalogSkill[], key: SortKey, getUses?: (name: string) => number | undefined): CatalogSkill[] {\n const list = [...skills]\n if (key === 'name') {\n list.sort((a, b) => a.name.localeCompare(b.name))\n } else if (key === 'added') {\n list.sort((a, b) => (b.addedAt ?? -Infinity) - (a.addedAt ?? -Infinity))\n } else if (key === 'uses') {\n list.sort((a, b) => (getUses?.(b.name) ?? 0) - (getUses?.(a.name) ?? 0))\n }\n return list\n}\n\n/** Localized relative-time tuple; the caller resolves it via tt(). */\nexport interface RelativeTime {\n key: 'time.justNow' | 'time.minutesAgo' | 'time.hoursAgo' | 'time.daysAgo' | 'time.weeksAgo'\n value?: number\n}\n\n/** Format an epoch-ms timestamp as a short relative time bucket. */\nexport function formatRelativeTime(ms: number, now = Date.now()): RelativeTime {\n const diff = Math.max(0, now - ms)\n const minutes = Math.floor(diff / 60_000)\n if (minutes < 1) return { key: 'time.justNow' }\n if (minutes < 60) return { key: 'time.minutesAgo', value: minutes }\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return { key: 'time.hoursAgo', value: hours }\n const days = Math.floor(hours / 24)\n if (days < 7) return { key: 'time.daysAgo', value: days }\n return { key: 'time.weeksAgo', value: Math.floor(days / 7) }\n}\n","/**\n * Shared panel helpers: the active-dictionary pick (document-language\n * based, family precedent) plus a small error-message extractor.\n */\nimport { en, t, zh, type HubKey, type TranslateValues } from './locales.ts'\n\n/** Active dictionary, picked by the document language at call time. */\nexport function dictionary(): Record<string, string> {\n const lang = typeof document !== 'undefined' ? document.documentElement.lang : 'zh'\n return lang.toLowerCase().startsWith('en') ? { ...en } : { ...zh }\n}\n\n/** Translate a key with optional {name} template params (current language). */\nexport function tt(key: HubKey, values?: TranslateValues): string {\n return t(dictionary(), key, values)\n}\n\n/** Human-readable error text from an unknown thrown value. */\nexport function errorMessage(error: unknown): string {\n if (error instanceof Error) return error.message\n return String(error)\n}\n\n","/**\n * Shared display helpers for the panel views (skill rows, detail view, and\n * dialogs): dot color styling, relative/absolute time text, and commit-SHA\n * shortening. Kept in one place so the views render identically.\n *\n * The invocation-status dot defaults live here (not in the settings card) so\n * both the panel legend and the chat `/` skill menu draw from one source and\n * so this primitives-free module stays unit-testable.\n */\n\nimport type { CSSProperties } from 'react'\nimport { formatRelativeTime } from '../grouping.ts'\nimport { tt } from '../helpers.ts'\n\n/** Model-invocable dot color default. Single source for the TS side; the\n * panel's CSS mirrors it via --hub-model (panel.module.css). */\nexport const DEFAULT_DOT_MODEL_COLOR = '#2f81f7'\n/** User-invocable dot color default. Single source for the TS side; the\n * panel's CSS mirrors it via --hub-user (panel.module.css). */\nexport const DEFAULT_DOT_USER_COLOR = '#3fb950'\n\n/** Dot inline style from the user-chosen color (undefined keeps the CSS default). */\nexport function dotStyle(color: string | undefined): CSSProperties | undefined {\n if (color === undefined) return undefined\n return { background: color, borderColor: color }\n}\n\n/** Localized relative-time text for a Unix-ms timestamp. */\nexport function relativeTimeText(ms: number): string {\n const rt = formatRelativeTime(ms)\n return tt(rt.key, rt.value !== undefined ? { value: rt.value } : undefined)\n}\n\n/** Localized absolute time for the detail meta (e.g. \"2026/8/16 11:00:00\"). */\nexport function formatDateTime(ms: number): string {\n return new Date(ms).toLocaleString()\n}\n\n/** Short form of a commit SHA for display. */\nexport function shortSha(sha: string): string {\n return sha.length > 7 ? sha.slice(0, 7) : sha\n}\n","/**\n * Slash-menu skill dots: puts the invocation-status dot (model-callable blue /\n * user-only green) in front of every skill candidate in the chat `/` menu.\n *\n * Mechanism (mirrors how dsh-at-file fills the menu icon slot): the candidate\n * menu's rows already render an optional `icon` slot (`MenuView` renders\n * `item.icon` in a 16×16 leading span when it's defined), but the core `/skill`\n * source (`dsh-client-ui-skill`) returns candidates without `icon`. This module\n * wraps that source's `candidates` and stamps each row with a colored dot,\n * reusing the same settings (dotModelColor / dotUserColor) and the same\n * `modelInvocable` classification the panel legend uses — so the chat menu and\n * the Settings → 技能 panel stay in sync, and editing the color updates both.\n *\n * The skill source is registered by the core plugin under the `name` \"skill\"\n * on the `/` trigger; re-registering the same name would throw, so this wraps\n * the already-registered source object instead (found through the runtime\n * source registry, which the frozen contract exposes only as `registerSource`\n * / `sessionOf` — the lookup below is defensive: it never throws).\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the Context merge for ctx.inputTriggers.\nimport type {} from '@deepseek-ai/dsh-client-ui-input-trigger/client'\n// Type-only: pulls the connection/reset event.\nimport type {} from '@deepseek-ai/dsh-client-connection/client'\nimport type { InputTriggerCandidate, InputTriggerServiceContract, InputTriggerSource } from '@deepseek-ai/dsh-client-ui-input-trigger/client'\nimport { createElement } from 'react'\nimport type { HubSettingsValue } from '../protocol.ts'\nimport type { SkillHubApi } from './api.ts'\nimport { DEFAULT_DOT_MODEL_COLOR, DEFAULT_DOT_USER_COLOR } from './panel/format.ts'\n\n/** The core plugin's skill source identity on the '/' trigger. */\nconst SKILL_SOURCE = { trigger: '/', name: 'skill' } as const\n\n/** How long one catalog-derived modelInvocable map stays hot before refresh. */\nconst MODEL_TTL_MS = 60_000\n\n/** Runtime view of the source registry (the contract keeps `live` private). */\ntype SourceRegistry = {\n live?: { sources?: InputTriggerSource[] }\n}\n\n/**\n * Find the core `/skill` source through the runtime registry, or undefined.\n * The lookup never throws: a missing/reshaped registry just means no dots. Exported\n * for unit tests; the apply path only calls it indirectly through setupSkillSlashDots.\n * @param service - the ctx.inputTriggers service face.\n * @returns the registered skill source, or undefined.\n */\nexport function findSkillSource(service: InputTriggerServiceContract): InputTriggerSource | undefined {\n const live = (service as unknown as SourceRegistry).live\n if (live?.sources === undefined) return undefined\n return live.sources.find((source) => source.trigger === SKILL_SOURCE.trigger && source.name === SKILL_SOURCE.name)\n}\n\n/** One catalog-derived name → modelInvocable snapshot with a load timestamp. */\nlet modelCache: { at: number; map: Map<string, boolean> } | { at: number; failed: true } | undefined\n\n/**\n * Clear the modelInvocable cache. Called on connection/reset so a fresh\n * catalog wins after reconnect; exported for deterministic unit tests.\n */\nexport function resetModelCache(): void {\n modelCache = undefined\n}\n\n/**\n * Resolve name → modelInvocable from the hub's catalog, cached for\n * MODEL_TTL_MS. A failed load caches the failure briefly so a downed route\n * doesn't hammer the host on every keystroke; the returned map is empty then\n * (callers fall back to the model dot for unknown names).\n * @param api - the hub browser API.\n * @returns name → whether the model may call the skill.\n */\nasync function modelInvocableMap(api: SkillHubApi): Promise<Map<string, boolean>> {\n const now = Date.now()\n const cached = modelCache\n if (cached !== undefined && now - cached.at < MODEL_TTL_MS) {\n return 'failed' in cached ? new Map() : cached.map\n }\n try {\n const catalog = await api.catalog()\n const map = new Map<string, boolean>(catalog.skills.map((skill) => [skill.name, skill.invocation.modelInvocable]))\n modelCache = { at: now, map }\n return map\n } catch (error) {\n console.error('[dsh-skill-hub] slash dot color lookup failed:', error)\n modelCache = { at: now, failed: true }\n return new Map()\n }\n}\n\n/**\n * One menu-row dot element. Inline span so it needs no CSS module; the\n * candidate menu centers it inside its 16×16 leading icon slot.\n * @param color - the dot's background color.\n * @returns a React node (memory-only, never crosses the Host boundary).\n */\nfunction dotIcon(color: string): InputTriggerCandidate['icon'] {\n return createElement('span', {\n 'aria-hidden': true,\n style: {\n display: 'inline-block',\n width: 6,\n height: 6,\n borderRadius: 3,\n background: color,\n flex: 'none',\n },\n }) as unknown as InputTriggerCandidate['icon']\n}\n\n/**\n * Wrap the core skill source so every menu row carries the invocation dot.\n * Exported for unit tests; production wiring goes through setupSkillSlashDots.\n * @param source - the registered `/skill` source.\n * @param api - hub browser API for the modelInvocable lookup.\n * @param scope - hub settings scope for the dot colors.\n * @returns a disposer restoring the original candidates.\n */\n/**\n * DOM 兜底:在 alpha.2 新版 MenuView(icon 仅枚举)下通过直接操作\n * 已渲染的 `[role=\"option\"]` 列表注入彩色点,绕过 `icon` 限制。\n * 旧版仍走 `icon` 注入,此处仅为新版。\n */\nfunction injectDotsViaDOM(modelByName: Map<string, boolean>, modelColor: string, userColor: string): void {\n if (typeof document === 'undefined' || typeof requestAnimationFrame === 'undefined') return\n const run = (): void => {\n const options = document.querySelectorAll('[role=\"option\"]')\n for (const opt of options) {\n if (opt.querySelector('[data-skill-dot]') !== null) continue\n const nameEl = opt.querySelector('[class*=\"itemName\"]') as HTMLElement | null\n if (nameEl === null) continue\n const name = (nameEl.textContent ?? '').trim()\n if (name.length === 0) continue\n const color = (modelByName.get(name) ?? true) ? modelColor : userColor\n // 复刻旧版 icon 槽:16×16 容器居中 6px 点,与升级前 `dotIcon` 在 `itemIcon` 内的效果一致\n const wrapper = document.createElement('span')\n wrapper.setAttribute('data-skill-dot', '')\n wrapper.setAttribute('aria-hidden', 'true')\n wrapper.style.width = '16px'\n wrapper.style.height = '16px'\n wrapper.style.display = 'inline-flex'\n wrapper.style.justifyContent = 'center'\n wrapper.style.alignItems = 'center'\n wrapper.style.flex = 'none'\n const dot = document.createElement('span')\n dot.style.display = 'inline-block'\n dot.style.width = '6px'\n dot.style.height = '6px'\n dot.style.borderRadius = '3px'\n dot.style.background = color\n dot.style.flex = 'none'\n wrapper.appendChild(dot)\n // 新版无 icon 槽,直接插在名称前,与旧版 `itemIcon` 位置一致\n nameEl.parentElement?.insertBefore(wrapper, nameEl)\n }\n }\n requestAnimationFrame(() => setTimeout(run, 0))\n}\n\nexport function wrapSkillSource(source: InputTriggerSource, api: SkillHubApi, scope: SettingsScope<HubSettingsValue>): () => void {\n const original = source.candidates\n source.candidates = async (session, req) => {\n const items = await original(session, req)\n if (req.signal.aborted) return items\n // Dual-compat: 0.1.2-alpha.2 的 MenuView 将 icon 收窄为 'file'|'folder'|'session'\n // 并通过 ReferenceIcon 渲染,旧版的自定义 ReactElement 点已无法展示。\n // 以 `drilled` 是否存在探测新版(alpha.2 必有,rc 无)。\n const isNewHost = req !== null && typeof req === 'object' && 'drilled' in (req as unknown as Record<string, unknown>)\n const modelByName = await modelInvocableMap(api)\n if (req.signal.aborted) return items\n const snapshot = scope.getSnapshot()\n const modelColor = snapshot.value?.dotModelColor ?? DEFAULT_DOT_MODEL_COLOR\n const userColor = snapshot.value?.dotUserColor ?? DEFAULT_DOT_USER_COLOR\n if (isNewHost) {\n // 新版:不通过 icon(枚举限制),改为 DOM 注入\n injectDotsViaDOM(modelByName, modelColor, userColor)\n return items\n }\n // 旧版:保持原有 icon 注入\n return items.map((item) => ({\n ...item,\n icon: dotIcon((modelByName.get(item.name) ?? true) ? modelColor : userColor),\n }))\n }\n return () => {\n source.candidates = original\n }\n}\n\n/**\n * Mount the slash-menu dots on the registered `/skill` source. Idempotent and\n * defensive: if the core source isn't registered yet (or the registry shape\n * changes), it retries briefly and then gives up silently — the chat keeps\n * working, it simply shows no dots. The returned disposer restores the\n * original candidates and clears the model cache.\n * @param ctx - the client root context (inputTriggers + events).\n * @param api - hub browser API.\n * @param scope - hub settings scope for dot colors.\n * @returns a cleanup function for `ctx.effect`.\n */\nexport function setupSkillSlashDots(\n ctx: ClientContext,\n api: SkillHubApi,\n scope: SettingsScope<HubSettingsValue>,\n): () => void {\n const inputTriggers = ctx.get('inputTriggers')\n if (inputTriggers === undefined) return () => {}\n\n let disposed = false\n let restore: (() => void) | undefined\n let attempts = 0\n\n // The core ui-skill source registers early in the bundle, but not strictly\n // before this apply runs — poll briefly so order never matters.\n const attempt = (): void => {\n if (disposed) return\n const source = findSkillSource(inputTriggers)\n if (source === undefined) {\n if (attempts < 10) {\n attempts += 1\n setTimeout(attempt, 100)\n }\n return\n }\n restore = wrapSkillSource(source, api, scope)\n }\n attempt()\n\n const clearCache = (): void => {\n resetModelCache()\n }\n // ctx.on returns the listener disposer; cordis has no ctx.off.\n const offReset = ctx.on('connection/reset', clearCache)\n\n return () => {\n disposed = true\n offReset()\n restore?.()\n restore = undefined\n }\n}\n","/**\n * Vendored UI icons for dsh-skill-hub.\n *\n * These were originally imported from `@deepseek-ai/dsh-client-ui-primitives`.\n * That package is still published for the rc.7/rc.2 SDK families, but newer dsh\n * web builds no longer expose it as a standalone plugin module — they keep a\n * static compatibility module instead. Vendoring the few tiny outline icons the\n * hub uses makes the browser half self-contained and equally compatible with\n * older and newer dsh hosts.\n *\n * SVG paths are copied verbatim from dsh-client-ui-primitives (MIT licensed)\n * so the visuals remain pixel-identical to the dsh icon family.\n */\n\nimport type { JSX } from 'react'\n\n/** Props understood by the dsh icon family: size + optional className. */\nexport interface IconProps {\n size?: number\n className?: string\n}\n\n/** ic_ds_chevron_down_outline_14 */\nexport function IconChevronDownOutline14({ size = 14, className }: IconProps): JSX.Element {\n return (\n <svg width={size} height={size} className={className} viewBox='0 0 14 14' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z'\n fill='currentColor'\n />\n </svg>\n )\n}\n\n/** ic_ds_trash_outline_16 */\nexport function IconTrashOutline16({ size = 16, className }: IconProps): JSX.Element {\n return (\n <svg width={size} height={size} className={className} viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M14.4782 4.84067L14.2138 10.1152C14.1102 12.1872 14.067 13.0115 13.3866 13.9607C13.1044 14.3546 12.7498 14.6912 12.3424 14.9535C11.8239 15.2872 11.2415 15.4316 10.5585 15.4998C9.88727 15.5668 9.04946 15.5656 7.99998 15.5656C6.95051 15.5656 6.1127 15.5668 5.44142 15.4998C4.75851 15.4316 4.17602 15.2872 3.65753 14.9535C3.25012 14.6912 2.89559 14.3546 2.61332 13.9607C1.93296 13.0115 1.88979 12.1872 1.78619 10.1152L1.52179 4.84067L2.89006 4.77277L3.15343 10.0463C3.26221 12.2218 3.32452 12.6015 3.72646 13.1624C3.90825 13.4161 4.13686 13.6334 4.39927 13.8023C4.66204 13.9714 5.00263 14.0792 5.57825 14.1367C6.16562 14.1953 6.92298 14.1963 7.99998 14.1963C9.07699 14.1963 9.83434 14.1953 10.4217 14.1367C10.9973 14.0792 11.3379 13.9714 11.6007 13.8023C11.8631 13.6334 12.0917 13.4161 12.2735 13.1624C12.6755 12.6015 12.7378 12.2218 12.8465 10.0463L13.1099 4.77277L14.4782 4.84067ZM5.43011 6.22849H6.7994V11.3909H5.43011V6.22849ZM9.20056 6.22849H10.5699V11.3909H9.20056V6.22849ZM8.53597 0.434431C9.17976 0.434431 9.6522 0.426926 10.0966 0.571258C10.2357 0.616451 10.3717 0.672554 10.502 0.738948C10.9182 0.951107 11.2464 1.29099 11.7015 1.74612L12.4978 2.54136H15.3742V3.91169H0.625732V2.54136H3.50218L4.29845 1.74612C4.75358 1.29099 5.08174 0.951107 5.49801 0.738948C5.62831 0.672554 5.76425 0.616451 5.90334 0.571258C6.34776 0.426926 6.82021 0.434431 7.46399 0.434431H8.53597ZM7.46399 1.80476C6.73208 1.80476 6.51641 1.81187 6.32617 1.87369C6.25545 1.89667 6.18668 1.92533 6.12041 1.95907C5.96398 2.03878 5.82348 2.16253 5.44142 2.54136H10.5585C10.1765 2.16253 10.036 2.03878 9.87955 1.95907C9.81329 1.92533 9.74452 1.89667 9.6738 1.87369C9.48356 1.81187 9.26789 1.80476 8.53597 1.80476H7.46399Z'\n fill='currentColor'\n />\n </svg>\n )\n}\n\n/** ic_ds_skill_outline_16 */\nexport function IconSkillOutline16({ size = 16, className }: IconProps): JSX.Element {\n return (\n <svg width={size} height={size} className={className} viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'>\n <path\n d='M12.5113 15.4067C12.4395 15.6249 12.1308 15.6249 12.059 15.4067L11.643 14.1416C11.454 13.567 11.0033 13.1164 10.4288 12.9274L9.16369 12.5113C8.94544 12.4395 8.94544 12.1308 9.16369 12.059L10.4288 11.643C11.0033 11.454 11.454 11.0033 11.643 10.4288L12.059 9.16369C12.1308 8.94544 12.4395 8.94544 12.5113 9.16369L12.9274 10.4288C13.1164 11.0033 13.567 11.454 14.1416 11.643L15.4067 12.059C15.6249 12.1308 15.6249 12.4395 15.4067 12.5113L14.1416 12.9274C13.567 13.1164 13.1164 13.567 12.9274 14.1416L12.5113 15.4067Z'\n fill='currentColor'\n />\n <path\n d='M9.02246 0.546878C9.9822 0.546878 10.7564 0.545403 11.374 0.612307C12.0042 0.680586 12.5515 0.826244 13.0273 1.17188C13.3052 1.37376 13.5501 1.61868 13.752 1.89649C14.0975 2.37225 14.2432 2.91984 14.3115 3.54981C14.3784 4.16727 14.377 4.94206 14.377 5.90137V8.51367C13.9611 8.29533 13.5071 8.13985 13.0273 8.06055V5.90137C13.0273 4.9121 13.0259 4.22322 12.9688 3.69532C12.9129 3.18044 12.8098 2.89782 12.6592 2.69043C12.5406 2.52724 12.3966 2.38326 12.2334 2.26465C12.026 2.11404 11.7437 2.0109 11.2285 1.95508C10.7005 1.89789 10.0122 1.89649 9.02246 1.89649H6.55371C5.56395 1.89649 4.87569 1.89787 4.34766 1.95508C3.83242 2.01092 3.55022 2.11398 3.34278 2.26465C3.17953 2.38329 3.03564 2.52719 2.91699 2.69043C2.76642 2.89782 2.66325 3.18042 2.60742 3.69532C2.55027 4.22322 2.54883 4.9121 2.54883 5.90137V10.0986C2.54883 11.0878 2.55031 11.7768 2.60742 12.3047C2.66326 12.8196 2.76642 13.1032 2.91699 13.3105C3.03558 13.4736 3.17966 13.6178 3.34278 13.7363C3.5502 13.8869 3.83265 13.9901 4.34766 14.0459C4.87568 14.1031 5.56398 14.1035 6.55371 14.1035H8.08399C8.27443 14.6025 8.55077 15.0585 8.89551 15.4541H6.55371C5.59402 15.4541 4.81976 15.4546 4.20215 15.3877C3.57204 15.3194 3.02468 15.1738 2.54883 14.8281C2.27111 14.6263 2.02606 14.3813 1.82422 14.1035C1.47883 13.6278 1.33293 13.08 1.26465 12.4502C1.19783 11.8327 1.19922 11.0579 1.19922 10.0986V5.90137C1.19922 4.94206 1.1978 4.16727 1.26465 3.54981C1.33295 2.91984 1.47867 2.37225 1.82422 1.89649C2.02613 1.61864 2.27098 1.37379 2.54883 1.17188C3.02472 0.826181 3.57197 0.6806 4.20215 0.612307C4.81976 0.545393 5.594 0.546877 6.55371 0.546878H9.02246ZM9.19629 9.14649H4.5459V7.84571H9.19629V9.14649ZM11.0303 6.10645H4.5459V4.80567H11.0303V6.10645Z'\n fill='currentColor'\n />\n </svg>\n )\n}","/**\n * Shared chrome for the plugin settings card, aligned with the official\n * dsh-client-ui-settings-plugins PluginCard design language: the same tokens,\n * disclosure header, field rhythm, and copy. Renders nothing while the\n * namespace is unavailable — a deployment that does not compose the owning\n * plugin should show no trace of it.\n */\n\nimport { useState, type ReactElement } from 'react'\nimport { IconChevronDownOutline14 } from './icons.tsx'\nimport type { HubKey } from './locales.ts'\nimport type { CardShell } from './settings-form.ts'\nimport css from './settings-card.module.css'\n\n/** Card-level chrome props. */\nexport interface PluginSettingsCardProps {\n /** Locale translator for the owning plugin's namespace (its own key domain). */\n t: (key: HubKey) => string\n /** Locale key of the card title. */\n titleKey: HubKey\n /** Locale key of the card description. */\n descriptionKey: HubKey\n /** 插件自身版本(可选):显示在标题旁的小徽标;缺省不渲染。 */\n version?: string\n /** The form shell state. */\n state: CardShell\n onSave: () => void\n onDiscard: () => void\n children?: ReactElement | ReactElement[]\n}\n\n/**\n * Render one plugin settings card.\n * @param props - the plugin's copy keys, its form state, and its controls.\n * @returns the card, or nothing while the namespace is still loading.\n */\nexport function PluginSettingsCard(props: PluginSettingsCardProps): ReactElement | null {\n const [open, setOpen] = useState(false)\n const { state } = props\n if (!state.available) return null\n const title = props.t(props.titleKey)\n const blocked = !state.dirty || state.invalid || state.saving\n\n const header = (\n <button\n type='button'\n className={css.header}\n aria-expanded={open}\n aria-label={props.t(open ? 'settings.collapse' : 'settings.expand') + ': ' + title}\n onClick={() => { setOpen(!open) }}\n >\n <span className={css.headText}>\n <span className={css.name}>{title}{props.version !== undefined ? <span className={css.versionTag}>v{props.version}</span> : null}</span>\n <span className={css.description}>{props.t(props.descriptionKey)}</span>\n </span>\n {state.dirty ? <span className={css.pending}>{props.t('settings.unsaved')}</span> : null}\n <IconChevronDownOutline14 className={open ? css.chevronOpen : css.chevron} />\n </button>\n )\n\n if (!state.exposed) {\n return (\n <li className={css.card + (open ? ' ' + css.cardOpen : '')}>\n {header}\n {open ? <div className={css.body}><p className={css.notExposed} role='status'>{props.t('settings.notExposed')}</p></div> : null}\n </li>\n )\n }\n\n return (\n <li className={css.card + (open ? ' ' + css.cardOpen : '')}>\n {header}\n {open ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role='status'>{props.t('settings.readOnly')}</p> : null}\n {props.children}\n <div className={css.footer}>\n {state.failed ? <p className={css.failed} role='status'>{props.t('settings.saveFailed')}</p> : null}\n <button type='button' className={css.discard} disabled={!state.dirty || state.saving} onClick={props.onDiscard}>\n {props.t('settings.discard')}\n </button>\n <button type='button' className={css.save} disabled={blocked} onClick={props.onSave}>\n {props.t(!state.saving ? 'settings.save' : 'settings.saving')}\n </button>\n </div>\n </div>\n ) : null}\n </li>\n )\n}\n\n/** One staged boolean field: 继承 / 开 / 关. */\nexport interface BooleanFieldProps {\n id: string\n label: string\n hint: string\n inheritLabel: string\n onLabel: string\n offLabel: string\n overriddenLabel: string\n resetLabel: string\n disabled: boolean\n text: string\n overridden: boolean\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function BooleanField(props: BooleanFieldProps): ReactElement {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <select id={props.id} className={css.input} value={props.text} disabled={props.disabled} onChange={(event) => { props.onEdit(event.target.value) }}>\n <option value=''>{props.inheritLabel}</option>\n <option value='true'>{props.onLabel}</option>\n <option value='false'>{props.offLabel}</option>\n </select>\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n\n\n/**\n * A compact sliding switch for the card's master enable/disable control.\n * An empty text value means the field inherits its default; the switch still\n * reflects the effective default and becomes an explicit override on click.\n */\nexport interface SwitchFieldProps {\n label: string\n hint: string\n disabled: boolean\n text: string\n overridden: boolean\n overriddenLabel: string\n resetLabel: string\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function SwitchField(props: SwitchFieldProps): ReactElement {\n const checked = props.text !== 'false'\n return (\n <div className={css.field}>\n <div className={css.switchRow}>\n <div className={css.switchText}>\n <div className={css.head}>\n <span className={css.label}>{props.label}</span>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <p className={css.hint}>{props.hint}</p>\n </div>\n <button\n type='button'\n className={checked ? css.switchOn : css.switch}\n role='switch'\n aria-checked={checked}\n aria-label={props.label}\n disabled={props.disabled}\n onClick={() => { props.onEdit(String(!checked)) }}\n >\n <span className={css.switchThumb} />\n </button>\n </div>\n </div>\n )\n}\n\n/** One staged color field: a native color picker plus the hex draft text. */\nexport interface ColorFieldProps {\n id: string\n label: string\n hint: string\n inheritLabel: string\n overriddenLabel: string\n resetLabel: string\n disabled: boolean\n /** Effective hex (#rrggbb) when overridden; empty string means inherit. */\n text: string\n /** The default color the picker shows while inheriting (per-field). */\n defaultColor: string\n overridden: boolean\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function ColorField(props: ColorFieldProps): ReactElement {\n const value = /^#[0-9a-f]{6}$/i.test(props.text) ? props.text : props.defaultColor\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <div className={css.colorRow}>\n <input\n id={props.id}\n type='color'\n className={css.colorInput}\n value={value}\n disabled={props.disabled}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <input\n type='text'\n className={css.input + ' ' + css.colorText}\n value={props.text}\n disabled={props.disabled}\n placeholder={props.inheritLabel}\n onChange={(event) => { props.onEdit(event.target.value.trim()) }}\n />\n </div>\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n\n/** One staged numeric field: a numeric draft text input with inherit/reset semantics. */\nexport interface NumberFieldProps {\n id: string\n label: string\n hint: string\n /** Placeholder shown while the field inherits its default. */\n inheritLabel: string\n overriddenLabel: string\n resetLabel: string\n disabled: boolean\n /** Effective number when overridden; empty string means inherit. */\n text: string\n overridden: boolean\n invalid?: boolean\n onEdit: (text: string) => void\n onReset: () => void\n}\n\nexport function NumberField(props: NumberFieldProps): ReactElement {\n return (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor={props.id}>{props.label}</label>\n {props.overridden ? (\n <span className={css.badges}>\n <span className={css.badge}>{props.overriddenLabel}</span>\n <button type='button' className={css.reset} disabled={props.disabled} onClick={props.onReset}>\n {props.resetLabel}\n </button>\n </span>\n ) : null}\n </div>\n <input\n id={props.id}\n type='text'\n inputMode='numeric'\n className={css.input}\n value={props.text}\n disabled={props.disabled}\n placeholder={props.inheritLabel}\n aria-invalid={props.invalid === true}\n onChange={(event) => { props.onEdit(event.target.value) }}\n />\n <p className={css.hint}>{props.hint}</p>\n </div>\n )\n}\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const destroy = () => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") {\n console.warn(\n \"[DEPRECATED] The `destroy` method will be unsupported in a future version. Instead use unsubscribe function returned by subscribe. Everything will be garbage-collected if store is garbage-collected.\"\n );\n }\n listeners.clear();\n };\n const api = { setState, getState, subscribe, destroy };\n state = createState(setState, getState, api);\n return api;\n};\nconst createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;\nvar vanilla = (createState) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") {\n console.warn(\n \"[DEPRECATED] Default export is deprecated. Instead use import { createStore } from 'zustand/vanilla'.\"\n );\n }\n return createStore(createState);\n};\n\nexport { createStore, vanilla as default };\n","const reduxImpl = (reducer, initial) => (set, _get, api) => {\n api.dispatch = (action) => {\n set((state) => reducer(state, action), false, action);\n return action;\n };\n api.dispatchFromDevtools = true;\n return { dispatch: (...a) => api.dispatch(...a), ...initial };\n};\nconst redux = reduxImpl;\n\nconst trackedConnections = /* @__PURE__ */ new Map();\nconst getTrackedConnectionState = (name) => {\n const api = trackedConnections.get(name);\n if (!api)\n return {};\n return Object.fromEntries(\n Object.entries(api.stores).map(([key, api2]) => [key, api2.getState()])\n );\n};\nconst extractConnectionInformation = (store, extensionConnector, options) => {\n if (store === void 0) {\n return {\n type: \"untracked\",\n connection: extensionConnector.connect(options)\n };\n }\n const existingConnection = trackedConnections.get(options.name);\n if (existingConnection) {\n return { type: \"tracked\", store, ...existingConnection };\n }\n const newConnection = {\n connection: extensionConnector.connect(options),\n stores: {}\n };\n trackedConnections.set(options.name, newConnection);\n return { type: \"tracked\", store, ...newConnection };\n};\nconst devtoolsImpl = (fn, devtoolsOptions = {}) => (set, get, api) => {\n const { enabled, anonymousActionType, store, ...options } = devtoolsOptions;\n let extensionConnector;\n try {\n extensionConnector = (enabled != null ? enabled : (import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") && window.__REDUX_DEVTOOLS_EXTENSION__;\n } catch (e) {\n }\n if (!extensionConnector) {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && enabled) {\n console.warn(\n \"[zustand devtools middleware] Please install/enable Redux devtools extension\"\n );\n }\n return fn(set, get, api);\n }\n const { connection, ...connectionInformation } = extractConnectionInformation(store, extensionConnector, options);\n let isRecording = true;\n api.setState = (state, replace, nameOrAction) => {\n const r = set(state, replace);\n if (!isRecording)\n return r;\n const action = nameOrAction === void 0 ? { type: anonymousActionType || \"anonymous\" } : typeof nameOrAction === \"string\" ? { type: nameOrAction } : nameOrAction;\n if (store === void 0) {\n connection == null ? void 0 : connection.send(action, get());\n return r;\n }\n connection == null ? void 0 : connection.send(\n {\n ...action,\n type: `${store}/${action.type}`\n },\n {\n ...getTrackedConnectionState(options.name),\n [store]: api.getState()\n }\n );\n return r;\n };\n const setStateFromDevtools = (...a) => {\n const originalIsRecording = isRecording;\n isRecording = false;\n set(...a);\n isRecording = originalIsRecording;\n };\n const initialState = fn(api.setState, get, api);\n if (connectionInformation.type === \"untracked\") {\n connection == null ? void 0 : connection.init(initialState);\n } else {\n connectionInformation.stores[connectionInformation.store] = api;\n connection == null ? void 0 : connection.init(\n Object.fromEntries(\n Object.entries(connectionInformation.stores).map(([key, store2]) => [\n key,\n key === connectionInformation.store ? initialState : store2.getState()\n ])\n )\n );\n }\n if (api.dispatchFromDevtools && typeof api.dispatch === \"function\") {\n let didWarnAboutReservedActionType = false;\n const originalDispatch = api.dispatch;\n api.dispatch = (...a) => {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\" && a[0].type === \"__setState\" && !didWarnAboutReservedActionType) {\n console.warn(\n '[zustand devtools middleware] \"__setState\" action type is reserved to set state from the devtools. Avoid using it.'\n );\n didWarnAboutReservedActionType = true;\n }\n originalDispatch(...a);\n };\n }\n connection.subscribe((message) => {\n var _a;\n switch (message.type) {\n case \"ACTION\":\n if (typeof message.payload !== \"string\") {\n console.error(\n \"[zustand devtools middleware] Unsupported action format\"\n );\n return;\n }\n return parseJsonThen(\n message.payload,\n (action) => {\n if (action.type === \"__setState\") {\n if (store === void 0) {\n setStateFromDevtools(action.state);\n return;\n }\n if (Object.keys(action.state).length !== 1) {\n console.error(\n `\n [zustand devtools middleware] Unsupported __setState action format. \n When using 'store' option in devtools(), the 'state' should have only one key, which is a value of 'store' that was passed in devtools(),\n and value of this only key should be a state object. Example: { \"type\": \"__setState\", \"state\": { \"abc123Store\": { \"foo\": \"bar\" } } }\n `\n );\n }\n const stateFromDevtools = action.state[store];\n if (stateFromDevtools === void 0 || stateFromDevtools === null) {\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(stateFromDevtools)) {\n setStateFromDevtools(stateFromDevtools);\n }\n return;\n }\n if (!api.dispatchFromDevtools)\n return;\n if (typeof api.dispatch !== \"function\")\n return;\n api.dispatch(action);\n }\n );\n case \"DISPATCH\":\n switch (message.payload.type) {\n case \"RESET\":\n setStateFromDevtools(initialState);\n if (store === void 0) {\n return connection == null ? void 0 : connection.init(api.getState());\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"COMMIT\":\n if (store === void 0) {\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n return connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n case \"ROLLBACK\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n connection == null ? void 0 : connection.init(api.getState());\n return;\n }\n setStateFromDevtools(state[store]);\n connection == null ? void 0 : connection.init(getTrackedConnectionState(options.name));\n });\n case \"JUMP_TO_STATE\":\n case \"JUMP_TO_ACTION\":\n return parseJsonThen(message.state, (state) => {\n if (store === void 0) {\n setStateFromDevtools(state);\n return;\n }\n if (JSON.stringify(api.getState()) !== JSON.stringify(state[store])) {\n setStateFromDevtools(state[store]);\n }\n });\n case \"IMPORT_STATE\": {\n const { nextLiftedState } = message.payload;\n const lastComputedState = (_a = nextLiftedState.computedStates.slice(-1)[0]) == null ? void 0 : _a.state;\n if (!lastComputedState)\n return;\n if (store === void 0) {\n setStateFromDevtools(lastComputedState);\n } else {\n setStateFromDevtools(lastComputedState[store]);\n }\n connection == null ? void 0 : connection.send(\n null,\n // FIXME no-any\n nextLiftedState\n );\n return;\n }\n case \"PAUSE_RECORDING\":\n return isRecording = !isRecording;\n }\n return;\n }\n });\n return initialState;\n};\nconst devtools = devtoolsImpl;\nconst parseJsonThen = (stringified, f) => {\n let parsed;\n try {\n parsed = JSON.parse(stringified);\n } catch (e) {\n console.error(\n \"[zustand devtools middleware] Could not parse the received json\",\n e\n );\n }\n if (parsed !== void 0)\n f(parsed);\n};\n\nconst subscribeWithSelectorImpl = (fn) => (set, get, api) => {\n const origSubscribe = api.subscribe;\n api.subscribe = (selector, optListener, options) => {\n let listener = selector;\n if (optListener) {\n const equalityFn = (options == null ? void 0 : options.equalityFn) || Object.is;\n let currentSlice = selector(api.getState());\n listener = (state) => {\n const nextSlice = selector(state);\n if (!equalityFn(currentSlice, nextSlice)) {\n const previousSlice = currentSlice;\n optListener(currentSlice = nextSlice, previousSlice);\n }\n };\n if (options == null ? void 0 : options.fireImmediately) {\n optListener(currentSlice, currentSlice);\n }\n }\n return origSubscribe(listener);\n };\n const initialState = fn(set, get, api);\n return initialState;\n};\nconst subscribeWithSelector = subscribeWithSelectorImpl;\n\nconst combine = (initialState, create) => (...a) => Object.assign({}, initialState, create(...a));\n\nfunction createJSONStorage(getStorage, options) {\n let storage;\n try {\n storage = getStorage();\n } catch (e) {\n return;\n }\n const persistStorage = {\n getItem: (name) => {\n var _a;\n const parse = (str2) => {\n if (str2 === null) {\n return null;\n }\n return JSON.parse(str2, options == null ? void 0 : options.reviver);\n };\n const str = (_a = storage.getItem(name)) != null ? _a : null;\n if (str instanceof Promise) {\n return str.then(parse);\n }\n return parse(str);\n },\n setItem: (name, newValue) => storage.setItem(\n name,\n JSON.stringify(newValue, options == null ? void 0 : options.replacer)\n ),\n removeItem: (name) => storage.removeItem(name)\n };\n return persistStorage;\n}\nconst toThenable = (fn) => (input) => {\n try {\n const result = fn(input);\n if (result instanceof Promise) {\n return result;\n }\n return {\n then(onFulfilled) {\n return toThenable(onFulfilled)(result);\n },\n catch(_onRejected) {\n return this;\n }\n };\n } catch (e) {\n return {\n then(_onFulfilled) {\n return this;\n },\n catch(onRejected) {\n return toThenable(onRejected)(e);\n }\n };\n }\n};\nconst oldImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n getStorage: () => localStorage,\n serialize: JSON.stringify,\n deserialize: JSON.parse,\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage;\n try {\n storage = options.getStorage();\n } catch (e) {\n }\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const thenableSerialize = toThenable(options.serialize);\n const setItem = () => {\n const state = options.partialize({ ...get() });\n let errorInSync;\n const thenable = thenableSerialize({ state, version: options.version }).then(\n (serializedValue) => storage.setItem(options.name, serializedValue)\n ).catch((e) => {\n errorInSync = e;\n });\n if (errorInSync) {\n throw errorInSync;\n }\n return thenable;\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n void setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n void setItem();\n },\n get,\n api\n );\n let stateFromStorage;\n const hydrate = () => {\n var _a;\n if (!storage)\n return;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => cb(get()));\n const postRehydrationCallback = ((_a = options.onRehydrateStorage) == null ? void 0 : _a.call(options, get())) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((storageValue) => {\n if (storageValue) {\n return options.deserialize(storageValue);\n }\n }).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n return options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return deserializedStorageValue.state;\n }\n }\n }).then((migratedState) => {\n var _a2;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n return setItem();\n }).then(() => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.getStorage) {\n storage = newOptions.getStorage();\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n hydrate();\n return stateFromStorage || configResult;\n};\nconst newImpl = (config, baseOptions) => (set, get, api) => {\n let options = {\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => state,\n version: 0,\n merge: (persistedState, currentState) => ({\n ...currentState,\n ...persistedState\n }),\n ...baseOptions\n };\n let hasHydrated = false;\n const hydrationListeners = /* @__PURE__ */ new Set();\n const finishHydrationListeners = /* @__PURE__ */ new Set();\n let storage = options.storage;\n if (!storage) {\n return config(\n (...args) => {\n console.warn(\n `[zustand persist middleware] Unable to update item '${options.name}', the given storage is currently unavailable.`\n );\n set(...args);\n },\n get,\n api\n );\n }\n const setItem = () => {\n const state = options.partialize({ ...get() });\n return storage.setItem(options.name, {\n state,\n version: options.version\n });\n };\n const savedSetState = api.setState;\n api.setState = (state, replace) => {\n savedSetState(state, replace);\n void setItem();\n };\n const configResult = config(\n (...args) => {\n set(...args);\n void setItem();\n },\n get,\n api\n );\n let stateFromStorage;\n const hydrate = () => {\n var _a, _b;\n if (!storage)\n return;\n hasHydrated = false;\n hydrationListeners.forEach((cb) => {\n var _a2;\n return cb((_a2 = get()) != null ? _a2 : configResult);\n });\n const postRehydrationCallback = ((_b = options.onRehydrateStorage) == null ? void 0 : _b.call(options, (_a = get()) != null ? _a : configResult)) || void 0;\n return toThenable(storage.getItem.bind(storage))(options.name).then((deserializedStorageValue) => {\n if (deserializedStorageValue) {\n if (typeof deserializedStorageValue.version === \"number\" && deserializedStorageValue.version !== options.version) {\n if (options.migrate) {\n return options.migrate(\n deserializedStorageValue.state,\n deserializedStorageValue.version\n );\n }\n console.error(\n `State loaded from storage couldn't be migrated since no migrate function was provided`\n );\n } else {\n return deserializedStorageValue.state;\n }\n }\n }).then((migratedState) => {\n var _a2;\n stateFromStorage = options.merge(\n migratedState,\n (_a2 = get()) != null ? _a2 : configResult\n );\n set(stateFromStorage, true);\n return setItem();\n }).then(() => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(stateFromStorage, void 0);\n stateFromStorage = get();\n hasHydrated = true;\n finishHydrationListeners.forEach((cb) => cb(stateFromStorage));\n }).catch((e) => {\n postRehydrationCallback == null ? void 0 : postRehydrationCallback(void 0, e);\n });\n };\n api.persist = {\n setOptions: (newOptions) => {\n options = {\n ...options,\n ...newOptions\n };\n if (newOptions.storage) {\n storage = newOptions.storage;\n }\n },\n clearStorage: () => {\n storage == null ? void 0 : storage.removeItem(options.name);\n },\n getOptions: () => options,\n rehydrate: () => hydrate(),\n hasHydrated: () => hasHydrated,\n onHydrate: (cb) => {\n hydrationListeners.add(cb);\n return () => {\n hydrationListeners.delete(cb);\n };\n },\n onFinishHydration: (cb) => {\n finishHydrationListeners.add(cb);\n return () => {\n finishHydrationListeners.delete(cb);\n };\n }\n };\n if (!options.skipHydration) {\n hydrate();\n }\n return stateFromStorage || configResult;\n};\nconst persistImpl = (config, baseOptions) => {\n if (\"getStorage\" in baseOptions || \"serialize\" in baseOptions || \"deserialize\" in baseOptions) {\n if ((import.meta.env ? import.meta.env.MODE : void 0) !== \"production\") {\n console.warn(\n \"[DEPRECATED] `getStorage`, `serialize` and `deserialize` options are deprecated. Use `storage` option instead.\"\n );\n }\n return oldImpl(config, baseOptions);\n }\n return newImpl(config, baseOptions);\n};\nconst persist = persistImpl;\n\nexport { combine, createJSONStorage, devtools, persist, redux, subscribeWithSelector };\n","// src/utils/env.ts\nvar NOTHING = Symbol.for(\"immer-nothing\");\nvar DRAFTABLE = Symbol.for(\"immer-draftable\");\nvar DRAFT_STATE = Symbol.for(\"immer-state\");\n\n// src/utils/errors.ts\nvar errors = process.env.NODE_ENV !== \"production\" ? [\n // All error codes, starting by 0:\n function(plugin) {\n return `The plugin for '${plugin}' has not been loaded into Immer. To enable the plugin, import and call \\`enable${plugin}()\\` when initializing your application.`;\n },\n function(thing) {\n return `produce can only be called on things that are draftable: plain objects, arrays, Map, Set or classes that are marked with '[immerable]: true'. Got '${thing}'`;\n },\n \"This object has been frozen and should not be mutated\",\n function(data) {\n return \"Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? \" + data;\n },\n \"An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.\",\n \"Immer forbids circular references\",\n \"The first or second argument to `produce` must be a function\",\n \"The third argument to `produce` must be a function or undefined\",\n \"First argument to `createDraft` must be a plain object, an array, or an immerable object\",\n \"First argument to `finishDraft` must be a draft returned by `createDraft`\",\n function(thing) {\n return `'current' expects a draft, got: ${thing}`;\n },\n \"Object.defineProperty() cannot be used on an Immer draft\",\n \"Object.setPrototypeOf() cannot be used on an Immer draft\",\n \"Immer only supports deleting array indices\",\n \"Immer only supports setting array indices and the 'length' property\",\n function(thing) {\n return `'original' expects a draft, got: ${thing}`;\n }\n // Note: if more errors are added, the errorOffset in Patches.ts should be increased\n // See Patches.ts for additional errors\n] : [];\nfunction die(error, ...args) {\n if (process.env.NODE_ENV !== \"production\") {\n const e = errors[error];\n const msg = typeof e === \"function\" ? e.apply(null, args) : e;\n throw new Error(`[Immer] ${msg}`);\n }\n throw new Error(\n `[Immer] minified error nr: ${error}. Full error at: https://bit.ly/3cXEKWf`\n );\n}\n\n// src/utils/common.ts\nvar getPrototypeOf = Object.getPrototypeOf;\nfunction isDraft(value) {\n return !!value && !!value[DRAFT_STATE];\n}\nfunction isDraftable(value) {\n if (!value)\n return false;\n return isPlainObject(value) || Array.isArray(value) || !!value[DRAFTABLE] || !!value.constructor?.[DRAFTABLE] || isMap(value) || isSet(value);\n}\nvar objectCtorString = Object.prototype.constructor.toString();\nvar cachedCtorStrings = /* @__PURE__ */ new WeakMap();\nfunction isPlainObject(value) {\n if (!value || typeof value !== \"object\")\n return false;\n const proto = Object.getPrototypeOf(value);\n if (proto === null || proto === Object.prototype)\n return true;\n const Ctor = Object.hasOwnProperty.call(proto, \"constructor\") && proto.constructor;\n if (Ctor === Object)\n return true;\n if (typeof Ctor !== \"function\")\n return false;\n let ctorString = cachedCtorStrings.get(Ctor);\n if (ctorString === void 0) {\n ctorString = Function.toString.call(Ctor);\n cachedCtorStrings.set(Ctor, ctorString);\n }\n return ctorString === objectCtorString;\n}\nfunction original(value) {\n if (!isDraft(value))\n die(15, value);\n return value[DRAFT_STATE].base_;\n}\nfunction each(obj, iter, strict = true) {\n if (getArchtype(obj) === 0 /* Object */) {\n const keys = strict ? Reflect.ownKeys(obj) : Object.keys(obj);\n keys.forEach((key) => {\n iter(key, obj[key], obj);\n });\n } else {\n obj.forEach((entry, index) => iter(index, entry, obj));\n }\n}\nfunction getArchtype(thing) {\n const state = thing[DRAFT_STATE];\n return state ? state.type_ : Array.isArray(thing) ? 1 /* Array */ : isMap(thing) ? 2 /* Map */ : isSet(thing) ? 3 /* Set */ : 0 /* Object */;\n}\nfunction has(thing, prop) {\n return getArchtype(thing) === 2 /* Map */ ? thing.has(prop) : Object.prototype.hasOwnProperty.call(thing, prop);\n}\nfunction get(thing, prop) {\n return getArchtype(thing) === 2 /* Map */ ? thing.get(prop) : thing[prop];\n}\nfunction set(thing, propOrOldValue, value) {\n const t = getArchtype(thing);\n if (t === 2 /* Map */)\n thing.set(propOrOldValue, value);\n else if (t === 3 /* Set */) {\n thing.add(value);\n } else\n thing[propOrOldValue] = value;\n}\nfunction is(x, y) {\n if (x === y) {\n return x !== 0 || 1 / x === 1 / y;\n } else {\n return x !== x && y !== y;\n }\n}\nfunction isMap(target) {\n return target instanceof Map;\n}\nfunction isSet(target) {\n return target instanceof Set;\n}\nfunction latest(state) {\n return state.copy_ || state.base_;\n}\nfunction shallowCopy(base, strict) {\n if (isMap(base)) {\n return new Map(base);\n }\n if (isSet(base)) {\n return new Set(base);\n }\n if (Array.isArray(base))\n return Array.prototype.slice.call(base);\n const isPlain = isPlainObject(base);\n if (strict === true || strict === \"class_only\" && !isPlain) {\n const descriptors = Object.getOwnPropertyDescriptors(base);\n delete descriptors[DRAFT_STATE];\n let keys = Reflect.ownKeys(descriptors);\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n const desc = descriptors[key];\n if (desc.writable === false) {\n desc.writable = true;\n desc.configurable = true;\n }\n if (desc.get || desc.set)\n descriptors[key] = {\n configurable: true,\n writable: true,\n // could live with !!desc.set as well here...\n enumerable: desc.enumerable,\n value: base[key]\n };\n }\n return Object.create(getPrototypeOf(base), descriptors);\n } else {\n const proto = getPrototypeOf(base);\n if (proto !== null && isPlain) {\n return { ...base };\n }\n const obj = Object.create(proto);\n return Object.assign(obj, base);\n }\n}\nfunction freeze(obj, deep = false) {\n if (isFrozen(obj) || isDraft(obj) || !isDraftable(obj))\n return obj;\n if (getArchtype(obj) > 1) {\n Object.defineProperties(obj, {\n set: dontMutateMethodOverride,\n add: dontMutateMethodOverride,\n clear: dontMutateMethodOverride,\n delete: dontMutateMethodOverride\n });\n }\n Object.freeze(obj);\n if (deep)\n Object.values(obj).forEach((value) => freeze(value, true));\n return obj;\n}\nfunction dontMutateFrozenCollections() {\n die(2);\n}\nvar dontMutateMethodOverride = {\n value: dontMutateFrozenCollections\n};\nfunction isFrozen(obj) {\n if (obj === null || typeof obj !== \"object\")\n return true;\n return Object.isFrozen(obj);\n}\n\n// src/utils/plugins.ts\nvar plugins = {};\nfunction getPlugin(pluginKey) {\n const plugin = plugins[pluginKey];\n if (!plugin) {\n die(0, pluginKey);\n }\n return plugin;\n}\nfunction loadPlugin(pluginKey, implementation) {\n if (!plugins[pluginKey])\n plugins[pluginKey] = implementation;\n}\n\n// src/core/scope.ts\nvar currentScope;\nfunction getCurrentScope() {\n return currentScope;\n}\nfunction createScope(parent_, immer_) {\n return {\n drafts_: [],\n parent_,\n immer_,\n // Whenever the modified draft contains a draft from another scope, we\n // need to prevent auto-freezing so the unowned draft can be finalized.\n canAutoFreeze_: true,\n unfinalizedDrafts_: 0\n };\n}\nfunction usePatchesInScope(scope, patchListener) {\n if (patchListener) {\n getPlugin(\"Patches\");\n scope.patches_ = [];\n scope.inversePatches_ = [];\n scope.patchListener_ = patchListener;\n }\n}\nfunction revokeScope(scope) {\n leaveScope(scope);\n scope.drafts_.forEach(revokeDraft);\n scope.drafts_ = null;\n}\nfunction leaveScope(scope) {\n if (scope === currentScope) {\n currentScope = scope.parent_;\n }\n}\nfunction enterScope(immer2) {\n return currentScope = createScope(currentScope, immer2);\n}\nfunction revokeDraft(draft) {\n const state = draft[DRAFT_STATE];\n if (state.type_ === 0 /* Object */ || state.type_ === 1 /* Array */)\n state.revoke_();\n else\n state.revoked_ = true;\n}\n\n// src/core/finalize.ts\nfunction processResult(result, scope) {\n scope.unfinalizedDrafts_ = scope.drafts_.length;\n const baseDraft = scope.drafts_[0];\n const isReplaced = result !== void 0 && result !== baseDraft;\n if (isReplaced) {\n if (baseDraft[DRAFT_STATE].modified_) {\n revokeScope(scope);\n die(4);\n }\n if (isDraftable(result)) {\n result = finalize(scope, result);\n if (!scope.parent_)\n maybeFreeze(scope, result);\n }\n if (scope.patches_) {\n getPlugin(\"Patches\").generateReplacementPatches_(\n baseDraft[DRAFT_STATE].base_,\n result,\n scope.patches_,\n scope.inversePatches_\n );\n }\n } else {\n result = finalize(scope, baseDraft, []);\n }\n revokeScope(scope);\n if (scope.patches_) {\n scope.patchListener_(scope.patches_, scope.inversePatches_);\n }\n return result !== NOTHING ? result : void 0;\n}\nfunction finalize(rootScope, value, path) {\n if (isFrozen(value))\n return value;\n const useStrictIteration = rootScope.immer_.shouldUseStrictIteration();\n const state = value[DRAFT_STATE];\n if (!state) {\n each(\n value,\n (key, childValue) => finalizeProperty(rootScope, state, value, key, childValue, path),\n useStrictIteration\n );\n return value;\n }\n if (state.scope_ !== rootScope)\n return value;\n if (!state.modified_) {\n maybeFreeze(rootScope, state.base_, true);\n return state.base_;\n }\n if (!state.finalized_) {\n state.finalized_ = true;\n state.scope_.unfinalizedDrafts_--;\n const result = state.copy_;\n let resultEach = result;\n let isSet2 = false;\n if (state.type_ === 3 /* Set */) {\n resultEach = new Set(result);\n result.clear();\n isSet2 = true;\n }\n each(\n resultEach,\n (key, childValue) => finalizeProperty(\n rootScope,\n state,\n result,\n key,\n childValue,\n path,\n isSet2\n ),\n useStrictIteration\n );\n maybeFreeze(rootScope, result, false);\n if (path && rootScope.patches_) {\n getPlugin(\"Patches\").generatePatches_(\n state,\n path,\n rootScope.patches_,\n rootScope.inversePatches_\n );\n }\n }\n return state.copy_;\n}\nfunction finalizeProperty(rootScope, parentState, targetObject, prop, childValue, rootPath, targetIsSet) {\n if (childValue == null) {\n return;\n }\n if (typeof childValue !== \"object\" && !targetIsSet) {\n return;\n }\n const childIsFrozen = isFrozen(childValue);\n if (childIsFrozen && !targetIsSet) {\n return;\n }\n if (process.env.NODE_ENV !== \"production\" && childValue === targetObject)\n die(5);\n if (isDraft(childValue)) {\n const path = rootPath && parentState && parentState.type_ !== 3 /* Set */ && // Set objects are atomic since they have no keys.\n !has(parentState.assigned_, prop) ? rootPath.concat(prop) : void 0;\n const res = finalize(rootScope, childValue, path);\n set(targetObject, prop, res);\n if (isDraft(res)) {\n rootScope.canAutoFreeze_ = false;\n } else\n return;\n } else if (targetIsSet) {\n targetObject.add(childValue);\n }\n if (isDraftable(childValue) && !childIsFrozen) {\n if (!rootScope.immer_.autoFreeze_ && rootScope.unfinalizedDrafts_ < 1) {\n return;\n }\n if (parentState && parentState.base_ && parentState.base_[prop] === childValue && childIsFrozen) {\n return;\n }\n finalize(rootScope, childValue);\n if ((!parentState || !parentState.scope_.parent_) && typeof prop !== \"symbol\" && (isMap(targetObject) ? targetObject.has(prop) : Object.prototype.propertyIsEnumerable.call(targetObject, prop)))\n maybeFreeze(rootScope, childValue);\n }\n}\nfunction maybeFreeze(scope, value, deep = false) {\n if (!scope.parent_ && scope.immer_.autoFreeze_ && scope.canAutoFreeze_) {\n freeze(value, deep);\n }\n}\n\n// src/core/proxy.ts\nfunction createProxyProxy(base, parent) {\n const isArray = Array.isArray(base);\n const state = {\n type_: isArray ? 1 /* Array */ : 0 /* Object */,\n // Track which produce call this is associated with.\n scope_: parent ? parent.scope_ : getCurrentScope(),\n // True for both shallow and deep changes.\n modified_: false,\n // Used during finalization.\n finalized_: false,\n // Track which properties have been assigned (true) or deleted (false).\n assigned_: {},\n // The parent draft state.\n parent_: parent,\n // The base state.\n base_: base,\n // The base proxy.\n draft_: null,\n // set below\n // The base copy with any updated values.\n copy_: null,\n // Called by the `produce` function.\n revoke_: null,\n isManual_: false\n };\n let target = state;\n let traps = objectTraps;\n if (isArray) {\n target = [state];\n traps = arrayTraps;\n }\n const { revoke, proxy } = Proxy.revocable(target, traps);\n state.draft_ = proxy;\n state.revoke_ = revoke;\n return proxy;\n}\nvar objectTraps = {\n get(state, prop) {\n if (prop === DRAFT_STATE)\n return state;\n const source = latest(state);\n if (!has(source, prop)) {\n return readPropFromProto(state, source, prop);\n }\n const value = source[prop];\n if (state.finalized_ || !isDraftable(value)) {\n return value;\n }\n if (value === peek(state.base_, prop)) {\n prepareCopy(state);\n return state.copy_[prop] = createProxy(value, state);\n }\n return value;\n },\n has(state, prop) {\n return prop in latest(state);\n },\n ownKeys(state) {\n return Reflect.ownKeys(latest(state));\n },\n set(state, prop, value) {\n const desc = getDescriptorFromProto(latest(state), prop);\n if (desc?.set) {\n desc.set.call(state.draft_, value);\n return true;\n }\n if (!state.modified_) {\n const current2 = peek(latest(state), prop);\n const currentState = current2?.[DRAFT_STATE];\n if (currentState && currentState.base_ === value) {\n state.copy_[prop] = value;\n state.assigned_[prop] = false;\n return true;\n }\n if (is(value, current2) && (value !== void 0 || has(state.base_, prop)))\n return true;\n prepareCopy(state);\n markChanged(state);\n }\n if (state.copy_[prop] === value && // special case: handle new props with value 'undefined'\n (value !== void 0 || prop in state.copy_) || // special case: NaN\n Number.isNaN(value) && Number.isNaN(state.copy_[prop]))\n return true;\n state.copy_[prop] = value;\n state.assigned_[prop] = true;\n return true;\n },\n deleteProperty(state, prop) {\n if (peek(state.base_, prop) !== void 0 || prop in state.base_) {\n state.assigned_[prop] = false;\n prepareCopy(state);\n markChanged(state);\n } else {\n delete state.assigned_[prop];\n }\n if (state.copy_) {\n delete state.copy_[prop];\n }\n return true;\n },\n // Note: We never coerce `desc.value` into an Immer draft, because we can't make\n // the same guarantee in ES5 mode.\n getOwnPropertyDescriptor(state, prop) {\n const owner = latest(state);\n const desc = Reflect.getOwnPropertyDescriptor(owner, prop);\n if (!desc)\n return desc;\n return {\n writable: true,\n configurable: state.type_ !== 1 /* Array */ || prop !== \"length\",\n enumerable: desc.enumerable,\n value: owner[prop]\n };\n },\n defineProperty() {\n die(11);\n },\n getPrototypeOf(state) {\n return getPrototypeOf(state.base_);\n },\n setPrototypeOf() {\n die(12);\n }\n};\nvar arrayTraps = {};\neach(objectTraps, (key, fn) => {\n arrayTraps[key] = function() {\n arguments[0] = arguments[0][0];\n return fn.apply(this, arguments);\n };\n});\narrayTraps.deleteProperty = function(state, prop) {\n if (process.env.NODE_ENV !== \"production\" && isNaN(parseInt(prop)))\n die(13);\n return arrayTraps.set.call(this, state, prop, void 0);\n};\narrayTraps.set = function(state, prop, value) {\n if (process.env.NODE_ENV !== \"production\" && prop !== \"length\" && isNaN(parseInt(prop)))\n die(14);\n return objectTraps.set.call(this, state[0], prop, value, state[0]);\n};\nfunction peek(draft, prop) {\n const state = draft[DRAFT_STATE];\n const source = state ? latest(state) : draft;\n return source[prop];\n}\nfunction readPropFromProto(state, source, prop) {\n const desc = getDescriptorFromProto(source, prop);\n return desc ? `value` in desc ? desc.value : (\n // This is a very special case, if the prop is a getter defined by the\n // prototype, we should invoke it with the draft as context!\n desc.get?.call(state.draft_)\n ) : void 0;\n}\nfunction getDescriptorFromProto(source, prop) {\n if (!(prop in source))\n return void 0;\n let proto = getPrototypeOf(source);\n while (proto) {\n const desc = Object.getOwnPropertyDescriptor(proto, prop);\n if (desc)\n return desc;\n proto = getPrototypeOf(proto);\n }\n return void 0;\n}\nfunction markChanged(state) {\n if (!state.modified_) {\n state.modified_ = true;\n if (state.parent_) {\n markChanged(state.parent_);\n }\n }\n}\nfunction prepareCopy(state) {\n if (!state.copy_) {\n state.copy_ = shallowCopy(\n state.base_,\n state.scope_.immer_.useStrictShallowCopy_\n );\n }\n}\n\n// src/core/immerClass.ts\nvar Immer2 = class {\n constructor(config) {\n this.autoFreeze_ = true;\n this.useStrictShallowCopy_ = false;\n this.useStrictIteration_ = true;\n /**\n * The `produce` function takes a value and a \"recipe function\" (whose\n * return value often depends on the base state). The recipe function is\n * free to mutate its first argument however it wants. All mutations are\n * only ever applied to a __copy__ of the base state.\n *\n * Pass only a function to create a \"curried producer\" which relieves you\n * from passing the recipe function every time.\n *\n * Only plain objects and arrays are made mutable. All other objects are\n * considered uncopyable.\n *\n * Note: This function is __bound__ to its `Immer` instance.\n *\n * @param {any} base - the initial state\n * @param {Function} recipe - function that receives a proxy of the base state as first argument and which can be freely modified\n * @param {Function} patchListener - optional function that will be called with all the patches produced here\n * @returns {any} a new state, or the initial state if nothing was modified\n */\n this.produce = (base, recipe, patchListener) => {\n if (typeof base === \"function\" && typeof recipe !== \"function\") {\n const defaultBase = recipe;\n recipe = base;\n const self = this;\n return function curriedProduce(base2 = defaultBase, ...args) {\n return self.produce(base2, (draft) => recipe.call(this, draft, ...args));\n };\n }\n if (typeof recipe !== \"function\")\n die(6);\n if (patchListener !== void 0 && typeof patchListener !== \"function\")\n die(7);\n let result;\n if (isDraftable(base)) {\n const scope = enterScope(this);\n const proxy = createProxy(base, void 0);\n let hasError = true;\n try {\n result = recipe(proxy);\n hasError = false;\n } finally {\n if (hasError)\n revokeScope(scope);\n else\n leaveScope(scope);\n }\n usePatchesInScope(scope, patchListener);\n return processResult(result, scope);\n } else if (!base || typeof base !== \"object\") {\n result = recipe(base);\n if (result === void 0)\n result = base;\n if (result === NOTHING)\n result = void 0;\n if (this.autoFreeze_)\n freeze(result, true);\n if (patchListener) {\n const p = [];\n const ip = [];\n getPlugin(\"Patches\").generateReplacementPatches_(base, result, p, ip);\n patchListener(p, ip);\n }\n return result;\n } else\n die(1, base);\n };\n this.produceWithPatches = (base, recipe) => {\n if (typeof base === \"function\") {\n return (state, ...args) => this.produceWithPatches(state, (draft) => base(draft, ...args));\n }\n let patches, inversePatches;\n const result = this.produce(base, recipe, (p, ip) => {\n patches = p;\n inversePatches = ip;\n });\n return [result, patches, inversePatches];\n };\n if (typeof config?.autoFreeze === \"boolean\")\n this.setAutoFreeze(config.autoFreeze);\n if (typeof config?.useStrictShallowCopy === \"boolean\")\n this.setUseStrictShallowCopy(config.useStrictShallowCopy);\n if (typeof config?.useStrictIteration === \"boolean\")\n this.setUseStrictIteration(config.useStrictIteration);\n }\n createDraft(base) {\n if (!isDraftable(base))\n die(8);\n if (isDraft(base))\n base = current(base);\n const scope = enterScope(this);\n const proxy = createProxy(base, void 0);\n proxy[DRAFT_STATE].isManual_ = true;\n leaveScope(scope);\n return proxy;\n }\n finishDraft(draft, patchListener) {\n const state = draft && draft[DRAFT_STATE];\n if (!state || !state.isManual_)\n die(9);\n const { scope_: scope } = state;\n usePatchesInScope(scope, patchListener);\n return processResult(void 0, scope);\n }\n /**\n * Pass true to automatically freeze all copies created by Immer.\n *\n * By default, auto-freezing is enabled.\n */\n setAutoFreeze(value) {\n this.autoFreeze_ = value;\n }\n /**\n * Pass true to enable strict shallow copy.\n *\n * By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties.\n */\n setUseStrictShallowCopy(value) {\n this.useStrictShallowCopy_ = value;\n }\n /**\n * Pass false to use faster iteration that skips non-enumerable properties\n * but still handles symbols for compatibility.\n *\n * By default, strict iteration is enabled (includes all own properties).\n */\n setUseStrictIteration(value) {\n this.useStrictIteration_ = value;\n }\n shouldUseStrictIteration() {\n return this.useStrictIteration_;\n }\n applyPatches(base, patches) {\n let i;\n for (i = patches.length - 1; i >= 0; i--) {\n const patch = patches[i];\n if (patch.path.length === 0 && patch.op === \"replace\") {\n base = patch.value;\n break;\n }\n }\n if (i > -1) {\n patches = patches.slice(i + 1);\n }\n const applyPatchesImpl = getPlugin(\"Patches\").applyPatches_;\n if (isDraft(base)) {\n return applyPatchesImpl(base, patches);\n }\n return this.produce(\n base,\n (draft) => applyPatchesImpl(draft, patches)\n );\n }\n};\nfunction createProxy(value, parent) {\n const draft = isMap(value) ? getPlugin(\"MapSet\").proxyMap_(value, parent) : isSet(value) ? getPlugin(\"MapSet\").proxySet_(value, parent) : createProxyProxy(value, parent);\n const scope = parent ? parent.scope_ : getCurrentScope();\n scope.drafts_.push(draft);\n return draft;\n}\n\n// src/core/current.ts\nfunction current(value) {\n if (!isDraft(value))\n die(10, value);\n return currentImpl(value);\n}\nfunction currentImpl(value) {\n if (!isDraftable(value) || isFrozen(value))\n return value;\n const state = value[DRAFT_STATE];\n let copy;\n let strict = true;\n if (state) {\n if (!state.modified_)\n return state.base_;\n state.finalized_ = true;\n copy = shallowCopy(value, state.scope_.immer_.useStrictShallowCopy_);\n strict = state.scope_.immer_.shouldUseStrictIteration();\n } else {\n copy = shallowCopy(value, true);\n }\n each(\n copy,\n (key, childValue) => {\n set(copy, key, currentImpl(childValue));\n },\n strict\n );\n if (state) {\n state.finalized_ = false;\n }\n return copy;\n}\n\n// src/plugins/patches.ts\nfunction enablePatches() {\n const errorOffset = 16;\n if (process.env.NODE_ENV !== \"production\") {\n errors.push(\n 'Sets cannot have \"replace\" patches.',\n function(op) {\n return \"Unsupported patch operation: \" + op;\n },\n function(path) {\n return \"Cannot apply patch, path doesn't resolve: \" + path;\n },\n \"Patching reserved attributes like __proto__, prototype and constructor is not allowed\"\n );\n }\n const REPLACE = \"replace\";\n const ADD = \"add\";\n const REMOVE = \"remove\";\n function generatePatches_(state, basePath, patches, inversePatches) {\n switch (state.type_) {\n case 0 /* Object */:\n case 2 /* Map */:\n return generatePatchesFromAssigned(\n state,\n basePath,\n patches,\n inversePatches\n );\n case 1 /* Array */:\n return generateArrayPatches(state, basePath, patches, inversePatches);\n case 3 /* Set */:\n return generateSetPatches(\n state,\n basePath,\n patches,\n inversePatches\n );\n }\n }\n function generateArrayPatches(state, basePath, patches, inversePatches) {\n let { base_, assigned_ } = state;\n let copy_ = state.copy_;\n if (copy_.length < base_.length) {\n ;\n [base_, copy_] = [copy_, base_];\n [patches, inversePatches] = [inversePatches, patches];\n }\n for (let i = 0; i < base_.length; i++) {\n if (assigned_[i] && copy_[i] !== base_[i]) {\n const path = basePath.concat([i]);\n patches.push({\n op: REPLACE,\n path,\n // Need to maybe clone it, as it can in fact be the original value\n // due to the base/copy inversion at the start of this function\n value: clonePatchValueIfNeeded(copy_[i])\n });\n inversePatches.push({\n op: REPLACE,\n path,\n value: clonePatchValueIfNeeded(base_[i])\n });\n }\n }\n for (let i = base_.length; i < copy_.length; i++) {\n const path = basePath.concat([i]);\n patches.push({\n op: ADD,\n path,\n // Need to maybe clone it, as it can in fact be the original value\n // due to the base/copy inversion at the start of this function\n value: clonePatchValueIfNeeded(copy_[i])\n });\n }\n for (let i = copy_.length - 1; base_.length <= i; --i) {\n const path = basePath.concat([i]);\n inversePatches.push({\n op: REMOVE,\n path\n });\n }\n }\n function generatePatchesFromAssigned(state, basePath, patches, inversePatches) {\n const { base_, copy_ } = state;\n each(state.assigned_, (key, assignedValue) => {\n const origValue = get(base_, key);\n const value = get(copy_, key);\n const op = !assignedValue ? REMOVE : has(base_, key) ? REPLACE : ADD;\n if (origValue === value && op === REPLACE)\n return;\n const path = basePath.concat(key);\n patches.push(op === REMOVE ? { op, path } : { op, path, value });\n inversePatches.push(\n op === ADD ? { op: REMOVE, path } : op === REMOVE ? { op: ADD, path, value: clonePatchValueIfNeeded(origValue) } : { op: REPLACE, path, value: clonePatchValueIfNeeded(origValue) }\n );\n });\n }\n function generateSetPatches(state, basePath, patches, inversePatches) {\n let { base_, copy_ } = state;\n let i = 0;\n base_.forEach((value) => {\n if (!copy_.has(value)) {\n const path = basePath.concat([i]);\n patches.push({\n op: REMOVE,\n path,\n value\n });\n inversePatches.unshift({\n op: ADD,\n path,\n value\n });\n }\n i++;\n });\n i = 0;\n copy_.forEach((value) => {\n if (!base_.has(value)) {\n const path = basePath.concat([i]);\n patches.push({\n op: ADD,\n path,\n value\n });\n inversePatches.unshift({\n op: REMOVE,\n path,\n value\n });\n }\n i++;\n });\n }\n function generateReplacementPatches_(baseValue, replacement, patches, inversePatches) {\n patches.push({\n op: REPLACE,\n path: [],\n value: replacement === NOTHING ? void 0 : replacement\n });\n inversePatches.push({\n op: REPLACE,\n path: [],\n value: baseValue\n });\n }\n function applyPatches_(draft, patches) {\n patches.forEach((patch) => {\n const { path, op } = patch;\n let base = draft;\n for (let i = 0; i < path.length - 1; i++) {\n const parentType = getArchtype(base);\n let p = path[i];\n if (typeof p !== \"string\" && typeof p !== \"number\") {\n p = \"\" + p;\n }\n if ((parentType === 0 /* Object */ || parentType === 1 /* Array */) && (p === \"__proto__\" || p === \"constructor\"))\n die(errorOffset + 3);\n if (typeof base === \"function\" && p === \"prototype\")\n die(errorOffset + 3);\n base = get(base, p);\n if (typeof base !== \"object\")\n die(errorOffset + 2, path.join(\"/\"));\n }\n const type = getArchtype(base);\n const value = deepClonePatchValue(patch.value);\n const key = path[path.length - 1];\n switch (op) {\n case REPLACE:\n switch (type) {\n case 2 /* Map */:\n return base.set(key, value);\n case 3 /* Set */:\n die(errorOffset);\n default:\n return base[key] = value;\n }\n case ADD:\n switch (type) {\n case 1 /* Array */:\n return key === \"-\" ? base.push(value) : base.splice(key, 0, value);\n case 2 /* Map */:\n return base.set(key, value);\n case 3 /* Set */:\n return base.add(value);\n default:\n return base[key] = value;\n }\n case REMOVE:\n switch (type) {\n case 1 /* Array */:\n return base.splice(key, 1);\n case 2 /* Map */:\n return base.delete(key);\n case 3 /* Set */:\n return base.delete(patch.value);\n default:\n return delete base[key];\n }\n default:\n die(errorOffset + 1, op);\n }\n });\n return draft;\n }\n function deepClonePatchValue(obj) {\n if (!isDraftable(obj))\n return obj;\n if (Array.isArray(obj))\n return obj.map(deepClonePatchValue);\n if (isMap(obj))\n return new Map(\n Array.from(obj.entries()).map(([k, v]) => [k, deepClonePatchValue(v)])\n );\n if (isSet(obj))\n return new Set(Array.from(obj).map(deepClonePatchValue));\n const cloned = Object.create(getPrototypeOf(obj));\n for (const key in obj)\n cloned[key] = deepClonePatchValue(obj[key]);\n if (has(obj, DRAFTABLE))\n cloned[DRAFTABLE] = obj[DRAFTABLE];\n return cloned;\n }\n function clonePatchValueIfNeeded(obj) {\n if (isDraft(obj)) {\n return deepClonePatchValue(obj);\n } else\n return obj;\n }\n loadPlugin(\"Patches\", {\n applyPatches_,\n generatePatches_,\n generateReplacementPatches_\n });\n}\n\n// src/plugins/mapset.ts\nfunction enableMapSet() {\n class DraftMap extends Map {\n constructor(target, parent) {\n super();\n this[DRAFT_STATE] = {\n type_: 2 /* Map */,\n parent_: parent,\n scope_: parent ? parent.scope_ : getCurrentScope(),\n modified_: false,\n finalized_: false,\n copy_: void 0,\n assigned_: void 0,\n base_: target,\n draft_: this,\n isManual_: false,\n revoked_: false\n };\n }\n get size() {\n return latest(this[DRAFT_STATE]).size;\n }\n has(key) {\n return latest(this[DRAFT_STATE]).has(key);\n }\n set(key, value) {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n if (!latest(state).has(key) || latest(state).get(key) !== value) {\n prepareMapCopy(state);\n markChanged(state);\n state.assigned_.set(key, true);\n state.copy_.set(key, value);\n state.assigned_.set(key, true);\n }\n return this;\n }\n delete(key) {\n if (!this.has(key)) {\n return false;\n }\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n prepareMapCopy(state);\n markChanged(state);\n if (state.base_.has(key)) {\n state.assigned_.set(key, false);\n } else {\n state.assigned_.delete(key);\n }\n state.copy_.delete(key);\n return true;\n }\n clear() {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n if (latest(state).size) {\n prepareMapCopy(state);\n markChanged(state);\n state.assigned_ = /* @__PURE__ */ new Map();\n each(state.base_, (key) => {\n state.assigned_.set(key, false);\n });\n state.copy_.clear();\n }\n }\n forEach(cb, thisArg) {\n const state = this[DRAFT_STATE];\n latest(state).forEach((_value, key, _map) => {\n cb.call(thisArg, this.get(key), key, this);\n });\n }\n get(key) {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n const value = latest(state).get(key);\n if (state.finalized_ || !isDraftable(value)) {\n return value;\n }\n if (value !== state.base_.get(key)) {\n return value;\n }\n const draft = createProxy(value, state);\n prepareMapCopy(state);\n state.copy_.set(key, draft);\n return draft;\n }\n keys() {\n return latest(this[DRAFT_STATE]).keys();\n }\n values() {\n const iterator = this.keys();\n return {\n [Symbol.iterator]: () => this.values(),\n next: () => {\n const r = iterator.next();\n if (r.done)\n return r;\n const value = this.get(r.value);\n return {\n done: false,\n value\n };\n }\n };\n }\n entries() {\n const iterator = this.keys();\n return {\n [Symbol.iterator]: () => this.entries(),\n next: () => {\n const r = iterator.next();\n if (r.done)\n return r;\n const value = this.get(r.value);\n return {\n done: false,\n value: [r.value, value]\n };\n }\n };\n }\n [(DRAFT_STATE, Symbol.iterator)]() {\n return this.entries();\n }\n }\n function proxyMap_(target, parent) {\n return new DraftMap(target, parent);\n }\n function prepareMapCopy(state) {\n if (!state.copy_) {\n state.assigned_ = /* @__PURE__ */ new Map();\n state.copy_ = new Map(state.base_);\n }\n }\n class DraftSet extends Set {\n constructor(target, parent) {\n super();\n this[DRAFT_STATE] = {\n type_: 3 /* Set */,\n parent_: parent,\n scope_: parent ? parent.scope_ : getCurrentScope(),\n modified_: false,\n finalized_: false,\n copy_: void 0,\n base_: target,\n draft_: this,\n drafts_: /* @__PURE__ */ new Map(),\n revoked_: false,\n isManual_: false\n };\n }\n get size() {\n return latest(this[DRAFT_STATE]).size;\n }\n has(value) {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n if (!state.copy_) {\n return state.base_.has(value);\n }\n if (state.copy_.has(value))\n return true;\n if (state.drafts_.has(value) && state.copy_.has(state.drafts_.get(value)))\n return true;\n return false;\n }\n add(value) {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n if (!this.has(value)) {\n prepareSetCopy(state);\n markChanged(state);\n state.copy_.add(value);\n }\n return this;\n }\n delete(value) {\n if (!this.has(value)) {\n return false;\n }\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n prepareSetCopy(state);\n markChanged(state);\n return state.copy_.delete(value) || (state.drafts_.has(value) ? state.copy_.delete(state.drafts_.get(value)) : (\n /* istanbul ignore next */\n false\n ));\n }\n clear() {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n if (latest(state).size) {\n prepareSetCopy(state);\n markChanged(state);\n state.copy_.clear();\n }\n }\n values() {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n prepareSetCopy(state);\n return state.copy_.values();\n }\n entries() {\n const state = this[DRAFT_STATE];\n assertUnrevoked(state);\n prepareSetCopy(state);\n return state.copy_.entries();\n }\n keys() {\n return this.values();\n }\n [(DRAFT_STATE, Symbol.iterator)]() {\n return this.values();\n }\n forEach(cb, thisArg) {\n const iterator = this.values();\n let result = iterator.next();\n while (!result.done) {\n cb.call(thisArg, result.value, result.value, this);\n result = iterator.next();\n }\n }\n }\n function proxySet_(target, parent) {\n return new DraftSet(target, parent);\n }\n function prepareSetCopy(state) {\n if (!state.copy_) {\n state.copy_ = /* @__PURE__ */ new Set();\n state.base_.forEach((value) => {\n if (isDraftable(value)) {\n const draft = createProxy(value, state);\n state.drafts_.set(value, draft);\n state.copy_.add(draft);\n } else {\n state.copy_.add(value);\n }\n });\n }\n }\n function assertUnrevoked(state) {\n if (state.revoked_)\n die(3, JSON.stringify(latest(state)));\n }\n loadPlugin(\"MapSet\", { proxyMap_, proxySet_ });\n}\n\n// src/immer.ts\nvar immer = new Immer2();\nvar produce = immer.produce;\nvar produceWithPatches = /* @__PURE__ */ immer.produceWithPatches.bind(\n immer\n);\nvar setAutoFreeze = /* @__PURE__ */ immer.setAutoFreeze.bind(immer);\nvar setUseStrictShallowCopy = /* @__PURE__ */ immer.setUseStrictShallowCopy.bind(\n immer\n);\nvar setUseStrictIteration = /* @__PURE__ */ immer.setUseStrictIteration.bind(\n immer\n);\nvar applyPatches = /* @__PURE__ */ immer.applyPatches.bind(immer);\nvar createDraft = /* @__PURE__ */ immer.createDraft.bind(immer);\nvar finishDraft = /* @__PURE__ */ immer.finishDraft.bind(immer);\nfunction castDraft(value) {\n return value;\n}\nfunction castImmutable(value) {\n return value;\n}\nexport {\n Immer2 as Immer,\n applyPatches,\n castDraft,\n castImmutable,\n createDraft,\n current,\n enableMapSet,\n enablePatches,\n finishDraft,\n freeze,\n DRAFTABLE as immerable,\n isDraft,\n isDraftable,\n NOTHING as nothing,\n original,\n produce,\n produceWithPatches,\n setAutoFreeze,\n setUseStrictIteration,\n setUseStrictShallowCopy\n};\n//# sourceMappingURL=immer.mjs.map","import { createStore } from \"zustand/vanilla\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\nimport { shallow } from \"zustand/shallow\";\nimport { freeze, produce } from \"immer\";\n//#region lib/types/index.js\n/**\n* React-free snapshot store engine (zustand vanilla + immer + subscribeWithSelector +\n* rafFlush middleware + opt-in persist + dev freeze) plus the declarative\n* shell over it: {@link defineStore} bakes an init/persist/actions literal\n* into a {@link StoreHandle}, the registration-side store seat of slot\n* terminals. Engine products are bare observables — subscribe/getSnapshot/\n* update/set, NO selector hook. Hook synthesis is ui-renderer's (the one\n* uSES bridge, cached per source at the binding site).\n*/\n/**\n* Notify an observer set without allowing one callback to starve the rest.\n* @param listeners - current observer callbacks; copied before dispatch.\n* @param label - diagnostic owner prefix.\n* @param args - callback arguments.\n*/\nfunction notifySubscribers(listeners, label, ...args) {\n\tfor (const listener of [...listeners]) try {\n\t\tlistener(...args);\n\t} catch (error) {\n\t\tconsole.error(`${label} subscriber failed:`, error);\n\t}\n}\n/**\n* Shallow equality for selector slices (zustand/shallow semantics; travels\n* with the engine so hook consumers need no zustand dependency).\n* @param a - left value.\n* @param b - right value.\n* @returns whether the values are shallowly equal.\n*/\nfunction shallowEqual(a, b) {\n\treturn shallow(a, b);\n}\n/** Batches subscriber notification into one flush per animation frame. */\nfunction rafBatch(notify) {\n\tconst schedule = typeof requestAnimationFrame === \"function\" ? (fn) => {\n\t\trequestAnimationFrame(() => {\n\t\t\tfn();\n\t\t});\n\t} : (fn) => {\n\t\tqueueMicrotask(fn);\n\t};\n\tlet scheduled = false;\n\treturn () => {\n\t\tif (scheduled) return;\n\t\tscheduled = true;\n\t\tschedule(() => {\n\t\t\tscheduled = false;\n\t\t\tnotify();\n\t\t});\n\t};\n}\n/**\n* Create a snapshot store.\n*\n* Flush default is 'sync' (controlled inputs need same-tick echo); frame-driven\n* stores opt into 'raf', where a frame's worth of updates coalesces into one\n* notification. Known raf-mode tradeoff: a component mounting mid-frame reads\n* fresh state while existing subscribers hear it next flush — transient\n* frame-level skew, same nature as the object layer's microtask batching.\n*\n* @param init - initial state.\n* @param opts - flush mode and opt-in persistence (localStorage, keyed by name).\n* @returns the store.\n*/\nfunction createSnapshotStore(init, opts) {\n\tconst withSelector = subscribeWithSelector(() => init);\n\tconst api = createStore()(withSelector);\n\tif (opts?.persist) attachPersistence(api, opts.persist.name);\n\tlet subscribe = (fn) => api.subscribe(() => {\n\t\tnotifySubscribers([fn], \"[client-store]\");\n\t});\n\tif (opts?.flush === \"raf\") {\n\t\tconst listeners = /* @__PURE__ */ new Set();\n\t\tconst flush = rafBatch(() => {\n\t\t\tnotifySubscribers(listeners, \"[client-store]\");\n\t\t});\n\t\tapi.subscribe(flush);\n\t\tsubscribe = (fn) => {\n\t\t\tlisteners.add(fn);\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(fn);\n\t\t\t};\n\t\t};\n\t}\n\treturn {\n\t\tgetSnapshot: () => api.getState(),\n\t\tsubscribe: (fn) => subscribe(fn),\n\t\tupdate: (mutator) => {\n\t\t\tapi.setState(produce(api.getState(), (draft) => {\n\t\t\t\tmutator(draft);\n\t\t\t}), true);\n\t\t},\n\t\tset: (next) => {\n\t\t\tapi.setState(devFreeze(next), true);\n\t\t}\n\t};\n}\n/**\n* Whole-value JSON persistence to localStorage. Hand-rolled instead of the\n* zustand persist middleware: its write path spreads state into an object\n* (`partialize({ ...get() })`), exploding primitive state (a persisted string\n* draft becomes {0:'h',1:'e',...}) — not fixable via merge/deserialize options\n* because the corruption happens before serialization. Storage failures\n* (quota, private mode) only disable persistence, never break the store.\n*/\nfunction attachPersistence(api, name) {\n\tif (typeof localStorage === \"undefined\") return;\n\ttry {\n\t\tconst raw = localStorage.getItem(name);\n\t\tif (raw !== null) api.setState(devFreeze(JSON.parse(raw)), true);\n\t} catch (error) {\n\t\tconsole.error(`snapshot store '${name}' rehydration failed:`, error);\n\t}\n\tapi.subscribe((state) => {\n\t\ttry {\n\t\t\tlocalStorage.setItem(name, JSON.stringify(state));\n\t\t} catch (error) {\n\t\t\tconsole.error(`snapshot store '${name}' persistence failed:`, error);\n\t\t}\n\t});\n}\n/** Deep-freeze draftable wholesale-set state outside production: set() bypasses immer's freeze. */\nfunction devFreeze(value) {\n\treturn freeze(value, true);\n}\n/**\n* Declare a store: initial state, optional persistence, and the full write\n* set as pure draft mutators. The returned handle is the registration\n* currency of the store seat — its identity keys instance sharing. Satisfies\n* ui-slots' DefineStore contract (the handle/instance are the engine-extended\n* subtypes).\n*\n* The `A & ActionsDecl<T>` actions position is load-bearing: T resolves from\n* `init` in the first inference round, and the intersection then contextually\n* types each mutator's draft parameter (context-sensitive functions defer),\n* so call sites write `(d, x: X) => { ... }` with no draft annotation. If a\n* future TS version breaks this single-literal inference, the design's\n* documented fallback is currying (`defineStore(init).actions({...})`).\n* @param decl - init lambda (fresh state per instance), optional persist key, actions table.\n* @returns the store handle.\n*/\nfunction defineStore(decl) {\n\treturn {\n\t\tspec: decl,\n\t\tcreate(scopeKey) {\n\t\t\tconst persistKey = decl.persist === void 0 ? void 0 : scopeKey === void 0 ? decl.persist : `${decl.persist}.${scopeKey}`;\n\t\t\tconst store = createSnapshotStore(decl.init(), persistKey !== void 0 ? { persist: { name: persistKey } } : void 0);\n\t\t\tconst actions = {};\n\t\t\tfor (const key of Object.keys(decl.actions)) {\n\t\t\t\tconst mutate = decl.actions[key];\n\t\t\t\tactions[key] = (...params) => {\n\t\t\t\t\tstore.update((draft) => {\n\t\t\t\t\t\tmutate(draft, ...params);\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tactions,\n\t\t\t\tgetSnapshot: () => store.getSnapshot(),\n\t\t\t\tsubscribe: (fn) => store.subscribe(fn),\n\t\t\t\tstore,\n\t\t\t\tclearPersisted: () => {\n\t\t\t\t\tif (persistKey === void 0 || typeof localStorage === \"undefined\") return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlocalStorage.removeItem(persistKey);\n\t\t\t\t\t} catch {}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t};\n}\n//#endregion\nexport { createSnapshotStore, defineStore, notifySubscribers, shallowEqual };\n\n//# sourceMappingURL=index.js.map","/**\n * Settings-card form machinery, vendored from the dsh-web-ui family bucket\n * (packages/dsh-task-board/src/client/settings-form.ts) and re-typed. Stages\n * one card's edits over one settings namespace and writes them on save.\n *\n * The Host is the only authority on whether a value was accepted — its\n * validators own the constraints no schema can express — so the outcome is\n * read back from the section rather than predicted here. A save that did not\n * land keeps its drafts, so the user can correct them instead of retyping.\n */\n\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client'\n\n/** One staged field: its draft text plus the clear/reset marker. */\ninterface StagedEdit {\n text: string\n clear: boolean\n}\n\n/** One editable field spec: formatting plus text parsing. */\nexport interface FieldSpec {\n field: string\n format: (value: unknown) => string\n parse: (text: string) => { kind: 'set'; value: unknown } | { kind: 'clear' } | undefined\n}\n\n/** A boolean field, edited through true/false draft text. */\nexport function booleanField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'boolean' ? String(value) : ''),\n parse: (text) => {\n if (text === 'true') return { kind: 'set', value: true }\n if (text === 'false') return { kind: 'set', value: false }\n return undefined\n },\n }\n}\n\n/** A #rrggbb color field, edited through hex draft text. */\nexport function colorField(field: string): FieldSpec {\n return {\n field,\n format: (value) => (typeof value === 'string' && /^#[0-9a-f]{6}$/i.test(value) ? value : ''),\n parse: (text) => {\n if (/^#[0-9a-f]{6}$/i.test(text)) return { kind: 'set', value: text }\n return undefined\n },\n }\n}\n\n/**\n * A numeric field with range clamping. Integer by default: a fractional draft\n * is truncated so \"5.5 分钟\" cannot sneak past an integer-only schema.\n */\nexport function numberField(field: string, options: { min?: number; max?: number; integer?: boolean } = {}): FieldSpec {\n const min = options.min ?? Number.NEGATIVE_INFINITY\n const max = options.max ?? Number.POSITIVE_INFINITY\n const integer = options.integer ?? true\n return {\n field,\n format: (value) => (typeof value === 'number' && Number.isFinite(value) ? String(value) : ''),\n parse: (text) => {\n const trimmed = text.trim()\n if (!/^-?\\d+(\\.\\d+)?$/.test(trimmed)) return undefined\n const parsed = integer ? Math.trunc(Number(trimmed)) : Number(trimmed)\n if (!Number.isFinite(parsed) || parsed < min || parsed > max) return undefined\n return { kind: 'set', value: parsed }\n },\n }\n}\n\n/** Card-level state the chrome renders. */\nexport interface CardShell {\n available: boolean\n exposed: boolean\n writable: boolean\n dirty: boolean\n invalid: boolean\n saving: boolean\n failed: boolean\n}\n\n/** One field's state from the effective section and its staged draft. */\nexport interface FieldState {\n text: string\n overridden: boolean\n invalid: boolean\n}\n\n/** The settings scope face the form consumes (subset of SettingsScope<T>). */\nexport interface FormScope {\n subscribe(listener: () => void): () => void\n getSnapshot(): { status: string; writable: boolean; value?: Record<string, unknown>; base?: unknown; user?: unknown }\n set(field: string, value: unknown): Promise<void>\n unset(field: string): Promise<void>\n}\n\n/** Stages one card's edits and writes them through the settings transport. */\nexport class CardForm {\n private readonly scope: FormScope\n private readonly specs = new Map<string, FieldSpec>()\n private readonly staged = new Map<string, StagedEdit>()\n private readonly listeners = new Set<() => void>()\n private saving = false\n private failed = false\n\n /** @param scope - the bound settings scope for this card's namespace. */\n constructor(scope: FormScope, specs: FieldSpec[]) {\n this.scope = scope\n for (const spec of specs) this.specs.set(spec.field, spec)\n scope.subscribe(() => { this.publish() })\n }\n\n /** Publish a projection of this form, rebuilt whenever the scope or a draft changes. */\n bind<T>(project: () => T) {\n const store = createSnapshotStore(project())\n this.listeners.add(() => { store.set(project()) })\n return store\n }\n\n /** Read the card-level state: what the Host serves, and what a save would do. */\n shell(): CardShell {\n const snapshot = this.scope.getSnapshot()\n const plan = this.plan()\n return {\n available: snapshot.status !== 'loading',\n exposed: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: plan.length > 0,\n invalid: plan.some((item) => item.run === undefined),\n saving: this.saving,\n failed: this.failed,\n }\n }\n\n /** Read one field's state from the effective section and its staged draft. */\n field(field: string): FieldState {\n const spec = this.specOf(field)\n const staged = this.staged.get(field)\n if (staged === undefined) {\n return { text: spec.format(this.sectionValue(field)), overridden: this.stored(field), invalid: false }\n }\n const write = staged.clear ? { kind: 'clear' as const } : spec.parse(staged.text)\n return { text: staged.text, overridden: write?.kind === 'set', invalid: write === undefined }\n }\n\n /** The actions the card's slot registration injects. */\n actions() {\n return {\n edit: (field: string, text: string) => { this.stage(field, { text, clear: false }) },\n resetField: (field: string) => {\n this.stage(field, { text: this.specOf(field).format(this.baseValue(field)), clear: true })\n },\n save: () => { void this.save() },\n discard: () => {\n if (this.staged.size === 0 && !this.failed) return\n this.staged.clear()\n this.failed = false\n this.publish()\n },\n }\n }\n\n /** Write every staged edit, then re-seed from what the Host accepted. */\n async save(): Promise<void> {\n const plan = this.plan()\n const writes = plan.flatMap((item) => (item.run === undefined ? [] : [item.run]))\n if (plan.length === 0 || this.saving || writes.length !== plan.length) return\n this.saving = true\n this.failed = false\n this.publish()\n let landed = true\n for (const write of writes) landed = (await write()) && landed\n if (landed) this.staged.clear()\n this.saving = false\n this.failed = !landed\n this.publish()\n }\n\n /** Every staged edit a save would write, in staging order. */\n plan(): Array<{ field: string; run: (() => Promise<boolean>) | undefined }> {\n const plan: Array<{ field: string; run: (() => Promise<boolean>) | undefined }> = []\n for (const [field, staged] of this.staged) {\n const spec = this.specOf(field)\n if (staged.clear) {\n if (this.stored(field)) plan.push({ field, run: () => this.clear(field) })\n continue\n }\n if (staged.text === spec.format(this.sectionValue(field))) continue\n const write = spec.parse(staged.text)\n if (write === undefined) plan.push({ field, run: undefined })\n else if (write.kind === 'clear') plan.push({ field, run: () => this.clear(field) })\n else plan.push({ field, run: () => this.store(field, write.value) })\n }\n return plan\n }\n\n private async clear(field: string): Promise<boolean> {\n await this.scope.unset(field)\n return !this.stored(field)\n }\n\n private async store(field: string, value: unknown): Promise<boolean> {\n await this.scope.set(field, value)\n return this.userLayer()?.[field] === value\n }\n\n private userRecord(): Record<string, unknown> | undefined {\n const user = this.scope.getSnapshot().user\n return typeof user === 'object' && user !== null ? user as Record<string, unknown> : undefined\n }\n\n private stage(field: string, edit: StagedEdit): void {\n this.staged.set(field, edit)\n this.failed = false\n this.publish()\n }\n\n private specOf(field: string): FieldSpec {\n const spec = this.specs.get(field)\n if (spec === undefined) throw new Error('settings card has no field ' + field)\n return spec\n }\n\n private sectionValue(field: string): unknown {\n return this.scope.getSnapshot().value?.[field]\n }\n\n private baseValue(field: string): unknown {\n const base = this.scope.getSnapshot().base\n return typeof base === 'object' && base !== null ? (base as Record<string, unknown>)[field] : undefined\n }\n\n private userLayer(): Record<string, unknown> | undefined {\n return this.userRecord()\n }\n\n private stored(field: string): boolean {\n const user = this.userRecord()\n return user !== undefined && Object.hasOwn(user, field)\n }\n\n private publish(): void {\n for (const listener of this.listeners) listener()\n }\n}\n\n","/**\n * The dsh-skill-hub plugin settings card: bridges the hub's settings\n * namespace (bound through the official settings transport) onto the\n * family-style staged card form (enabled master switch + agent announcement).\n * Registered into the official `settings.plugin.item` slot keyed by that\n * namespace, so the plugin shows up in Settings → 插件 on dsh rc.7+.\n */\n\nimport { useEffect, useState, type ReactElement } from 'react'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { SkillHubApi } from './api.ts'\nimport { ColorField, NumberField, PluginSettingsCard, SwitchField } from './settings-card.tsx'\nimport { booleanField, CardForm, colorField, numberField, type CardShell, type FieldState, type FormScope } from './settings-form.ts'\n// Single source for the TS-side dot defaults (the panel CSS mirrors these).\nimport { DEFAULT_DOT_MODEL_COLOR, DEFAULT_DOT_USER_COLOR } from './panel/format.ts'\n// Re-export for any consumer that imported them from the card before the move.\nexport { DEFAULT_DOT_MODEL_COLOR, DEFAULT_DOT_USER_COLOR }\n\n/** The card's projected state. */\nexport interface SkillHubSettingsState extends CardShell {\n enabled: FieldState\n announceToAgent: FieldState\n dotModelColor: FieldState\n dotUserColor: FieldState\n showUseCount: FieldState\n showUseTime: FieldState\n showGroupSummary: FieldState\n statsWindowDays: FieldState\n statsScanMinutes: FieldState\n}\n\n/** The business face the card's slot registration injects. */\nexport interface SkillHubSettingsCardFace {\n hooks: {\n /** The card's snapshot store (projected form state). */\n skillHubSettingsCard: SnapshotStore<SkillHubSettingsState>\n }\n save: () => void\n discard: () => void\n edit: (field: string, text: string) => void\n resetField: (field: string) => void\n}\n\n/** Props the slot renderer binds (locale copy + injected form actions). */\nexport type SkillHubSettingsCardProps =\n PropsRuntime<'settings.plugin.item'> & PropsLocale<'dsh-skill-hub'> & InjectFace<SkillHubSettingsCardFace>\n\n/** Bridges the hub's config scope onto the card's staged form. */\nexport class SkillHubSettingsCardController {\n private readonly form: CardForm\n private readonly store: SnapshotStore<SkillHubSettingsState>\n\n /** @param scope - the hub settings scope the card edits (FormScope-compatible). */\n constructor(scope: FormScope) {\n this.form = new CardForm(scope, [booleanField('enabled'), booleanField('announceToAgent'), colorField('dotModelColor'), colorField('dotUserColor'), booleanField('showUseCount'), booleanField('showUseTime'), booleanField('showGroupSummary'), numberField('statsWindowDays', { min: 0, max: 3650 }), numberField('statsScanMinutes', { min: 1, max: 1440 })])\n this.store = this.form.bind(() => this.projection())\n }\n\n private projection(): SkillHubSettingsState {\n return {\n ...this.form.shell(),\n enabled: this.form.field('enabled'),\n announceToAgent: this.form.field('announceToAgent'),\n dotModelColor: this.form.field('dotModelColor'),\n dotUserColor: this.form.field('dotUserColor'),\n showUseCount: this.form.field('showUseCount'),\n showUseTime: this.form.field('showUseTime'),\n showGroupSummary: this.form.field('showGroupSummary'),\n statsWindowDays: this.form.field('statsWindowDays'),\n statsScanMinutes: this.form.field('statsScanMinutes'),\n }\n }\n\n /**\n * Build the face the card's slot registration injects.\n * @returns the card's snapshot hook and its form actions.\n */\n inject(): SkillHubSettingsCardFace {\n return {\n hooks: { skillHubSettingsCard: this.store },\n ...this.form.actions(),\n }\n }\n}\n\n/**\n * Render the dsh-skill-hub card.\n * @param props - locale copy, the card snapshot, and its form actions.\n * @returns the card.\n */\nexport function SkillHubSettingsCard(props: SkillHubSettingsCardProps): ReactElement {\n const { t } = props\n const state = props.useSkillHubSettingsCard((snapshot) => snapshot)\n // 插件自身版本:挂载时从 config 路由取一次(与面板标题徽标同源),失败静默不显示。\n const [version, setVersion] = useState<string | undefined>(undefined)\n useEffect(() => {\n let cancelled = false\n void new SkillHubApi().config()\n .then((res) => { if (!cancelled && res.ok) setVersion(res.pluginVersion) })\n .catch(() => { /* 版本徽标是装饰性的,失败不提示 */ })\n return () => { cancelled = true }\n }, [])\n const disabled = !state.writable\n const fieldProps = {\n overriddenLabel: t('settings.overridden'),\n resetLabel: t('settings.reset'),\n disabled,\n }\n return (\n <PluginSettingsCard\n t={t}\n titleKey='settings.title'\n descriptionKey='settings.description'\n version={version}\n state={state}\n onSave={props.save}\n onDiscard={props.discard}\n >\n <SwitchField\n label={t('settings.enabled')}\n hint={t('settings.enabledHint')}\n {...fieldProps}\n {...state.enabled}\n onEdit={(text) => { props.edit('enabled', text) }}\n onReset={() => { props.resetField('enabled') }}\n />\n <SwitchField\n label={t('settings.announceToAgent')}\n hint={t('settings.announceToAgentHint')}\n {...fieldProps}\n {...state.announceToAgent}\n onEdit={(text) => { props.edit('announceToAgent', text) }}\n onReset={() => { props.resetField('announceToAgent') }}\n />\n <ColorField\n id='skill-hub-dot-model-color'\n label={t('settings.dotModelColor')}\n hint={t('settings.dotModelColorHint')}\n inheritLabel={t('settings.inherit')}\n defaultColor={DEFAULT_DOT_MODEL_COLOR}\n {...fieldProps}\n {...state.dotModelColor}\n onEdit={(text) => { props.edit('dotModelColor', text) }}\n onReset={() => { props.resetField('dotModelColor') }}\n />\n <ColorField\n id='skill-hub-dot-user-color'\n label={t('settings.dotUserColor')}\n hint={t('settings.dotUserColorHint')}\n inheritLabel={t('settings.inherit')}\n defaultColor={DEFAULT_DOT_USER_COLOR}\n {...fieldProps}\n {...state.dotUserColor}\n onEdit={(text) => { props.edit('dotUserColor', text) }}\n onReset={() => { props.resetField('dotUserColor') }}\n />\n <SwitchField\n label={t('settings.showUseCount')}\n hint={t('settings.showUseCountHint')}\n {...fieldProps}\n {...state.showUseCount}\n onEdit={(text) => { props.edit('showUseCount', text) }}\n onReset={() => { props.resetField('showUseCount') }}\n />\n <SwitchField\n label={t('settings.showUseTime')}\n hint={t('settings.showUseTimeHint')}\n {...fieldProps}\n {...state.showUseTime}\n onEdit={(text) => { props.edit('showUseTime', text) }}\n onReset={() => { props.resetField('showUseTime') }}\n />\n <SwitchField\n label={t('settings.showGroupSummary')}\n hint={t('settings.showGroupSummaryHint')}\n {...fieldProps}\n {...state.showGroupSummary}\n onEdit={(text) => { props.edit('showGroupSummary', text) }}\n onReset={() => { props.resetField('showGroupSummary') }}\n />\n <NumberField\n id='skill-hub-stats-window-days'\n label={t('settings.statsWindowDays')}\n hint={t('settings.statsWindowDaysHint')}\n inheritLabel={t('settings.inherit')}\n {...fieldProps}\n text={state.statsWindowDays.text}\n overridden={state.statsWindowDays.overridden}\n invalid={state.statsWindowDays.invalid}\n onEdit={(text) => { props.edit('statsWindowDays', text) }}\n onReset={() => { props.resetField('statsWindowDays') }}\n />\n <NumberField\n id='skill-hub-stats-scan-minutes'\n label={t('settings.statsScanMinutes')}\n hint={t('settings.statsScanMinutesHint')}\n inheritLabel={t('settings.inherit')}\n {...fieldProps}\n text={state.statsScanMinutes.text}\n overridden={state.statsScanMinutes.overridden}\n invalid={state.statsScanMinutes.invalid}\n onEdit={(text) => { props.edit('statsScanMinutes', text) }}\n onReset={() => { props.resetField('statsScanMinutes') }}\n />\n </PluginSettingsCard>\n )\n}\n","/**\n * Source check-status badges (up-to-date / updated / deleted / error /\n * throttled / unverified). Shared by the panel's source-group headers and\n * the skill detail view.\n *\n * In the group headers the badge doubles as the re-check affordance: it\n * shows a clickable \"检查更新\" badge before the first check, \"检查中…\" while\n * checking, and the status badge (clickable again to re-check) afterwards.\n */\n\nimport type { JSX } from 'react'\nimport type { SourceCheckResult } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\n\nexport function SourceStatusBadge(props: {\n check: SourceCheckResult | undefined\n /** 正在检查该来源(显示「检查中…」)。 */\n checking?: boolean\n /** 提供后徽章区域可点击触发检查(组头用;详情页有自己的检查按钮)。 */\n onCheck?: () => void\n}): JSX.Element | null {\n const { check, checking, onCheck } = props\n if (checking === true) {\n return <span className={css.statusBadge}>{tt('source.checking')}</span>\n }\n if (check === undefined) {\n if (onCheck === undefined) return null\n return (\n <button type='button' className={css.statusBadge + ' ' + css.statusButton} title={tt('source.checkHint')} onClick={onCheck}>\n {tt('source.check')}\n </button>\n )\n }\n const badges = ((): JSX.Element | null => {\n if (check.error !== undefined) {\n return <span className={css.statusBadge + ' ' + css.statusError}>{tt('source.error')}</span>\n }\n if (check.throttled === true) {\n return <span className={css.statusBadge}>{tt('source.throttled')}</span>\n }\n if (check.unverified === true) {\n return <span className={css.statusBadge}>{tt('source.unverified')}</span>\n }\n if (check.changed) {\n return (\n <span className={css.statusBadges}>\n {check.updated.length > 0 ? <span className={css.statusBadge + ' ' + css.statusUpdated}>{tt('source.updated', { count: check.updated.length })}</span> : null}\n {check.deleted.length > 0 ? <span className={css.statusBadge + ' ' + css.statusError}>{tt('source.deleted', { count: check.deleted.length })}</span> : null}\n </span>\n )\n }\n return <span className={css.statusBadge + ' ' + css.statusOk}>{tt('source.upToDate')}</span>\n })()\n if (onCheck === undefined) return badges\n return (\n <button type='button' className={css.statusWrap} title={tt('source.checkHint')} onClick={onCheck}>\n {badges}\n </button>\n )\n}\n","/**\n * Full-page skill detail view: metadata, upstream source card with\n * check/sync/follow-delete actions, and the raw SKILL.md body. Pure\n * presentation — every state value and action arrives as a prop, so the\n * panel stays the single owner of state.\n */\n\nimport type { JSX } from 'react'\nimport type { GroupsResponse, HubConfig, SkillDetail, SourceCheckResult, SourcesResponse } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\nimport { dotStyle, formatDateTime, shortSha } from './format.ts'\nimport { SourceStatusBadge } from './SourceStatusBadge.tsx'\n\nexport interface SkillDetailViewProps {\n detail: SkillDetail\n hubConfig: HubConfig | null\n /** skillName → usage stat (count + last used). */\n uses: ReadonlyMap<string, { count: number; lastUsed?: number }>\n groupsState: GroupsResponse | null\n sourcesState: SourcesResponse | null\n sourceCheck: Readonly<Record<string, SourceCheckResult>>\n checkingSource: string | null\n syncingSource: string | null\n loading: boolean\n onBack: () => void\n /** Check one source repo for upstream updates. */\n onCheck: (repo: string) => void\n /** Request syncing the skill (overwrites local edits; opens a confirm). */\n onSync: (repo: string, skills: string[]) => void\n /** Request following the upstream deletion (moves into the trash). */\n onFollowDelete: (repo: string, skills: string[]) => void\n}\n\nexport function SkillDetailView(props: SkillDetailViewProps): JSX.Element {\n const { detail, hubConfig, uses, groupsState, sourcesState, sourceCheck, checkingSource, syncingSource, loading, onBack, onCheck, onSync, onFollowDelete } = props\n const detailSource = sourcesState?.sources.find((source) => source.skills.includes(detail.name))\n const detailCheck = detailSource !== undefined ? sourceCheck[detailSource.repo] : undefined\n return (\n <div className={css.panel}>\n <div className={css.detailHead}>\n <button type='button' className={css.back} onClick={onBack}>{tt('detail.back')}</button>\n <span className={css.detailName}>\n {detail.name}\n {/* 单一状态圆点:模型可调 → 蓝;否则用户可调 → 绿。与聊天 / 菜单同规则。 */}\n {detail.invocation.modelInvocable\n ? <span className={css.dot + ' ' + css.dotModel} style={dotStyle(hubConfig?.dotModelColor)} title={tt('legend.model')} />\n : detail.invocation.userInvocable\n ? <span className={css.dot + ' ' + css.dotUser} style={dotStyle(hubConfig?.dotUserColor)} title={tt('legend.user')} />\n : null}\n </span>\n </div>\n <div className={css.detailMeta}>\n <div className={css.detailMetaLine}>{tt('detail.provider')}: {detail.provider}</div>\n {detail.addedAt !== undefined ? <div className={css.detailMetaLine}>{tt('detail.addedAt')}: {formatDateTime(detail.addedAt)}</div> : null}\n {detail.updatedAt !== undefined ? <div className={css.detailMetaLine}>{tt('detail.updatedAt')}: {formatDateTime(detail.updatedAt)}</div> : null}\n {detail.path !== undefined ? <div className={css.detailMetaLine}>{tt('detail.path')}: {detail.path}</div> : null}\n {detail.whenToUse !== undefined ? <div className={css.detailMetaLine}>{tt('detail.whenToUse')}: {detail.whenToUse}</div> : null}\n {(() => {\n const stat = uses.get(detail.name)\n if (stat === undefined || stat.count === 0) return null\n const at = stat.lastUsed !== undefined ? ' · ' + new Date(stat.lastUsed).toLocaleString() : ''\n return <div className={css.detailMetaLine}>{tt('detail.uses')}: {stat.count}{at}</div>\n })()}\n {(() => {\n const tags = (groupsState?.tags ?? []).filter((tag) => tag.skillNames.includes(detail.name)).map((tag) => tag.name)\n return tags.length > 0 ? <div className={css.detailMetaLine}>{tt('detail.groups')}: {tags.join(', ')}</div> : null\n })()}\n </div>\n {detailSource !== undefined ? (\n <div className={css.sourceCard}>\n <div className={css.sourceCardTitle}>\n <a className={css.sourceLink} href={'https://github.com/' + detailSource.repo} target='_blank' rel='noreferrer'>{detailSource.repo}</a>\n {detailSource.ref !== undefined ? <span className={css.badge + ' ' + css.badgeSource}>{detailSource.ref}</span> : null}\n <SourceStatusBadge check={detailCheck} />\n </div>\n <div className={css.detailMetaLine}>\n {tt('source.commit')}: {detailSource.commitSha === '' ? tt('source.unverified') : shortSha(detailSource.commitSha)}\n </div>\n <div className={css.buttons + ' ' + css.actionsTop}>\n <button type='button' className={css.opBtn} disabled={checkingSource !== null} onClick={() => { onCheck(detailSource.repo) }}>\n {checkingSource === detailSource.repo ? tt('source.checking') : tt('source.check')}\n </button>\n <button type='button' className={css.opBtn} disabled={syncingSource !== null} onClick={() => { onSync(detailSource.repo, [detail.name]) }}>\n {syncingSource === detailSource.repo ? tt('source.syncing') : tt('source.sync')}\n </button>\n {detailCheck?.deleted.includes(detail.name) === true\n ? <button type='button' className={css.opBtn + ' ' + css.opDanger} onClick={() => { onFollowDelete(detailSource.repo, [detail.name]) }}>{tt('source.followDelete')}</button>\n : null}\n </div>\n </div>\n ) : (\n <p className={css.hintLine}>{tt('source.private')}</p>\n )}\n {loading ? <div className={css.muted}>{tt('detail.loading')}</div> : null}\n <pre className={css.detailContent}>{detail.content}</pre>\n </div>\n )\n}\n","/**\n * Full-page tag (scene) editor: rename / delete header, member checkbox\n * lists (enabled + disabled skills), and the save-members action. Pure\n * presentation — the draft state lives in the panel and arrives as props.\n */\n\nimport type { JSX } from 'react'\nimport type { CatalogResponse, SkillTag } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport css from './panel.module.css'\n\nexport interface TagEditorViewProps {\n tag: SkillTag\n /** Current name draft (panel-owned). */\n editName: string\n /** Current member-checkbox draft (panel-owned). */\n membersDraft: ReadonlySet<string>\n /** Current member-list search text (panel-owned). */\n editSearch: string\n catalog: CatalogResponse | null\n tagBusy: boolean\n onBack: () => void\n onEditName: (value: string) => void\n onEditSearch: (value: string) => void\n onToggleMember: (name: string, checked: boolean) => void\n /** Rename with the current draft (disabled while blank). */\n onRename: () => void\n /** Delete this tag (hidden for the default scene). */\n onDelete: () => void\n /** Persist the current member draft and leave the editor. */\n onSaveMembers: () => void\n}\n\nexport function TagEditorView(props: TagEditorViewProps): JSX.Element {\n const { tag, editName, membersDraft, editSearch, catalog, tagBusy, onBack, onEditName, onEditSearch, onToggleMember, onRename, onDelete, onSaveMembers } = props\n const editQuery = editSearch.trim().toLocaleLowerCase()\n const editSkills = (catalog?.skills ?? []).filter((skill) => editQuery.length === 0 || skill.name.toLocaleLowerCase().includes(editQuery) || skill.description.toLocaleLowerCase().includes(editQuery))\n const editDisabled = (catalog?.disabled ?? []).filter((record) => editQuery.length === 0 || record.name.toLocaleLowerCase().includes(editQuery) || record.description.toLocaleLowerCase().includes(editQuery))\n return (\n <div className={css.panel}>\n <div className={css.detailHead}>\n <button type='button' className={css.back} onClick={onBack}>{tt('detail.back')}</button>\n <input\n className={css.input + ' ' + css.grow}\n value={editName}\n onChange={(event) => { onEditName(event.target.value) }}\n placeholder={tt('groups.namePlaceholder')}\n />\n <button type='button' className={css.opBtn} disabled={tagBusy || editName.trim() === ''} onClick={onRename}>{tt('groups.rename')}</button>\n {tag.default !== true\n ? <button type='button' className={css.opBtn} disabled={tagBusy} onClick={onDelete}>{tt('groups.delete')}</button>\n : null}\n </div>\n <p className={css.hintLine}>{tt('groups.membersHint')}</p>\n <input className={css.search} value={editSearch} onChange={(event) => { onEditSearch(event.target.value) }} placeholder={tt('panel.search')} />\n <div className={css.section}>\n {editSkills.map((skill) => (\n <label key={skill.name} className={css.row}>\n <input\n type='checkbox'\n checked={membersDraft.has(skill.name)}\n onChange={(event) => { onToggleMember(skill.name, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{skill.name}</div>\n <div className={css.rowDesc}>{skill.description}</div>\n </div>\n </label>\n ))}\n {editDisabled.map((record) => (\n <label key={record.name} className={css.row}>\n <input\n type='checkbox'\n checked={membersDraft.has(record.name)}\n onChange={(event) => { onToggleMember(record.name, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{record.name}</div>\n <div className={css.rowDesc}>{record.description} · {tt('panel.disabled')}</div>\n </div>\n </label>\n ))}\n </div>\n <div className={css.buttons}>\n <button type='button' className={css.button + ' ' + css.primary} disabled={tagBusy} onClick={onSaveMembers}>{tt('groups.saveMembers')}</button>\n </div>\n </div>\n )\n}\n","/**\n * One enabled skill row: name + invocation dots + usage meta, delete and\n * disable actions. Shared by the flat list and both grouped views.\n */\n\nimport type { JSX, KeyboardEvent } from 'react'\nimport type { CatalogSkill } from '../../protocol.ts'\nimport { IconTrashOutline16 } from '../icons.tsx'\nimport { tt } from '../helpers.ts'\nimport { dotStyle, relativeTimeText } from './format.ts'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function SkillRow(props: { skill: CatalogSkill; hub: SkillHubState }): JSX.Element {\n const { skill, hub } = props\n const stat = hub.uses.get(skill.name)\n const count = stat?.count ?? 0\n const lastUsed = stat?.lastUsed\n /** 单一状态圆点:模型可调 → 蓝;否则用户可调 → 绿。与聊天 / 菜单同规则。 */\n const dot = skill.invocation.modelInvocable\n ? <span className={css.dot + ' ' + css.dotModel} style={dotStyle(hub.hubConfig?.dotModelColor)} title={tt('legend.model')} />\n : skill.invocation.userInvocable\n ? <span className={css.dot + ' ' + css.dotUser} style={dotStyle(hub.hubConfig?.dotUserColor)} title={tt('legend.user')} />\n : null\n /** 键盘打开详情:Enter 或空格。仅当焦点在行本身(而非行内按钮)时生效。 */\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>): void => {\n if (event.target !== event.currentTarget) return\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n void hub.openDetail(skill.name)\n }\n }\n return (\n <div\n className={css.row}\n role='button'\n tabIndex={0}\n aria-label={tt('row.open', { name: skill.name })}\n onClick={() => { void hub.openDetail(skill.name) }}\n onKeyDown={onKeyDown}\n >\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <span className={css.rowNameText}>{skill.name}</span>\n {count > 0 && hub.hubConfig?.showUseCount !== false ? <span className={css.useCount}>{count}</span> : null}\n {dot}\n {lastUsed !== undefined && hub.hubConfig?.showUseTime !== false ? <span className={css.useTime}>{relativeTimeText(lastUsed)}</span> : null}\n </div>\n <div className={css.rowDesc}>{skill.description}</div>\n </div>\n {skill.writable\n ? <>\n <button\n type='button'\n role='switch'\n aria-checked={true}\n aria-label={tt('row.disable')}\n className={css.switch + ' ' + css.switchOn}\n disabled={hub.busyNames.has(skill.name)}\n onClick={(event) => { event.stopPropagation(); void hub.toggle(skill, false) }}\n ><span className={css.switchThumb} /></button>\n {hub.editMode ? <button\n type='button'\n className={css.opBtn + ' ' + css.opDanger + ' ' + css.iconBtn}\n disabled={hub.busyNames.has(skill.name) || hub.tagBusy}\n title={tt('row.delete')}\n aria-label={tt('row.delete')}\n onClick={(event) => { event.stopPropagation(); hub.requestDeleteSkill(skill.name) }}\n ><IconTrashOutline16 size={14} /></button> : null}\n </>\n : <span className={css.badge + ' ' + css.badgeReadonly}>{tt('row.readonly')}</span>}\n </div>\n )\n}\n","/**\n * One disabled skill row (name + description + root badge + enable switch).\n * Shared by the source-group lists, the scene-group lists, and the bottom\n * disabled section.\n */\n\nimport type { JSX } from 'react'\nimport type { DisabledSkill, WritableRoot } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport type { HubKey } from '../locales.ts'\nimport css from './panel.module.css'\n\n/** Source badge label for a disabled record, derived from its writable root. */\nfunction disabledSourceLabel(root: WritableRoot): string {\n return tt(('badge.source.' + root) as HubKey)\n}\n\nexport function DisabledRow(props: { record: DisabledSkill; busy: boolean; onEnable: () => void }): JSX.Element {\n const { record, busy, onEnable } = props\n return (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>{record.name}</div>\n <div className={css.rowDesc}>{record.description}</div>\n </div>\n <span className={css.badges}>\n <span className={css.badge + ' ' + css.badgeSource}>{disabledSourceLabel(record.root)}</span>\n </span>\n <button type='button' role='switch' aria-checked={false} aria-label={tt('row.enable')} className={css.switch} disabled={busy} onClick={onEnable}><span className={css.switchThumb} /></button>\n </div>\n )\n}\n","/**\n * Group-header usage summary: total invocation count chip + the group's most\n * recent last-used time. Honours the showGroupSummary config switch.\n */\n\nimport type { JSX } from 'react'\nimport { relativeTimeText } from './format.ts'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function GroupSummary(props: { members: readonly string[]; hub: SkillHubState }): JSX.Element {\n const { members, hub } = props\n let total = 0\n let latest: number | undefined\n for (const name of members) {\n const stat = hub.uses.get(name)\n if (stat === undefined) continue\n total += stat.count\n if (stat.lastUsed !== undefined && (latest === undefined || stat.lastUsed > latest)) latest = stat.lastUsed\n }\n return (\n <span className={css.groupTitleInner}>\n {hub.hubConfig?.showGroupSummary !== false && total > 0 ? <span className={css.useCount}>{total}</span> : null}\n {hub.hubConfig?.showGroupSummary !== false && latest !== undefined ? <span className={css.useTime + ' ' + css.groupTime}>{relativeTimeText(latest)}</span> : null}\n </span>\n )\n}\n","/**\n * Sources tab: the flat skill list or the grouped view — a project-level\n * three-tier tree (workspaces from workspace.json, each optionally split by\n * .dsh/.agents), one card per upstream collection with check/sync/\n * follow-delete actions and the tri-state switch, plus the uncategorized\n * \"personal\" card (project skills never count as personal).\n */\n\nimport { useState, type JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { filterBySource, groupSwitchView, isProjectSource, PRIVATE_SOURCE } from '../grouping.ts'\nimport { SourceStatusBadge } from './SourceStatusBadge.tsx'\nimport { SkillRow } from './SkillRow.tsx'\nimport { DisabledRow } from './DisabledRow.tsx'\nimport { GroupSummary } from './GroupSummary.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\n/** 项目级三级树:项目级 → 具体工作区(可折叠、可细分)→ .dsh/.agents。 */\nfunction ProjectTree(props: { hub: SkillHubState }): JSX.Element | null {\n const { hub } = props\n const { sorted, sourceFilter, origins, collapsedGroups, subdividedProjects, toggleGroupCollapse, toggleSubdivide } = hub\n const projectSkills = filterBySource(sorted, sourceFilter, origins).filter((skill) => isProjectSource(skill.source))\n if (projectSkills.length === 0) return null\n // workspace 缺失(过渡态)时按 source 降级分组,避免空标题。\n const byProject = new Map<string, { title: string; skills: typeof projectSkills }>()\n for (const skill of projectSkills) {\n const key = skill.workspace ?? skill.source\n const entry = byProject.get(key)\n if (entry === undefined) {\n byProject.set(key, {\n title: skill.workspaceTitle ?? skill.workspace ?? tt('groups.project'),\n skills: [skill],\n })\n } else {\n entry.skills.push(skill)\n }\n }\n const topCollapsed = collapsedGroups.has('project')\n return (\n <section className={css.section}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!topCollapsed} onClick={() => { toggleGroupCollapse('project') }}>\n <span className={css.chevron + (topCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tt('groups.project')} · {byProject.size}\n </span>\n </button>\n </div>\n {!topCollapsed ? [...byProject.entries()].map(([key, proj]) => {\n const projKey = 'project:' + key\n const projCollapsed = collapsedGroups.has(projKey)\n const subdivided = subdividedProjects.has(key)\n return (\n <div key={projKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!projCollapsed} onClick={() => { toggleGroupCollapse(projKey) }}>\n <span className={css.chevron + (projCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {proj.title} · {proj.skills.length}\n <GroupSummary members={proj.skills.map((skill) => skill.name)} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <button type='button' className={css.opBtn} onClick={(event) => { event.stopPropagation(); toggleSubdivide(key) }}>\n {subdivided ? tt('groups.merge') : tt('groups.subdivide')}\n </button>\n </span>\n </div>\n {!projCollapsed ? (\n subdivided ? (\n <div className={css.projectNest}>\n {(['project-dsh', 'project-agents'] as const).map((source) => {\n const list = proj.skills.filter((skill) => skill.source === source)\n if (list.length === 0) return null\n const srcKey = projKey + ':' + source\n const srcCollapsed = collapsedGroups.has(srcKey)\n return (\n <div key={srcKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!srcCollapsed} onClick={() => { toggleGroupCollapse(srcKey) }}>\n <span className={css.chevron + (srcCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tt(('badge.source.' + source) as 'badge.source.project-dsh' | 'badge.source.project-agents')} · {list.length}\n </span>\n </button>\n </div>\n {!srcCollapsed ? list.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />) : null}\n </div>\n )\n })}\n </div>\n ) : proj.skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)\n ) : null}\n </div>\n )\n }) : null}\n </section>\n )\n}\n\nexport function SourcesView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { catalog, groupsState, skillView, sourceFilter, origins, sorted, normalized, collapsedGroups, viewNames, sourceCheck, actionNames, checkingSource, syncingSource, batchBusy, busyNames, toggleGroupCollapse, checkSources, requestSync, requestDelete, requestDeleteGroup, toggleGroup, enableDisabled } = hub\n const [topDragKey, setTopDragKey] = useState<string | null>(null)\n const [topOverKey, setTopOverKey] = useState<string | null>(null)\n\n if (skillView === 'flat') {\n return <>{filterBySource(sorted, sourceFilter, origins).map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}</>\n }\n\n // ----- 顶层分组统一拖拽(project / col:xxx / personal 全部可拖) -----\n const projectSkillsAll = filterBySource(sorted, sourceFilter, origins).filter((skill) => isProjectSource(skill.source))\n const hasProject = projectSkillsAll.length > 0\n const collections = groupsState?.collections ?? []\n const uncategorized = filterBySource(sorted, sourceFilter, origins).filter((skill) => origins[skill.name] === undefined && !isProjectSource(skill.source))\n const personalDisabledAll = (catalog?.disabled ?? []).filter((record) => origins[record.name] === undefined)\n .filter((record) => normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized))\n .filter((record) => sourceFilter === 'all' || sourceFilter === PRIVATE_SOURCE)\n const allPersonalNamesAll = [...uncategorized.map((s) => s.name), ...personalDisabledAll.map((r) => r.name)]\n const hasPersonal = allPersonalNamesAll.length > 0\n const defaultTopKeys: string[] = [\n ...(hasProject ? ['project'] : []),\n ...collections.map((c) => 'col:' + c.name),\n ...(hasPersonal ? ['uncategorized-source'] : []),\n ]\n const storedTopOrder = groupsState?.sourceGroupOrder ?? []\n const topOrderedKeys = (() => {\n if (storedTopOrder.length === 0) return defaultTopKeys\n const set = new Set(storedTopOrder)\n const result = storedTopOrder.filter((k) => defaultTopKeys.includes(k))\n for (const k of defaultTopKeys) if (!set.has(k)) result.push(k)\n // 兼容旧 collectionOrder:若 storedTopOrder 为空但旧 order 有值,已在 defaultTopKeys 中体现 collection 顺序\n if (result.length === 0) return defaultTopKeys\n return result\n })()\n const handleTopDrop = (targetKey: string): void => {\n if (topDragKey === null || topDragKey === targetKey) return\n const from = topOrderedKeys.indexOf(topDragKey)\n const to = topOrderedKeys.indexOf(targetKey)\n if (from === -1 || to === -1) return\n const next = [...topOrderedKeys]\n const [moved] = next.splice(from, 1)\n next.splice(to, 0, moved)\n void hub.reorderSourceGroups(next)\n }\n // 兼容旧逻辑:若用户拖的是 collection 且未使用顶层排序,回退到 collectionReorder(保留旧数据兼容)\n const handleCollectionDropLegacy = (targetName: string): void => {\n // 仅当顶层排序未启用时(storedTopOrder 为空)才用旧接口\n if ((groupsState?.sourceGroupOrder?.length ?? 0) > 0) { handleTopDrop('col:' + targetName); return }\n const dragCol = topDragKey !== null && topDragKey.startsWith('col:') ? topDragKey.slice(4) : null\n if (dragCol === null || dragCol === targetName || groupsState === null) return\n const names = groupsState.collections.map((c) => c.name)\n const from = names.indexOf(dragCol)\n const to = names.indexOf(targetName)\n if (from === -1 || to === -1) return\n const next = [...names]\n const [moved] = next.splice(from, 1)\n next.splice(to, 0, moved)\n void hub.reorderCollections(next)\n }\n\n // 空状态:没有任何分组时提示\n const isEmptyTop = !hasProject && collections.length === 0 && !hasPersonal\n return (\n <>\n {isEmptyTop ? <div className={css.empty}>{tt('groups.noCollections')}</div> : null}\n {topOrderedKeys.map((topKey) => {\n // Project 顶层卡片(可拖)\n if (topKey === 'project' && hasProject) {\n const topCollapsed = collapsedGroups.has('project')\n const isDragging = topDragKey === 'project'\n const isOver = topOverKey === 'project' && topDragKey !== 'project'\n // 按 workspace 聚合,与 ProjectTree 逻辑一致\n const byProject = new Map<string, { title: string; skills: typeof projectSkillsAll }>()\n for (const skill of projectSkillsAll) {\n const key = skill.workspace ?? skill.source\n const entry = byProject.get(key)\n if (entry === undefined) byProject.set(key, { title: skill.workspaceTitle ?? skill.workspace ?? tt('groups.project'), skills: [skill] })\n else entry.skills.push(skill)\n }\n return (\n <section\n key=\"project\"\n className={css.section + (isDragging ? ' ' + css.dragging : '') + (isOver ? ' ' + css.dragOver : '')}\n draggable\n onDragStart={(e) => { setTopDragKey('project'); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', 'project') }}\n onDragOver={(e) => { e.preventDefault(); if (topOverKey !== 'project') setTopOverKey('project') }}\n onDragLeave={() => { if (topOverKey === 'project') setTopOverKey(null) }}\n onDrop={(e) => { e.preventDefault(); handleTopDrop('project'); setTopOverKey(null) }}\n onDragEnd={() => { setTopDragKey(null); setTopOverKey(null) }}\n >\n <div className={css.groupHead}>\n <span className={css.dragHandle} aria-hidden title=\"拖拽调整顺序\">⋮⋮</span>\n <button type='button' className={css.disclosure} aria-expanded={!topCollapsed} onClick={() => { toggleGroupCollapse('project') }}>\n <span className={css.chevron + (topCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>{tt('groups.project')} · {byProject.size}</span>\n </button>\n </div>\n {!topCollapsed ? [...byProject.entries()].map(([key, proj]) => {\n const projKey = 'project:' + key\n const projCollapsed = collapsedGroups.has(projKey)\n const subdivided = hub.subdividedProjects.has(key)\n return (\n <div key={projKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!projCollapsed} onClick={() => { toggleGroupCollapse(projKey) }}>\n <span className={css.chevron + (projCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>{proj.title} · {proj.skills.length}<GroupSummary members={proj.skills.map((s) => s.name)} hub={hub} /></span>\n </button>\n <span className={css.groupOps}>\n <button type='button' className={css.opBtn} onClick={(event) => { event.stopPropagation(); hub.toggleSubdivide(key) }}>{subdivided ? tt('groups.merge') : tt('groups.subdivide')}</button>\n </span>\n </div>\n {!projCollapsed ? (\n subdivided ? (\n <div className={css.projectNest}>\n {(['project-dsh', 'project-agents'] as const).map((source) => {\n const list = proj.skills.filter((skill) => skill.source === source)\n if (list.length === 0) return null\n const srcKey = projKey + ':' + source\n const srcCollapsed = collapsedGroups.has(srcKey)\n return (\n <div key={srcKey} className={css.projectNest}>\n <div className={css.groupHead}>\n <button type='button' className={css.disclosure} aria-expanded={!srcCollapsed} onClick={() => { toggleGroupCollapse(srcKey) }}>\n <span className={css.chevron + (srcCollapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>{tt(('badge.source.' + source) as 'badge.source.project-dsh' | 'badge.source.project-agents')} · {list.length}</span>\n </button>\n </div>\n {!srcCollapsed ? list.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />) : null}\n </div>\n )\n })}\n </div>\n ) : proj.skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)\n ) : null}\n </div>\n )\n }) : null}\n </section>\n )\n }\n // Collection 卡片(可拖,归属顶层排序)\n if (topKey.startsWith('col:')) {\n const colName = topKey.slice(4)\n const collection = collections.find((c) => c.name === colName)\n if (collection === undefined) return null\n const skills = filterBySource(sorted, sourceFilter, origins).filter((skill) => collection.skillNames.includes(skill.name))\n const disabledMembers = (catalog?.disabled ?? []).filter((record) =>\n collection.skillNames.includes(record.name)\n && (normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized))\n && (sourceFilter === 'all' || (origins[record.name] ?? PRIVATE_SOURCE) === sourceFilter))\n const collapsed = collapsedGroups.has('col:' + collection.name)\n const view = groupSwitchView(collection.skillNames, viewNames)\n const check = sourceCheck[collection.name]\n const hasWritable = collection.skillNames.some((name) => actionNames.has(name))\n const isDragging = topDragKey === topKey\n const isOver = topOverKey === topKey && topDragKey !== topKey\n return (\n <section\n key={'col:' + collection.name}\n className={css.section + (isDragging ? ' ' + css.dragging : '') + (isOver ? ' ' + css.dragOver : '')}\n draggable\n onDragStart={(e) => { setTopDragKey(topKey); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', topKey) }}\n onDragOver={(e) => { e.preventDefault(); if (topOverKey !== topKey) setTopOverKey(topKey) }}\n onDragLeave={() => { if (topOverKey === topKey) setTopOverKey(null) }}\n onDrop={(e) => { e.preventDefault(); handleTopDrop(topKey); setTopOverKey(null) }}\n onDragEnd={() => { setTopDragKey(null); setTopOverKey(null) }}\n >\n <div className={css.groupHead}>\n <span className={css.dragHandle} aria-hidden title=\"拖拽调整顺序\">⋮⋮</span>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('col:' + collection.name) }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n <a className={css.sourceLink} href={'https://github.com/' + collection.name} target='_blank' rel='noreferrer' onClick={(event) => { event.stopPropagation() }}>{collection.name}</a>\n {' · ' + collection.skillNames.length}\n <GroupSummary members={collection.skillNames} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <SourceStatusBadge\n check={check}\n checking={checkingSource === collection.name}\n onCheck={() => { void checkSources(collection.name) }}\n />\n {check !== undefined && check.changed && check.updated.length > 0\n ? <button type='button' className={css.opBtn} disabled={syncingSource !== null} onClick={(event) => { event.stopPropagation(); requestSync(collection.name, check.updated) }}>\n {syncingSource === collection.name ? tt('source.syncing') : tt('source.sync')}\n </button>\n : null}\n {check !== undefined && check.deleted.length > 0\n ? <button type='button' className={css.opBtn + ' ' + css.opDanger} onClick={(event) => { event.stopPropagation(); requestDelete(collection.name, check.deleted) }}>{tt('source.followDelete')}</button>\n : null}\n <button type='button' role='switch' aria-checked={view.state !== 'off'} aria-label={collection.name}\n className={css.switch + (view.state === 'on' ? ' ' + css.switchOn : view.state === 'mixed' ? ' ' + css.switchMixed : '')}\n disabled={batchBusy || collection.skillNames.length === 0 || (view.state !== 'off' && !hasWritable)}\n title={view.state !== 'off' && !hasWritable ? tt('groups.noWritable') : undefined}\n onClick={(event) => { event.stopPropagation(); toggleGroup('col:' + collection.name, collection.name, view.state) }}>\n <span className={css.switchThumb} />\n </button>\n {hub.editMode ? <button\n type='button'\n className={css.opBtn + ' ' + css.opDanger}\n title={tt('source.deleteGroupHint', { count: collection.skillNames.length })}\n onClick={(event) => { event.stopPropagation(); requestDeleteGroup(collection.name, collection.skillNames) }}\n >\n {tt('source.deleteGroup')}\n </button> : null}\n </span>\n </div>\n {!collapsed ? (\n <>\n {skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}\n {disabledMembers.map((record) => (\n <DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />\n ))}\n </>\n ) : null}\n </section>\n )\n }\n // Personal 顶层卡片(可拖)\n if (topKey === 'uncategorized-source' && hasPersonal) {\n const uncategorized = filterBySource(sorted, sourceFilter, origins).filter((skill) => origins[skill.name] === undefined && !isProjectSource(skill.source))\n const personalDisabled = (catalog?.disabled ?? []).filter((record) => origins[record.name] === undefined)\n .filter((record) => normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized))\n .filter((record) => sourceFilter === 'all' || sourceFilter === PRIVATE_SOURCE)\n const allPersonalNames = [...uncategorized.map((s) => s.name), ...personalDisabled.map((r) => r.name)]\n if (allPersonalNames.length === 0) return null\n const collapsed = collapsedGroups.has('uncategorized-source')\n const isDragging = topDragKey === 'uncategorized-source'\n const isOver = topOverKey === 'uncategorized-source' && topDragKey !== 'uncategorized-source'\n return (\n <section\n key=\"uncategorized-source\"\n className={css.section + (isDragging ? ' ' + css.dragging : '') + (isOver ? ' ' + css.dragOver : '')}\n draggable\n onDragStart={(e) => { setTopDragKey('uncategorized-source'); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', 'uncategorized-source') }}\n onDragOver={(e) => { e.preventDefault(); if (topOverKey !== 'uncategorized-source') setTopOverKey('uncategorized-source') }}\n onDragLeave={() => { if (topOverKey === 'uncategorized-source') setTopOverKey(null) }}\n onDrop={(e) => { e.preventDefault(); handleTopDrop('uncategorized-source'); setTopOverKey(null) }}\n onDragEnd={() => { setTopDragKey(null); setTopOverKey(null) }}\n >\n <div className={css.groupHead}>\n <span className={css.dragHandle} aria-hidden title=\"拖拽调整顺序\">⋮⋮</span>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('uncategorized-source') }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>{tt('groups.personal')} · {allPersonalNames.length}<GroupSummary members={allPersonalNames} hub={hub} /></span>\n </button>\n <span className={css.groupOps}>\n {hub.editMode ? <button type='button' className={css.opBtn + ' ' + css.opDanger} title={tt('source.deleteGroupHint', { count: allPersonalNames.length })} onClick={(event) => { event.stopPropagation(); requestDeleteGroup(tt('groups.personal'), allPersonalNames) }}>{tt('source.deleteGroup')}</button> : null}\n </span>\n </div>\n {!collapsed ? (\n <>\n {uncategorized.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}\n {personalDisabled.map((record) => (<DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />))}\n </>\n ) : null}\n </section>\n )\n }\n return null\n })}\n </>\n )\n}\n","/**\n * Scenes tab: user tag groups (one card per scene with the tri-state switch\n * and edit entry) plus the new-scene form. Scenes are the user's own\n * enable/disable units (e.g. a Godot scene vs a Java scene); upstream repos\n * are managed in the sources tab.\n */\n\nimport { useState, type JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { groupSwitchView } from '../grouping.ts'\nimport { SkillRow } from './SkillRow.tsx'\nimport { DisabledRow } from './DisabledRow.tsx'\nimport { GroupSummary } from './GroupSummary.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport function ScenesView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { catalog, groupsState, sorted, normalized, collapsedGroups, viewNames, actionNames, batchBusy, busyNames, newTagName, setNewTagName, tagBusy, createTag, toggleGroupCollapse, toggleGroup, setEditingTag, setEditName, setMembersDraft, setEditSearch, enableDisabled } = hub\n const [dragId, setDragId] = useState<string | null>(null)\n const [overId, setOverId] = useState<string | null>(null)\n const handleDrop = (targetId: string): void => {\n if (dragId === null || dragId === targetId || groupsState === null) return\n const ids = groupsState.tags.map((t) => t.id)\n const from = ids.indexOf(dragId)\n const to = ids.indexOf(targetId)\n if (from === -1 || to === -1) return\n const next = [...ids]\n const [moved] = next.splice(from, 1)\n next.splice(to, 0, moved)\n void hub.reorderTags(next)\n }\n return (\n <>\n <form className={css.form} onSubmit={(event) => { void createTag(event) }}>\n <div className={css.buttons}>\n <input\n className={css.input + ' ' + css.grow}\n value={newTagName}\n onChange={(event) => { setNewTagName(event.target.value) }}\n placeholder={tt('groups.namePlaceholder')}\n />\n <button type='submit' className={css.button + ' ' + css.primary} disabled={tagBusy || newTagName.trim() === ''}>{tt('groups.new')}</button>\n </div>\n </form>\n\n {groupsState !== null && groupsState.tags.length === 0 ? <div className={css.empty}>{tt('groups.empty')}</div> : null}\n {groupsState?.tags.map((tag) => {\n const skills = sorted.filter((skill) => tag.skillNames.includes(skill.name))\n const disabledMembers = (catalog?.disabled ?? []).filter((record) => tag.skillNames.includes(record.name) && (normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized)))\n const collapsed = collapsedGroups.has('tag:' + tag.id)\n const view = groupSwitchView(tag.skillNames, viewNames)\n const hasWritable = tag.skillNames.some((name) => actionNames.has(name))\n const isDragging = dragId === tag.id\n const isOver = overId === tag.id && dragId !== tag.id\n return (\n <section\n key={'tag:' + tag.id}\n className={css.section + (isDragging ? ' ' + css.dragging : '') + (isOver ? ' ' + css.dragOver : '')}\n draggable\n onDragStart={(e) => { setDragId(tag.id); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', tag.id) }}\n onDragOver={(e) => { e.preventDefault(); if (overId !== tag.id) setOverId(tag.id) }}\n onDragLeave={() => { if (overId === tag.id) setOverId(null) }}\n onDrop={(e) => { e.preventDefault(); handleDrop(tag.id); setOverId(null) }}\n onDragEnd={() => { setDragId(null); setOverId(null) }}\n >\n <div className={css.groupHead}>\n <span className={css.dragHandle} aria-hidden title=\"拖拽调整顺序\">⋮⋮</span>\n <button type='button' className={css.disclosure} aria-expanded={!collapsed} onClick={() => { toggleGroupCollapse('tag:' + tag.id) }}>\n <span className={css.chevron + (collapsed ? ' ' + css.chevronCollapsed : '')} />\n <span className={css.groupTitle}>\n {tag.name} · {tag.skillNames.length}\n <GroupSummary members={tag.skillNames} hub={hub} />\n </span>\n </button>\n <span className={css.groupOps}>\n <button type='button' role='switch' aria-checked={view.state !== 'off'} aria-label={tag.name}\n className={css.switch + (view.state === 'on' ? ' ' + css.switchOn : view.state === 'mixed' ? ' ' + css.switchMixed : '')}\n disabled={batchBusy || tag.skillNames.length === 0 || (view.state !== 'off' && !hasWritable)}\n title={view.state !== 'off' && !hasWritable ? tt('groups.noWritable') : undefined}\n onClick={(event) => { event.stopPropagation(); toggleGroup('tag:' + tag.id, tag.name, view.state) }}>\n <span className={css.switchThumb} />\n </button>\n <button type='button' className={css.opBtn} onClick={() => { setEditingTag(tag); setEditName(tag.name); setMembersDraft(new Set(tag.skillNames)); setEditSearch('') }}>{tt('groups.edit')}</button>\n </span>\n </div>\n {!collapsed ? (\n <>\n {skills.map((skill) => <SkillRow key={skill.name} skill={skill} hub={hub} />)}\n {disabledMembers.map((record) => (\n <DisabledRow key={record.name} record={record} busy={busyNames.has(record.name)} onEnable={() => { void enableDisabled(record) }} />\n ))}\n </>\n ) : null}\n </section>\n )\n })}\n </>\n )\n}\n","/**\n * Built-in market catalog: well-known skill repos shown on the market tab so\n * users can browse and install without knowing repo URLs.\n * Only the repo slug lives here; adding goes through the normal\n * market-source route and records upstream tracking like any manual source.\n */\n\nimport type { HubKey } from './locales.ts'\n\nexport interface MarketCatalogEntry {\n repo: string\n /** locales.ts key for the one-line description. */\n descriptionKey: HubKey\n}\n\n/** 默认市场目录:精选技能仓库(顺序即展示顺序)。 */\nexport const MARKET_CATALOG: readonly MarketCatalogEntry[] = [\n { repo: 'anthropics/skills', descriptionKey: 'market.catalog.anthropics' },\n { repo: 'obra/superpowers', descriptionKey: 'market.catalog.superpowers' },\n { repo: 'mattpocock/skills', descriptionKey: 'market.catalog.mattpocock' },\n { repo: 'nexu-io/open-design', descriptionKey: 'market.catalog.openDesign' },\n]\n","/**\n * Shared dialog family for the panel: one overlay shell plus the specific\n * dialogs (group-close conflict, sync/delete confirm, branch picker, and\n * market sync selection). Every dialog closes on outside click and keeps\n * the same role/aria shell; the panel owns all dialog state.\n */\n\nimport { useEffect, type JSX, type ReactNode } from 'react'\nimport type { CollectionGroup, SkillTag } from '../../protocol.ts'\nimport { tt } from '../helpers.ts'\nimport { groupNamesOf } from '../grouping.ts'\nimport css from './panel.module.css'\n\n/** A group-close conflict waiting for the user's decision. */\nexport interface ConflictDialogState {\n /** Group key: 'tag:<id>' or 'col:<name>'. */\n key: string\n name: string\n /** Conflicting skill names (enabled here and in other groups). */\n conflicts: string[]\n}\n\n/** A destructive/sync confirmation waiting for the user's decision. */\nexport interface ConfirmDialogState {\n kind: 'sync' | 'delete'\n repo: string\n /** Skills the action applies to. */\n skills: string[]\n}\n\n/** Branch picker shown when a repo has no release and no pinned ref. */\nexport interface BranchChoiceState {\n repo: string\n branches: string[]\n selected: string\n}\n\n/** Post-sync skill update dialog: which tracked skills to refresh. */\nexport interface MarketSyncDialogState {\n repo: string\n ref: string\n skills: string[]\n selected: ReadonlySet<string>\n}\n\n/** Overlay + centered alert-dialog shell; outside click or Escape cancels. */\nfunction DialogShell(props: { onClose: () => void; children: ReactNode }): JSX.Element {\n useEffect(() => {\n const onKey = (event: KeyboardEvent): void => {\n if (event.key === 'Escape') props.onClose()\n }\n window.addEventListener('keydown', onKey)\n return () => { window.removeEventListener('keydown', onKey) }\n })\n return (\n <div className={css.dialogOverlay} onClick={props.onClose}>\n <div className={css.dialog} role='alertdialog' aria-modal='true' onClick={(event) => { event.stopPropagation() }}>\n {props.children}\n </div>\n </div>\n )\n}\n\n/** Simple confirm dialog: title + text + optional skill list + cancel/confirm. */\nexport function ConfirmDialog(props: {\n title: string\n text: string\n /** Optional skill names listed between the text and the buttons. */\n items?: readonly string[]\n confirmLabel: string\n /** Danger-styled confirm button (destructive actions). */\n danger?: boolean\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { title, text, items, confirmLabel, danger, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{title}</h3>\n <p className={css.dialogText}>{text}</p>\n {items !== undefined ? (\n <ul className={css.dialogList}>\n {items.map((name) => <li key={name}><span className={css.rowNameText}>{name}</span></li>)}\n </ul>\n ) : null}\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('form.cancel')}</button>\n <button type='button' className={css.button + (danger === true ? ' ' + css.danger : ' ' + css.primary)} onClick={onConfirm}>\n {confirmLabel}\n </button>\n </div>\n </DialogShell>\n )\n}\n\n/** Group-close conflict: which skills stay on, and which other groups also enable them. */\nexport function ConflictDialog(props: {\n dialog: ConflictDialogState\n tags: readonly SkillTag[]\n collections: readonly CollectionGroup[]\n onClose: () => void\n onKeepOn: () => void\n onCloseAll: () => void\n}): JSX.Element {\n const { dialog, tags, collections, onClose, onKeepOn, onCloseAll } = props\n return (\n <DialogShell onClose={onClose}>\n <h3 className={css.dialogTitle}>{tt('groups.conflictTitle')}</h3>\n <p className={css.dialogText}>{tt('groups.conflictText')}</p>\n <ul className={css.dialogList}>\n {dialog.conflicts.map((name) => (\n <li key={name}>\n <span className={css.rowNameText}>{name}</span>\n {' — ' + groupNamesOf(name, [...tags], [...collections]).join(', ')}\n </li>\n ))}\n </ul>\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onKeepOn}>{tt('groups.keepOn')}</button>\n <button type='button' className={css.button + ' ' + css.primary} onClick={onCloseAll}>{tt('groups.closeAll')}</button>\n </div>\n </DialogShell>\n )\n}\n\n/** Branch picker for a repo without releases (pins the ref, then rescans). */\nexport function BranchChoiceDialog(props: {\n choice: BranchChoiceState\n busy: boolean\n onSelect: (branch: string) => void\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { choice, busy, onSelect, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{tt('market.branchTitle')}</h3>\n <p className={css.dialogText}>{tt('market.branchHint')}</p>\n <select className={css.select + ' ' + css.dialogSelect} value={choice.selected}\n onChange={(event) => { onSelect(event.target.value) }}>\n {choice.branches.map((branch) => <option key={branch} value={branch}>{branch}</option>)}\n </select>\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('form.cancel')}</button>\n <button type='button' className={css.button + ' ' + css.primary} disabled={busy} onClick={onConfirm}>{tt('market.branchConfirm')}</button>\n </div>\n </DialogShell>\n )\n}\n\n/** Post-sync selection: which tracked skills to batch-update to the new version. */\nexport function MarketSyncDialog(props: {\n dialog: MarketSyncDialogState\n busy: boolean\n onToggle: (name: string, checked: boolean) => void\n onCancel: () => void\n onConfirm: () => void\n}): JSX.Element {\n const { dialog, busy, onToggle, onCancel, onConfirm } = props\n return (\n <DialogShell onClose={onCancel}>\n <h3 className={css.dialogTitle}>{tt('market.syncTitle')}</h3>\n <p className={css.dialogText}>{tt('market.syncText', { ref: dialog.ref })}</p>\n {dialog.skills.length === 0 ? (\n <p className={css.dialogText}>{tt('market.syncNone')}</p>\n ) : (\n <div className={css.dialogList}>\n {dialog.skills.map((name) => (\n <label key={name} className={css.dialogRow}>\n <input type='checkbox' checked={dialog.selected.has(name)}\n onChange={(event) => { onToggle(name, event.target.checked) }} />\n <span className={css.rowNameText}>{name}</span>\n </label>\n ))}\n </div>\n )}\n <div className={css.dialogActions}>\n <button type='button' className={css.button} onClick={onCancel}>{tt('market.syncCancel')}</button>\n <button type='button' className={css.button + ' ' + css.primary} disabled={busy || dialog.skills.length === 0} onClick={onConfirm}>\n {busy ? tt('source.syncing') : tt('source.sync')}\n </button>\n </div>\n </DialogShell>\n )\n}\n","/**\n * Market tab: one unified market list — built-in catalog entries (add\n * button while not yet added) and the user's market sources (full state\n * badges + actions once added, plus custom sources), with check-all and\n * update-all actions and the repo scan result with the importable checklist.\n */\n\nimport { Fragment, useEffect, useMemo, useState, type JSX } from 'react'\nimport { tt } from '../helpers.ts'\nimport { MARKET_CATALOG } from '../market-catalog.ts'\nimport type { MarketSourceRecord, RepoSkillEntry } from '../../protocol.ts'\nimport { ConfirmDialog } from './dialogs.tsx'\nimport type { SkillHubState } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\n/** Compact byte size for repo preview rows. */\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return bytes + ' B'\n if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'\n return (bytes / 1024 / 1024).toFixed(1) + ' MB'\n}\nfunction formatSpeed(bps?: number): string {\n if (bps === undefined || bps <= 0) return ''\n if (bps < 1024) return bps + ' B/s'\n if (bps < 1024 * 1024) return (bps / 1024).toFixed(1) + ' KB/s'\n return (bps / 1024 / 1024).toFixed(1) + ' MB/s'\n}\n\nexport function MarketView(props: { hub: SkillHubState }): JSX.Element {\n const { hub } = props\n const { marketState, marketCheck, sourceCheck, sourcesState, repoDiscoverState, scanningRepo, repoSelected, setRepoSelected, repoImporting, repoResult, newSourceName, setNewSourceName, syncingMarket, tagBusy, checkingSource, addSource, addMarketSource, removeMarketSource, scanRepo, checkMarket, checkSources, syncMarketSource, toggleRepoSelected, importRepo, cancelImport, updateAllDialog, setUpdateAllDialog, updateAll } = hub\n /** 有可更新技能的来源(全部更新按钮与确认列表共用)。 */\n const updatableRepos = Object.entries(sourceCheck).filter(([, check]) => check.changed && check.updated.length > 0)\n\n // 276 列表本地状态:搜索 / 过滤 / 分页(精简:扁平列表,无 A-Z 分组)\n const [repoSearch, setRepoSearch] = useState('')\n const [repoFilter, setRepoFilter] = useState<string>('all')\n const [visibleCount, setVisibleCount] = useState(50)\n useEffect(() => { setVisibleCount(50) }, [repoDiscoverState, repoSearch, repoFilter])\n\n /** 一个已添加来源的完整行:状态徽章 + 操作按钮。B 方案:扫描主按钮 + 智能更新按钮(检查/更新二合一)+ 溢出移除 */\n const sourceRow = (record: MarketSourceRecord): JSX.Element => {\n const releaseCheck = marketCheck[record.repo]\n const skillCheck = sourceCheck[record.repo]\n const installedCount = sourcesState?.sources.find((source) => source.repo === record.repo)?.skills.length ?? 0\n const scanning = scanningRepo === record.repo\n const syncing = syncingMarket === record.repo\n const checking = checkingSource === record.repo\n const hasSkillUpdate = skillCheck?.changed === true && skillCheck.updated.length > 0\n const hasReleaseUpdate = releaseCheck?.updateAvailable === true\n const hasUpdate = hasSkillUpdate || hasReleaseUpdate\n const isChecked = releaseCheck !== undefined || skillCheck !== undefined\n // 智能按钮三态:未检查→检查更新,未检查完/有更新→更新 N 个,已检查无更新→已是最新\n let updateLabel: string\n let updateDisabled = false\n let updateDanger = false\n let updateAction: () => void = () => {}\n if (syncing) {\n updateLabel = tt('market.syncing')\n updateDisabled = true\n } else if (checking) {\n updateLabel = tt('market.checking')\n updateDisabled = true\n } else if (!isChecked) {\n updateLabel = tt('market.checkUpdate')\n updateAction = () => { void checkSources(record.repo); void checkMarket() }\n } else if (hasUpdate) {\n const count = hasSkillUpdate ? skillCheck!.updated.length : 1\n updateLabel = count > 1 || hasSkillUpdate ? tt('market.updateCount', { count }) : tt('market.update')\n updateDanger = true\n updateAction = () => { void syncMarketSource(record.repo) }\n } else {\n updateLabel = tt('market.upToDate')\n updateDisabled = true\n }\n return (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <a className={css.sourceLink} href={'https://github.com/' + record.repo} target='_blank' rel='noreferrer'>{record.repo}</a>\n {record.ref !== undefined ? <span className={css.badge + ' ' + css.badgeSource}>{record.ref}</span> : null}\n {installedCount > 0 ? <span className={css.badge + ' ' + css.badgeCount}>{tt('market.installed', { count: installedCount })}</span> : null}\n {hasSkillUpdate\n ? <span className={css.badge + ' ' + css.statusUpdated}>{tt('market.updatable', { count: skillCheck!.updated.length })}</span>\n : null}\n {skillCheck !== undefined && skillCheck.deleted.length > 0\n ? <span className={css.badge + ' ' + css.statusError}>{tt('market.deletedUpstream', { count: skillCheck.deleted.length })}</span>\n : null}\n {hasReleaseUpdate\n ? <span className={css.badge + ' ' + css.statusUpdated}>{releaseCheck!.latestTag !== undefined ? tt('market.newRelease', { version: releaseCheck!.latestTag }) : tt('market.updated')}</span>\n : null}\n </div>\n </div>\n <button type='button' className={css.button + ' ' + css.primary} style={{ padding:'4px 10px', fontSize:12 }} disabled={scanning} onClick={() => { void scanRepo(record.repo) }}>\n {scanning ? tt('market.scanning') : tt('market.scan')}\n </button>\n <button\n type='button'\n className={css.opBtn + (updateDanger ? ' ' + css.opDanger : '')}\n disabled={updateDisabled}\n title={hasUpdate ? '将同步到上游最新版并提示可更新的本地技能' : undefined}\n onClick={updateAction}\n >\n {updateLabel}\n </button>\n <button\n type='button'\n className={css.opBtn}\n disabled={tagBusy}\n title={tt('market.removeHint')}\n aria-label={tt('market.deleteSource')}\n onClick={() => { void removeMarketSource(record.repo) }}\n style={{ padding:'4px 8px', minWidth:28 }}\n >×</button>\n </div>\n )\n }\n\n // 统一列表:内置目录(未添加 → 描述+添加按钮;已添加 → 完整行)在前,\n // 自定义市场源(不在内置目录里)随后。同一个仓库不会出现两次。\n const rows: Array<{ key: string; element: JSX.Element }> = []\n for (const entry of MARKET_CATALOG) {\n const record = marketState.repos.find((item) => item.repo === entry.repo)\n if (record !== undefined) {\n rows.push({ key: entry.repo, element: sourceRow(record) })\n } else {\n const busy = scanningRepo !== null || tagBusy\n rows.push({\n key: entry.repo,\n element: (\n <div className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>\n <a className={css.sourceLink} href={'https://github.com/' + entry.repo} target='_blank' rel='noreferrer'>{entry.repo}</a>\n </div>\n <div className={css.rowDesc}>{tt(entry.descriptionKey)}</div>\n </div>\n <button type='button' className={css.opBtn} disabled={busy} onClick={() => { void addSource(entry.repo) }}>{tt('market.add')}</button>\n </div>\n ),\n })\n }\n }\n for (const record of marketState.repos) {\n if (MARKET_CATALOG.some((entry) => entry.repo === record.repo)) continue\n rows.push({ key: record.repo, element: sourceRow(record) })\n }\n const unaddedCatalog = MARKET_CATALOG.filter((entry) => !marketState.repos.some((record) => record.repo === entry.repo))\n\n return (\n <>\n <section className={css.section}>\n <div className={css.sectionTitle + ' ' + css.sectionHeadRow}>\n <span className={css.sectionTitleFill}>{tt('market.title')}</span>\n <button type='button' className={css.opBtn} onClick={() => { void checkSources(); void checkMarket() }}>{tt('market.checkAll')}</button>\n <button\n type='button'\n className={css.opBtn + (updatableRepos.length > 0 ? ' ' + css.opDanger : '')}\n disabled={updatableRepos.length === 0 || tagBusy}\n onClick={() => { setUpdateAllDialog(true) }}\n >{tt('market.updateAll')}</button>\n </div>\n <div className={css.buttons + ' ' + css.actionsPadded}>\n <input\n className={css.input + ' ' + css.grow}\n value={newSourceName}\n onChange={(event) => { setNewSourceName(event.target.value) }}\n onKeyDown={(event) => { if (event.key === 'Enter') { event.preventDefault(); void addMarketSource() } }}\n placeholder={tt('market.addPlaceholder')}\n />\n <button type='button' className={css.button + ' ' + css.primary} disabled={newSourceName.trim() === ''} onClick={() => { void addMarketSource() }}>{tt('market.addSource')}</button>\n </div>\n {unaddedCatalog.length > 0 ? <p className={css.hintLine + ' ' + css.hintPadded}>{tt('market.catalogHint')}</p> : null}\n\n {marketState.status === 'loading' ? <div className={css.empty}>{tt('panel.loading')}</div> : null}\n {marketState.status !== 'loading' && rows.length === 0 ? <div className={css.empty}>{tt('market.noSources')}</div> : null}\n {marketState.status !== 'loading' ? rows.map((row) => <Fragment key={row.key}>{row.element}</Fragment>) : null}\n </section>\n {/* 扫描结果归属卡片:用同一 section 卡片包裹扫描中/错误/就绪,标题直接点明所属仓库,消除割裂感 */}\n {(repoDiscoverState.status !== 'idle' || repoResult !== null) ? (\n <section className={css.section} style={{ borderLeft: '3px solid var(--hub-model, #2f81f7)', background: 'rgba(47,129,247,0.04)' }}>\n <div className={css.sectionTitle + ' ' + css.sectionHeadRow} style={{ margin: '10px 14px 6px' }}>\n <span className={css.sectionTitleFill} style={{ display:'flex', alignItems:'center', gap:6 }}>\n <span style={{ width:7, height:7, borderRadius:'50%', background:'var(--hub-model, #2f81f7)', display:'inline-block' }} />\n 扫描结果\n <span style={{ fontWeight:400, opacity:.75 }}>\n — {repoDiscoverState.status === 'ready' ? repoDiscoverState.data.repo : repoDiscoverState.status === 'error' ? (scanningRepo ?? '') : (scanningRepo ?? '')}\n {repoDiscoverState.status === 'ready' && repoDiscoverState.data.ref !== null ? <span style={{ opacity:.5, marginLeft:6 }}>ref {repoDiscoverState.data.ref}</span> : null}\n </span>\n </span>\n <button type='button' className={css.opBtn} onClick={() => { hub.clearScan() }}>关闭</button>\n </div>\n <div style={{ padding:'0 12px 12px' }}>\n {repoDiscoverState.status === 'scanning' ? <div className={css.empty} style={{ padding:'12px 0' }}>{tt('market.scanning')}</div> : null}\n {repoDiscoverState.status === 'error' ? <div className={css.errorBanner}>{repoDiscoverState.message}</div> : null}\n {repoDiscoverState.status === 'ready' ? (() => {\n const entries = repoDiscoverState.data.entries\n // 导入后 catalog 已包含新技能,但 scan 快照的 existing 仍为 false,需用实时 catalog + 本次导入结果兜底,避免已导入仍可选\n const installedNames = new Set<string>([\n ...((hub.catalog?.skills ?? []).map((s) => s.name)),\n ...((hub.catalog?.disabled ?? []).map((d) => d.name)),\n ...((repoResult?.imported ?? []).map((r) => r.name)),\n ...((repoResult?.skipped ?? []).map((r) => r.name)),\n ])\n const isExisting = (entry: RepoSkillEntry): boolean => entry.existing || installedNames.has(entry.name)\n const selected = entries.filter((entry) => repoSelected.has(entry.path) && !isExisting(entry))\n const selectedBytes = selected.reduce((s, e) => s + e.totalBytes, 0)\n // 过滤 + 搜索(276 场景核心)\n const filtered = entries.filter((entry) => {\n if (repoFilter !== 'all' && entry.root !== repoFilter) return false\n if (repoSearch.trim() !== '' && !entry.name.toLowerCase().includes(repoSearch.trim().toLowerCase())) return false\n return true\n }).sort((a, b) => a.name.localeCompare(b.name))\n const paged = filtered.slice(0, visibleCount)\n return (\n <>\n <p className={css.hintLine + ' ' + css.hintInline}>{tt('repo.ready', { count: entries.length })} · {repoDiscoverState.data.ref !== null ? `ref ${repoDiscoverState.data.ref}` : ''}</p>\n {entries.length === 0 ? <div className={css.empty}>{tt('repo.empty')}</div> : (\n <>\n {/* 搜索 + 过滤 + 统计 — 精简 */}\n {(() => {\n // 动态根:按已知顺序 skills/design-templates 优先,其余按字母序\n const order = new Map<string, number>([['skills', 0], ['design-templates', 1]])\n const roots = [...new Set(entries.map((e) => e.root))].sort((a, b) => {\n const ao = order.get(a) ?? 99\n const bo = order.get(b) ?? 99\n return ao !== bo ? ao - bo : a.localeCompare(b)\n })\n const counts = new Map<string, number>()\n for (const e of entries) counts.set(e.root, (counts.get(e.root) ?? 0) + 1)\n return (\n <div style={{ display:'flex', gap:8, marginBottom:8, flexWrap:'wrap' }}>\n <input\n className={css.input}\n style={{ flex:1, minWidth:140 }}\n value={repoSearch}\n onChange={(e) => setRepoSearch(e.target.value)}\n placeholder=\"搜索技能名…\"\n />\n <button type='button' className={css.button + (repoFilter === 'all' ? ' ' + css.primary : '')} style={{ padding:'6px 10px', fontSize:12 }} onClick={() => setRepoFilter('all')}>全部 {entries.length}</button>\n {roots.map((root) => (\n <button key={root} type='button' className={css.button + (repoFilter === root ? ' ' + css.primary : '')} style={{ padding:'6px 10px', fontSize:12 }} onClick={() => setRepoFilter(root)}>{root} {counts.get(root) ?? 0}</button>\n ))}\n </div>\n )\n })()}\n <div className={css.hintLine} style={{ display:'flex', justifyContent:'space-between', flexWrap:'wrap', gap:8 }}>\n <span>已选 {selected.length}/{entries.length} · {formatBytes(selectedBytes)} · 显示 {paged.length}/{filtered.length}(过滤后)</span>\n <span style={{ display:'flex', gap:6 }}>\n <button type='button' className={css.button} style={{ padding:'4px 8px', fontSize:11 }} onClick={() => { setRepoSelected(new Set(filtered.filter((e)=>!isExisting(e)).slice(0, visibleCount).map((e)=>e.path))) }}>全选当前显示</button>\n <button type='button' className={css.button} style={{ padding:'4px 8px', fontSize:11 }} onClick={() => { setRepoSelected(new Set(entries.filter((e)=>!isExisting(e)).map((e)=>e.path))) }}>全选全部 {entries.filter(e=>!isExisting(e)).length}</button>\n <button type='button' className={css.button} style={{ padding:'4px 8px', fontSize:11 }} onClick={() => { setRepoSelected(new Set()) }}>{tt('repo.clearAll')}</button>\n </span>\n </div>\n\n {/* 扁平虚拟滚动容器 — 主题自适应,CSS Modules */}\n <div className={css.scanList}>\n {paged.length === 0 ? <div className={css.empty} style={{ padding:20 }}>无匹配技能</div> : paged.map((entry) => {\n const existing = isExisting(entry)\n return (\n <label key={entry.path} className={css.row + (existing ? ' ' + css.rowMuted : '')}>\n <input\n type='checkbox'\n checked={repoSelected.has(entry.path)}\n disabled={existing}\n onChange={(event) => { toggleRepoSelected(entry.path, event.target.checked) }}\n />\n <div className={css.rowMain}>\n <div className={css.rowName}>{entry.name}</div>\n <div className={css.rowDesc}>{entry.dir} · {tt('repo.files', { count: entry.fileCount, size: formatBytes(entry.totalBytes) })}</div>\n </div>\n {existing\n ? <span className={css.badge + ' ' + css.badgeReadonly}>{tt('repo.existing')}</span>\n : <span className={css.badge + ' ' + css.badgeSource}>{entry.origin}</span>}\n </label>\n )})}\n </div>\n {visibleCount < filtered.length ? (\n <div style={{ textAlign:'center', marginTop:8 }}>\n <button type='button' className={css.button} onClick={() => setVisibleCount((n) => n + 50)}>加载更多 50 (剩余 {filtered.length - visibleCount})</button>\n </div>\n ) : null}\n\n <div className={css.buttons + ' ' + css.actionsTop}>\n <button type='button' className={css.button + ' ' + css.primary} disabled={selected.length === 0 || repoImporting} onClick={() => { void importRepo() }}>{repoImporting ? tt('repo.importing') : `${tt('repo.import', { count: selected.length })} · ${formatBytes(selectedBytes)}`}</button>\n {repoImporting ? <button type='button' className={css.button} onClick={() => { void cancelImport() }}>{tt('repo.cancel')}</button> : null}\n </div>\n {repoResult !== null && repoResult.status === 'running' ? (() => {\n const pct = repoResult.totalBytes > 0 ? Math.min(100, Math.round(repoResult.downloadedBytes / repoResult.totalBytes * 100)) : (repoResult.total > 0 ? Math.round(repoResult.done / repoResult.total * 100) : 0)\n const speed = formatSpeed(repoResult.bytesPerSecond)\n return (\n <div className={css.formSuccess + ' ' + css.actionsTop}>\n <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:6 }}>\n <div className={css.scanProgressTrack}>\n <div className={css.scanProgressFill} style={{ width: `${pct}%` }} />\n </div>\n <span style={{ fontSize:11, opacity:.75, minWidth:32, textAlign:'right' }}>{pct}%</span>\n </div>\n <div className={css.hintLine}>\n {formatBytes(repoResult.downloadedBytes)} / {formatBytes(repoResult.totalBytes)}\n {speed !== '' ? ` · ${speed}` : ''} · {repoResult.done}/{repoResult.total} 个技能\n </div>\n <div className={css.hintLine} style={{marginTop:4}}>\n {repoResult.current !== undefined ? tt('repo.importingCurrent', { name: repoResult.current, done: repoResult.done + 1, total: repoResult.total }) : tt('repo.importing')}\n {repoResult.currentFile !== undefined ? ` · ${repoResult.currentFile}` : ''}\n </div>\n {repoResult.failed.length > 0 ? <div className={css.errorBanner} style={{marginTop:6}}>{repoResult.failed.map(f => `${f.name}: ${f.error}`).join('; ')}</div> : null}\n </div>\n )\n })() : null}\n </>\n )}\n </>\n )\n })() : null}\n {repoResult !== null && repoResult.status !== 'running' ? (\n <div className={repoResult.status === 'cancelled' ? css.errorBanner + ' ' + css.actionsTop : css.formSuccess + ' ' + css.actionsTop}>\n {repoResult.status === 'cancelled' ? tt('repo.cancelled', { imported: repoResult.imported.length, total: repoResult.total }) : `${tt('repo.imported', { count: repoResult.imported.length })} · ${tt('repo.skippedExisting', { count: repoResult.skipped.length })} · ${tt('repo.failed', { count: repoResult.failed.length })}`}\n {repoResult.failed.length > 0 ? <div style={{marginTop:6}}>{repoResult.failed.map(f => `${f.name}: ${f.error}`).join('; ')}</div> : null}\n {repoResult.status === 'error' && repoResult.error ? <div style={{marginTop:6}}>{repoResult.error}</div> : null}\n </div>\n ) : null}\n </div>\n </section>\n ) : null}\n\n {updateAllDialog ? (\n <ConfirmDialog\n title={tt('market.updateAllConfirmTitle')}\n text={tt('market.updateAllConfirmText')}\n items={updatableRepos.map(([repo, check]) => tt('market.updateAllItem', { repo, count: check.updated.length }))}\n confirmLabel={tt('market.updateAll')}\n danger\n onCancel={() => { setUpdateAllDialog(false) }}\n onConfirm={() => { void updateAll() }}\n />\n ) : null}\n </>\n )\n}\n","/**\n * useSkillHub — the panel's state owner. Everything the skill hub panel\n * knows (catalog, groups, sources, market, dialogs, drafts) plus every\n * async flow lives here; the panel itself only renders. All hooks run\n * unconditionally at the top, so the panel may early-return for the detail\n * and tag-editor views without violating the rules of hooks.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState, type FormEvent } from 'react'\nimport type {\n CatalogResponse,\n CatalogSkill,\n DisabledSkill,\n GroupsResponse,\n HubConfig,\n MarketCheckResponse,\n MarketSourceRecord,\n RepoDiscoverResponse,\n RepoImportProgressResponse,\n RepoImportResponse,\n SkillDetail,\n SkillTag,\n SourceCheckResult,\n SourcesResponse,\n UpdateCheckResponse,\n WritableRoot,\n} from '../../protocol.ts'\nimport type { SkillHubApi } from '../api.ts'\nimport { errorMessage, tt } from '../helpers.ts'\nimport { conflictsOnClose, isProjectSource, PRIVATE_SOURCE, sortSkills, type SortKey, type GroupSwitchState } from '../grouping.ts'\nimport type { BranchChoiceState, ConfirmDialogState, ConflictDialogState, MarketSyncDialogState } from './dialogs.tsx'\n\n/** Catalog poll interval while the panel is mounted (the provider watcher feeds this). */\nconst POLL_MS = 5000\n/** Relaxed poll for slower-changing data (stats, groups, sources, config). */\nconst SLOW_POLL_MS = 60_000\n\n/** localStorage key of the last daily auto-check timestamp (survives sessions). */\nconst AUTO_CHECK_KEY = 'skill-hub.last-auto-check'\n/** Daily auto-check interval: at most one network round per day. */\nconst AUTO_CHECK_INTERVAL_MS = 24 * 60 * 60_000\n\n/** Whether the daily auto-check should run now (first visit or ≥24h since the last). */\nfunction shouldAutoCheck(): boolean {\n try {\n const raw = localStorage.getItem(AUTO_CHECK_KEY)\n const last = raw === null ? NaN : Number(raw)\n if (!Number.isFinite(last)) return true\n return Date.now() - last >= AUTO_CHECK_INTERVAL_MS\n } catch {\n // 无 localStorage(隐私模式等):每次打开都尝试,服务端 5 分钟节流兜底。\n return true\n }\n}\n\n/** Record that the daily auto-check ran. */\nfunction markAutoChecked(): void {\n try {\n localStorage.setItem(AUTO_CHECK_KEY, String(Date.now()))\n } catch {\n // 无 localStorage:不记录,下次打开仍会尝试(服务端节流兜底)。\n }\n}\n\n/** One-shot self-update check state. */\ntype UpdateState =\n | { status: 'idle' }\n | { status: 'checking' }\n | { status: 'ready'; data: UpdateCheckResponse }\n | { status: 'error'; message: string }\n\n/** Repo scanner/import state (drives the market source preview). */\ntype RepoDiscoverState =\n | { status: 'idle' }\n | { status: 'scanning' }\n | { status: 'ready'; data: RepoDiscoverResponse }\n | { status: 'error'; message: string }\n\n/** Market sources list state. */\ntype MarketState = { status: 'loading' | 'ready' | 'error'; repos: MarketSourceRecord[] }\n\n/** One market source's update-check outcome. */\ntype MarketCheckResult = MarketCheckResponse['results'][number]\n\n/** The hook's result: the panel's complete state + action surface. */\nexport type SkillHubState = ReturnType<typeof useSkillHub>\n\nexport function useSkillHub(api: SkillHubApi) {\n const [catalog, setCatalog] = useState<CatalogResponse | null>(null)\n const [loading, setLoading] = useState(true)\n const [loadError, setLoadError] = useState<string | null>(null)\n /** Green success banner (create finished); shown outside the closing form. */\n const [successBanner, setSuccessBanner] = useState<string | null>(null)\n const [updateState, setUpdateState] = useState<UpdateState>({ status: 'idle' })\n const [repoDiscoverState, setRepoDiscoverState] = useState<RepoDiscoverState>({ status: 'idle' })\n /** Market repo currently being scanned (null when idle); per-row busy state. */\n const [scanningRepo, setScanningRepo] = useState<string | null>(null)\n const [repoSelected, setRepoSelected] = useState<ReadonlySet<string>>(new Set())\n const [repoImporting, setRepoImporting] = useState(false)\n const [repoResult, setRepoResult] = useState<RepoImportProgressResponse | null>(null)\n const [importJobId, setImportJobId] = useState<string | null>(null)\n const pollAbortRef = useRef<AbortController | null>(null)\n const [search, setSearch] = useState('')\n /** 工作区(项目)路径;空 = 只看用户级技能。 */\n const [workspace, setWorkspace] = useState('')\n const [detail, setDetail] = useState<SkillDetail | null>(null)\n const [detailLoading, setDetailLoading] = useState(false)\n const [busyNames, setBusyNames] = useState<ReadonlySet<string>>(new Set())\n const [batchBusy, setBatchBusy] = useState(false)\n const [showForm, setShowForm] = useState(false)\n const [formName, setFormName] = useState('')\n const [formDesc, setFormDesc] = useState('')\n const [formRoot, setFormRoot] = useState<WritableRoot>('user-dsh')\n const [formBusy, setFormBusy] = useState(false)\n const [formMessage, setFormMessage] = useState<{ kind: 'error' | 'success'; text: string } | null>(null)\n const [uses, setUses] = useState<ReadonlyMap<string, { count: number; lastUsed?: number }>>(new Map())\n const [hubConfig, setHubConfig] = useState<HubConfig | null>(null)\n const [tab, setTab] = useState<'sources' | 'scenes' | 'market'>('sources')\n const [skillView, setSkillView] = useState<'flat' | 'groups'>('groups')\n const [sourceFilter, setSourceFilter] = useState('all')\n const [sortKey, setSortKey] = useState<SortKey>('name')\n const [marketState, setMarketState] = useState<MarketState>({ status: 'loading', repos: [] })\n const [marketCheck, setMarketCheck] = useState<Readonly<Record<string, MarketCheckResult>>>({})\n const [branchChoice, setBranchChoice] = useState<BranchChoiceState | null>(null)\n const [branchBusy, setBranchBusy] = useState(false)\n const [marketSyncDialog, setMarketSyncDialog] = useState<MarketSyncDialogState | null>(null)\n const [syncingMarket, setSyncingMarket] = useState<string | null>(null)\n const [syncBusy, setSyncBusy] = useState(false)\n const [newSourceName, setNewSourceName] = useState('')\n const [groupsState, setGroupsState] = useState<GroupsResponse | null>(null)\n const [sourcesState, setSourcesState] = useState<SourcesResponse | null>(null)\n const [sourceCheck, setSourceCheck] = useState<Readonly<Record<string, SourceCheckResult>>>({})\n const [checkingSource, setCheckingSource] = useState<string | null>(null)\n const [syncingSource, setSyncingSource] = useState<string | null>(null)\n const [conflictDialog, setConflictDialog] = useState<ConflictDialogState | null>(null)\n const [confirmDialog, setConfirmDialog] = useState<ConfirmDialogState | null>(null)\n const [deleteSkillDialog, setDeleteSkillDialog] = useState<string | null>(null)\n const [deleteGroupDialog, setDeleteGroupDialog] = useState<{ name: string; skillNames: string[] } | null>(null)\n const [confirmClearTrash, setConfirmClearTrash] = useState(false)\n /** 「全部更新」确认对话框(市场 tab)。 */\n const [updateAllDialog, setUpdateAllDialog] = useState(false)\n const [editingTag, setEditingTag] = useState<SkillTag | null>(null)\n const [editName, setEditName] = useState('')\n const [membersDraft, setMembersDraft] = useState<ReadonlySet<string>>(new Set())\n const [newTagName, setNewTagName] = useState('')\n const [tagBusy, setTagBusy] = useState(false)\n const [editSearch, setEditSearch] = useState('')\n /** 分组视图里收起的分组(key 为 tag:<id>、col:<name> 或 project 树键)。 */\n const [collapsedGroups, setCollapsedGroups] = useState<ReadonlySet<string>>(new Set())\n /** 项目级三级树里已细分(按 .dsh/.agents)的项目键。 */\n const [subdividedProjects, setSubdividedProjects] = useState<ReadonlySet<string>>(new Set())\n const [showLegend, setShowLegend] = useState(false)\n const [editMode, setEditMode] = useState(false)\n\n const toggleGroupCollapse = useCallback((key: string): void => {\n setCollapsedGroups((previous) => {\n const next = new Set(previous)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [])\n\n const toggleSubdivide = useCallback((key: string): void => {\n setSubdividedProjects((previous) => {\n const next = new Set(previous)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [])\n\n const load = useCallback(async (): Promise<void> => {\n try {\n const next = await api.catalog(workspace !== '' ? { cwd: workspace } : undefined)\n setCatalog(next)\n setLoadError(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setLoading(false)\n }\n }, [api, workspace])\n\n const loadUses = useCallback(async (): Promise<void> => {\n try {\n const result = await api.stats()\n if (result.available) setUses(new Map(result.stats.map((stat) => [stat.name, { count: stat.count, ...(stat.lastUsed !== undefined ? { lastUsed: stat.lastUsed } : {}) }])))\n } catch {\n // Invocation counts are best-effort; a stats failure must not disturb the catalog.\n }\n }, [api])\n\n const loadConfig = useCallback(async (): Promise<void> => {\n try {\n setHubConfig((await api.config()).config)\n } catch {\n // Dot colors are cosmetic; a config failure falls back to the defaults.\n }\n }, [api])\n\n /** Check the hub's own GitHub release once, and again on demand. */\n const checkUpdate = useCallback(async (): Promise<void> => {\n setUpdateState({ status: 'checking' })\n try {\n setUpdateState({ status: 'ready', data: await api.updateCheck() })\n } catch (error) {\n setUpdateState({ status: 'error', message: errorMessage(error) })\n }\n }, [api])\n\n /** 加载用户 tag 分组 + 系统集合组 + origin 映射。 */\n const loadGroups = useCallback(async (): Promise<void> => {\n try {\n setGroupsState(await api.groups())\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 加载来源记录 + 回收站。 */\n const loadSources = useCallback(async (): Promise<void> => {\n try {\n setSourcesState(await api.sources())\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 加载市场源列表。 */\n const loadMarket = useCallback(async (): Promise<void> => {\n try {\n const next = await api.market()\n setMarketState({ status: 'ready', repos: next.repos })\n } catch (error) {\n setMarketState({ status: 'error', repos: [] })\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 把最新的 tag 列表合并进 groups 状态(tags 以外的字段保持原样)。 */\n const applyTags = useCallback((tags: SkillTag[]): void => {\n setGroupsState((previous) => previous === null\n ? { ok: true, tags, collections: [], origins: {} }\n : { ...previous, tags })\n }, [])\n\n // 初始全量加载 + 双速轮询:目录是「活视图」(文件变化要 5 秒内可见),\n // 统计/分组/来源/配置变化慢,60 秒一次足够;写操作本身会触发即时刷新。\n // 更新检查、来源检查、市场检查全部改为手动按钮触发,打开面板不再自动\n // 打三路 GitHub 请求。\n useEffect(() => {\n void load()\n void loadUses()\n void loadGroups()\n void loadSources()\n void loadConfig()\n const fast = window.setInterval(() => { void load() }, POLL_MS)\n const slow = window.setInterval(() => { void loadUses(); void loadGroups(); void loadSources(); void loadConfig() }, SLOW_POLL_MS)\n return () => { window.clearInterval(fast); window.clearInterval(slow) }\n }, [load, loadUses, loadGroups, loadSources, loadConfig])\n\n const openDetail = useCallback(async (name: string): Promise<void> => {\n setDetailLoading(true)\n setLoadError(null)\n try {\n setDetail(await api.skill(name, workspace !== '' ? { cwd: workspace } : undefined))\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setDetailLoading(false)\n }\n }, [api, workspace])\n\n const toggle = useCallback(async (skill: CatalogSkill, enabled: boolean): Promise<void> => {\n setBusyNames((previous) => new Set(previous).add(skill.name))\n setLoadError(null)\n try {\n const next = await api.toggle(skill.name, enabled)\n setCatalog(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBusyNames((previous) => {\n const next = new Set(previous)\n next.delete(skill.name)\n return next\n })\n }\n }, [api])\n\n const enableDisabled = useCallback(async (record: DisabledSkill): Promise<void> => {\n setBusyNames((previous) => new Set(previous).add(record.name))\n setLoadError(null)\n try {\n const next = await api.toggle(record.name, true)\n setCatalog(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBusyNames((previous) => {\n const next = new Set(previous)\n next.delete(record.name)\n return next\n })\n }\n }, [api])\n\n /** Toggle an explicit name set in one write (enables disabled members too). */\n const batchToggleNames = useCallback(async (names: string[], enabled: boolean): Promise<void> => {\n if (names.length === 0) return\n setBatchBusy(true)\n setLoadError(null)\n try {\n const next = await api.toggleBatch(names, enabled)\n setCatalog(next.catalog)\n if (next.failures.length > 0) {\n setLoadError('toggle-batch: ' + next.failures.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBatchBusy(false)\n }\n }, [api])\n\n // -------------------------------------------------------- group switches\n\n /** 所有分组:key → 成员名(tag 与来源集合)。 */\n const groupMap = useCallback((): Map<string, string[]> => {\n const map = new Map<string, string[]>()\n for (const tag of groupsState?.tags ?? []) map.set('tag:' + tag.id, tag.skillNames)\n for (const collection of groupsState?.collections ?? []) map.set('col:' + collection.name, collection.skillNames)\n return map\n }, [groupsState])\n\n /** 当前启用且可写的技能名(组开关只作用于它们)。 */\n const actionNames = useMemo(() => new Set((catalog?.skills ?? []).filter((skill) => skill.writable).map((skill) => skill.name)), [catalog])\n\n /** 当前启用的全部技能名(含只读,用于派生开关状态)。 */\n const viewNames = useMemo(() => new Set((catalog?.skills ?? []).map((skill) => skill.name)), [catalog])\n\n /**\n * Toggle a whole group via its tri-state switch. Closing with members that\n * are enabled in other groups opens the conflict dialog instead.\n */\n const toggleGroup = useCallback((key: string, name: string, view: GroupSwitchState): void => {\n const members = groupMap().get(key) ?? []\n if (members.length === 0) return\n if (view === 'off') {\n void batchToggleNames(members, true)\n return\n }\n const others = [...groupMap().entries()].filter(([otherKey]) => otherKey !== key).map(([, memberNames]) => ({ members: memberNames }))\n const conflicts = conflictsOnClose(members, actionNames, others)\n if (conflicts.length > 0) {\n setConflictDialog({ key, name, conflicts })\n } else {\n void batchToggleNames(members.filter((member) => actionNames.has(member)), false)\n }\n }, [groupMap, actionNames, batchToggleNames])\n\n /** Resolve the open conflict dialog. */\n const resolveConflict = useCallback(async (closeAll: boolean): Promise<void> => {\n const dialog = conflictDialog\n if (dialog === null) return\n setConflictDialog(null)\n const members = groupMap().get(dialog.key) ?? []\n if (closeAll) {\n await batchToggleNames(members.filter((member) => actionNames.has(member)), false)\n } else {\n await batchToggleNames(\n members.filter((member) => actionNames.has(member) && !dialog.conflicts.includes(member)),\n false,\n )\n }\n }, [conflictDialog, groupMap, actionNames, batchToggleNames])\n\n /** Dismiss a confirm dialog and run the pending source action. */\n const runConfirmed = useCallback(async (): Promise<void> => {\n const dialog = confirmDialog\n if (dialog === null) return\n setConfirmDialog(null)\n if (dialog.kind === 'sync') {\n setSyncingSource(dialog.repo)\n setLoadError(null)\n try {\n const result = await api.syncSource(dialog.repo, dialog.skills)\n await Promise.all([load(), loadGroups(), loadSources()])\n if (result.failed.length > 0) {\n setLoadError('sync: ' + result.failed.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncingSource(null)\n }\n } else {\n setLoadError(null)\n try {\n await api.confirmDeleteSource(dialog.repo, dialog.skills)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }\n }, [confirmDialog, api, load, loadGroups, loadSources])\n\n // ---------------------------------------------------------- source ops\n\n /** 检查全部来源的上游更新(服务端 5 分钟节流)。 */\n const checkSources = useCallback(async (repo?: string): Promise<void> => {\n setCheckingSource(repo ?? 'all')\n setLoadError(null)\n try {\n const result = await api.checkSources(repo)\n const next: Record<string, SourceCheckResult> = { ...sourceCheck }\n for (const item of result.results) next[item.repo] = item\n setSourceCheck(next)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setCheckingSource(null)\n }\n }, [api, sourceCheck])\n\n /** 请求同步某个来源的所选技能(弹确认,因为会覆盖本地修改)。 */\n const requestSync = useCallback((repo: string, skills: string[]): void => {\n setConfirmDialog({ kind: 'sync', repo, skills })\n }, [])\n\n /** 请求跟进上游删除(弹确认,移入回收站)。 */\n const requestDelete = useCallback((repo: string, skills: string[]): void => {\n setConfirmDialog({ kind: 'delete', repo, skills })\n }, [])\n\n /** 从回收站恢复一个技能。 */\n const restoreTrash = useCallback(async (name: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n await api.restoreSource(name)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, load, loadGroups, loadSources])\n\n /** 确认后永久删除回收站里的全部技能。 */\n const clearTrash = useCallback(async (): Promise<void> => {\n setConfirmClearTrash(false)\n setTagBusy(true)\n setLoadError(null)\n try {\n const result = await api.clearTrash()\n if (result.failed.length > 0) {\n setLoadError('clear trash: ' + result.failed.map((failure) => failure.name + ': ' + failure.error).join('; '))\n }\n await Promise.all([load(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, load, loadSources])\n\n /** 打开单个技能的删除确认(移入回收站,可恢复)。 */\n const requestDeleteSkill = useCallback((name: string): void => {\n setDeleteSkillDialog(name)\n }, [])\n\n /** 执行删除确认后的回收站迁移。 */\n const runDeleteSkill = useCallback(async (): Promise<void> => {\n const name = deleteSkillDialog\n if (name === null) return\n setDeleteSkillDialog(null)\n setTagBusy(true)\n setLoadError(null)\n try {\n await api.deleteSkill(name)\n await Promise.all([load(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, deleteSkillDialog, load, loadGroups, loadSources])\n\n /** 打开整组删除确认(来源分组一键删除)。 */\n const requestDeleteGroup = useCallback((name: string, skillNames: string[]): void => {\n setDeleteGroupDialog({ name, skillNames })\n }, [])\n\n /** 执行整组删除(逐个移入回收站,跳过只读)。 */\n const runDeleteGroup = useCallback(async (): Promise<void> => {\n const dialog = deleteGroupDialog\n if (dialog === null) return\n setDeleteGroupDialog(null)\n setTagBusy(true)\n setLoadError(null)\n const failures: string[] = []\n let done = 0\n for (const name of dialog.skillNames) {\n try {\n await api.deleteSkill(name)\n done += 1\n } catch (error) {\n // 只读/不存在的跳过并记录\n failures.push(name + ': ' + errorMessage(error))\n }\n }\n await Promise.all([load(), loadGroups(), loadSources()])\n setTagBusy(false)\n if (failures.length > 0) {\n setLoadError(`删除整组 \"${dialog.name}\":成功 ${done} 个,失败 ${failures.length} 个:` + failures.join('; '))\n } else if (done > 0) {\n setSuccessBanner(`已删除整组 \"${dialog.name}\":${done} 个技能已移入回收站`)\n }\n }, [api, deleteGroupDialog, load, loadGroups, loadSources])\n\n /** 新建一个空 tag 分组。 */\n const createTag = useCallback(async (event: FormEvent): Promise<void> => {\n event.preventDefault()\n const name = newTagName.trim()\n if (name === '') return\n setTagBusy(true)\n setLoadError(null)\n try {\n applyTags(await api.saveTag({ name }))\n setNewTagName('')\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags, newTagName])\n\n /** 删除一个 tag 分组(不影响技能文件)。 */\n const deleteTag = useCallback(async (id: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n applyTags(await api.deleteTag(id))\n setEditingTag(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags])\n\n /** 重命名 tag,或保存成员勾选后回到列表。 */\n const saveTag = useCallback(async (id: string, name: string, memberNames: string[] | null): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const safeName = name.trim()\n let tags: SkillTag[] | null = null\n if (safeName !== '') tags = await api.saveTag({ id, name: safeName })\n if (memberNames !== null) tags = await api.setTagMembers(id, memberNames)\n if (tags === null) return\n applyTags(tags)\n setEditingTag(null)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags])\n\n /** 拖拽重排场景分组 */\n const reorderTags = useCallback(async (orderedIds: string[]): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const tags = await api.reorderTags(orderedIds)\n applyTags(tags)\n } catch (error) {\n const msg = errorMessage(error)\n if (msg.includes('404') || msg.toLowerCase().includes('not found')) {\n // 旧宿主无此路由:本地重排\n const byId = new Map(groupsState?.tags.map((t) => [t.id, t] as const) ?? [])\n const reordered = orderedIds.map((id) => byId.get(id)).filter((t): t is NonNullable<typeof t> => t !== undefined)\n if (reordered.length === orderedIds.length) {\n applyTags(reordered as typeof groupsState extends { tags: infer T } ? T : never)\n setSuccessBanner('已临时调整顺序(本地生效,重启宿主后持久化)')\n } else {\n setLoadError(msg)\n }\n } else {\n setLoadError(msg)\n }\n } finally {\n setTagBusy(false)\n }\n }, [api, applyTags, groupsState])\n\n /** 拖拽重排来源集合 */\n const reorderCollections = useCallback(async (orderedNames: string[]): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const collections = await api.reorderCollections(orderedNames)\n setGroupsState((prev) => prev === null ? prev : { ...prev, collections })\n void loadGroups()\n } catch (error) {\n const msg = errorMessage(error)\n // 404 说明宿主仍在跑旧版(需重启后才有新路由),降级为本地即时生效\n if (msg.includes('404') || msg.toLowerCase().includes('not found')) {\n setGroupsState((prev) => {\n if (prev === null) return prev\n const map = new Map(prev.collections.map((c) => [c.name, c] as const))\n const reordered = orderedNames.map((n) => map.get(n)).filter((c): c is NonNullable<typeof c> => c !== undefined)\n // 补上未在 orderedNames 中的集合(新出现的)\n for (const c of prev.collections) if (!reordered.some((r) => r.name === c.name)) reordered.push(c)\n return { ...prev, collections: reordered }\n })\n setSuccessBanner('已临时调整顺序(本地生效,重启宿主后持久化)')\n } else {\n setLoadError(msg)\n }\n } finally {\n setTagBusy(false)\n }\n }, [api, loadGroups])\n\n /** 拖拽重排来源顶层分组(project / col:xxx / personal 全量可拖) */\n const reorderSourceGroups = useCallback(async (orderedKeys: string[]): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n await api.reorderSourceGroups(orderedKeys)\n await loadGroups()\n } catch (error) {\n const msg = errorMessage(error)\n if (msg.includes('404') || msg.toLowerCase().includes('not found')) {\n // 旧宿主无此路由:本地重排顶层顺序,提示重启后持久化\n setGroupsState((prev) => {\n if (prev === null) return prev\n // 本地重排 collections 以匹配 topOrderedKeys 中的 col:xxx 顺序\n const colOrder = orderedKeys.filter((k) => k.startsWith('col:')).map((k) => k.slice(4))\n const map = new Map(prev.collections.map((c) => [c.name, c] as const))\n const reordered = colOrder.map((n) => map.get(n)).filter((c): c is NonNullable<typeof c> => c !== undefined)\n for (const c of prev.collections) if (!reordered.some((r) => r.name === c.name)) reordered.push(c)\n return { ...prev, collections: reordered, sourceGroupOrder: orderedKeys }\n })\n setSuccessBanner('已临时调整顺序(本地生效,重启宿主后持久化)')\n } else {\n setLoadError(msg)\n }\n } finally {\n setTagBusy(false)\n }\n }, [api, loadGroups])\n\n // -------------------------------------------------------------- market\n\n /** 添加一个市场源(内置市场目录与手动输入共用),并立即扫描它。 */\n const addSource = useCallback(async (input: string): Promise<void> => {\n const value = input.trim()\n if (value === '') return\n setLoadError(null)\n try {\n const result = await api.addMarketSource(value)\n setMarketState({ status: 'ready', repos: result.repos })\n setNewSourceName('')\n setRepoResult(null)\n setRepoSelected(new Set())\n // 用服务端归一化后的 slug 扫描(URL/owner@repo 输入都能对上记录)。\n const slug = result.repos[result.repos.length - 1].repo\n setScanningRepo(slug)\n setRepoDiscoverState({ status: 'scanning' })\n try {\n const data = await api.repoDiscover(slug)\n setRepoDiscoverState({ status: 'ready', data })\n } catch (error) {\n setRepoDiscoverState({ status: 'error', message: errorMessage(error) })\n } finally {\n setScanningRepo(null)\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n }\n }, [api])\n\n /** 手动输入框的添加动作。 */\n const addMarketSource = useCallback(async (): Promise<void> => {\n await addSource(newSourceName)\n }, [addSource, newSourceName])\n\n /** 删除一个市场源(不影响已装技能)。 */\n const removeMarketSource = useCallback(async (repo: string): Promise<void> => {\n setTagBusy(true)\n setLoadError(null)\n try {\n const result = await api.removeMarketSource(repo)\n setMarketState({ status: 'ready', repos: result.repos })\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setTagBusy(false)\n }\n }, [api])\n\n /** 扫描一个市场源(或手动输入)的仓库。 */\n const scanRepo = useCallback(async (input: string): Promise<void> => {\n const value = input.trim()\n if (value === '') return\n setRepoResult(null)\n setRepoSelected(new Set())\n setScanningRepo(value)\n setRepoDiscoverState({ status: 'scanning' })\n setLoadError(null)\n try {\n const data = await api.repoDiscover(value)\n if (data.ref === null) {\n // 无 release 且未定版:让用户选分支(默认第一项,通常是 main)。\n setBranchChoice({ repo: data.repo, branches: data.branches ?? [], selected: (data.branches ?? [])[0] ?? 'main' })\n setRepoDiscoverState({ status: 'idle' })\n return\n }\n setRepoDiscoverState({ status: 'ready', data })\n } catch (error) {\n setRepoDiscoverState({ status: 'error', message: errorMessage(error) })\n } finally {\n setScanningRepo(null)\n }\n }, [api])\n\n /** 确认分支选择:持久化 ref 后重新扫描。 */\n const confirmBranchChoice = useCallback(async (): Promise<void> => {\n if (branchChoice === null) return\n setBranchBusy(true)\n setLoadError(null)\n try {\n await api.setMarketSourceRef(branchChoice.repo, branchChoice.selected)\n setBranchChoice(null)\n await scanRepo(branchChoice.repo)\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setBranchBusy(false)\n }\n }, [api, branchChoice, scanRepo])\n\n /** Toggle one repo preview row. */\n const toggleRepoSelected = useCallback((path: string, checked: boolean): void => {\n setRepoSelected((previous) => {\n const next = new Set(previous)\n if (checked) next.add(path)\n else next.delete(path)\n return next\n })\n }, [])\n\n /** Import every checked, non-existing repo skill (B方案:job+轮询+进度). */\n const importRepo = useCallback(async (): Promise<void> => {\n if (repoDiscoverState.status !== 'ready') return\n setRepoImporting(true)\n setRepoResult(null)\n setImportJobId(null)\n setLoadError(null)\n let finalProgress: RepoImportProgressResponse | null = null\n try {\n const created = await api.repoImport(repoDiscoverState.data.repo, [...repoSelected], repoDiscoverState.data.ref ?? undefined)\n setImportJobId(created.jobId)\n // 初始占位,让进度卡片立刻出现(带真实 totalBytes)\n setRepoResult({ ok: true, jobId: created.jobId, status: 'running', total: created.total, done: 0, totalBytes: created.totalBytes, downloadedBytes: 0, imported: [], skipped: [], failed: [] })\n // 轮询直到 done/cancelled/error(800ms 起步 + 退避,避免 276 技能 900 次请求)\n pollAbortRef.current?.abort()\n pollAbortRef.current = new AbortController()\n const signal = pollAbortRef.current.signal\n let attempt = 0\n for (;;) {\n if (signal.aborted) break\n const delay = Math.min(2000, 800 + attempt * 200)\n await new Promise((r) => setTimeout(r, delay))\n if (signal.aborted) break\n try {\n const progress = await api.repoImportProgress(created.jobId)\n setRepoResult(progress)\n finalProgress = progress\n if (progress.status !== 'running') {\n break\n }\n attempt = 0\n } catch (pollError) {\n // 轮询失败退避重试\n const msg = errorMessage(pollError)\n if (msg.includes('not found')) break\n attempt += 1\n if (attempt > 8) break\n }\n }\n await Promise.all([load(), loadMarket(), loadGroups(), loadSources()])\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n // 导入完成后把已导入/已跳过的项从勾选中移除,并把扫描快照里的 existing 置为 true,避免“仍可勾选已导入”的错觉\n if (finalProgress !== null && (finalProgress.imported.length > 0 || finalProgress.skipped.length > 0)) {\n const doneNames = new Set([...finalProgress.imported.map((r) => r.name), ...finalProgress.skipped.map((r) => r.name)])\n const donePaths = new Set(\n repoDiscoverState.data.entries.filter((e) => doneNames.has(e.name)).map((e) => e.path),\n )\n setRepoSelected((prev) => {\n const next = new Set(prev)\n for (const p of donePaths) next.delete(p)\n return next\n })\n setRepoDiscoverState((prev) => {\n if (prev.status !== 'ready') return prev\n return {\n ...prev,\n data: {\n ...prev.data,\n entries: prev.data.entries.map((e) => doneNames.has(e.name) ? { ...e, existing: true } : e),\n },\n }\n })\n }\n setRepoImporting(false)\n }\n }, [api, repoDiscoverState, repoSelected, load, loadMarket, loadGroups, loadSources])\n\n // 卸载时中断轮询,避免泄露\n useEffect(() => {\n return () => { pollAbortRef.current?.abort() }\n }, [])\n\n /** 取消正在进行的导入(选项2:唯有取消才停) */\n const cancelImport = useCallback(async (): Promise<void> => {\n if (importJobId === null) return\n pollAbortRef.current?.abort()\n try {\n const res = await api.repoImportCancel(importJobId)\n // 立刻刷新一次进度\n try {\n const progress = await api.repoImportProgress(importJobId)\n setRepoResult(progress)\n } catch {\n setRepoResult((prev) => prev !== null ? { ...prev, status: res.status as 'cancelled' } : prev)\n }\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setRepoImporting(false)\n }\n }, [api, importJobId])\n\n /** 清空扫描结果(关闭归属卡片) */\n const clearScan = useCallback((): void => {\n setRepoDiscoverState({ status: 'idle' })\n setScanningRepo(null)\n setRepoResult(null)\n setRepoSelected(new Set())\n setImportJobId(null)\n pollAbortRef.current?.abort()\n }, [])\n\n /** 检查所有市场源的上游更新(服务端节流)。 */\n const checkMarket = useCallback(async (): Promise<void> => {\n try {\n const result = await api.marketCheck()\n const next: Record<string, MarketCheckResult> = {}\n for (const item of result.results) next[item.repo] = item\n setMarketCheck(next)\n } catch {\n // 检查失败不打扰市场列表本身。\n }\n }, [api])\n\n /** 市场源同步:版本对齐后询问是否批量更新本地技能。 */\n const syncMarketSource = useCallback(async (repo: string): Promise<void> => {\n setSyncingMarket(repo)\n setLoadError(null)\n try {\n const result = await api.marketSync(repo)\n setMarketSyncDialog({ repo: result.repo, ref: result.ref, skills: result.skills, selected: new Set(result.skills) })\n await loadMarket()\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncingMarket(null)\n }\n }, [api, loadMarket])\n\n /** 批量更新本地技能到市场源当前版本(复用来源同步路径)。 */\n const confirmMarketSync = useCallback(async (): Promise<void> => {\n if (marketSyncDialog === null) return\n const selected = [...marketSyncDialog.selected]\n setSyncBusy(true)\n setLoadError(null)\n try {\n if (selected.length > 0) {\n const result = await api.syncSource(marketSyncDialog.repo, selected)\n if (result.failed.length > 0) setLoadError(result.failed.map((item) => item.name + ': ' + item.error).join('\\n'))\n }\n setMarketSyncDialog(null)\n await Promise.all([load(), loadGroups(), loadSources()])\n void checkMarket()\n } catch (error) {\n setLoadError(errorMessage(error))\n } finally {\n setSyncBusy(false)\n }\n }, [api, marketSyncDialog, load, loadGroups, loadSources, checkMarket])\n\n /**\n * 一键全部更新:把每个「有可更新技能」的来源逐个同步到上游最新版本\n * (复用来源同步路径,覆盖本地修改),随后刷新并重新检查。\n */\n const updateAll = useCallback(async (): Promise<void> => {\n setUpdateAllDialog(false)\n setBatchBusy(true)\n setLoadError(null)\n const failures: string[] = []\n let done = 0\n try {\n for (const [repo, check] of Object.entries(sourceCheck)) {\n if (!check.changed || check.updated.length === 0) continue\n try {\n const result = await api.syncSource(repo, check.updated)\n done += 1\n if (result.failed.length > 0) {\n failures.push(tt('market.updateAllItem', { repo, count: result.failed.length }) + ': ' + result.failed.map((item) => item.name + ': ' + item.error).join('; '))\n }\n } catch (error) {\n failures.push(repo + ': ' + errorMessage(error))\n }\n }\n await Promise.all([load(), loadGroups(), loadSources()])\n await checkSources()\n void checkMarket()\n if (failures.length > 0) setLoadError(failures.join('\\n'))\n else if (done > 0) setSuccessBanner(tt('market.updateAllDone', { count: done }))\n } finally {\n setBatchBusy(false)\n }\n }, [api, sourceCheck, checkSources, checkMarket, load, loadGroups, loadSources])\n\n // ------------------------------------------------- daily auto-check\n // 打开面板时每天最多自动检查一次(自身更新 + 全部来源 + 全部市场源),\n // 时间戳存 localStorage 跨会话生效;手动按钮随时可用,不受节流限制。\n useEffect(() => {\n if (!shouldAutoCheck()) return\n markAutoChecked()\n void checkUpdate()\n void checkSources()\n void checkMarket()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n // ---------------------------------------------------------------- create\n\n const create = useCallback(async (event: FormEvent): Promise<void> => {\n event.preventDefault()\n setFormBusy(true)\n setFormMessage(null)\n setSuccessBanner(null)\n try {\n const result = await api.create({ name: formName, description: formDesc, root: formRoot })\n // The form closes on success, so the confirmation lives in the green\n // banner outside it (a success message inside the closing form is\n // never visible).\n setSuccessBanner(tt('form.success') + result.path)\n setFormName('')\n setFormDesc('')\n setShowForm(false)\n await load()\n } catch (error) {\n setFormMessage({ kind: 'error', text: tt('form.error') + errorMessage(error) })\n } finally {\n setFormBusy(false)\n }\n }, [api, formName, formDesc, formRoot, load])\n\n // ------------------------------------------------------------- derived\n\n const normalized = search.trim().toLocaleLowerCase()\n /** skillName → origin repo(无来源记录的技能不在此映射中,筛选中视为 private)。 */\n const origins = groupsState?.origins ?? {}\n /** 来源筛选选项:来源记录中的仓库(排序)+ 末尾的「个人」;没有技能的仓库不列。 */\n const sourceOptions = useMemo(() => {\n const skills = catalog?.skills ?? []\n const repos = [...new Set(skills.map((skill) => origins[skill.name]).filter((repo): repo is string => repo !== undefined))].sort()\n // 项目级技能(有 workspace 归属)不算「个人」。\n const hasPrivate = skills.some((skill) => origins[skill.name] === undefined && !isProjectSource(skill.source))\n return [...repos, ...(hasPrivate ? [PRIVATE_SOURCE] : [])]\n }, [catalog, origins])\n const filtered = useMemo(() => (catalog?.skills ?? []).filter((skill) =>\n normalized.length === 0 || skill.name.toLocaleLowerCase().includes(normalized) || skill.description.toLocaleLowerCase().includes(normalized),\n ), [catalog, normalized])\n /** 排序后的技能列表(所有视图共用;调用次数未知按 0 处理)。 */\n const sorted = useMemo(() => sortSkills(filtered, sortKey, (name) => uses.get(name)?.count), [filtered, sortKey, uses])\n\n return {\n // state\n catalog, loading, loadError, successBanner, updateState, repoDiscoverState, scanningRepo, repoSelected, repoImporting, repoResult, importJobId,\n search, workspace, detail, detailLoading, busyNames, batchBusy, showForm, formName, formDesc, formRoot, formBusy, formMessage,\n uses, hubConfig, tab, skillView, sourceFilter, sortKey, marketState, marketCheck, branchChoice, branchBusy,\n marketSyncDialog, syncingMarket, syncBusy, newSourceName, groupsState, sourcesState, sourceCheck, checkingSource, syncingSource,\n conflictDialog, confirmDialog, deleteSkillDialog, deleteGroupDialog, confirmClearTrash, updateAllDialog, editingTag, editName, membersDraft, newTagName, tagBusy,\n editSearch, collapsedGroups, subdividedProjects, showLegend, editMode,\n // derived\n actionNames, viewNames, normalized, origins, sourceOptions, filtered, sorted,\n // actions + setters\n setLoadError, setSuccessBanner, setSearch, setWorkspace, setDetail, setShowForm, setFormName, setFormDesc, setFormRoot, setFormMessage,\n setRepoSelected, setTab, setSkillView,\n setSourceFilter, setSortKey, setBranchChoice, setMarketSyncDialog, setNewSourceName, setConflictDialog, setConfirmDialog,\n setDeleteSkillDialog, setDeleteGroupDialog, setConfirmClearTrash, setUpdateAllDialog, setEditingTag, setEditName, setMembersDraft, setNewTagName, setEditSearch, setShowLegend, setEditMode,\n toggleGroupCollapse, toggleSubdivide, checkUpdate, loadMarket, openDetail, toggle, enableDisabled, batchToggleNames, toggleGroup, resolveConflict,\n runConfirmed, checkSources, requestSync, requestDelete, restoreTrash, clearTrash, requestDeleteSkill, runDeleteSkill, requestDeleteGroup, runDeleteGroup, createTag,\n deleteTag, saveTag, reorderTags, reorderCollections, reorderSourceGroups, addSource, addMarketSource, removeMarketSource, scanRepo, confirmBranchChoice, toggleRepoSelected, importRepo, cancelImport, clearScan,\n checkMarket, syncMarketSource, confirmMarketSync, updateAll, create,\n }\n}\n","/**\n * The skill hub panel: catalog grouped by tags + source collections, search\n * and filter in one row, per-group tri-state switches with conflict dialogs,\n * upstream source tracking (check / sync / follow upstream deletion into a\n * restorable trash), market sources, disabled re-enable,\n * detail inspection, and the new-skill scaffold form.\n *\n * Thin shell: state and flows live in useSkillHub, the tab contents live in\n * SourcesView / ScenesView / MarketView, and the dialog family lives in\n * dialogs.tsx. This component owns only the shared chrome (header, banners,\n * filter bar, shared sections) and the view routing — and holds no hooks,\n * so the detail / tag-editor early returns are safe.\n */\n\nimport { useState } from 'react'\nimport type { WritableRoot } from '../../protocol.ts'\nimport { IconSkillOutline16 } from '../icons.tsx'\nimport type { SkillHubApi } from '../api.ts'\nimport { tt } from '../helpers.ts'\nimport { PRIVATE_SOURCE, type SortKey } from '../grouping.ts'\nimport { dotStyle, relativeTimeText } from './format.ts'\nimport { SkillDetailView } from './SkillDetailView.tsx'\nimport { TagEditorView } from './TagEditorView.tsx'\nimport { SourcesView } from './SourcesView.tsx'\nimport { ScenesView } from './ScenesView.tsx'\nimport { MarketView } from './MarketView.tsx'\nimport { BranchChoiceDialog, ConfirmDialog, ConflictDialog, MarketSyncDialog } from './dialogs.tsx'\nimport { useSkillHub } from './useSkillHub.ts'\nimport css from './panel.module.css'\n\nexport interface SkillHubPanelProps {\n api: SkillHubApi\n}\n\nexport function SkillHubPanel(props: SkillHubPanelProps): React.JSX.Element {\n const hub = useSkillHub(props.api)\n /** 工作区输入草稿:回车才应用,避免每次按键都触发目录重拉。 */\n const [workspaceDraft, setWorkspaceDraft] = useState('')\n const {\n catalog, loading, loadError, successBanner, updateState, detail, detailLoading, showForm, formName, formDesc,\n formRoot, formBusy, formMessage, hubConfig, tab, skillView, sourceFilter, sortKey, search,\n workspace, setWorkspace,\n sourcesState, tagBusy, busyNames, normalized, origins, sourceOptions, filtered,\n conflictDialog, confirmDialog, deleteSkillDialog, deleteGroupDialog, confirmClearTrash, branchChoice, branchBusy, marketSyncDialog,\n syncBusy, editingTag, editName, membersDraft, editSearch, uses, groupsState, sourceCheck, checkingSource, syncingSource,\n showLegend, editMode,\n setLoadError, setSuccessBanner, setDetail, setShowForm, setFormName, setFormDesc, setFormRoot, setFormMessage, setTab,\n setSkillView, setSourceFilter, setSortKey, setSearch, setConflictDialog, setConfirmDialog, setDeleteSkillDialog, setDeleteGroupDialog,\n setConfirmClearTrash, setBranchChoice, setMarketSyncDialog, setEditingTag, setEditName, setMembersDraft, setEditSearch,\n setShowLegend, setEditMode,\n checkUpdate, loadMarket, checkSources, requestSync, requestDelete, restoreTrash, clearTrash, runDeleteSkill, runDeleteGroup,\n runConfirmed, resolveConflict, confirmBranchChoice, confirmMarketSync, create, saveTag, deleteTag, enableDisabled,\n } = hub\n\n // -------------------------------------------------------------- detail\n\n if (detail !== null) {\n return (\n <SkillDetailView\n detail={detail}\n hubConfig={hubConfig}\n uses={uses}\n groupsState={groupsState}\n sourcesState={sourcesState}\n sourceCheck={sourceCheck}\n checkingSource={checkingSource}\n syncingSource={syncingSource}\n loading={detailLoading}\n onBack={() => { setDetail(null) }}\n onCheck={(repo) => { void checkSources(repo) }}\n onSync={requestSync}\n onFollowDelete={requestDelete}\n />\n )\n }\n\n if (editingTag !== null) {\n return (\n <TagEditorView\n tag={editingTag}\n editName={editName}\n membersDraft={membersDraft}\n editSearch={editSearch}\n catalog={catalog}\n tagBusy={tagBusy}\n onBack={() => { setEditingTag(null) }}\n onEditName={setEditName}\n onEditSearch={setEditSearch}\n onToggleMember={(name, checked) => {\n setMembersDraft((previous) => {\n const next = new Set(previous)\n if (checked) next.add(name)\n else next.delete(name)\n return next\n })\n }}\n onRename={() => { void saveTag(editingTag.id, editName, null) }}\n onDelete={() => { void deleteTag(editingTag.id) }}\n onSaveMembers={() => { void saveTag(editingTag.id, editName, [...membersDraft]) }}\n />\n )\n }\n\n /** 检查结果的悬停提示:收敛到「检查更新」按钮上,不再占面板顶部横幅。 */\n const updateTitle = ((): string | undefined => {\n if (updateState.status === 'checking') return tt('update.checking')\n if (updateState.status === 'error') return tt('update.error', { error: updateState.message })\n if (updateState.status === 'ready') {\n const data = updateState.data\n if (data.error !== undefined) return tt('update.error', { error: data.error })\n if (data.updateAvailable) return tt('update.available', { version: data.latestVersion ?? '', current: data.currentVersion })\n if (data.latestVersion === null) return tt('update.unavailable')\n return tt('update.upToDate', { version: data.latestVersion })\n }\n return undefined\n })()\n\n return (\n <div className={css.panel}>\n <div className={css.header}>\n <h2 className={css.title}><IconSkillOutline16 size={16} className={css.titleIcon} /> {tt('panel.title')}{catalog !== null ? <span className={css.pluginVersion}>v{catalog.pluginVersion}</span> : null}</h2>\n {catalog !== null\n ? <span className={css.headerCount}>\n {tt('panel.count', { count: catalog.skills.length + catalog.disabled.length })}\n {catalog.disabled.length > 0 ? ' · ' + tt('panel.disabledCount', { count: catalog.disabled.length }) : null}\n </span>\n : null}\n {catalog !== null && !catalog.complete ? <span className={css.hint}>{tt('panel.incomplete')}</span> : null}\n <span className={css.actions}>\n <button type='button' className={css.button} disabled={updateState.status === 'checking'} title={updateTitle} onClick={() => { void checkUpdate() }}>{updateState.status === 'checking' ? tt('update.checking') : tt('update.check')}</button>\n {updateState.status === 'ready' && updateState.data.updateAvailable && updateState.data.url !== null\n ? <a className={css.updateLink} href={updateState.data.url} target='_blank' rel='noreferrer'>{tt('update.newVersion', { version: updateState.data.latestVersion ?? '' })}</a>\n : null}\n </span>\n </div>\n <div className={css.subbar}>\n <span className={css.segmented}>\n <button type='button' className={css.segBtn + (tab === 'sources' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('sources') }}>{tt('view.sources')}</button>\n <button type='button' className={css.segBtn + (tab === 'scenes' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('scenes') }}>{tt('view.scenes')}</button>\n <button type='button' className={css.segBtn + (tab === 'market' ? ' ' + css.segBtnActive : '')} onClick={() => { setTab('market'); void loadMarket() }}>{tt('view.market')}</button>\n </span>\n <span className={css.workspaceBox}>\n <input\n className={css.search + ' ' + css.workspaceInput}\n value={workspaceDraft}\n placeholder={workspace !== '' ? workspace : tt('panel.workspacePlaceholder')}\n title={tt('panel.workspaceHint')}\n onChange={(event) => { setWorkspaceDraft(event.target.value) }}\n onKeyDown={(event) => { if (event.key === 'Enter') setWorkspace((event.target as HTMLInputElement).value.trim()) }}\n />\n {workspace !== ''\n ? <button type='button' className={css.opBtn} title={tt('panel.workspaceClear')} onClick={() => { setWorkspace(''); setWorkspaceDraft('') }}>✕</button>\n : null}\n </span>\n <button type='button' className={css.legendToggle + (showLegend ? ' ' + css.legendToggleActive : '')} onClick={() => { setShowLegend((value) => !value) }} title={tt('legend.hint')}>?</button>\n <span className={css.actions}>\n <button type='button' className={css.button + ' ' + css.primary} onClick={() => { setShowForm((value) => !value) }}>{tt('panel.new')}</button>\n </span>\n </div>\n\n {showForm ? (\n <form className={css.form} onSubmit={(event) => { void create(event) }}>\n <p className={css.hintLine}>{tt('form.capabilityHint')}</p>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.name')}</label>\n <input className={css.input} value={formName} onChange={(event) => { setFormName(event.target.value) }} placeholder='code-review' />\n </div>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.desc')}</label>\n <input className={css.input} value={formDesc} onChange={(event) => { setFormDesc(event.target.value) }} placeholder={tt('form.descPlaceholder')} />\n </div>\n <div className={css.formRow}>\n <label className={css.formLabel}>{tt('form.root')}</label>\n <select className={css.select} value={formRoot} onChange={(event) => { setFormRoot(event.target.value as WritableRoot) }}>\n <option value='user-dsh'>~/.dsh/skills</option>\n <option value='user-agents'>~/.agents/skills</option>\n </select>\n </div>\n {formMessage !== null ? <div className={formMessage.kind === 'error' ? css.formError : css.formSuccess}>{formMessage.text}</div> : null}\n <div className={css.buttons}>\n <button type='submit' className={css.button + ' ' + css.primary} disabled={formBusy}>{formBusy ? tt('form.busy') : tt('form.submit')}</button>\n <button type='button' className={css.button} onClick={() => { setShowForm(false); setFormMessage(null) }}>{tt('form.cancel')}</button>\n </div>\n </form>\n ) : null}\n\n {loadError !== null ? (\n <div className={css.errorBanner}>\n <span>{loadError}</span>\n <button type='button' className={css.button} onClick={() => { setLoadError(null) }}>{tt('err.dismiss')}</button>\n </div>\n ) : null}\n\n {successBanner !== null ? (\n <div className={css.successBanner}>\n <span>{successBanner}</span>\n <button type='button' className={css.button} onClick={() => { setSuccessBanner(null) }}>{tt('err.dismiss')}</button>\n </div>\n ) : null}\n\n {showLegend ? (\n <div className={css.legend}>\n <span className={css.legendItem}><span className={css.dot + ' ' + css.dotModel} style={dotStyle(hubConfig?.dotModelColor)} />{tt('legend.model')}</span>\n <span className={css.legendItem}><span className={css.dot + ' ' + css.dotUser} style={dotStyle(hubConfig?.dotUserColor)} />{tt('legend.user')}</span>\n <span className={css.legendHint}>{tt('legend.hint')}</span>\n </div>\n ) : null}\n\n {loading ? <div className={css.empty}>{tt('panel.loading')}</div> : null}\n\n {detailLoading ? <div className={css.empty}>{tt('detail.loading')}</div> : null}\n\n {tab === 'market' ? (\n <MarketView hub={hub} />\n ) : catalog !== null ? (\n <>\n <div className={css.filterBar}>\n {tab === 'sources' ? (\n <>\n <span className={css.segmented}>\n <button type='button' className={css.segBtn + (skillView === 'flat' ? ' ' + css.segBtnActive : '')} onClick={() => { setSkillView('flat') }}>{tt('view.flat')}</button>\n <button type='button' className={css.segBtn + (skillView === 'groups' ? ' ' + css.segBtnActive : '')} onClick={() => { setSkillView('groups') }}>{tt('view.grouped')}</button>\n </span>\n <select className={css.select} value={sourceFilter} onChange={(event) => { setSourceFilter(event.target.value) }}>\n <option value='all'>{tt('filter.allSources')}</option>\n {sourceOptions.map((source) => (\n <option key={source} value={source}>{source === PRIVATE_SOURCE ? tt('filter.private') : source}</option>\n ))}\n </select>\n </>\n ) : null}\n <select className={css.select} value={sortKey} onChange={(event) => { setSortKey(event.target.value as SortKey) }}>\n <option value='name'>{tt('sort.name')}</option>\n <option value='added'>{tt('sort.added')}</option>\n <option value='uses'>{tt('sort.uses')}</option>\n </select>\n <input className={css.search} value={search} onChange={(event) => { setSearch(event.target.value) }} placeholder={tt('panel.search')} />\n <button type='button' className={css.button + (editMode ? ' ' + css.primary : '')} style={{ marginLeft:'auto' }} onClick={() => setEditMode((v) => !v)}>{editMode ? '完成' : '编辑'}</button>\n </div>\n\n {filtered.length === 0 && search.trim() !== '' ? <div className={css.empty}>{tt('panel.empty')}</div> : null}\n {filtered.length === 0 && search.trim() === '' && catalog.skills.length === 0 && catalog.disabled.length === 0 && catalog.diagnostics.length === 0\n ? <div className={css.empty}>{tt('panel.emptyAll')}</div>\n : null}\n\n {tab === 'sources' ? <SourcesView hub={hub} /> : <ScenesView hub={hub} />}\n\n {sourcesState !== null && sourcesState.trash.length > 0 ? (\n <section className={css.section}>\n <div className={css.sectionTitle + ' ' + css.sectionHeadRow}>\n <span className={css.sectionTitleFill}>{tt('source.trash')}</span>\n <button type='button' className={css.opBtn + ' ' + css.opDanger} disabled={tagBusy} onClick={() => { setConfirmClearTrash(true) }}>{tt('source.clearTrash')}</button>\n </div>\n {sourcesState.trash.map((entry) => (\n <div key={entry.name} className={css.row + ' ' + css.rowStatic}>\n <div className={css.rowMain}>\n <div className={css.rowName}>{entry.name}</div>\n <div className={css.rowDesc}>{relativeTimeText(entry.movedAt)}</div>\n </div>\n <button type='button' className={css.opBtn} disabled={tagBusy} onClick={() => { void restoreTrash(entry.name) }}>{tt('source.restore')}</button>\n </div>\n ))}\n </section>\n ) : null}\n\n {catalog.diagnostics.length > 0 ? (\n <section className={css.section}>\n <div className={css.sectionTitle}>{tt('panel.diagnostics')}</div>\n {catalog.diagnostics.map((entry) => (\n <div key={entry.path} className={css.diagRow}>\n <div className={css.diagPath}>{entry.path}</div>\n <div className={css.diagReason}>{entry.reason}</div>\n </div>\n ))}\n </section>\n ) : null}\n </>\n ) : null}\n\n {conflictDialog !== null ? (\n <ConflictDialog\n dialog={conflictDialog}\n tags={groupsState?.tags ?? []}\n collections={groupsState?.collections ?? []}\n onClose={() => { setConflictDialog(null) }}\n onKeepOn={() => { void resolveConflict(false) }}\n onCloseAll={() => { void resolveConflict(true) }}\n />\n ) : null}\n\n {confirmDialog !== null ? (\n <ConfirmDialog\n title={confirmDialog.kind === 'sync' ? tt('source.syncConfirmTitle') : tt('source.deleteConfirmTitle')}\n text={confirmDialog.kind === 'sync' ? tt('source.syncConfirmText') : tt('source.deleteConfirmText')}\n items={confirmDialog.skills}\n confirmLabel={confirmDialog.kind === 'sync' ? tt('source.sync') : tt('source.followDelete')}\n danger={confirmDialog.kind === 'delete'}\n onCancel={() => { setConfirmDialog(null) }}\n onConfirm={() => { void runConfirmed() }}\n />\n ) : null}\n\n {branchChoice !== null ? (\n <BranchChoiceDialog\n choice={branchChoice}\n busy={branchBusy}\n onSelect={(selected) => { setBranchChoice({ ...branchChoice, selected }) }}\n onCancel={() => { setBranchChoice(null) }}\n onConfirm={() => { void confirmBranchChoice() }}\n />\n ) : null}\n\n {marketSyncDialog !== null ? (\n <MarketSyncDialog\n dialog={marketSyncDialog}\n busy={syncBusy}\n onToggle={(name, checked) => {\n const next = new Set(marketSyncDialog.selected)\n if (checked) next.add(name)\n else next.delete(name)\n setMarketSyncDialog({ ...marketSyncDialog, selected: next })\n }}\n onCancel={() => { setMarketSyncDialog(null) }}\n onConfirm={() => { void confirmMarketSync() }}\n />\n ) : null}\n\n {deleteSkillDialog !== null ? (\n <ConfirmDialog\n title={tt('delete.confirmTitle')}\n text={tt('delete.confirmText', { name: deleteSkillDialog })}\n confirmLabel={tt('delete.confirm')}\n danger\n onCancel={() => { setDeleteSkillDialog(null) }}\n onConfirm={() => { void runDeleteSkill() }}\n />\n ) : null}\n\n {deleteGroupDialog !== null ? (\n <ConfirmDialog\n title={tt('source.deleteGroupTitle')}\n text={tt('source.deleteGroupText', { name: deleteGroupDialog.name, count: deleteGroupDialog.skillNames.length })}\n items={deleteGroupDialog.skillNames}\n confirmLabel={tt('source.deleteGroup')}\n danger\n onCancel={() => { setDeleteGroupDialog(null) }}\n onConfirm={() => { void runDeleteGroup() }}\n />\n ) : null}\n\n {confirmClearTrash ? (\n <ConfirmDialog\n title={tt('source.clearTrashConfirmTitle')}\n text={tt('source.clearTrashConfirmText')}\n confirmLabel={tt('source.clearTrashConfirm')}\n danger\n onCancel={() => { setConfirmClearTrash(false) }}\n onConfirm={() => { void clearTrash() }}\n />\n ) : null}\n </div>\n )\n}\n","/**\n * Browser-half entry for the dsh-skill-hub plugin — runs inside the dsh\n * web GUI.\n *\n * Registers the dsh-skill-hub locale dictionaries and mounts two Settings\n * surfaces, both through official slots (no DOM injection):\n * - a plugin-management card in the `settings.plugin.item` slot (Settings →\n * 插件 → 可配置插件列表), keyed by the hub's settings namespace and bound\n * through the official settings transport (dsh rc.7 serves every\n * registered namespace to the web client, and the tab dispatches cards by\n * namespace) — the family-bucket card pattern (PluginSettingsCard +\n * CardForm vendored from dsh-task-board);\n * - a top-level Settings section (Settings → 技能) hosting the skill hub\n * panel: catalog, search, enable/disable, diagnostics, new-skill form.\n *\n * Failure policy: mounting problems are logged, never thrown — the web\n * shell fails the whole boot when a plugin apply throws, and an external\n * plugin must not take the GUI down.\n *\n * Export discipline (packages/client rule): the /client surface carries\n * what cordis loading needs plus types only — all value exports stay\n * internal.\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the settings-scope service merge and the settings.section slot.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the LocaleNamespaceMap merge table.\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\n// Type-only: pulls the settings-plugins SlotMap merge (settings.plugin.item).\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\n// Type-only: pulls the Context merge for ctx.inputTriggers (slash-dots wiring).\nimport type {} from '@deepseek-ai/dsh-client-ui-input-trigger/client'\n// Type-only: pulls the connection/reset event.\nimport type {} from '@deepseek-ai/dsh-client-connection/client'\n\n// 0.1.2-alpha.2: slots service moved to ui-renderer; provide local augmentation for build.\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n slots: any\n }\n}\nimport type { HubSettingsValue } from '../protocol.ts'\nimport { SkillHubApi } from './api.ts'\nimport { en, zh, type HubKey } from './locales.ts'\nimport { applySettingsNavIcon } from './settings-nav-icon.ts'\nimport { setupSkillSlashDots } from './slash-dots.tsx'\nimport { SkillHubSettingsCard, SkillHubSettingsCardController } from './SkillHubSettingsCard.tsx'\nimport { SkillHubPanel } from './panel/SkillHubPanel.tsx'\n\n/** Locale namespace this plugin owns. */\nconst NS = 'dsh-skill-hub'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** dsh-skill-hub surface copy. */\n 'dsh-skill-hub': HubKey\n }\n}\n\n/**\n * Required services (fiber inject waiting — the runtime must be up first).\n * `connection`/`remote` are the settings transport's own prerequisites\n * (`ctx.settingsScope.bind` resolves them on the caller's fiber), and\n * `settingsScope` is the namespace-scope binder itself; mirror the official\n * settings-plugins inject list.\n */\nexport const inject = ['slots', 'locale', 'connection', 'remote', 'settingsScope', 'inputTriggers']\n\n/** Type-only surface (export discipline: no value exports beyond the plugin contract). */\nexport type { SkillHubPanelProps } from './panel/SkillHubPanel.tsx'\nexport type { SkillHubSettingsState } from './SkillHubSettingsCard.tsx'\nexport type { HubKey } from './locales.ts'\n\n/**\n * Mount the settings card and the skill hub section.\n * @param ctx - client root context (slots, locale).\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-skill-hub: dictionaries')\n const t = ctx.locale.bind(NS)\n const api = new SkillHubApi()\n\n // The card edits the hub's settings namespace through the official\n // settings transport — the configurable-plugins tab only dispatches cards\n // whose key the Host serves, and the Host serves every registered namespace\n // since rc.7, so this is what makes the card appear (and stay in sync).\n const settingsCard = new SkillHubSettingsCardController(\n ctx.settingsScope.bind<HubSettingsValue>({ namespace: NS }),\n )\n\n // Chat `/` menu skill dots: wrap the core skill source so every candidate\n // row carries the invocation dot, colored from the same settings the panel\n // legend uses (dotModelColor / dotUserColor). Own scope = independent reader;\n // fails silent, never takes the GUI down.\n ctx.effect(\n () => setupSkillSlashDots(ctx, api, ctx.settingsScope.bind<HubSettingsValue>({ namespace: NS })),\n 'dsh-skill-hub: slash dots',\n )\n\n // Plugin-management card: Settings → 插件 → 可配置插件列表.\n // rc.7's slot contract declares this keyed slot with options `key`\n // (the settings namespace the card edits), so registration is fully typed.\n ctx.effect(\n () => ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n key: NS,\n locale: NS,\n inject: () => settingsCard.inject(),\n }, SkillHubSettingsCard)),\n 'dsh-skill-hub: settings card',\n )\n\n // Top-level Settings section: the skill management page.\n ctx.effect(\n () => ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'skill-hub',\n order: 12,\n label: () => t('entry.label'),\n locale: NS,\n inject: () => ({}),\n }, () => <SkillHubPanel api={api} />)),\n 'dsh-skill-hub: settings section',\n )\n\n // Host shell has no section-icon registration; keep the nav gear swapped for the skill icon.\n ctx.effect(() => applySettingsNavIcon(), 'dsh-skill-hub: settings nav icon')\n}\n"],"x_google_ignoreList":[10,11,12,13],"mappings":"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"}
|