agentus 0.15.5 → 0.15.6

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/README.md CHANGED
@@ -57,7 +57,7 @@ background process comes back as a turn of its own), an **ACP session that write
57
57
  cockpit-side failure is diagnosable afterwards), and a **DeepSeek web backend** (search +
58
58
  extract on the model key) — come from the fork's integration build instead. That is a five-line install:
59
59
  [§ Which Hermes to run](docs/installation.md#which-hermes-to-run) — currently the tag
60
- `agentus/v0.22.0/merge-20261028-1949`, on Hermes `v0.22.0`.
60
+ `agentus/v0.22.0/merge-20261028-2028`, on Hermes `v0.22.0`.
61
61
 
62
62
  The first slot you start will use the Hermes home **your own agent already uses**
63
63
  (`~/.hermes`) unless the backend row names another one — see "HERMES_HOME" below.
package/README.zh-CN.md CHANGED
@@ -51,7 +51,7 @@ web bundle、配套 APK —— 然后直接退出,不启动任何东西)。
51
51
  以及 **DeepSeek 的 web 后端**(搜索 + 正文抓取,共用模型 key)—— 来自 fork 的集成构建(tag)。
52
52
  装法就五行:
53
53
  [§ 该跑哪份 Hermes](docs/installation.zh-CN.md#该跑哪份-hermes) —— 当前是 tag
54
- `agentus/v0.22.0/merge-20261028-1949`,基座 Hermes `v0.22.0`。
54
+ `agentus/v0.22.0/merge-20261028-2028`,基座 Hermes `v0.22.0`。
55
55
 
56
56
  你启动的第一个 slot 会使用**你自己的 agent 已经在用的**那个 Hermes home(`~/.hermes`),除非后端那一行
57
57
  指定了另一个 —— 见下面的「HERMES_HOME」。
@@ -60,7 +60,7 @@ ref and gets rebuilt, while a tag never moves — so pin the tag. The `agentus/`
60
60
  ours apart from upstream's own tags (`v0.22.0`, `v0.22.0+canary.*`), and the timestamp in the
61
61
  last segment sorts, so "newest" is a `sort -V`.
62
62
 
63
- **Current integration build: `agentus/v0.22.0/merge-20261028-1949`** — the newest tag on the fork,
63
+ **Current integration build: `agentus/v0.22.0/merge-20261028-2028`** — the newest tag on the fork,
64
64
  built on Hermes `v0.22.0`. This line is for orientation only, not the source of truth: the
65
65
  `TAG=$(…)` step below resolves the newest one on every run, so read it there if this sentence
66
66
  ever looks stale.
@@ -52,7 +52,7 @@ agentus/<hermes 内部版本>/merge-<YYYYMMDD-HHMM>
52
52
  tag。`agentus/` 这个前缀也把它和上游自己的 tag(`v0.22.0`、`v0.22.0+canary.*`)分开;最后一段是时间戳,
53
53
  可排序,所以「最新」就是一次 `sort -V`。
54
54
 
55
- **当前集成构建:`agentus/v0.22.0/merge-20261028-1949`** —— fork 上最新的那个 tag,基座 Hermes
55
+ **当前集成构建:`agentus/v0.22.0/merge-20261028-2028`** —— fork 上最新的那个 tag,基座 Hermes
56
56
  `v0.22.0`。这行只为一眼看个大概,不是权威:下面的 `TAG=$(…)` 每次都会自己解析出最新,觉得这行过期就
57
57
  以它为准。
58
58
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentus",
3
- "version": "0.15.5",
3
+ "version": "0.15.6",
4
4
  "description": "Multi-session web cockpit for ACP-speaking coding agents (Qoder CLI / Hermes). UI has no intelligence — the agent lives in spawned CLI subprocesses.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -1402,7 +1402,11 @@ export class SessionManager {
1402
1402
  // 就会改到默认 profile 的默认模型上,当前会话那个 profile 反而没变。
1403
1403
  profile: shape.spec.profile ?? null,
1404
1404
  });
1405
- if (!r.ok) console.log(`[agentus] model default not written (${info.backend}): ${r.reason}`);
1405
+ if (!r.ok) {
1406
+ // 唯一一处"操作者需要动手"的失败:set-model 已经把成功回给页面了,这句日志如果不显眼,
1407
+ // 下一次新会话会悄悄退回到旧默认(#72 的症状原样回来)。所以带上 backend 与会话,稳定可 grep。
1408
+ console.warn(`[agentus] modelWriteBack: refused for ${info.id} (${info.backend}, picked ${modelId}): ${r.reason}`);
1409
+ }
1406
1410
  else if (r.changed) {
1407
1411
  console.log(`[agentus] model default → ${r.model ?? modelId}${r.provider ? ` (provider ${r.provider})` : ""} for ${info.backend} (picked ${modelId})`);
1408
1412
  }
@@ -3092,6 +3096,9 @@ export class SessionManager {
3092
3096
  if (!row) throw new Error(`no such session: ${id}`);
3093
3097
  const known = ((row.models ?? null) as SessionInfo["models"])?.availableModels ?? [];
3094
3098
  if (known.length && !known.some((m) => m.modelId === modelId)) {
3099
+ // 重放的是对话框里的旧值:这一行的清单已经不认它了。不是操作者的错,也不该变成一条红色
3100
+ // 错误:什么都不做,让会话按自己的默认起来(缓存那份由下一次启动的握手刷掉)。
3101
+ if (opts.fromReplay) return this.#coldInfo(id);
3095
3102
  throw new Error(`unknown model: ${modelId}`);
3096
3103
  }
3097
3104
  if (!this.#store.setPendingModel(id, modelId)) throw new Error(`no such session: ${id}`);
@@ -3103,6 +3110,14 @@ export class SessionManager {
3103
3110
  if (!conn || !s.info.acpSessionId) throw new Error("session not ready — resume it first");
3104
3111
  const known = s.info.models?.availableModels ?? [];
3105
3112
  if (known.length && !known.some((m) => m.modelId === modelId)) {
3113
+ if (opts.fromReplay) {
3114
+ // 同上,但活会话有更新的清单在手上:顺手把缓存里的陈旧 id 换掉,下一次对话框就显示真的默认。
3115
+ this.#store.recordHandshakeModels(s.info.backend, {
3116
+ currentModelId: s.info.models?.currentModelId ?? null,
3117
+ available: known.map((m) => m.modelId).filter(Boolean),
3118
+ });
3119
+ return s.info;
3120
+ }
3106
3121
  throw new Error(`unknown model: ${modelId}`);
3107
3122
  }
3108
3123
  const reply = await conn.request("session/set_model", { sessionId: s.info.acpSessionId, modelId });
@@ -3125,15 +3140,19 @@ export class SessionManager {
3125
3140
  }
3126
3141
  // #72:缓存握手是"上一次真启动"的快照,新建会话对话框只读它 —— 换了模型却不改它,对话框会一直
3127
3142
  // 显示(并且把)切换前的那个 id 当中文默认值。活会话手里有完整清单,顺手把两份都刷新。
3143
+ // 以**活会话**为准:agent 可能在回复里规范化了 id(或表示"没变"),那时缓存的默认值必须跟它走,
3144
+ // 否则对话框显示的、重放的,都是槽位没在跑的那个 id(MINOR 4)。
3128
3145
  this.#store.recordHandshakeModels(s.info.backend, {
3129
- currentModelId: modelId,
3146
+ currentModelId: s.info.models?.currentModelId ?? modelId,
3130
3147
  available: (s.info.models?.availableModels ?? []).map((m) => m.modelId).filter(Boolean),
3131
3148
  });
3132
3149
  if (s.info.pendingModelId) s.info.pendingModelId = null;
3133
3150
  this.#store.setPendingModel(id, null);
3134
3151
  // #62-1: 只有 agent **接受**过的切换才计数 —— 被拒的条目永不加分,于是"广告了但实际不可用"
3135
3152
  // 的模型会自己沉到列表底部,不需要任何端点探活。
3136
- bumpModelUsage(`${s.info.backend}|${modelId}`);
3153
+ // 重放(新建会话时把对话框里的选择下发)不是操作者的切换动作:既不该改写全局默认,也不该给
3154
+ // 「常用模型」加分,否则排序量的是"起了多少会话",不是"选了哪个模型"(#72 review MINOR 6)。
3155
+ if (!opts.fromReplay) bumpModelUsage(`${s.info.backend}|${modelId}`);
3137
3156
  // #62-3:选定即成为 agent 的全局默认(设置里可关)。同样只在这一行之后 —— 被拒的模型不落盘。
3138
3157
  // **重放不算**:冷槽上留下的意图可能被一次无人值守的 completion 唤醒带上(resume <-
3139
3158
  // `this.resume(e.origin)`),那时代码里没有"操作者在选模型"这件事,不该改全局配置。
@@ -2159,7 +2159,7 @@ wss.on("connection", (ws) => {
2159
2159
  await mgr.setConfig(cmd.sessionId, cmd.configId, cmd.value);
2160
2160
  break;
2161
2161
  case "set-model":
2162
- await mgr.setModel(cmd.sessionId, cmd.modelId);
2162
+ await mgr.setModel(cmd.sessionId, cmd.modelId, { fromReplay: cmd.fromReplay === true });
2163
2163
  break;
2164
2164
  case "respond-permission": {
2165
2165
  const applied = mgr.respondPermission(cmd.sessionId, cmd.requestId, cmd.decision, {
@@ -126,8 +126,17 @@ function setKey(lines: string[], key: string, value: string, indent: string): st
126
126
  export interface EndpointInfo {
127
127
  /** 持久身份:`custom:<config 键>`(legacy 条目用规范化后的 name) */
128
128
  id: string;
129
+ /** 条目自己声明的端点;`null` = 这个块没有端点(见 `namedEndpoints` 为什么跳过它) */
129
130
  apiUrl: string | null;
130
131
  apiMode: string | null;
132
+ /** 条目声明的模型 id;`models:` 没写就是空数组(靠发现拿模型的那种条目) */
133
+ models: string[];
134
+ }
135
+
136
+ /** 一张表两个命名空间:**键**是身份,**显示名**只是弱别名。 */
137
+ export interface NamedEndpoints {
138
+ byKey: Map<string, EndpointInfo>;
139
+ byAlias: Map<string, EndpointInfo>;
131
140
  }
132
141
 
133
142
  /** hermes 的 `custom_provider_slug`:小写、空格换连字符、补 `custom:` 前缀。 */
@@ -138,25 +147,49 @@ const customSlug = (display: string): string => {
138
147
 
139
148
  const bareName = (id: string): string => id.trim().toLowerCase().replace(/^custom:/, "");
140
149
 
141
- /** hermes 的 `is_provider_enabled`:`enabled:` 的假值一律视为停用。 */
150
+ /** hermes 的 `is_provider_enabled`:假值一律视为停用(非字符串非布尔的容器值按 truthiness)。 */
142
151
  const isDisabled = (entry: Record<string, unknown>): boolean => {
143
152
  const raw = entry.enabled;
144
153
  if (raw === undefined || raw === null) return false;
145
154
  if (typeof raw === "boolean") return !raw;
146
- return ["false", "no", "off", "0", "disabled"].includes(String(raw).trim().toLowerCase());
155
+ if (typeof raw === "string") {
156
+ return ["false", "no", "off", "0", "disabled"].includes(raw.trim().toLowerCase());
157
+ }
158
+ return !raw;
159
+ };
160
+
161
+ /** 条目声明的模型 id(`models:` 里元素可以是字符串或 `{id|model|name}`)。 */
162
+ const declaredModels = (entry: Record<string, unknown>): string[] => {
163
+ const raw = entry.models;
164
+ if (!Array.isArray(raw)) return [];
165
+ const out: string[] = [];
166
+ for (const item of raw) {
167
+ const value = typeof item === "string" ? item
168
+ : item && typeof item === "object" ? ((item as Record<string, unknown>).id
169
+ ?? (item as Record<string, unknown>).model ?? (item as Record<string, unknown>).name) : null;
170
+ const text = typeof value === "string" ? value.trim() : "";
171
+ if (text) out.push(text);
172
+ }
173
+ return out;
147
174
  };
148
175
 
149
- /** 配置里的命名端点,**键是持久身份** `custom:<条目>`;显示名另作别名指向同一条目。
176
+ /** 配置里**真的能路由**的命名端点:键是持久身份 `custom:<条目>`,显示名另作弱别名。
177
+ *
178
+ * 三条判据都是 hermes 自己的:
150
179
  *
151
- * 为什么别名也进这张表:choice id 是身份的权威来源(`custom:<键>:<模型>`),但旧形状
152
- * (`custom:<模型>`)与裸模型名只剩描述里的**显示名**可用。用显示名当 `model.provider` 写下去,
153
- * 一旦操作者改了 `name:`,那份配置就再也解析不回来 —— 所以别名必须翻译成 `custom:<键>`,
154
- * 而不是跟着名字走。
180
+ * 1. **没有端点的块不是命名端点。** `providers.bedrock: {stale_timeout_seconds: 600}` 是给内置
181
+ * provider 调参的,`_pick_provider_base_url` 为空的条目会被 `get_compatible_custom_providers`
182
+ * 丢掉、`resolve_user_provider` 也不认 —— 把它当端点写下去,`custom:bedrock` 是个谁都不认识的
183
+ * 身份,还会顺手删掉块里唯一能路由的 `base_url`。所以这种块整条跳过。
184
+ * 2. **停用条目不存在**(`enabled: false`):写进 `model.provider` 等于让下一次 spawn 起不来。
185
+ * 3. **别名永不覆盖键。** 条目 A 的 `name:` 可能与条目 B 的键同名;键是身份、别名只是「描述里印的
186
+ * 是哪个名字」,所以别名只在键查不到时用,且先到先得(hermes 的解析也是取第一个匹配)。
155
187
  *
156
- * 端点字段的顺序照 hermes 的 `_pick_provider_base_url`:`base_url` → `url` → `api`。
157
- * `api_url` 是 inventory 行(运行时)的字段,不是 config 键;它只作为最后的容错。 */
158
- export function namedEndpoints(doc: unknown): Map<string, EndpointInfo> {
159
- const out = new Map<string, EndpointInfo>();
188
+ * 端点字段顺序照 hermes 的 `_pick_provider_base_url`:`base_url` → `url` → `api`。
189
+ * `api_url` 是 inventory 行(运行时)的字段,不是 config 键;只作最后容错。 */
190
+ export function namedEndpoints(doc: unknown): NamedEndpoints {
191
+ const byKey = new Map<string, EndpointInfo>();
192
+ const byAlias = new Map<string, EndpointInfo>();
160
193
  const endpointOf = (entry: Record<string, unknown>): string | null => {
161
194
  for (const key of ["base_url", "url", "api", "api_url"]) {
162
195
  const value = entry[key];
@@ -165,10 +198,20 @@ export function namedEndpoints(doc: unknown): Map<string, EndpointInfo> {
165
198
  return null;
166
199
  };
167
200
  const add = (id: string, entry: Record<string, unknown>): void => {
168
- const info: EndpointInfo = { id, apiUrl: endpointOf(entry), apiMode: typeof entry.api_mode === "string" ? entry.api_mode : null };
169
- out.set(id, info);
201
+ const apiUrl = endpointOf(entry);
202
+ if (!apiUrl) return; // 见上:调参块不是端点
203
+ const info: EndpointInfo = {
204
+ id, apiUrl,
205
+ apiMode: typeof entry.api_mode === "string" ? entry.api_mode : null,
206
+ models: declaredModels(entry),
207
+ };
208
+ // 同一个键写两遍时后者覆盖(YAML 本身也不允许),但别名绝不覆盖任何已存在的**键**。
209
+ byKey.set(id, info);
170
210
  const display = typeof entry.name === "string" ? entry.name.trim() : "";
171
- if (display) out.set(customSlug(display), info);
211
+ if (display) {
212
+ const alias = customSlug(display);
213
+ if (!byKey.has(alias) && !byAlias.has(alias)) byAlias.set(alias, info);
214
+ }
172
215
  };
173
216
  const d = (doc ?? {}) as { providers?: unknown; custom_providers?: unknown };
174
217
  const providers = d.providers;
@@ -176,7 +219,7 @@ export function namedEndpoints(doc: unknown): Map<string, EndpointInfo> {
176
219
  for (const [key, entry] of Object.entries(providers as Record<string, unknown>)) {
177
220
  if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
178
221
  const raw = entry as Record<string, unknown>;
179
- if (isDisabled(raw)) continue; // hermes 不认停用条目:写进 provider 等于让下一次 spawn 起不来
222
+ if (isDisabled(raw)) continue;
180
223
  // 键是身份(显示名可以改),和 hermes 的 custom_provider_slug(display, key) 同一个取向。
181
224
  add(customSlug(key), raw);
182
225
  }
@@ -192,82 +235,99 @@ export function namedEndpoints(doc: unknown): Map<string, EndpointInfo> {
192
235
  add(customSlug(name), raw);
193
236
  }
194
237
  }
195
- return out;
238
+ return { byKey, byAlias };
196
239
  }
197
240
 
198
241
  export interface ChoiceSplit {
199
242
  /** hermes `model.default` 该写的值:裸模型名 */
200
243
  model: string;
201
- /** hermes `model.provider` 该写的值;null = 推不出来,保持原样 */
244
+ /** hermes `model.provider` 该写的值;null = 推不出来,**保持原样**(不猜) */
202
245
  provider: string | null;
203
- /** true = 这个 id 描述了一个本配置里不存在的条目:**不许写**,也算不出可信的模型名 */
246
+ /** true = 这个 id 描述了一个本配置里没有的条目,且连 provider 都定不下来:不许写 */
204
247
  unresolved?: boolean;
205
248
  }
206
249
 
207
250
  /** 把选择器的 choice id 拆回 `(裸模型名, 持久 provider 身份)`。
208
251
  *
209
252
  * 规则就是 hermes 自己的那条:provider 只在左半段是**已知 provider/条目**时才算分隔符,
210
- * 否则整串都是模型名(`anthropic/claude-3.5-sonnet:beta` 不能被切)。条目名到身份的映射由
211
- * `namedEndpoints` 提供,所以这里不需要再猜"哪些名字是 provider"。 */
253
+ * 否则整串都是模型名(`anthropic/claude-3.5-sonnet:beta` 不能被切)。
254
+ *
255
+ * 描述(`Provider: <名字>`)只当**弱**信号用,这是这里最容易错的地方:
256
+ * - 它印的是条目的**显示名**,可能与另一个条目/内置 provider 重名,所以只有「条目自己声明了这个
257
+ * 模型」时它才算证据(否则 `OpenRouter` 这个显示名会把内置 openrouter 的 pick 拽到本地代理上);
258
+ * - 带前缀的 id(`<左段>:<模型>`)里左段不是键时一律按 canonical/provider 读,不看描述 —— 行自己
259
+ * 带来的前缀比描述更权威;
260
+ * - 什么都推不出来时返回 `provider: null`(调用方保持 `model.provider` 原样),不写一个不存在的
261
+ * slug —— 那会让下一次 spawn 拿到一个解析不了的 provider。 */
212
262
  export function splitChoiceId(
213
263
  modelId: string,
214
264
  providerHint: string | null,
215
- endpoints: Map<string, EndpointInfo>,
265
+ named: NamedEndpoints,
216
266
  ): ChoiceSplit {
217
267
  const raw = (modelId ?? "").trim();
218
268
  if (!raw) return { model: raw, provider: null };
219
269
  const lowered = raw.toLowerCase();
270
+ const hintSlug = providerHint
271
+ ? (providerHint.includes(":") ? providerHint.trim().toLowerCase() : customSlug(providerHint))
272
+ : null;
273
+ const keyInfo = hintSlug ? named.byKey.get(hintSlug) : undefined;
274
+ const aliasInfo = hintSlug && !keyInfo ? named.byAlias.get(hintSlug) : undefined;
275
+ /** 描述指向的条目身份(键优先,别名次之)。只在 `custom:` 前缀已经把「这是条目」说清的地方用。 */
276
+ const hintEntryId = keyInfo?.id ?? aliasInfo?.id ?? null;
277
+ /** 描述本身长得像一个 provider slug(而不是一句显示名):`Alibaba` / `kimi-coding`。 */
278
+ const hintIsSlug = Boolean(hintSlug && /^[a-z0-9][a-z0-9._-]*$/.test(hintSlug.replace(/^custom:/, "")));
279
+ const declares = (info: EndpointInfo | undefined, model: string): boolean =>
280
+ Boolean(info && model && info.models.some((m) => m.toLowerCase() === model.toLowerCase()));
220
281
 
221
- // 描述里的名字是**显示名**:先翻成持久身份(改名也不会断),翻不到才当 canonical slug 用。
222
- const hintSlug = providerHint ? (providerHint.includes(":") ? providerHint.trim().toLowerCase() : customSlug(providerHint)) : null;
223
- const hintInfo = hintSlug ? endpoints.get(hintSlug) : undefined;
224
- const hintId = hintInfo?.id ?? null;
225
- const hintBares = new Set<string>();
226
- if (hintSlug) hintBares.add(bareName(hintSlug));
227
- if (hintId) hintBares.add(bareName(hintId));
228
- hintBares.delete("custom");
229
- hintBares.delete("");
230
-
231
- // 1) 描述里声明的条目自己认领前缀:`custom:<条目>:<模型>` / `<条目>:<模型>`。
232
- for (const bare of hintBares) {
233
- const customPrefix = `custom:${bare}:`;
234
- if (lowered.startsWith(customPrefix)) {
235
- // 只有这个条目真的在配置里,才允许把它的名字当成身份写下去。
236
- const entry = endpoints.get(`custom:${bare}`);
237
- return { model: raw.slice(customPrefix.length).trim(), provider: entry?.id ?? hintId ?? null,
238
- unresolved: entry ? undefined : true };
239
- }
240
- if (!lowered.startsWith("custom:") && lowered.startsWith(`${bare}:`)) {
241
- return { model: raw.slice(bare.length + 1).trim(), provider: hintId ?? bare };
242
- }
243
- }
244
-
245
- // 2) `custom:` 开头的三段 id:第二段是已配置条目才切。
282
+ // 1) `custom:<…>` —— 前缀自己说明「这是个 custom 条目」,所以这里别名也算数(F5:显示名 → 键)。
246
283
  if (lowered.startsWith("custom:")) {
247
284
  const rest = raw.slice("custom:".length);
248
285
  const cut = rest.indexOf(":");
249
286
  if (cut > 0) {
250
- const named = endpoints.get(customSlug(rest.slice(0, cut)));
251
- if (named) return { model: rest.slice(cut + 1).trim(), provider: named.id };
252
- // 这个条目本配置里没有(被改名/删掉,而对话框拿的是旧快照)。把整串写进 model.default
253
- // 正是 #72 的病灶:模型名变成 `条目:模型`,或者被按第一个冒号切成 provider=custom。
254
- return { model: raw, provider: hintId, unresolved: true };
287
+ const head = customSlug(rest.slice(0, cut));
288
+ const entry = named.byKey.get(head) ?? named.byAlias.get(head);
289
+ if (entry) return { model: rest.slice(cut + 1).trim(), provider: entry.id };
290
+ // 第二段不是条目,两种读法都说得通,只能让条目自己的声明白话:
291
+ // · 条目**声明了** `qwen3:32b` 这种带冒号的模型 → 旧形状(模型名是整段)
292
+ // · 条目声明了后半段 → 条目前缀是陈旧的(条目被改名/删掉过,对话框还是旧快照)
293
+ // 两种都对上(或都没声明)才是真歧义:那时不写,让调用方看到原因。
294
+ if (keyInfo && declares(keyInfo, rest)) return { model: rest.trim(), provider: keyInfo.id };
295
+ if (keyInfo && declares(keyInfo, rest.slice(cut + 1).trim())) {
296
+ return { model: rest.slice(cut + 1).trim(), provider: keyInfo.id };
297
+ }
298
+ // 真歧义:条目既没声明整段、也没声明后半段。写哪个都得赌一次,所以不写(reason 会带上)。
299
+ return { model: raw, provider: null, unresolved: true };
255
300
  }
256
- // `custom:<模型>`(旧形状):模型名是确定的那半,provider 只能靠描述推。
257
- return { model: rest.trim(), provider: hintId };
301
+ // `custom:<模型>`:模型名是确定的那半,provider 只能靠描述推。
302
+ return { model: rest.trim(), provider: hintEntryId };
258
303
  }
259
304
 
260
- // 3) `<provider>:<模型>`:左半段是已配置条目(含显示名)、或就是描述里声明的那个名字。
261
- const colon = raw.indexOf(":");
262
- if (colon > 0) {
263
- const left = raw.slice(0, colon).trim().toLowerCase();
264
- const named = endpoints.get(customSlug(left));
265
- if (named) return { model: raw.slice(colon + 1).trim(), provider: named.id };
266
- if (hintBares.has(left)) return { model: raw.slice(colon + 1).trim(), provider: hintId ?? left };
305
+ // 2) `<左段>:<模型>`:左段是配置键 → 身份权威;否则整段就是模型名的一部分被行前缀带着,
306
+ // 按 provider/canonical slug 原样写(`openrouter:claude` 绝不能因为显示名重名改成 custom:x)。
307
+ const cut = raw.indexOf(":");
308
+ if (cut > 0) {
309
+ const left = raw.slice(0, cut).trim().toLowerCase();
310
+ const tail = raw.slice(cut + 1).trim();
311
+ const entry = named.byKey.get(customSlug(left));
312
+ if (entry) return { model: tail, provider: entry.id };
313
+ // 左段与描述指的是同一个名字,且那个名字是个 provider slug ⇒ 左段就是 provider(`alibaba:x`)。
314
+ if (hintIsSlug && bareName(customSlug(left)) === bareName(hintSlug ?? "")) {
315
+ // 只有**键**能当身份:别名说「描述里印的是这个名字」,而 cloud 与本地代理重名时
316
+ // 正是靠这一条才不会把云 provider 的 pick 写成本地条目(MAJOR 3)。
317
+ return { model: tail, provider: keyInfo?.id ?? left };
318
+ }
319
+ // 其余情况:左段不是已知条目/描述里的名字,那它可能只是模型名的一部分
320
+ // (`anthropic/claude-3.5-sonnet:beta` 的冒号在斜杠后面)。整串留着,不猜。
321
+ return { model: raw, provider: null };
267
322
  }
268
323
 
269
- // 4) 裸模型名 + 描述里的条目:描述只用来定 provider,绝不改模型名。
270
- return { model: raw, provider: hintId ?? (hintSlug && hintBares.size ? [...hintBares][0] : null) };
324
+ // 3) 裸模型名:键就是证据;显示名要再对上「条目声明了这个模型」才算(重名时不敢认)。
325
+ if (keyInfo) return { model: raw, provider: keyInfo.id };
326
+ if (aliasInfo && declares(aliasInfo, raw)) return { model: raw, provider: aliasInfo.id };
327
+ // 描述是个 slug 形状(`Alibaba`/`kimi-coding`)⇒ canonical provider,写下去 hermes 认得。
328
+ // 一句显示名(`My Lab Box`)推不出任何身份,保持 `model.provider` 原样。
329
+ if (hintIsSlug && hintSlug) return { model: raw, provider: bareName(hintSlug) };
330
+ return { model: raw, provider: null };
271
331
  }
272
332
 
273
333
  function deleteKey(lines: string[], key: string): string[] {
@@ -311,8 +371,8 @@ export function writeModelDefault(
311
371
  // 配置里有哪些命名端点,决定了 choice id 怎么拆、以及块内残留的端点要不要清。
312
372
  let before: unknown = null;
313
373
  try { before = parseYaml(text); } catch { before = null; }
314
- const endpoints = namedEndpoints(before);
315
- const split = splitChoiceId(modelId, options.provider ?? null, endpoints);
374
+ const named = namedEndpoints(before);
375
+ const split = splitChoiceId(modelId, options.provider ?? null, named);
316
376
  const provider = split.provider;
317
377
  const desiredModel = split.model;
318
378
  if (split.unresolved) {
@@ -327,13 +387,15 @@ export function writeModelDefault(
327
387
  const previousProvider = (before as { model?: { provider?: unknown } } | null)?.model?.provider;
328
388
  const previous = typeof previousProvider === "string" ? previousProvider.trim() : null;
329
389
  const providerChanged = provider != null && provider !== previous;
330
- const entry = provider ? endpoints.get(provider) : undefined;
390
+ // 端点归属问的是「这个条目**声明了**端点吗」,不是「有这个条目吗」:没有端点的块是给内置
391
+ // provider 调参用的(见 namedEndpoints),它既不拥有块里的 base_url,也当不了 model.provider。
392
+ const entry = provider ? named.byKey.get(provider) : undefined;
331
393
  // 块级的 base_url/api_mode 是**上一个 provider 的口子**,两种情况下都必然过期或多余:
332
394
  // · 换了 provider —— 它描述的是被换掉的那一个;
333
395
  // · 新 provider 是命名条目 —— 端点归条目所有(条目改了端口/协议,块里那份就成了矛盾状态)。
334
396
  // 只按「换 provider 且端点归某个条目」判断,会漏掉 `custom → openrouter`(新 provider 不声明端点),
335
397
  // 于是写出「provider 是云厂商、base_url 还指着本地边车」的块,那正是 #72 B 段的错路由。
336
- const dropEndpointKeys = providerChanged || Boolean(entry);
398
+ const dropEndpointKeys = providerChanged || Boolean(entry?.apiUrl);
337
399
 
338
400
  const indent = blockIndent(lines);
339
401
  let work = lines;
@@ -349,6 +411,9 @@ export function writeModelDefault(
349
411
 
350
412
  // 写盘前的最后一道闸:真解析一遍。不只看"两行读得回",要看**这个块自洽**——
351
413
  // provider 指向的条目和块里的端点必须是同一个端点,否则整次拒写(旧闸门会稳定放过矛盾状态)。
414
+ // 常规路径上端点键已经在上面被删掉了,所以这里主要拦 `deleteKey` 正则认不出的写法
415
+ // (`base_url :` 中间带空格之类)—— 门槛低但便宜,且它是唯一一处验证「磁盘上的块」而不是
416
+ // 「我打算写的块」的地方。
352
417
  let doc: unknown;
353
418
  try {
354
419
  doc = parseYaml(next);
@@ -1815,7 +1815,13 @@ export class Store {
1815
1815
  // `current` must stay inside `available`: the dialog only shows an id that is in the list
1816
1816
  // (`startModelValue`), so caching a current the list cannot contain would silently downgrade the
1817
1817
  // next new-session default to "agent default" right after the operator switched (#72 review).
1818
- const available = current && !supplied.includes(current) ? [current, ...supplied] : supplied;
1818
+ // …but it must not GROW the cache either: `available` is the new-session dialog's model list, so a
1819
+ // prepend per switch would accrete ids of endpoints/models that no longer exist, each one a
1820
+ // selectable row that answers "unknown model". Keep the list's length and let the oldest entry
1821
+ // fall off — the next real agent start refreshes the whole snapshot anyway (#72 review).
1822
+ const available = current && !supplied.includes(current)
1823
+ ? [current, ...supplied.filter((m) => m !== current)].slice(0, Math.max(supplied.length, 1))
1824
+ : supplied;
1819
1825
  hs.models = { ...hs.models, currentModelId: current, available };
1820
1826
  this.#db.prepare("update backends set handshake = ? where id = ?").run(JSON.stringify(hs), id);
1821
1827
  }
@@ -502,7 +502,9 @@ export type ClientCommand =
502
502
  | { t: "cancel"; sessionId: string }
503
503
  | { t: "set-mode"; sessionId: string; modeId: string }
504
504
  | { t: "set-config"; sessionId: string; configId: string; value: string | number | boolean }
505
- | { t: "set-model"; sessionId: string; modelId: string }
505
+ /** `fromReplay` = 这条帧是在重放对话框里的选择(新会话建立时那一轮),不是操作者刚点的切换:
506
+ * 写回全局默认与用量计数都只认后者(见 session-manager 的 `#writeBackModelDefault`/`bumpModelUsage`)。 */
507
+ | { t: "set-model"; sessionId: string; modelId: string; fromReplay?: boolean }
506
508
  | {
507
509
  t: "respond-permission";
508
510
  sessionId: string;
@@ -40,7 +40,7 @@ Error generating stack: `+r.message+`
40
40
  `+r.stack}return{value:e,source:t,stack:i,digest:null}}function ef(e,t,s){return{value:e,source:null,stack:s??null,digest:t??null}}function jp(e,t){try{console.error(t.value)}catch(s){setTimeout(function(){throw s})}}var P2=typeof WeakMap=="function"?WeakMap:Map;function Ox(e,t,s){s=Ri(-1,s),s.tag=3,s.payload={element:null};var n=t.value;return s.callback=function(){vh||(vh=!0,$p=n),jp(e,t)},s}function Bx(e,t,s){s=Ri(-1,s),s.tag=3;var n=e.type.getDerivedStateFromError;if(typeof n=="function"){var i=t.value;s.payload=function(){return n(i)},s.callback=function(){jp(e,t)}}var r=e.stateNode;return r!==null&&typeof r.componentDidCatch=="function"&&(s.callback=function(){jp(e,t),typeof n!="function"&&(_r===null?_r=new Set([this]):_r.add(this));var a=t.stack;this.componentDidCatch(t.value,{componentStack:a!==null?a:""})}),s}function Av(e,t,s){var n=e.pingCache;if(n===null){n=e.pingCache=new P2;var i=new Set;n.set(t,i)}else i=n.get(t),i===void 0&&(i=new Set,n.set(t,i));i.has(s)||(i.add(s),e=G2.bind(null,e,t,s),t.then(e,e))}function Mv(e){do{var t;if((t=e.tag===13)&&(t=e.memoizedState,t=t!==null?t.dehydrated!==null:!0),t)return e;e=e.return}while(e!==null);return null}function Dv(e,t,s,n,i){return e.mode&1?(e.flags|=65536,e.lanes=i,e):(e===t?e.flags|=65536:(e.flags|=128,s.flags|=131072,s.flags&=-52805,s.tag===1&&(s.alternate===null?s.tag=17:(t=Ri(-1,1),t.tag=2,gr(s,t,1))),s.lanes|=1),e)}var L2=Li.ReactCurrentOwner,qs=!1;function Ps(e,t,s,n){t.child=e===null?fx(t,null,s,n):ma(t,e.child,s,n)}function Iv(e,t,s,n,i){s=s.render;var r=t.ref;return aa(t,i),n=Og(e,t,s,n,r,i),s=Bg(),e!==null&&!qs?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,Pi(e,t,i)):(wt&&s&&Cg(t),t.flags|=1,Ps(e,t,n,i),t.child)}function Pv(e,t,s,n,i){if(e===null){var r=s.type;return typeof r=="function"&&!Yg(r)&&r.defaultProps===void 0&&s.compare===null&&s.defaultProps===void 0?(t.tag=15,t.type=r,$x(e,t,r,n,i)):(e=Hu(s.type,null,n,t,t.mode,i),e.ref=t.ref,e.return=t,t.child=e)}if(r=e.child,!(e.lanes&i)){var a=r.memoizedProps;if(s=s.compare,s=s!==null?s:Ql,s(a,n)&&e.ref===t.ref)return Pi(e,t,i)}return t.flags|=1,e=yr(r,n),e.ref=t.ref,e.return=t,t.child=e}function $x(e,t,s,n,i){if(e!==null){var r=e.memoizedProps;if(Ql(r,n)&&e.ref===t.ref)if(qs=!1,t.pendingProps=n=r,(e.lanes&i)!==0)e.flags&131072&&(qs=!0);else return t.lanes=e.lanes,Pi(e,t,i)}return Tp(e,t,s,n,i)}function Fx(e,t,s){var n=t.pendingProps,i=n.children,r=e!==null?e.memoizedState:null;if(n.mode==="hidden")if(!(t.mode&1))t.memoizedState={baseLanes:0,cachePool:null,transitions:null},pt(ea,sn),sn|=s;else{if(!(s&1073741824))return e=r!==null?r.baseLanes|s:s,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,pt(ea,sn),sn|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},n=r!==null?r.baseLanes:s,pt(ea,sn),sn|=n}else r!==null?(n=r.baseLanes|s,t.memoizedState=null):n=s,pt(ea,sn),sn|=n;return Ps(e,t,i,s),t.child}function zx(e,t){var s=t.ref;(e===null&&s!==null||e!==null&&e.ref!==s)&&(t.flags|=512,t.flags|=2097152)}function Tp(e,t,s,n,i){var r=Ys(s)?io:js.current;return r=fa(t,r),aa(t,i),s=Og(e,t,s,n,r,i),n=Bg(),e!==null&&!qs?(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~i,Pi(e,t,i)):(wt&&n&&Cg(t),t.flags|=1,Ps(e,t,s,i),t.child)}function Lv(e,t,s,n,i){if(Ys(s)){var r=!0;lh(t)}else r=!1;if(aa(t,i),t.stateNode===null)$u(e,t),Lx(t,s,n),Rp(t,s,n,i),n=!0;else if(e===null){var a=t.stateNode,l=t.memoizedProps;a.props=l;var c=a.context,u=s.contextType;typeof u=="object"&&u!==null?u=kn(u):(u=Ys(s)?io:js.current,u=fa(t,u));var h=s.getDerivedStateFromProps,d=typeof h=="function"||typeof a.getSnapshotBeforeUpdate=="function";d||typeof a.UNSAFE_componentWillReceiveProps!="function"&&typeof a.componentWillReceiveProps!="function"||(l!==n||c!==u)&&Tv(t,a,n,u),er=!1;var p=t.memoizedState;a.state=p,fh(t,n,a,i),c=t.memoizedState,l!==n||p!==c||Vs.current||er?(typeof h=="function"&&(Np(t,s,h,n),c=t.memoizedState),(l=er||jv(t,s,l,n,p,c,u))?(d||typeof a.UNSAFE_componentWillMount!="function"&&typeof a.componentWillMount!="function"||(typeof a.componentWillMount=="function"&&a.componentWillMount(),typeof a.UNSAFE_componentWillMount=="function"&&a.UNSAFE_componentWillMount()),typeof a.componentDidMount=="function"&&(t.flags|=4194308)):(typeof a.componentDidMount=="function"&&(t.flags|=4194308),t.memoizedProps=n,t.memoizedState=c),a.props=n,a.state=c,a.context=u,n=l):(typeof a.componentDidMount=="function"&&(t.flags|=4194308),n=!1)}else{a=t.stateNode,mx(e,t),l=t.memoizedProps,u=t.type===t.elementType?l:Pn(t.type,l),a.props=u,d=t.pendingProps,p=a.context,c=s.contextType,typeof c=="object"&&c!==null?c=kn(c):(c=Ys(s)?io:js.current,c=fa(t,c));var f=s.getDerivedStateFromProps;(h=typeof f=="function"||typeof a.getSnapshotBeforeUpdate=="function")||typeof a.UNSAFE_componentWillReceiveProps!="function"&&typeof a.componentWillReceiveProps!="function"||(l!==d||p!==c)&&Tv(t,a,n,c),er=!1,p=t.memoizedState,a.state=p,fh(t,n,a,i);var m=t.memoizedState;l!==d||p!==m||Vs.current||er?(typeof f=="function"&&(Np(t,s,f,n),m=t.memoizedState),(u=er||jv(t,s,u,n,p,m,c)||!1)?(h||typeof a.UNSAFE_componentWillUpdate!="function"&&typeof a.componentWillUpdate!="function"||(typeof a.componentWillUpdate=="function"&&a.componentWillUpdate(n,m,c),typeof a.UNSAFE_componentWillUpdate=="function"&&a.UNSAFE_componentWillUpdate(n,m,c)),typeof a.componentDidUpdate=="function"&&(t.flags|=4),typeof a.getSnapshotBeforeUpdate=="function"&&(t.flags|=1024)):(typeof a.componentDidUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),typeof a.getSnapshotBeforeUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),t.memoizedProps=n,t.memoizedState=m),a.props=n,a.state=m,a.context=c,n=u):(typeof a.componentDidUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),typeof a.getSnapshotBeforeUpdate!="function"||l===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),n=!1)}return Ap(e,t,s,n,r,i)}function Ap(e,t,s,n,i,r){zx(e,t);var a=(t.flags&128)!==0;if(!n&&!a)return i&&wv(t,s,!1),Pi(e,t,r);n=t.stateNode,L2.current=t;var l=a&&typeof s.getDerivedStateFromError!="function"?null:n.render();return t.flags|=1,e!==null&&a?(t.child=ma(t,e.child,null,r),t.child=ma(t,null,l,r)):Ps(e,t,l,r),t.memoizedState=n.state,i&&wv(t,s,!0),t.child}function Hx(e){var t=e.stateNode;t.pendingContext?bv(e,t.pendingContext,t.pendingContext!==t.context):t.context&&bv(e,t.context,!1),Dg(e,t.containerInfo)}function Ov(e,t,s,n,i){return pa(),Ng(i),t.flags|=256,Ps(e,t,s,n),t.child}var Mp={dehydrated:null,treeContext:null,retryLane:0};function Dp(e){return{baseLanes:e,cachePool:null,transitions:null}}function Ux(e,t,s){var n=t.pendingProps,i=Tt.current,r=!1,a=(t.flags&128)!==0,l;if((l=a)||(l=e!==null&&e.memoizedState===null?!1:(i&2)!==0),l?(r=!0,t.flags&=-129):(e===null||e.memoizedState!==null)&&(i|=1),pt(Tt,i&1),e===null)return Cp(t),e=t.memoizedState,e!==null&&(e=e.dehydrated,e!==null)?(t.mode&1?e.data==="$!"?t.lanes=8:t.lanes=1073741824:t.lanes=1,null):(a=n.children,e=n.fallback,r?(n=t.mode,r=t.child,a={mode:"hidden",children:a},!(n&1)&&r!==null?(r.childLanes=0,r.pendingProps=a):r=od(a,n,0,null),e=Xr(e,n,s,null),r.return=t,e.return=t,r.sibling=e,t.child=r,t.child.memoizedState=Dp(s),t.memoizedState=Mp,e):zg(t,a));if(i=e.memoizedState,i!==null&&(l=i.dehydrated,l!==null))return O2(e,t,a,n,l,i,s);if(r){r=n.fallback,a=t.mode,i=e.child,l=i.sibling;var c={mode:"hidden",children:n.children};return!(a&1)&&t.child!==i?(n=t.child,n.childLanes=0,n.pendingProps=c,t.deletions=null):(n=yr(i,c),n.subtreeFlags=i.subtreeFlags&14680064),l!==null?r=yr(l,r):(r=Xr(r,a,s,null),r.flags|=2),r.return=t,n.return=t,n.sibling=r,t.child=n,n=r,r=t.child,a=e.child.memoizedState,a=a===null?Dp(s):{baseLanes:a.baseLanes|s,cachePool:null,transitions:a.transitions},r.memoizedState=a,r.childLanes=e.childLanes&~s,t.memoizedState=Mp,n}return r=e.child,e=r.sibling,n=yr(r,{mode:"visible",children:n.children}),!(t.mode&1)&&(n.lanes=s),n.return=t,n.sibling=null,e!==null&&(s=t.deletions,s===null?(t.deletions=[e],t.flags|=16):s.push(e)),t.child=n,t.memoizedState=null,n}function zg(e,t){return t=od({mode:"visible",children:t},e.mode,0,null),t.return=e,e.child=t}function ru(e,t,s,n){return n!==null&&Ng(n),ma(t,e.child,null,s),e=zg(t,t.pendingProps.children),e.flags|=2,t.memoizedState=null,e}function O2(e,t,s,n,i,r,a){if(s)return t.flags&256?(t.flags&=-257,n=ef(Error(ie(422))),ru(e,t,a,n)):t.memoizedState!==null?(t.child=e.child,t.flags|=128,null):(r=n.fallback,i=t.mode,n=od({mode:"visible",children:n.children},i,0,null),r=Xr(r,i,a,null),r.flags|=2,n.return=t,r.return=t,n.sibling=r,t.child=n,t.mode&1&&ma(t,e.child,null,a),t.child.memoizedState=Dp(a),t.memoizedState=Mp,r);if(!(t.mode&1))return ru(e,t,a,null);if(i.data==="$!"){if(n=i.nextSibling&&i.nextSibling.dataset,n)var l=n.dgst;return n=l,r=Error(ie(419)),n=ef(r,n,void 0),ru(e,t,a,n)}if(l=(a&e.childLanes)!==0,qs||l){if(n=cs,n!==null){switch(a&-a){case 4:i=2;break;case 16:i=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:i=32;break;case 536870912:i=268435456;break;default:i=0}i=i&(n.suspendedLanes|a)?0:i,i!==0&&i!==r.retryLane&&(r.retryLane=i,Ii(e,i),zn(n,e,i,-1))}return Vg(),n=ef(Error(ie(421))),ru(e,t,a,n)}return i.data==="$?"?(t.flags|=128,t.child=e.child,t=J2.bind(null,e),i._reactRetry=t,null):(e=r.treeContext,on=mr(i.nextSibling),ln=t,wt=!0,On=null,e!==null&&(vn[yn++]=Ci,vn[yn++]=Ei,vn[yn++]=ro,Ci=e.id,Ei=e.overflow,ro=t),t=zg(t,n.children),t.flags|=4096,t)}function Bv(e,t,s){e.lanes|=t;var n=e.alternate;n!==null&&(n.lanes|=t),Ep(e.return,t,s)}function tf(e,t,s,n,i){var r=e.memoizedState;r===null?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:n,tail:s,tailMode:i}:(r.isBackwards=t,r.rendering=null,r.renderingStartTime=0,r.last=n,r.tail=s,r.tailMode=i)}function Wx(e,t,s){var n=t.pendingProps,i=n.revealOrder,r=n.tail;if(Ps(e,t,n.children,s),n=Tt.current,n&2)n=n&1|2,t.flags|=128;else{if(e!==null&&e.flags&128)e:for(e=t.child;e!==null;){if(e.tag===13)e.memoizedState!==null&&Bv(e,s,t);else if(e.tag===19)Bv(e,s,t);else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;e.sibling===null;){if(e.return===null||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}n&=1}if(pt(Tt,n),!(t.mode&1))t.memoizedState=null;else switch(i){case"forwards":for(s=t.child,i=null;s!==null;)e=s.alternate,e!==null&&ph(e)===null&&(i=s),s=s.sibling;s=i,s===null?(i=t.child,t.child=null):(i=s.sibling,s.sibling=null),tf(t,!1,i,s,r);break;case"backwards":for(s=null,i=t.child,t.child=null;i!==null;){if(e=i.alternate,e!==null&&ph(e)===null){t.child=i;break}e=i.sibling,i.sibling=s,s=i,i=e}tf(t,!0,s,null,r);break;case"together":tf(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function $u(e,t){!(t.mode&1)&&e!==null&&(e.alternate=null,t.alternate=null,t.flags|=2)}function Pi(e,t,s){if(e!==null&&(t.dependencies=e.dependencies),ao|=t.lanes,!(s&t.childLanes))return null;if(e!==null&&t.child!==e.child)throw Error(ie(153));if(t.child!==null){for(e=t.child,s=yr(e,e.pendingProps),t.child=s,s.return=t;e.sibling!==null;)e=e.sibling,s=s.sibling=yr(e,e.pendingProps),s.return=t;s.sibling=null}return t.child}function B2(e,t,s){switch(t.tag){case 3:Hx(t),pa();break;case 5:gx(t);break;case 1:Ys(t.type)&&lh(t);break;case 4:Dg(t,t.stateNode.containerInfo);break;case 10:var n=t.type._context,i=t.memoizedProps.value;pt(hh,n._currentValue),n._currentValue=i;break;case 13:if(n=t.memoizedState,n!==null)return n.dehydrated!==null?(pt(Tt,Tt.current&1),t.flags|=128,null):s&t.child.childLanes?Ux(e,t,s):(pt(Tt,Tt.current&1),e=Pi(e,t,s),e!==null?e.sibling:null);pt(Tt,Tt.current&1);break;case 19:if(n=(s&t.childLanes)!==0,e.flags&128){if(n)return Wx(e,t,s);t.flags|=128}if(i=t.memoizedState,i!==null&&(i.rendering=null,i.tail=null,i.lastEffect=null),pt(Tt,Tt.current),n)break;return null;case 22:case 23:return t.lanes=0,Fx(e,t,s)}return Pi(e,t,s)}var Kx,Ip,qx,Vx;Kx=function(e,t){for(var s=t.child;s!==null;){if(s.tag===5||s.tag===6)e.appendChild(s.stateNode);else if(s.tag!==4&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break;for(;s.sibling===null;){if(s.return===null||s.return===t)return;s=s.return}s.sibling.return=s.return,s=s.sibling}};Ip=function(){};qx=function(e,t,s,n){var i=e.memoizedProps;if(i!==n){e=t.stateNode,Vr(ai.current);var r=null;switch(s){case"input":i=sp(e,i),n=sp(e,n),r=[];break;case"select":i=Mt({},i,{value:void 0}),n=Mt({},n,{value:void 0}),r=[];break;case"textarea":i=rp(e,i),n=rp(e,n),r=[];break;default:typeof i.onClick!="function"&&typeof n.onClick=="function"&&(e.onclick=oh)}ap(s,n);var a;s=null;for(u in i)if(!n.hasOwnProperty(u)&&i.hasOwnProperty(u)&&i[u]!=null)if(u==="style"){var l=i[u];for(a in l)l.hasOwnProperty(a)&&(s||(s={}),s[a]="")}else u!=="dangerouslySetInnerHTML"&&u!=="children"&&u!=="suppressContentEditableWarning"&&u!=="suppressHydrationWarning"&&u!=="autoFocus"&&(ql.hasOwnProperty(u)?r||(r=[]):(r=r||[]).push(u,null));for(u in n){var c=n[u];if(l=i?.[u],n.hasOwnProperty(u)&&c!==l&&(c!=null||l!=null))if(u==="style")if(l){for(a in l)!l.hasOwnProperty(a)||c&&c.hasOwnProperty(a)||(s||(s={}),s[a]="");for(a in c)c.hasOwnProperty(a)&&l[a]!==c[a]&&(s||(s={}),s[a]=c[a])}else s||(r||(r=[]),r.push(u,s)),s=c;else u==="dangerouslySetInnerHTML"?(c=c?c.__html:void 0,l=l?l.__html:void 0,c!=null&&l!==c&&(r=r||[]).push(u,c)):u==="children"?typeof c!="string"&&typeof c!="number"||(r=r||[]).push(u,""+c):u!=="suppressContentEditableWarning"&&u!=="suppressHydrationWarning"&&(ql.hasOwnProperty(u)?(c!=null&&u==="onScroll"&&vt("scroll",e),r||l===c||(r=[])):(r=r||[]).push(u,c))}s&&(r=r||[]).push("style",s);var u=r;(t.updateQueue=u)&&(t.flags|=4)}};Vx=function(e,t,s,n){s!==n&&(t.flags|=4)};function Ja(e,t){if(!wt)switch(e.tailMode){case"hidden":t=e.tail;for(var s=null;t!==null;)t.alternate!==null&&(s=t),t=t.sibling;s===null?e.tail=null:s.sibling=null;break;case"collapsed":s=e.tail;for(var n=null;s!==null;)s.alternate!==null&&(n=s),s=s.sibling;n===null?t||e.tail===null?e.tail=null:e.tail.sibling=null:n.sibling=null}}function Cs(e){var t=e.alternate!==null&&e.alternate.child===e.child,s=0,n=0;if(t)for(var i=e.child;i!==null;)s|=i.lanes|i.childLanes,n|=i.subtreeFlags&14680064,n|=i.flags&14680064,i.return=e,i=i.sibling;else for(i=e.child;i!==null;)s|=i.lanes|i.childLanes,n|=i.subtreeFlags,n|=i.flags,i.return=e,i=i.sibling;return e.subtreeFlags|=n,e.childLanes=s,t}function $2(e,t,s){var n=t.pendingProps;switch(Eg(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Cs(t),null;case 1:return Ys(t.type)&&ah(),Cs(t),null;case 3:return n=t.stateNode,ga(),bt(Vs),bt(js),Pg(),n.pendingContext&&(n.context=n.pendingContext,n.pendingContext=null),(e===null||e.child===null)&&(nu(t)?t.flags|=4:e===null||e.memoizedState.isDehydrated&&!(t.flags&256)||(t.flags|=1024,On!==null&&(Hp(On),On=null))),Ip(e,t),Cs(t),null;case 5:Ig(t);var i=Vr(ic.current);if(s=t.type,e!==null&&t.stateNode!=null)qx(e,t,s,n,i),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!n){if(t.stateNode===null)throw Error(ie(166));return Cs(t),null}if(e=Vr(ai.current),nu(t)){n=t.stateNode,s=t.type;var r=t.memoizedProps;switch(n[ti]=t,n[sc]=r,e=(t.mode&1)!==0,s){case"dialog":vt("cancel",n),vt("close",n);break;case"iframe":case"object":case"embed":vt("load",n);break;case"video":case"audio":for(i=0;i<Sl.length;i++)vt(Sl[i],n);break;case"source":vt("error",n);break;case"img":case"image":case"link":vt("error",n),vt("load",n);break;case"details":vt("toggle",n);break;case"input":V_(n,r),vt("invalid",n);break;case"select":n._wrapperState={wasMultiple:!!r.multiple},vt("invalid",n);break;case"textarea":G_(n,r),vt("invalid",n)}ap(s,r),i=null;for(var a in r)if(r.hasOwnProperty(a)){var l=r[a];a==="children"?typeof l=="string"?n.textContent!==l&&(r.suppressHydrationWarning!==!0&&su(n.textContent,l,e),i=["children",l]):typeof l=="number"&&n.textContent!==""+l&&(r.suppressHydrationWarning!==!0&&su(n.textContent,l,e),i=["children",""+l]):ql.hasOwnProperty(a)&&l!=null&&a==="onScroll"&&vt("scroll",n)}switch(s){case"input":Yc(n),Y_(n,r,!0);break;case"textarea":Yc(n),J_(n);break;case"select":case"option":break;default:typeof r.onClick=="function"&&(n.onclick=oh)}n=i,t.updateQueue=n,n!==null&&(t.flags|=4)}else{a=i.nodeType===9?i:i.ownerDocument,e==="http://www.w3.org/1999/xhtml"&&(e=ww(s)),e==="http://www.w3.org/1999/xhtml"?s==="script"?(e=a.createElement("div"),e.innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):typeof n.is=="string"?e=a.createElement(s,{is:n.is}):(e=a.createElement(s),s==="select"&&(a=e,n.multiple?a.multiple=!0:n.size&&(a.size=n.size))):e=a.createElementNS(e,s),e[ti]=t,e[sc]=n,Kx(e,t,!1,!1),t.stateNode=e;e:{switch(a=lp(s,n),s){case"dialog":vt("cancel",e),vt("close",e),i=n;break;case"iframe":case"object":case"embed":vt("load",e),i=n;break;case"video":case"audio":for(i=0;i<Sl.length;i++)vt(Sl[i],e);i=n;break;case"source":vt("error",e),i=n;break;case"img":case"image":case"link":vt("error",e),vt("load",e),i=n;break;case"details":vt("toggle",e),i=n;break;case"input":V_(e,n),i=sp(e,n),vt("invalid",e);break;case"option":i=n;break;case"select":e._wrapperState={wasMultiple:!!n.multiple},i=Mt({},n,{value:void 0}),vt("invalid",e);break;case"textarea":G_(e,n),i=rp(e,n),vt("invalid",e);break;default:i=n}ap(s,i),l=i;for(r in l)if(l.hasOwnProperty(r)){var c=l[r];r==="style"?kw(e,c):r==="dangerouslySetInnerHTML"?(c=c?c.__html:void 0,c!=null&&xw(e,c)):r==="children"?typeof c=="string"?(s!=="textarea"||c!=="")&&Vl(e,c):typeof c=="number"&&Vl(e,""+c):r!=="suppressContentEditableWarning"&&r!=="suppressHydrationWarning"&&r!=="autoFocus"&&(ql.hasOwnProperty(r)?c!=null&&r==="onScroll"&&vt("scroll",e):c!=null&&hg(e,r,c,a))}switch(s){case"input":Yc(e),Y_(e,n,!1);break;case"textarea":Yc(e),J_(e);break;case"option":n.value!=null&&e.setAttribute("value",""+wr(n.value));break;case"select":e.multiple=!!n.multiple,r=n.value,r!=null?na(e,!!n.multiple,r,!1):n.defaultValue!=null&&na(e,!!n.multiple,n.defaultValue,!0);break;default:typeof i.onClick=="function"&&(e.onclick=oh)}switch(s){case"button":case"input":case"select":case"textarea":n=!!n.autoFocus;break e;case"img":n=!0;break e;default:n=!1}}n&&(t.flags|=4)}t.ref!==null&&(t.flags|=512,t.flags|=2097152)}return Cs(t),null;case 6:if(e&&t.stateNode!=null)Vx(e,t,e.memoizedProps,n);else{if(typeof n!="string"&&t.stateNode===null)throw Error(ie(166));if(s=Vr(ic.current),Vr(ai.current),nu(t)){if(n=t.stateNode,s=t.memoizedProps,n[ti]=t,(r=n.nodeValue!==s)&&(e=ln,e!==null))switch(e.tag){case 3:su(n.nodeValue,s,(e.mode&1)!==0);break;case 5:e.memoizedProps.suppressHydrationWarning!==!0&&su(n.nodeValue,s,(e.mode&1)!==0)}r&&(t.flags|=4)}else n=(s.nodeType===9?s:s.ownerDocument).createTextNode(n),n[ti]=t,t.stateNode=n}return Cs(t),null;case 13:if(bt(Tt),n=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(wt&&on!==null&&t.mode&1&&!(t.flags&128))hx(),pa(),t.flags|=98560,r=!1;else if(r=nu(t),n!==null&&n.dehydrated!==null){if(e===null){if(!r)throw Error(ie(318));if(r=t.memoizedState,r=r!==null?r.dehydrated:null,!r)throw Error(ie(317));r[ti]=t}else pa(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Cs(t),r=!1}else On!==null&&(Hp(On),On=null),r=!0;if(!r)return t.flags&65536?t:null}return t.flags&128?(t.lanes=s,t):(n=n!==null,n!==(e!==null&&e.memoizedState!==null)&&n&&(t.child.flags|=8192,t.mode&1&&(e===null||Tt.current&1?es===0&&(es=3):Vg())),t.updateQueue!==null&&(t.flags|=4),Cs(t),null);case 4:return ga(),Ip(e,t),e===null&&ec(t.stateNode.containerInfo),Cs(t),null;case 10:return Tg(t.type._context),Cs(t),null;case 17:return Ys(t.type)&&ah(),Cs(t),null;case 19:if(bt(Tt),r=t.memoizedState,r===null)return Cs(t),null;if(n=(t.flags&128)!==0,a=r.rendering,a===null)if(n)Ja(r,!1);else{if(es!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(a=ph(e),a!==null){for(t.flags|=128,Ja(r,!1),n=a.updateQueue,n!==null&&(t.updateQueue=n,t.flags|=4),t.subtreeFlags=0,n=s,s=t.child;s!==null;)r=s,e=n,r.flags&=14680066,a=r.alternate,a===null?(r.childLanes=0,r.lanes=e,r.child=null,r.subtreeFlags=0,r.memoizedProps=null,r.memoizedState=null,r.updateQueue=null,r.dependencies=null,r.stateNode=null):(r.childLanes=a.childLanes,r.lanes=a.lanes,r.child=a.child,r.subtreeFlags=0,r.deletions=null,r.memoizedProps=a.memoizedProps,r.memoizedState=a.memoizedState,r.updateQueue=a.updateQueue,r.type=a.type,e=a.dependencies,r.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext}),s=s.sibling;return pt(Tt,Tt.current&1|2),t.child}e=e.sibling}r.tail!==null&&zt()>va&&(t.flags|=128,n=!0,Ja(r,!1),t.lanes=4194304)}else{if(!n)if(e=ph(a),e!==null){if(t.flags|=128,n=!0,s=e.updateQueue,s!==null&&(t.updateQueue=s,t.flags|=4),Ja(r,!0),r.tail===null&&r.tailMode==="hidden"&&!a.alternate&&!wt)return Cs(t),null}else 2*zt()-r.renderingStartTime>va&&s!==1073741824&&(t.flags|=128,n=!0,Ja(r,!1),t.lanes=4194304);r.isBackwards?(a.sibling=t.child,t.child=a):(s=r.last,s!==null?s.sibling=a:t.child=a,r.last=a)}return r.tail!==null?(t=r.tail,r.rendering=t,r.tail=t.sibling,r.renderingStartTime=zt(),t.sibling=null,s=Tt.current,pt(Tt,n?s&1|2:s&1),t):(Cs(t),null);case 22:case 23:return qg(),n=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==n&&(t.flags|=8192),n&&t.mode&1?sn&1073741824&&(Cs(t),t.subtreeFlags&6&&(t.flags|=8192)):Cs(t),null;case 24:return null;case 25:return null}throw Error(ie(156,t.tag))}function F2(e,t){switch(Eg(t),t.tag){case 1:return Ys(t.type)&&ah(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return ga(),bt(Vs),bt(js),Pg(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return Ig(t),null;case 13:if(bt(Tt),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(ie(340));pa()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return bt(Tt),null;case 4:return ga(),null;case 10:return Tg(t.type._context),null;case 22:case 23:return qg(),null;case 24:return null;default:return null}}var ou=!1,Rs=!1,z2=typeof WeakSet=="function"?WeakSet:Set,we=null;function Qo(e,t){var s=e.ref;if(s!==null)if(typeof s=="function")try{s(null)}catch(n){Pt(e,t,n)}else s.current=null}function Pp(e,t,s){try{s()}catch(n){Pt(e,t,n)}}var $v=!1;function H2(e,t){if(vp=nh,e=Zw(),kg(e)){if("selectionStart"in e)var s={start:e.selectionStart,end:e.selectionEnd};else e:{s=(s=e.ownerDocument)&&s.defaultView||window;var n=s.getSelection&&s.getSelection();if(n&&n.rangeCount!==0){s=n.anchorNode;var i=n.anchorOffset,r=n.focusNode;n=n.focusOffset;try{s.nodeType,r.nodeType}catch{s=null;break e}var a=0,l=-1,c=-1,u=0,h=0,d=e,p=null;t:for(;;){for(var f;d!==s||i!==0&&d.nodeType!==3||(l=a+i),d!==r||n!==0&&d.nodeType!==3||(c=a+n),d.nodeType===3&&(a+=d.nodeValue.length),(f=d.firstChild)!==null;)p=d,d=f;for(;;){if(d===e)break t;if(p===s&&++u===i&&(l=a),p===r&&++h===n&&(c=a),(f=d.nextSibling)!==null)break;d=p,p=d.parentNode}d=f}s=l===-1||c===-1?null:{start:l,end:c}}else s=null}s=s||{start:0,end:0}}else s=null;for(yp={focusedElem:e,selectionRange:s},nh=!1,we=t;we!==null;)if(t=we,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,we=e;else for(;we!==null;){t=we;try{var m=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(m!==null){var b=m.memoizedProps,_=m.memoizedState,v=t.stateNode,y=v.getSnapshotBeforeUpdate(t.elementType===t.type?b:Pn(t.type,b),_);v.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var w=t.stateNode.containerInfo;w.nodeType===1?w.textContent="":w.nodeType===9&&w.documentElement&&w.removeChild(w.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(ie(163))}}catch(x){Pt(t,t.return,x)}if(e=t.sibling,e!==null){e.return=t.return,we=e;break}we=t.return}return m=$v,$v=!1,m}function Ol(e,t,s){var n=t.updateQueue;if(n=n!==null?n.lastEffect:null,n!==null){var i=n=n.next;do{if((i.tag&e)===e){var r=i.destroy;i.destroy=void 0,r!==void 0&&Pp(t,s,r)}i=i.next}while(i!==n)}}function id(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var s=t=t.next;do{if((s.tag&e)===e){var n=s.create;s.destroy=n()}s=s.next}while(s!==t)}}function Lp(e){var t=e.ref;if(t!==null){var s=e.stateNode;switch(e.tag){case 5:e=s;break;default:e=s}typeof t=="function"?t(e):t.current=e}}function Yx(e){var t=e.alternate;t!==null&&(e.alternate=null,Yx(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[ti],delete t[sc],delete t[xp],delete t[k2],delete t[C2])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function Gx(e){return e.tag===5||e.tag===3||e.tag===4}function Fv(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||Gx(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Op(e,t,s){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?s.nodeType===8?s.parentNode.insertBefore(e,t):s.insertBefore(e,t):(s.nodeType===8?(t=s.parentNode,t.insertBefore(e,s)):(t=s,t.appendChild(e)),s=s._reactRootContainer,s!=null||t.onclick!==null||(t.onclick=oh));else if(n!==4&&(e=e.child,e!==null))for(Op(e,t,s),e=e.sibling;e!==null;)Op(e,t,s),e=e.sibling}function Bp(e,t,s){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?s.insertBefore(e,t):s.appendChild(e);else if(n!==4&&(e=e.child,e!==null))for(Bp(e,t,s),e=e.sibling;e!==null;)Bp(e,t,s),e=e.sibling}var gs=null,Ln=!1;function qi(e,t,s){for(s=s.child;s!==null;)Jx(e,t,s),s=s.sibling}function Jx(e,t,s){if(oi&&typeof oi.onCommitFiberUnmount=="function")try{oi.onCommitFiberUnmount(Jh,s)}catch{}switch(s.tag){case 5:Rs||Qo(s,t);case 6:var n=gs,i=Ln;gs=null,qi(e,t,s),gs=n,Ln=i,gs!==null&&(Ln?(e=gs,s=s.stateNode,e.nodeType===8?e.parentNode.removeChild(s):e.removeChild(s)):gs.removeChild(s.stateNode));break;case 18:gs!==null&&(Ln?(e=gs,s=s.stateNode,e.nodeType===8?Yd(e.parentNode,s):e.nodeType===1&&Yd(e,s),Xl(e)):Yd(gs,s.stateNode));break;case 4:n=gs,i=Ln,gs=s.stateNode.containerInfo,Ln=!0,qi(e,t,s),gs=n,Ln=i;break;case 0:case 11:case 14:case 15:if(!Rs&&(n=s.updateQueue,n!==null&&(n=n.lastEffect,n!==null))){i=n=n.next;do{var r=i,a=r.destroy;r=r.tag,a!==void 0&&(r&2||r&4)&&Pp(s,t,a),i=i.next}while(i!==n)}qi(e,t,s);break;case 1:if(!Rs&&(Qo(s,t),n=s.stateNode,typeof n.componentWillUnmount=="function"))try{n.props=s.memoizedProps,n.state=s.memoizedState,n.componentWillUnmount()}catch(l){Pt(s,t,l)}qi(e,t,s);break;case 21:qi(e,t,s);break;case 22:s.mode&1?(Rs=(n=Rs)||s.memoizedState!==null,qi(e,t,s),Rs=n):qi(e,t,s);break;default:qi(e,t,s)}}function zv(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var s=e.stateNode;s===null&&(s=e.stateNode=new z2),t.forEach(function(n){var i=X2.bind(null,e,n);s.has(n)||(s.add(n),n.then(i,i))})}}function Dn(e,t){var s=t.deletions;if(s!==null)for(var n=0;n<s.length;n++){var i=s[n];try{var r=e,a=t,l=a;e:for(;l!==null;){switch(l.tag){case 5:gs=l.stateNode,Ln=!1;break e;case 3:gs=l.stateNode.containerInfo,Ln=!0;break e;case 4:gs=l.stateNode.containerInfo,Ln=!0;break e}l=l.return}if(gs===null)throw Error(ie(160));Jx(r,a,i),gs=null,Ln=!1;var c=i.alternate;c!==null&&(c.return=null),i.return=null}catch(u){Pt(i,t,u)}}if(t.subtreeFlags&12854)for(t=t.child;t!==null;)Xx(t,e),t=t.sibling}function Xx(e,t){var s=e.alternate,n=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(Dn(t,e),Jn(e),n&4){try{Ol(3,e,e.return),id(3,e)}catch(b){Pt(e,e.return,b)}try{Ol(5,e,e.return)}catch(b){Pt(e,e.return,b)}}break;case 1:Dn(t,e),Jn(e),n&512&&s!==null&&Qo(s,s.return);break;case 5:if(Dn(t,e),Jn(e),n&512&&s!==null&&Qo(s,s.return),e.flags&32){var i=e.stateNode;try{Vl(i,"")}catch(b){Pt(e,e.return,b)}}if(n&4&&(i=e.stateNode,i!=null)){var r=e.memoizedProps,a=s!==null?s.memoizedProps:r,l=e.type,c=e.updateQueue;if(e.updateQueue=null,c!==null)try{l==="input"&&r.type==="radio"&&r.name!=null&&yw(i,r),lp(l,a);var u=lp(l,r);for(a=0;a<c.length;a+=2){var h=c[a],d=c[a+1];h==="style"?kw(i,d):h==="dangerouslySetInnerHTML"?xw(i,d):h==="children"?Vl(i,d):hg(i,h,d,u)}switch(l){case"input":np(i,r);break;case"textarea":bw(i,r);break;case"select":var p=i._wrapperState.wasMultiple;i._wrapperState.wasMultiple=!!r.multiple;var f=r.value;f!=null?na(i,!!r.multiple,f,!1):p!==!!r.multiple&&(r.defaultValue!=null?na(i,!!r.multiple,r.defaultValue,!0):na(i,!!r.multiple,r.multiple?[]:"",!1))}i[sc]=r}catch(b){Pt(e,e.return,b)}}break;case 6:if(Dn(t,e),Jn(e),n&4){if(e.stateNode===null)throw Error(ie(162));i=e.stateNode,r=e.memoizedProps;try{i.nodeValue=r}catch(b){Pt(e,e.return,b)}}break;case 3:if(Dn(t,e),Jn(e),n&4&&s!==null&&s.memoizedState.isDehydrated)try{Xl(t.containerInfo)}catch(b){Pt(e,e.return,b)}break;case 4:Dn(t,e),Jn(e);break;case 13:Dn(t,e),Jn(e),i=e.child,i.flags&8192&&(r=i.memoizedState!==null,i.stateNode.isHidden=r,!r||i.alternate!==null&&i.alternate.memoizedState!==null||(Wg=zt())),n&4&&zv(e);break;case 22:if(h=s!==null&&s.memoizedState!==null,e.mode&1?(Rs=(u=Rs)||h,Dn(t,e),Rs=u):Dn(t,e),Jn(e),n&8192){if(u=e.memoizedState!==null,(e.stateNode.isHidden=u)&&!h&&e.mode&1)for(we=e,h=e.child;h!==null;){for(d=we=h;we!==null;){switch(p=we,f=p.child,p.tag){case 0:case 11:case 14:case 15:Ol(4,p,p.return);break;case 1:Qo(p,p.return);var m=p.stateNode;if(typeof m.componentWillUnmount=="function"){n=p,s=p.return;try{t=n,m.props=t.memoizedProps,m.state=t.memoizedState,m.componentWillUnmount()}catch(b){Pt(n,s,b)}}break;case 5:Qo(p,p.return);break;case 22:if(p.memoizedState!==null){Uv(d);continue}}f!==null?(f.return=p,we=f):Uv(d)}h=h.sibling}e:for(h=null,d=e;;){if(d.tag===5){if(h===null){h=d;try{i=d.stateNode,u?(r=i.style,typeof r.setProperty=="function"?r.setProperty("display","none","important"):r.display="none"):(l=d.stateNode,c=d.memoizedProps.style,a=c!=null&&c.hasOwnProperty("display")?c.display:null,l.style.display=Sw("display",a))}catch(b){Pt(e,e.return,b)}}}else if(d.tag===6){if(h===null)try{d.stateNode.nodeValue=u?"":d.memoizedProps}catch(b){Pt(e,e.return,b)}}else if((d.tag!==22&&d.tag!==23||d.memoizedState===null||d===e)&&d.child!==null){d.child.return=d,d=d.child;continue}if(d===e)break e;for(;d.sibling===null;){if(d.return===null||d.return===e)break e;h===d&&(h=null),d=d.return}h===d&&(h=null),d.sibling.return=d.return,d=d.sibling}}break;case 19:Dn(t,e),Jn(e),n&4&&zv(e);break;case 21:break;default:Dn(t,e),Jn(e)}}function Jn(e){var t=e.flags;if(t&2){try{e:{for(var s=e.return;s!==null;){if(Gx(s)){var n=s;break e}s=s.return}throw Error(ie(160))}switch(n.tag){case 5:var i=n.stateNode;n.flags&32&&(Vl(i,""),n.flags&=-33);var r=Fv(e);Bp(e,r,i);break;case 3:case 4:var a=n.stateNode.containerInfo,l=Fv(e);Op(e,l,a);break;default:throw Error(ie(161))}}catch(c){Pt(e,e.return,c)}e.flags&=-3}t&4096&&(e.flags&=-4097)}function U2(e,t,s){we=e,Zx(e)}function Zx(e,t,s){for(var n=(e.mode&1)!==0;we!==null;){var i=we,r=i.child;if(i.tag===22&&n){var a=i.memoizedState!==null||ou;if(!a){var l=i.alternate,c=l!==null&&l.memoizedState!==null||Rs;l=ou;var u=Rs;if(ou=a,(Rs=c)&&!u)for(we=i;we!==null;)a=we,c=a.child,a.tag===22&&a.memoizedState!==null?Wv(i):c!==null?(c.return=a,we=c):Wv(i);for(;r!==null;)we=r,Zx(r),r=r.sibling;we=i,ou=l,Rs=u}Hv(e)}else i.subtreeFlags&8772&&r!==null?(r.return=i,we=r):Hv(e)}}function Hv(e){for(;we!==null;){var t=we;if(t.flags&8772){var s=t.alternate;try{if(t.flags&8772)switch(t.tag){case 0:case 11:case 15:Rs||id(5,t);break;case 1:var n=t.stateNode;if(t.flags&4&&!Rs)if(s===null)n.componentDidMount();else{var i=t.elementType===t.type?s.memoizedProps:Pn(t.type,s.memoizedProps);n.componentDidUpdate(i,s.memoizedState,n.__reactInternalSnapshotBeforeUpdate)}var r=t.updateQueue;r!==null&&Ev(t,r,n);break;case 3:var a=t.updateQueue;if(a!==null){if(s=null,t.child!==null)switch(t.child.tag){case 5:s=t.child.stateNode;break;case 1:s=t.child.stateNode}Ev(t,a,s)}break;case 5:var l=t.stateNode;if(s===null&&t.flags&4){s=l;var c=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":c.autoFocus&&s.focus();break;case"img":c.src&&(s.src=c.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(t.memoizedState===null){var u=t.alternate;if(u!==null){var h=u.memoizedState;if(h!==null){var d=h.dehydrated;d!==null&&Xl(d)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;default:throw Error(ie(163))}Rs||t.flags&512&&Lp(t)}catch(p){Pt(t,t.return,p)}}if(t===e){we=null;break}if(s=t.sibling,s!==null){s.return=t.return,we=s;break}we=t.return}}function Uv(e){for(;we!==null;){var t=we;if(t===e){we=null;break}var s=t.sibling;if(s!==null){s.return=t.return,we=s;break}we=t.return}}function Wv(e){for(;we!==null;){var t=we;try{switch(t.tag){case 0:case 11:case 15:var s=t.return;try{id(4,t)}catch(c){Pt(t,s,c)}break;case 1:var n=t.stateNode;if(typeof n.componentDidMount=="function"){var i=t.return;try{n.componentDidMount()}catch(c){Pt(t,i,c)}}var r=t.return;try{Lp(t)}catch(c){Pt(t,r,c)}break;case 5:var a=t.return;try{Lp(t)}catch(c){Pt(t,a,c)}}}catch(c){Pt(t,t.return,c)}if(t===e){we=null;break}var l=t.sibling;if(l!==null){l.return=t.return,we=l;break}we=t.return}}var W2=Math.ceil,_h=Li.ReactCurrentDispatcher,Hg=Li.ReactCurrentOwner,xn=Li.ReactCurrentBatchConfig,it=0,cs=null,Yt=null,ys=0,sn=0,ea=Er(0),es=0,lc=null,ao=0,rd=0,Ug=0,Bl=null,Ws=null,Wg=0,va=1/0,wi=null,vh=!1,$p=null,_r=null,au=!1,lr=null,yh=0,$l=0,Fp=null,Fu=-1,zu=0;function Ls(){return it&6?zt():Fu!==-1?Fu:Fu=zt()}function vr(e){return e.mode&1?it&2&&ys!==0?ys&-ys:N2.transition!==null?(zu===0&&(zu=Lw()),zu):(e=ct,e!==0||(e=window.event,e=e===void 0?16:Uw(e.type)),e):1}function zn(e,t,s,n){if(50<$l)throw $l=0,Fp=null,Error(ie(185));Ec(e,s,n),(!(it&2)||e!==cs)&&(e===cs&&(!(it&2)&&(rd|=s),es===4&&rr(e,ys)),Gs(e,n),s===1&&it===0&&!(t.mode&1)&&(va=zt()+500,td&&Nr()))}function Gs(e,t){var s=e.callbackNode;NE(e,t);var n=sh(e,e===cs?ys:0);if(n===0)s!==null&&Q_(s),e.callbackNode=null,e.callbackPriority=0;else if(t=n&-n,e.callbackPriority!==t){if(s!=null&&Q_(s),t===1)e.tag===0?E2(Kv.bind(null,e)):lx(Kv.bind(null,e)),x2(function(){!(it&6)&&Nr()}),s=null;else{switch(Ow(n)){case 1:s=gg;break;case 4:s=Iw;break;case 16:s=th;break;case 536870912:s=Pw;break;default:s=th}s=oS(s,Qx.bind(null,e))}e.callbackPriority=t,e.callbackNode=s}}function Qx(e,t){if(Fu=-1,zu=0,it&6)throw Error(ie(327));var s=e.callbackNode;if(la()&&e.callbackNode!==s)return null;var n=sh(e,e===cs?ys:0);if(n===0)return null;if(n&30||n&e.expiredLanes||t)t=bh(e,n);else{t=n;var i=it;it|=2;var r=tS();(cs!==e||ys!==t)&&(wi=null,va=zt()+500,Jr(e,t));do try{V2();break}catch(l){eS(e,l)}while(!0);jg(),_h.current=r,it=i,Yt!==null?t=0:(cs=null,ys=0,t=es)}if(t!==0){if(t===2&&(i=fp(e),i!==0&&(n=i,t=zp(e,i))),t===1)throw s=lc,Jr(e,0),rr(e,n),Gs(e,zt()),s;if(t===6)rr(e,n);else{if(i=e.current.alternate,!(n&30)&&!K2(i)&&(t=bh(e,n),t===2&&(r=fp(e),r!==0&&(n=r,t=zp(e,r))),t===1))throw s=lc,Jr(e,0),rr(e,n),Gs(e,zt()),s;switch(e.finishedWork=i,e.finishedLanes=n,t){case 0:case 1:throw Error(ie(345));case 2:zr(e,Ws,wi);break;case 3:if(rr(e,n),(n&130023424)===n&&(t=Wg+500-zt(),10<t)){if(sh(e,0)!==0)break;if(i=e.suspendedLanes,(i&n)!==n){Ls(),e.pingedLanes|=e.suspendedLanes&i;break}e.timeoutHandle=wp(zr.bind(null,e,Ws,wi),t);break}zr(e,Ws,wi);break;case 4:if(rr(e,n),(n&4194240)===n)break;for(t=e.eventTimes,i=-1;0<n;){var a=31-Fn(n);r=1<<a,a=t[a],a>i&&(i=a),n&=~r}if(n=i,n=zt()-n,n=(120>n?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*W2(n/1960))-n,10<n){e.timeoutHandle=wp(zr.bind(null,e,Ws,wi),n);break}zr(e,Ws,wi);break;case 5:zr(e,Ws,wi);break;default:throw Error(ie(329))}}}return Gs(e,zt()),e.callbackNode===s?Qx.bind(null,e):null}function zp(e,t){var s=Bl;return e.current.memoizedState.isDehydrated&&(Jr(e,t).flags|=256),e=bh(e,t),e!==2&&(t=Ws,Ws=s,t!==null&&Hp(t)),e}function Hp(e){Ws===null?Ws=e:Ws.push.apply(Ws,e)}function K2(e){for(var t=e;;){if(t.flags&16384){var s=t.updateQueue;if(s!==null&&(s=s.stores,s!==null))for(var n=0;n<s.length;n++){var i=s[n],r=i.getSnapshot;i=i.value;try{if(!Un(r(),i))return!1}catch{return!1}}}if(s=t.child,t.subtreeFlags&16384&&s!==null)s.return=t,t=s;else{if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}function rr(e,t){for(t&=~Ug,t&=~rd,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var s=31-Fn(t),n=1<<s;e[s]=-1,t&=~n}}function Kv(e){if(it&6)throw Error(ie(327));la();var t=sh(e,0);if(!(t&1))return Gs(e,zt()),null;var s=bh(e,t);if(e.tag!==0&&s===2){var n=fp(e);n!==0&&(t=n,s=zp(e,n))}if(s===1)throw s=lc,Jr(e,0),rr(e,t),Gs(e,zt()),s;if(s===6)throw Error(ie(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,zr(e,Ws,wi),Gs(e,zt()),null}function Kg(e,t){var s=it;it|=1;try{return e(t)}finally{it=s,it===0&&(va=zt()+500,td&&Nr())}}function lo(e){lr!==null&&lr.tag===0&&!(it&6)&&la();var t=it;it|=1;var s=xn.transition,n=ct;try{if(xn.transition=null,ct=1,e)return e()}finally{ct=n,xn.transition=s,it=t,!(it&6)&&Nr()}}function qg(){sn=ea.current,bt(ea)}function Jr(e,t){e.finishedWork=null,e.finishedLanes=0;var s=e.timeoutHandle;if(s!==-1&&(e.timeoutHandle=-1,w2(s)),Yt!==null)for(s=Yt.return;s!==null;){var n=s;switch(Eg(n),n.tag){case 1:n=n.type.childContextTypes,n!=null&&ah();break;case 3:ga(),bt(Vs),bt(js),Pg();break;case 5:Ig(n);break;case 4:ga();break;case 13:bt(Tt);break;case 19:bt(Tt);break;case 10:Tg(n.type._context);break;case 22:case 23:qg()}s=s.return}if(cs=e,Yt=e=yr(e.current,null),ys=sn=t,es=0,lc=null,Ug=rd=ao=0,Ws=Bl=null,qr!==null){for(t=0;t<qr.length;t++)if(s=qr[t],n=s.interleaved,n!==null){s.interleaved=null;var i=n.next,r=s.pending;if(r!==null){var a=r.next;r.next=i,n.next=a}s.pending=n}qr=null}return e}function eS(e,t){do{var s=Yt;try{if(jg(),Ou.current=gh,mh){for(var n=At.memoizedState;n!==null;){var i=n.queue;i!==null&&(i.pending=null),n=n.next}mh=!1}if(oo=0,rs=Qt=At=null,Ll=!1,rc=0,Hg.current=null,s===null||s.return===null){es=1,lc=t,Yt=null;break}e:{var r=e,a=s.return,l=s,c=t;if(t=ys,l.flags|=32768,c!==null&&typeof c=="object"&&typeof c.then=="function"){var u=c,h=l,d=h.tag;if(!(h.mode&1)&&(d===0||d===11||d===15)){var p=h.alternate;p?(h.updateQueue=p.updateQueue,h.memoizedState=p.memoizedState,h.lanes=p.lanes):(h.updateQueue=null,h.memoizedState=null)}var f=Mv(a);if(f!==null){f.flags&=-257,Dv(f,a,l,r,t),f.mode&1&&Av(r,u,t),t=f,c=u;var m=t.updateQueue;if(m===null){var b=new Set;b.add(c),t.updateQueue=b}else m.add(c);break e}else{if(!(t&1)){Av(r,u,t),Vg();break e}c=Error(ie(426))}}else if(wt&&l.mode&1){var _=Mv(a);if(_!==null){!(_.flags&65536)&&(_.flags|=256),Dv(_,a,l,r,t),Ng(_a(c,l));break e}}r=c=_a(c,l),es!==4&&(es=2),Bl===null?Bl=[r]:Bl.push(r),r=a;do{switch(r.tag){case 3:r.flags|=65536,t&=-t,r.lanes|=t;var v=Ox(r,c,t);Cv(r,v);break e;case 1:l=c;var y=r.type,w=r.stateNode;if(!(r.flags&128)&&(typeof y.getDerivedStateFromError=="function"||w!==null&&typeof w.componentDidCatch=="function"&&(_r===null||!_r.has(w)))){r.flags|=65536,t&=-t,r.lanes|=t;var x=Bx(r,l,t);Cv(r,x);break e}}r=r.return}while(r!==null)}nS(s)}catch(S){t=S,Yt===s&&s!==null&&(Yt=s=s.return);continue}break}while(!0)}function tS(){var e=_h.current;return _h.current=gh,e===null?gh:e}function Vg(){(es===0||es===3||es===2)&&(es=4),cs===null||!(ao&268435455)&&!(rd&268435455)||rr(cs,ys)}function bh(e,t){var s=it;it|=2;var n=tS();(cs!==e||ys!==t)&&(wi=null,Jr(e,t));do try{q2();break}catch(i){eS(e,i)}while(!0);if(jg(),it=s,_h.current=n,Yt!==null)throw Error(ie(261));return cs=null,ys=0,es}function q2(){for(;Yt!==null;)sS(Yt)}function V2(){for(;Yt!==null&&!vE();)sS(Yt)}function sS(e){var t=rS(e.alternate,e,sn);e.memoizedProps=e.pendingProps,t===null?nS(e):Yt=t,Hg.current=null}function nS(e){var t=e;do{var s=t.alternate;if(e=t.return,t.flags&32768){if(s=F2(s,t),s!==null){s.flags&=32767,Yt=s;return}if(e!==null)e.flags|=32768,e.subtreeFlags=0,e.deletions=null;else{es=6,Yt=null;return}}else if(s=$2(s,t,sn),s!==null){Yt=s;return}if(t=t.sibling,t!==null){Yt=t;return}Yt=t=e}while(t!==null);es===0&&(es=5)}function zr(e,t,s){var n=ct,i=xn.transition;try{xn.transition=null,ct=1,Y2(e,t,s,n)}finally{xn.transition=i,ct=n}return null}function Y2(e,t,s,n){do la();while(lr!==null);if(it&6)throw Error(ie(327));s=e.finishedWork;var i=e.finishedLanes;if(s===null)return null;if(e.finishedWork=null,e.finishedLanes=0,s===e.current)throw Error(ie(177));e.callbackNode=null,e.callbackPriority=0;var r=s.lanes|s.childLanes;if(RE(e,r),e===cs&&(Yt=cs=null,ys=0),!(s.subtreeFlags&2064)&&!(s.flags&2064)||au||(au=!0,oS(th,function(){return la(),null})),r=(s.flags&15990)!==0,s.subtreeFlags&15990||r){r=xn.transition,xn.transition=null;var a=ct;ct=1;var l=it;it|=4,Hg.current=null,H2(e,s),Xx(s,e),p2(yp),nh=!!vp,yp=vp=null,e.current=s,U2(s),yE(),it=l,ct=a,xn.transition=r}else e.current=s;if(au&&(au=!1,lr=e,yh=i),r=e.pendingLanes,r===0&&(_r=null),xE(s.stateNode),Gs(e,zt()),t!==null)for(n=e.onRecoverableError,s=0;s<t.length;s++)i=t[s],n(i.value,{componentStack:i.stack,digest:i.digest});if(vh)throw vh=!1,e=$p,$p=null,e;return yh&1&&e.tag!==0&&la(),r=e.pendingLanes,r&1?e===Fp?$l++:($l=0,Fp=e):$l=0,Nr(),null}function la(){if(lr!==null){var e=Ow(yh),t=xn.transition,s=ct;try{if(xn.transition=null,ct=16>e?16:e,lr===null)var n=!1;else{if(e=lr,lr=null,yh=0,it&6)throw Error(ie(331));var i=it;for(it|=4,we=e.current;we!==null;){var r=we,a=r.child;if(we.flags&16){var l=r.deletions;if(l!==null){for(var c=0;c<l.length;c++){var u=l[c];for(we=u;we!==null;){var h=we;switch(h.tag){case 0:case 11:case 15:Ol(8,h,r)}var d=h.child;if(d!==null)d.return=h,we=d;else for(;we!==null;){h=we;var p=h.sibling,f=h.return;if(Yx(h),h===u){we=null;break}if(p!==null){p.return=f,we=p;break}we=f}}}var m=r.alternate;if(m!==null){var b=m.child;if(b!==null){m.child=null;do{var _=b.sibling;b.sibling=null,b=_}while(b!==null)}}we=r}}if(r.subtreeFlags&2064&&a!==null)a.return=r,we=a;else e:for(;we!==null;){if(r=we,r.flags&2048)switch(r.tag){case 0:case 11:case 15:Ol(9,r,r.return)}var v=r.sibling;if(v!==null){v.return=r.return,we=v;break e}we=r.return}}var y=e.current;for(we=y;we!==null;){a=we;var w=a.child;if(a.subtreeFlags&2064&&w!==null)w.return=a,we=w;else e:for(a=y;we!==null;){if(l=we,l.flags&2048)try{switch(l.tag){case 0:case 11:case 15:id(9,l)}}catch(S){Pt(l,l.return,S)}if(l===a){we=null;break e}var x=l.sibling;if(x!==null){x.return=l.return,we=x;break e}we=l.return}}if(it=i,Nr(),oi&&typeof oi.onPostCommitFiberRoot=="function")try{oi.onPostCommitFiberRoot(Jh,e)}catch{}n=!0}return n}finally{ct=s,xn.transition=t}}return!1}function qv(e,t,s){t=_a(s,t),t=Ox(e,t,1),e=gr(e,t,1),t=Ls(),e!==null&&(Ec(e,1,t),Gs(e,t))}function Pt(e,t,s){if(e.tag===3)qv(e,e,s);else for(;t!==null;){if(t.tag===3){qv(t,e,s);break}else if(t.tag===1){var n=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof n.componentDidCatch=="function"&&(_r===null||!_r.has(n))){e=_a(s,e),e=Bx(t,e,1),t=gr(t,e,1),e=Ls(),t!==null&&(Ec(t,1,e),Gs(t,e));break}}t=t.return}}function G2(e,t,s){var n=e.pingCache;n!==null&&n.delete(t),t=Ls(),e.pingedLanes|=e.suspendedLanes&s,cs===e&&(ys&s)===s&&(es===4||es===3&&(ys&130023424)===ys&&500>zt()-Wg?Jr(e,0):Ug|=s),Gs(e,t)}function iS(e,t){t===0&&(e.mode&1?(t=Xc,Xc<<=1,!(Xc&130023424)&&(Xc=4194304)):t=1);var s=Ls();e=Ii(e,t),e!==null&&(Ec(e,t,s),Gs(e,s))}function J2(e){var t=e.memoizedState,s=0;t!==null&&(s=t.retryLane),iS(e,s)}function X2(e,t){var s=0;switch(e.tag){case 13:var n=e.stateNode,i=e.memoizedState;i!==null&&(s=i.retryLane);break;case 19:n=e.stateNode;break;default:throw Error(ie(314))}n!==null&&n.delete(t),iS(e,s)}var rS;rS=function(e,t,s){if(e!==null)if(e.memoizedProps!==t.pendingProps||Vs.current)qs=!0;else{if(!(e.lanes&s)&&!(t.flags&128))return qs=!1,B2(e,t,s);qs=!!(e.flags&131072)}else qs=!1,wt&&t.flags&1048576&&cx(t,uh,t.index);switch(t.lanes=0,t.tag){case 2:var n=t.type;$u(e,t),e=t.pendingProps;var i=fa(t,js.current);aa(t,s),i=Og(null,t,n,e,i,s);var r=Bg();return t.flags|=1,typeof i=="object"&&i!==null&&typeof i.render=="function"&&i.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Ys(n)?(r=!0,lh(t)):r=!1,t.memoizedState=i.state!==null&&i.state!==void 0?i.state:null,Mg(t),i.updater=nd,t.stateNode=i,i._reactInternals=t,Rp(t,n,e,s),t=Ap(null,t,n,!0,r,s)):(t.tag=0,wt&&r&&Cg(t),Ps(null,t,i,s),t=t.child),t;case 16:n=t.elementType;e:{switch($u(e,t),e=t.pendingProps,i=n._init,n=i(n._payload),t.type=n,i=t.tag=Q2(n),e=Pn(n,e),i){case 0:t=Tp(null,t,n,e,s);break e;case 1:t=Lv(null,t,n,e,s);break e;case 11:t=Iv(null,t,n,e,s);break e;case 14:t=Pv(null,t,n,Pn(n.type,e),s);break e}throw Error(ie(306,n,""))}return t;case 0:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Pn(n,i),Tp(e,t,n,i,s);case 1:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Pn(n,i),Lv(e,t,n,i,s);case 3:e:{if(Hx(t),e===null)throw Error(ie(387));n=t.pendingProps,r=t.memoizedState,i=r.element,mx(e,t),fh(t,n,null,s);var a=t.memoizedState;if(n=a.element,r.isDehydrated)if(r={element:n,isDehydrated:!1,cache:a.cache,pendingSuspenseBoundaries:a.pendingSuspenseBoundaries,transitions:a.transitions},t.updateQueue.baseState=r,t.memoizedState=r,t.flags&256){i=_a(Error(ie(423)),t),t=Ov(e,t,n,s,i);break e}else if(n!==i){i=_a(Error(ie(424)),t),t=Ov(e,t,n,s,i);break e}else for(on=mr(t.stateNode.containerInfo.firstChild),ln=t,wt=!0,On=null,s=fx(t,null,n,s),t.child=s;s;)s.flags=s.flags&-3|4096,s=s.sibling;else{if(pa(),n===i){t=Pi(e,t,s);break e}Ps(e,t,n,s)}t=t.child}return t;case 5:return gx(t),e===null&&Cp(t),n=t.type,i=t.pendingProps,r=e!==null?e.memoizedProps:null,a=i.children,bp(n,i)?a=null:r!==null&&bp(n,r)&&(t.flags|=32),zx(e,t),Ps(e,t,a,s),t.child;case 6:return e===null&&Cp(t),null;case 13:return Ux(e,t,s);case 4:return Dg(t,t.stateNode.containerInfo),n=t.pendingProps,e===null?t.child=ma(t,null,n,s):Ps(e,t,n,s),t.child;case 11:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Pn(n,i),Iv(e,t,n,i,s);case 7:return Ps(e,t,t.pendingProps,s),t.child;case 8:return Ps(e,t,t.pendingProps.children,s),t.child;case 12:return Ps(e,t,t.pendingProps.children,s),t.child;case 10:e:{if(n=t.type._context,i=t.pendingProps,r=t.memoizedProps,a=i.value,pt(hh,n._currentValue),n._currentValue=a,r!==null)if(Un(r.value,a)){if(r.children===i.children&&!Vs.current){t=Pi(e,t,s);break e}}else for(r=t.child,r!==null&&(r.return=t);r!==null;){var l=r.dependencies;if(l!==null){a=r.child;for(var c=l.firstContext;c!==null;){if(c.context===n){if(r.tag===1){c=Ri(-1,s&-s),c.tag=2;var u=r.updateQueue;if(u!==null){u=u.shared;var h=u.pending;h===null?c.next=c:(c.next=h.next,h.next=c),u.pending=c}}r.lanes|=s,c=r.alternate,c!==null&&(c.lanes|=s),Ep(r.return,s,t),l.lanes|=s;break}c=c.next}}else if(r.tag===10)a=r.type===t.type?null:r.child;else if(r.tag===18){if(a=r.return,a===null)throw Error(ie(341));a.lanes|=s,l=a.alternate,l!==null&&(l.lanes|=s),Ep(a,s,t),a=r.sibling}else a=r.child;if(a!==null)a.return=r;else for(a=r;a!==null;){if(a===t){a=null;break}if(r=a.sibling,r!==null){r.return=a.return,a=r;break}a=a.return}r=a}Ps(e,t,i.children,s),t=t.child}return t;case 9:return i=t.type,n=t.pendingProps.children,aa(t,s),i=kn(i),n=n(i),t.flags|=1,Ps(e,t,n,s),t.child;case 14:return n=t.type,i=Pn(n,t.pendingProps),i=Pn(n.type,i),Pv(e,t,n,i,s);case 15:return $x(e,t,t.type,t.pendingProps,s);case 17:return n=t.type,i=t.pendingProps,i=t.elementType===n?i:Pn(n,i),$u(e,t),t.tag=1,Ys(n)?(e=!0,lh(t)):e=!1,aa(t,s),Lx(t,n,i),Rp(t,n,i,s),Ap(null,t,n,!0,e,s);case 19:return Wx(e,t,s);case 22:return Fx(e,t,s)}throw Error(ie(156,t.tag))};function oS(e,t){return Dw(e,t)}function Z2(e,t,s,n){this.tag=e,this.key=s,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=n,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function wn(e,t,s,n){return new Z2(e,t,s,n)}function Yg(e){return e=e.prototype,!(!e||!e.isReactComponent)}function Q2(e){if(typeof e=="function")return Yg(e)?1:0;if(e!=null){if(e=e.$$typeof,e===fg)return 11;if(e===pg)return 14}return 2}function yr(e,t){var s=e.alternate;return s===null?(s=wn(e.tag,t,e.key,e.mode),s.elementType=e.elementType,s.type=e.type,s.stateNode=e.stateNode,s.alternate=e,e.alternate=s):(s.pendingProps=t,s.type=e.type,s.flags=0,s.subtreeFlags=0,s.deletions=null),s.flags=e.flags&14680064,s.childLanes=e.childLanes,s.lanes=e.lanes,s.child=e.child,s.memoizedProps=e.memoizedProps,s.memoizedState=e.memoizedState,s.updateQueue=e.updateQueue,t=e.dependencies,s.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},s.sibling=e.sibling,s.index=e.index,s.ref=e.ref,s}function Hu(e,t,s,n,i,r){var a=2;if(n=e,typeof e=="function")Yg(e)&&(a=1);else if(typeof e=="string")a=5;else e:switch(e){case Wo:return Xr(s.children,i,r,t);case dg:a=8,i|=8;break;case Zf:return e=wn(12,s,t,i|2),e.elementType=Zf,e.lanes=r,e;case Qf:return e=wn(13,s,t,i),e.elementType=Qf,e.lanes=r,e;case ep:return e=wn(19,s,t,i),e.elementType=ep,e.lanes=r,e;case gw:return od(s,i,r,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case pw:a=10;break e;case mw:a=9;break e;case fg:a=11;break e;case pg:a=14;break e;case Qi:a=16,n=null;break e}throw Error(ie(130,e==null?e:typeof e,""))}return t=wn(a,s,t,i),t.elementType=e,t.type=n,t.lanes=r,t}function Xr(e,t,s,n){return e=wn(7,e,n,t),e.lanes=s,e}function od(e,t,s,n){return e=wn(22,e,n,t),e.elementType=gw,e.lanes=s,e.stateNode={isHidden:!1},e}function sf(e,t,s){return e=wn(6,e,null,t),e.lanes=s,e}function nf(e,t,s){return t=wn(4,e.children!==null?e.children:[],e.key,t),t.lanes=s,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function eN(e,t,s,n,i){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Od(0),this.expirationTimes=Od(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Od(0),this.identifierPrefix=n,this.onRecoverableError=i,this.mutableSourceEagerHydrationData=null}function Gg(e,t,s,n,i,r,a,l,c){return e=new eN(e,t,s,l,c),t===1?(t=1,r===!0&&(t|=8)):t=0,r=wn(3,null,null,t),e.current=r,r.stateNode=e,r.memoizedState={element:n,isDehydrated:s,cache:null,transitions:null,pendingSuspenseBoundaries:null},Mg(r),e}function tN(e,t,s){var n=3<arguments.length&&arguments[3]!==void 0?arguments[3]:null;return{$$typeof:Uo,key:n==null?null:""+n,children:e,containerInfo:t,implementation:s}}function aS(e){if(!e)return xr;e=e._reactInternals;e:{if(go(e)!==e||e.tag!==1)throw Error(ie(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(Ys(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(t!==null);throw Error(ie(171))}if(e.tag===1){var s=e.type;if(Ys(s))return ax(e,s,t)}return t}function lS(e,t,s,n,i,r,a,l,c){return e=Gg(s,n,!0,e,i,r,a,l,c),e.context=aS(null),s=e.current,n=Ls(),i=vr(s),r=Ri(n,i),r.callback=t??null,gr(s,r,i),e.current.lanes=i,Ec(e,i,n),Gs(e,n),e}function ad(e,t,s,n){var i=t.current,r=Ls(),a=vr(i);return s=aS(s),t.context===null?t.context=s:t.pendingContext=s,t=Ri(r,a),t.payload={element:e},n=n===void 0?null:n,n!==null&&(t.callback=n),e=gr(i,t,a),e!==null&&(zn(e,i,a,r),Lu(e,i,a)),a}function wh(e){if(e=e.current,!e.child)return null;switch(e.child.tag){case 5:return e.child.stateNode;default:return e.child.stateNode}}function Vv(e,t){if(e=e.memoizedState,e!==null&&e.dehydrated!==null){var s=e.retryLane;e.retryLane=s!==0&&s<t?s:t}}function Jg(e,t){Vv(e,t),(e=e.alternate)&&Vv(e,t)}function sN(){return null}var cS=typeof reportError=="function"?reportError:function(e){console.error(e)};function Xg(e){this._internalRoot=e}ld.prototype.render=Xg.prototype.render=function(e){var t=this._internalRoot;if(t===null)throw Error(ie(409));ad(e,t,null,null)};ld.prototype.unmount=Xg.prototype.unmount=function(){var e=this._internalRoot;if(e!==null){this._internalRoot=null;var t=e.containerInfo;lo(function(){ad(null,e,null,null)}),t[Di]=null}};function ld(e){this._internalRoot=e}ld.prototype.unstable_scheduleHydration=function(e){if(e){var t=Fw();e={blockedOn:null,target:e,priority:t};for(var s=0;s<ir.length&&t!==0&&t<ir[s].priority;s++);ir.splice(s,0,e),s===0&&Hw(e)}};function Zg(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11)}function cd(e){return!(!e||e.nodeType!==1&&e.nodeType!==9&&e.nodeType!==11&&(e.nodeType!==8||e.nodeValue!==" react-mount-point-unstable "))}function Yv(){}function nN(e,t,s,n,i){if(i){if(typeof n=="function"){var r=n;n=function(){var u=wh(a);r.call(u)}}var a=lS(t,n,e,0,null,!1,!1,"",Yv);return e._reactRootContainer=a,e[Di]=a.current,ec(e.nodeType===8?e.parentNode:e),lo(),a}for(;i=e.lastChild;)e.removeChild(i);if(typeof n=="function"){var l=n;n=function(){var u=wh(c);l.call(u)}}var c=Gg(e,0,!1,null,null,!1,!1,"",Yv);return e._reactRootContainer=c,e[Di]=c.current,ec(e.nodeType===8?e.parentNode:e),lo(function(){ad(t,c,s,n)}),c}function ud(e,t,s,n,i){var r=s._reactRootContainer;if(r){var a=r;if(typeof i=="function"){var l=i;i=function(){var c=wh(a);l.call(c)}}ad(t,a,e,i)}else a=nN(s,t,e,i,n);return wh(a)}Bw=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var s=xl(t.pendingLanes);s!==0&&(_g(t,s|1),Gs(t,zt()),!(it&6)&&(va=zt()+500,Nr()))}break;case 13:lo(function(){var n=Ii(e,1);if(n!==null){var i=Ls();zn(n,e,1,i)}}),Jg(e,1)}};vg=function(e){if(e.tag===13){var t=Ii(e,134217728);if(t!==null){var s=Ls();zn(t,e,134217728,s)}Jg(e,134217728)}};$w=function(e){if(e.tag===13){var t=vr(e),s=Ii(e,t);if(s!==null){var n=Ls();zn(s,e,t,n)}Jg(e,t)}};Fw=function(){return ct};zw=function(e,t){var s=ct;try{return ct=e,t()}finally{ct=s}};up=function(e,t,s){switch(t){case"input":if(np(e,s),t=s.name,s.type==="radio"&&t!=null){for(s=e;s.parentNode;)s=s.parentNode;for(s=s.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<s.length;t++){var n=s[t];if(n!==e&&n.form===e.form){var i=ed(n);if(!i)throw Error(ie(90));vw(n),np(n,i)}}}break;case"textarea":bw(e,s);break;case"select":t=s.value,t!=null&&na(e,!!s.multiple,t,!1)}};Nw=Kg;Rw=lo;var iN={usingClientEntryPoint:!1,Events:[Rc,Yo,ed,Cw,Ew,Kg]},Xa={findFiberByHostInstance:Kr,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},rN={bundleType:Xa.bundleType,version:Xa.version,rendererPackageName:Xa.rendererPackageName,rendererConfig:Xa.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:Li.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return e=Aw(e),e===null?null:e.stateNode},findFiberByHostInstance:Xa.findFiberByHostInstance||sN,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"){var lu=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!lu.isDisabled&&lu.supportsFiber)try{Jh=lu.inject(rN),oi=lu}catch{}}un.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=iN;un.createPortal=function(e,t){var s=2<arguments.length&&arguments[2]!==void 0?arguments[2]:null;if(!Zg(t))throw Error(ie(200));return tN(e,t,null,s)};un.createRoot=function(e,t){if(!Zg(e))throw Error(ie(299));var s=!1,n="",i=cS;return t!=null&&(t.unstable_strictMode===!0&&(s=!0),t.identifierPrefix!==void 0&&(n=t.identifierPrefix),t.onRecoverableError!==void 0&&(i=t.onRecoverableError)),t=Gg(e,1,!1,null,null,s,!1,n,i),e[Di]=t.current,ec(e.nodeType===8?e.parentNode:e),new Xg(t)};un.findDOMNode=function(e){if(e==null)return null;if(e.nodeType===1)return e;var t=e._reactInternals;if(t===void 0)throw typeof e.render=="function"?Error(ie(188)):(e=Object.keys(e).join(","),Error(ie(268,e)));return e=Aw(t),e=e===null?null:e.stateNode,e};un.flushSync=function(e){return lo(e)};un.hydrate=function(e,t,s){if(!cd(t))throw Error(ie(200));return ud(null,e,t,!0,s)};un.hydrateRoot=function(e,t,s){if(!Zg(e))throw Error(ie(405));var n=s!=null&&s.hydratedSources||null,i=!1,r="",a=cS;if(s!=null&&(s.unstable_strictMode===!0&&(i=!0),s.identifierPrefix!==void 0&&(r=s.identifierPrefix),s.onRecoverableError!==void 0&&(a=s.onRecoverableError)),t=lS(t,null,e,1,s??null,i,!1,r,a),e[Di]=t.current,ec(e),n)for(e=0;e<n.length;e++)s=n[e],i=s._getVersion,i=i(s._source),t.mutableSourceEagerHydrationData==null?t.mutableSourceEagerHydrationData=[s,i]:t.mutableSourceEagerHydrationData.push(s,i);return new ld(t)};un.render=function(e,t,s){if(!cd(t))throw Error(ie(200));return ud(null,e,t,!1,s)};un.unmountComponentAtNode=function(e){if(!cd(e))throw Error(ie(40));return e._reactRootContainer?(lo(function(){ud(null,null,e,!1,function(){e._reactRootContainer=null,e[Di]=null})}),!0):!1};un.unstable_batchedUpdates=Kg;un.unstable_renderSubtreeIntoContainer=function(e,t,s,n){if(!cd(s))throw Error(ie(200));if(e==null||e._reactInternals===void 0)throw Error(ie(38));return ud(e,t,s,!1,n)};un.version="18.3.1-next-f1338f8080-20240426";function uS(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(uS)}catch(e){console.error(e)}}uS(),uw.exports=un;var cc=uw.exports,hS,Gv=cc;hS=Gv.createRoot,Gv.hydrateRoot;const cu=10,Jv=6;function co(e,t,s){const n=g.useRef(t);n.current=t;const i=g.useRef(s);i.current=s,g.useEffect(()=>{if(!e)return;const r=c=>n.current.some(u=>u.current&&c instanceof Node&&u.current.contains(c)),a=c=>{r(c.target)||i.current()},l=c=>{c.key==="Escape"&&!c.defaultPrevented&&i.current()};return document.addEventListener("pointerdown",a,!0),document.addEventListener("keydown",l),()=>{document.removeEventListener("pointerdown",a,!0),document.removeEventListener("keydown",l)}},[e])}function dS(){const e=g.useRef(null);return g.useLayoutEffect(()=>{const t=e.current;if(!t)return;const s=()=>{if(t.style.top="",t.style.left="",t.style.maxHeight="",window.matchMedia("(max-width: 720px)").matches)return;const n=t.parentElement,i=(n?.firstElementChild??n)?.getBoundingClientRect();if(!i)return;const r=t.getBoundingClientRect().height,a=i.top-cu,l=window.innerHeight-i.bottom-cu,c=l>a,u=Math.min(Math.max(a,l),window.innerHeight*.46);t.style.maxHeight=`${Math.round(u)}px`;const h=Math.min(r,u);t.style.top=`${Math.round(c?i.bottom+Jv:i.top-Jv-h)}px`;const d=t.getBoundingClientRect().width;t.style.left=`${Math.round(Math.min(Math.max(i.left,cu),window.innerWidth-cu-d))}px`;const p=t.querySelector(".tb-opt.sel"),f=p?.closest(".tb-scroll")??t;if(p){const m=p.getBoundingClientRect(),b=f.getBoundingClientRect();m.top<b.top?f.scrollTop-=b.top-m.top+8:m.bottom>b.bottom&&(f.scrollTop+=m.bottom-b.bottom+8)}};return s(),window.addEventListener("resize",s),()=>window.removeEventListener("resize",s)},[]),e}function Ta(e,t){const s=g.useRef(t);s.current=t,g.useEffect(()=>{if(!e)return;const n=i=>{i.key==="Escape"&&!i.defaultPrevented&&s.current()};return document.addEventListener("keydown",n),()=>document.removeEventListener("keydown",n)},[e])}function Te(e,{size:t=16,className:s}){return o.jsx("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.6,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",className:s,children:e})}const fS=(e={})=>Te(o.jsx(o.Fragment,{children:o.jsx("path",{d:"M3 6h18M3 12h18M3 18h18"})}),e),oN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("circle",{cx:"12",cy:"5",r:"1.4"}),o.jsx("circle",{cx:"12",cy:"12",r:"1.4"}),o.jsx("circle",{cx:"12",cy:"19",r:"1.4"})]}),e),pS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M12 20h9"}),o.jsx("path",{d:"M16.5 3.5a2.12 2.12 0 0 1 3 3L8 18l-4 1 1-4z"})]}),e),mS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"9",y:"9",width:"12",height:"12",rx:"2"}),o.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]}),e),gS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M12 3v11"}),o.jsx("path",{d:"M7 10l5 5 5-5"}),o.jsx("path",{d:"M4 20h16"})]}),e),aN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"7",width:"18",height:"13",rx:"2"}),o.jsx("path",{d:"M3 11h18"}),o.jsx("path",{d:"M9 3h6"})]}),e),lN=(e={})=>Te(o.jsx("path",{d:"m4 12.5 5 5L20 6.5"}),e),uo=(e={})=>Te(o.jsx("path",{d:"M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"}),e),cN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M3 7a2 2 0 0 1 2-2h5l2 2h7a2 2 0 0 1 2 2v1.4"}),o.jsx("path",{d:"M3 10.4h17.2a1 1 0 0 1 .97 1.24l-1.6 6.06A2 2 0 0 1 17.65 19.2H5a2 2 0 0 1-2-2z"})]}),e),uN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("circle",{cx:"9",cy:"8",r:"3"}),o.jsx("path",{d:"M3.5 20a5.5 5.5 0 0 1 11 0"}),o.jsx("circle",{cx:"17",cy:"9.2",r:"2.2"}),o.jsx("path",{d:"M16.2 20a4.6 4.6 0 0 1 5.3-3.2"})]}),e),_S=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M3 10.5 12 3l9 7.5"}),o.jsx("path",{d:"M5 9.5V21h14V9.5"})]}),e),vS=(e={})=>Te(o.jsx("path",{d:"M12 3l7 3v5c0 4.5-3 8-7 10-4-2-7-5.5-7-10V6z"}),e),Xv=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M4 17a8 8 0 1 1 16 0"}),o.jsx("path",{d:"M12 17l4-5"})]}),e),hN=(e={})=>Te(o.jsx("path",{d:"M3 12h4l2.5-7 4 14 2.5-7H21"}),e),xh=(e={})=>Te(o.jsx("rect",{x:"6",y:"6",width:"12",height:"12",rx:"1.5",fill:"currentColor",stroke:"none"}),e),En=(e={})=>Te(o.jsx("path",{d:"M6 6l12 12M18 6L6 18"}),e),ya=(e={})=>Te(o.jsx("path",{d:"M6 9l6 6 6-6"}),e),an=(e={})=>Te(o.jsx("path",{d:"M9 6l6 6-6 6"}),e),yS=(e={})=>Te(o.jsx("path",{d:"M12 19V5M6 11l6-6 6 6"}),e),bS=(e={})=>Te(o.jsx("path",{d:"M12 5v14M6 13l6 6 6-6"}),e),Sh=(e={})=>Te(o.jsx("path",{d:"M4 12l16-8-6 8 6 8z"}),e),kh=(e={})=>Te(o.jsx("path",{d:"M12 5v14M5 12h14"}),e),dN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("circle",{cx:"11",cy:"11",r:"6.5"}),o.jsx("path",{d:"M16 16l4 4"})]}),e),wS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M12 4v8"}),o.jsx("path",{d:"M7.5 7a7 7 0 1 0 9 0"})]}),e),rf=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M3 12a9 9 0 1 0 3-6.7"}),o.jsx("path",{d:"M3 4v4h4"})]}),e),fN=(e={})=>Te(o.jsx("circle",{cx:"12",cy:"12",r:"4",fill:"currentColor",stroke:"none"}),e),pN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),o.jsx("path",{d:"M15 4v16"})]}),e),mN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),o.jsx("path",{d:"M9 4v16"})]}),e),gN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),o.jsx("path",{d:"M15 4v16"})]}),e),_N=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),o.jsx("path",{d:"m7 9 3 3-3 3M13 15h4"})]}),e),ui=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M6 2h8l4 4v16H6z"}),o.jsx("path",{d:"M14 2v4h4"})]}),e),ji=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"9",y:"3",width:"6",height:"11",rx:"3"}),o.jsx("path",{d:"M5 11a7 7 0 0 0 14 0M12 18v3M9 21h6"})]}),e),hd=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M11 5 6 9H3v6h3l5 4z"}),o.jsx("path",{d:"M15.5 8.5a5 5 0 0 1 0 7M18.5 5.5a9 9 0 0 1 0 13"})]}),e),xS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M11 5 6 9H3v6h3l5 4z"}),o.jsx("path",{d:"m16 9 5 6M21 9l-5 6"})]}),e),SS=o.jsx("path",{d:"M6.6 3.5h1.9c.8 0 1.5.6 1.7 1.4l.7 2.6c.2.8-.1 1.7-.8 2.2l-1.2.8a12.5 12.5 0 0 0 5.6 5.6l.8-1.2c.5-.7 1.4-1 2.2-.8l2.6.7c.8.2 1.4.9 1.4 1.7v1.9c0 1.2-1 2.2-2.2 2.1C11 20.9 3.1 13 3.2 5.7c0-1.2 1-2.2 2.2-2.2z"}),vN=(e={})=>Te(SS,e),yN=(e={})=>Te(o.jsx("g",{transform:"rotate(135 12 12)",children:SS}),e),bN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M9 9v2a3 3 0 0 0 4.6 2.5M15 11.5V6a3 3 0 0 0-5.7-1.3"}),o.jsx("path",{d:"M5 11a7 7 0 0 0 10.8 5.9M19 11v.5"}),o.jsx("path",{d:"M12 18v3M9 21h6"}),o.jsx("path",{d:"m4 4 16 16"})]}),e),wN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"6",width:"18",height:"12",rx:"2"}),o.jsx("path",{d:"M7 10h.01M11 10h.01M15 10h.01M7 14h10"})]}),e),xN=(e={})=>Te(o.jsx("path",{d:"M20 11.5 12 19.5a5 5 0 0 1-7-7l8-8a3.5 3.5 0 0 1 5 5l-8 8a2 2 0 0 1-3-3l7-7"}),e),Tc=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("circle",{cx:"12",cy:"12",r:"3"}),o.jsx("path",{d:"M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-2.9 1.2v.2a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-2.9-1.2l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1A1.7 1.7 0 0 0 3 15a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.2-2.9l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1A1.7 1.7 0 0 0 10 4.2V4a2 2 0 1 1 4 0v.2a1.7 1.7 0 0 0 2.9 1.2l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1A1.7 1.7 0 0 0 21 11h.2a2 2 0 1 1 0 4H21z"})]}),e),Qg=(e={})=>Te(o.jsx("path",{d:"M19 12H5M11 6l-6 6 6 6"}),e),ba=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M20 11a8 8 0 1 0-2 6"}),o.jsx("path",{d:"M20 5v6h-6"})]}),e),SN=(e={})=>Te(o.jsx(o.Fragment,{children:o.jsx("path",{d:"M4 8h13l-3-3M20 16H7l3 3"})}),e),e_=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"7",y:"7",width:"10",height:"10",rx:"2"}),o.jsx("path",{d:"M10 3v4M14 3v4M10 17v4M14 17v4M3 10h4M3 14h4M17 10h4M17 14h4"})]}),e),kN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M9.5 4a2.5 2.5 0 0 1 2.5 2.5v11a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 2.26-4.9A2.5 2.5 0 0 1 9.5 4Z"}),o.jsx("path",{d:"M14.5 4A2.5 2.5 0 0 0 12 6.5v11a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-2.26-4.9A2.5 2.5 0 0 0 14.5 4Z"})]}),e),kS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("circle",{cx:"7",cy:"5",r:"2"}),o.jsx("circle",{cx:"7",cy:"19",r:"2"}),o.jsx("circle",{cx:"17",cy:"9",r:"2"}),o.jsx("path",{d:"M7 7v10M17 11c0 3-3 4-6 4H9"})]}),e),CS=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M2 12s3.6-6 10-6 10 6 10 6-3.6 6-10 6-10-6-10-6z"}),o.jsx("circle",{cx:"12",cy:"12",r:"2.6"})]}),e),CN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M3 3l18 18"}),o.jsx("path",{d:"M10.6 6.2A9.9 9.9 0 0 1 12 6c6.4 0 10 6 10 6a17 17 0 0 1-2.8 3.3"}),o.jsx("path",{d:"M6.3 7.9A16.5 16.5 0 0 0 2 12s3.6 6 10 6c1.5 0 2.8-.3 4-.8"})]}),e),EN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"3",y:"4",width:"18",height:"12",rx:"2"}),o.jsx("path",{d:"M8 20h8M12 16v4"})]}),e),NN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"4",y:"10",width:"16",height:"10",rx:"2"}),o.jsx("path",{d:"M8 10V7a4 4 0 0 1 8 0v3"})]}),e),RN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("path",{d:"M3.5 12a8.5 8.5 0 1 0 2.6-6.1"}),o.jsx("path",{d:"M3 4v4h4"}),o.jsx("path",{d:"M12 8v4.4l3 1.8"})]}),e),jN=(e={})=>Te(o.jsxs(o.Fragment,{children:[o.jsx("rect",{x:"2.5",y:"5",width:"19",height:"14",rx:"3.5"}),o.jsx("path",{d:"M6.5 10.5h4.5M13.5 10.5h4M6.5 14h7"})]}),e);function t_(e,t){const s=(e||t||"").trim();if(!s)return"";const n=s.includes("·")?s.split("·").pop().trim():s;return(n.includes(":")?n.split(":").pop().trim():n)||n||s}function TN(e,t,s){const n=i=>!!i&&s.includes(i);return n(e)?e:n(t)?t:""}function Zv(e){const t=i=>i.replace(/[•·|,-]?\s*\b(current|active|selected|default)\b\s*$/i,"").replace(/[•·|,\s-]+$/g,"").trim(),s=/^\s*provider:\s*(.+)$/i.exec(e.description??"");if(s){const i=t(s[1]);if(i)return i}const n=e.modelId.includes(":")?e.modelId.split(":")[0]:e.modelId.includes("/")?e.modelId.split("/")[0]:"";return t(n)||"other"}function AN(e,t){const s=t_(e.name??"",e.modelId),n=`${t}/`;return s.startsWith(n)?s.slice(n.length):s}const MN=12;function ES({models:e,current:t,usage:s={},pending:n=null,onPick:i,bad:r={},err:a=null}){const[l,c]=g.useState(""),[u,h]=g.useState({}),d=dS(),p=g.useMemo(()=>{const f=l.trim().toLowerCase(),m=f?e.filter(w=>`${w.modelId} ${w.name} ${w.description??""}`.toLowerCase().includes(f)):e,b=new Map;for(const w of m){const x=Zv(w),S=b.get(x);S?S.push(w):b.set(x,[w])}const _=e.find(w=>w.modelId===t),v=_?Zv(_):"",y=w=>s[w]??0;return[...b.entries()].map(([w,x])=>{const S=[...x].sort((N,R)=>y(R.modelId)-y(N.modelId)||N.modelId.localeCompare(R.modelId));return{provider:w,list:S.slice(0,200),truncated:S.length>200,current:w===v,heat:S.reduce((N,R)=>N+y(R.modelId),0)}}).sort((w,x)=>w.current!==x.current?w.current?-1:1:x.heat-w.heat||w.provider.localeCompare(x.provider))},[e,l,t,s]);return o.jsxs("div",{className:"tb-list wide stacked",ref:d,children:[a?o.jsxs("div",{className:"tb-err",role:"alert","data-model-err":a.id,children:[o.jsx("span",{className:"tb-err-id",children:a.id}),o.jsx("span",{className:"tb-err-text",children:a.text})]}):null,e.length>MN?o.jsx("input",{className:"tb-search",autoFocus:!0,value:l,placeholder:`filter ${e.length} models…`,"aria-label":"filter models",onChange:f=>c(f.target.value)}):null,o.jsxs("div",{className:"tb-scroll",children:[p.map(f=>{const m=!!l.trim()||!u[f.provider];return o.jsxs("div",{className:"tb-group",children:[o.jsxs("button",{type:"button",className:`tb-group-head ${m?"open":""}`,"aria-expanded":m,title:`${f.provider} · ${f.list.length} model(s)`,"data-provider":f.provider,onClick:()=>h(b=>({...b,[f.provider]:!b[f.provider]})),children:[o.jsx(an,{size:11,className:`tb-group-chev ${m?"open":""}`}),o.jsx("span",{className:"tb-group-name",children:f.provider}),o.jsx("span",{className:"tb-group-count",children:f.list.length})]}),m?o.jsx("div",{className:"tb-group-body",children:f.list.map(b=>o.jsxs("button",{className:`tb-opt ${b.modelId===t?"sel":""} ${n===b.modelId?"pending":""} ${a?.id===b.modelId||r[b.modelId]?"bad":""}`,title:r[b.modelId]?`${b.modelId} — this agent refused it: ${r[b.modelId]}`:b.description?`${b.modelId} — ${b.description}`:b.modelId,"data-model":b.modelId,"data-model-refused":r[b.modelId]?"1":void 0,onClick:()=>i(b.modelId),children:[o.jsx("span",{className:"tb-opt-name",children:AN(b,f.provider)}),n===b.modelId?o.jsx("span",{className:"tb-opt-pending",children:"待生效"}):null]},b.modelId))}):null]},f.provider)}),p.length?null:o.jsxs("div",{className:"tb-empty",children:["no model matches “",l,"”"]})]})]})}let Zr=null,uu=null,Up=0;const Wp=new Set;function Kp(){Up+=1;for(const e of Wp)e()}function DN(e){return Wp.add(e),()=>{Wp.delete(e)}}function IN(){return Zr?Promise.resolve():(uu||(uu=fetch("/api/model-usage",{headers:{accept:"application/json"}}).then(e=>{if(!e.ok)throw new Error(`model-usage ${e.status}`);return e.json()}).then(e=>{Zr=e.usage??{},Kp()}).catch(()=>{Zr=null,uu=null,Kp()})),uu)}function PN(e,t){const s=`${e}|${t}`;Zr={...Zr??{},[s]:((Zr??{})[s]??0)+1},Kp()}function NS(e){return g.useSyncExternalStore(DN,()=>Up,()=>0),g.useEffect(()=>{IN()},[]),g.useMemo(()=>{const t={},s=Zr??{},n=`${e}|`;for(const[i,r]of Object.entries(s)){const a=i.indexOf("|");if(a<0||e&&!i.startsWith(n))continue;const l=i.slice(a+1);t[l]=(t[l]??0)+r}return t},[e,Up])}function Qv(e,t){const s=t?.messageId;return typeof s=="string"&&s?`${e}:${s}`:null}function LN(e,t){return e===t||e.replace(/\s+/g,"")===t.replace(/\s+/g,"")}function ON(e,t){const s=t.delta;if(s===void 0)return e===void 0?{action:"create",text:t.text}:t.key?LN(e,t.text)?{action:"skip"}:{action:"replace",text:t.text}:{action:"append",add:t.text};if(e===void 0)return{action:"create",text:s};if(t.n!==void 0){const i=t.n-e.length;return i<=0?{action:"skip"}:i>=s.length?{action:"append",add:s}:{action:"append",add:s.slice(s.length-i)}}const n=$N(e,s);return n?{action:"append",add:n}:{action:"skip"}}function BN(e,t,s,n){const i=e,r=d=>d,a=d=>{const p=s.key??`anon@${i.length}`;return i.push(r(n(p,{...s,text:d}))),s.key&&t.set(s.key,i.length-1),{pushed:!0,at:i.length-1}},l=s.key?t.get(s.key):void 0,c=l===void 0?void 0:i[l],u=c&&c.kind===s.kind?l:!s.key&&i.length>0&&i[i.length-1].kind===s.kind?i.length-1:void 0,h=ON(u===void 0?void 0:i[u].text,s);return h.action==="create"?a(h.text):u===void 0?h.action==="append"?a(h.add):h.action==="replace"?a(h.text):a(s.delta??s.text):h.action==="skip"?{pushed:!1,at:u}:(e[u]={...e[u],text:h.action==="append"?i[u].text+h.add:h.text},{pushed:!1,at:u})}function e0(e){const t=new Map;return e.forEach((s,n)=>{s.key.startsWith("anon@")?t.delete(s.key):t.set(s.key,n)}),t}function $N(e,t){if(!e||!t)return t;if(t.startsWith(e))return t.slice(e.length);const s=Math.min(e.length,t.length);for(let n=s;n>=16;n--)if(e.endsWith(t.slice(0,n)))return t.slice(n);return t}function s_(e,t){const s=e.length?e.replace(/\n$/,"").split(`
41
41
  `):[],n=t.length?t.replace(/\n$/,"").split(`
42
42
  `):[];let i=0;for(;i<s.length&&i<n.length&&s[i]===n[i];)i++;let r=0;for(;r<s.length-i&&r<n.length-i&&s[s.length-1-r]===n[n.length-1-r];)r++;const a=[],l=3;i>l&&a.push({kind:"gap",text:`⋯ 上面 ${i-l} 行未变 ⋯`,oldNo:null,newNo:null});for(let b=Math.max(0,i-l);b<i;b++)a.push({kind:"ctx",text:s[b],oldNo:b+1,newNo:b+1});const c=s.slice(i,s.length-r),u=n.slice(i,n.length-r),h=[];if(c.length*u.length>25e4)c.forEach((b,_)=>h.push({kind:"del",text:b,oldNo:i+_+1,newNo:null})),u.forEach((b,_)=>h.push({kind:"add",text:b,oldNo:null,newNo:i+_+1}));else{const b=c.length,_=u.length,v=Array.from({length:b+1},()=>new Array(_+1).fill(0));for(let x=b-1;x>=0;x--)for(let S=_-1;S>=0;S--)v[x][S]=c[x]===u[S]?v[x+1][S+1]+1:Math.max(v[x+1][S],v[x][S+1]);let y=0,w=0;for(;y<b&&w<_;)c[y]===u[w]?(h.push({kind:"ctx",text:c[y],oldNo:i+y+1,newNo:i+w+1}),y++,w++):v[y+1][w]>=v[y][w+1]?(h.push({kind:"del",text:c[y],oldNo:i+y+1,newNo:null}),y++):(h.push({kind:"add",text:u[w],oldNo:null,newNo:i+w+1}),w++);for(;y<b;)h.push({kind:"del",text:c[y],oldNo:i+y+1,newNo:null}),y++;for(;w<_;)h.push({kind:"add",text:u[w],oldNo:null,newNo:i+w+1}),w++}const d=[];for(let b=0;b<Math.min(r,l);b++)d.push({kind:"ctx",text:s[s.length-r+b],oldNo:s.length-r+b+1,newNo:n.length-r+b+1});r>l&&d.push({kind:"gap",text:`⋯ 下面 ${r-l} 行未变 ⋯`,oldNo:null,newNo:null});const p=new Array(h.length).fill(!1);h.forEach((b,_)=>{if(b.kind!=="ctx")for(let v=Math.max(0,_-l);v<=Math.min(h.length-1,_+l);v++)p[v]=!0});const f=[];let m=0;return h.forEach((b,_)=>{if(!p[_]){m++;return}m&&(f.push({kind:"gap",text:`⋯ 中间 ${m} 行未变 ⋯`,oldNo:null,newNo:null}),m=0),f.push(b)}),m&&f.push({kind:"gap",text:`⋯ 中间 ${m} 行未变 ⋯`,oldNo:null,newNo:null}),[...a,...f,...d]}const of=e=>typeof e=="string";function FN(e){const t=Math.max(e.lastIndexOf("/"),e.lastIndexOf("\\"));return t>=0?e.slice(t+1):e}function RS(e){if(!e||!/^(\+\+\+|---) /m.test(e))return null;let t="",s=0,n=0;for(const i of e.split(`
43
- `)){if(i.startsWith("+++ ")){const r=i.slice(4).trim().replace(/^b\//,"").replace(/\t.*$/,"");r&&r!=="/dev/null"&&(t=r);continue}i.startsWith("--- ")||(i.startsWith("+")?s++:i.startsWith("-")&&n++)}return t?{path:t,insertions:s,deletions:n}:null}function zN(e){const t=e??{},s=Array.isArray(t.content)?t.content:[],n=[],i=new Set,r=a=>{i.has(a.path)||(i.add(a.path),n.push(a))};for(const a of s){if(!a||typeof a!="object")continue;if(of(a.path)&&a.path&&(a.oldText!=null||a.newText!=null||a.type==="diff")){r({path:a.path,oldText:a.oldText??"",newText:a.newText??""});continue}const l=of(a.text)?a.text:of(a.content?.text)?a.content.text:"";if(!l)continue;const c=RS(l);c&&r({path:c.path,diffText:l})}return n}function HN(e){const t=[],s=new Map;for(const n of e){const i=s.get(n.path);if(!i){t.push(n.path),s.set(n.path,{first:n,last:n,edits:1,diffText:n.diffText});continue}i.last=n,i.edits++,n.oldText!=null||n.newText!=null?i.diffText=void 0:i.diffText||(i.diffText=n.diffText)}return t.map(n=>{const{first:i,last:r,edits:a,diffText:l}=s.get(n),c={path:n,name:FN(n),edits:a};if(i.oldText!=null||r.newText!=null){const u=i.oldText??"",h=r.newText??r.oldText??"",d=s_(u,h);return{...c,insertions:d.filter(p=>p.kind==="add").length,deletions:d.filter(p=>p.kind==="del").length,oldText:u,newText:h}}if(l){const u=RS(l);return{...c,insertions:u?.insertions??0,deletions:u?.deletions??0,oldText:"",newText:"",diffText:l}}return{...c,insertions:0,deletions:0,oldText:"",newText:""}})}function UN(e){let t=null,s=!1,n=[];function i(){const a=n;n=[];for(const l of a)l()}async function r(){if(!s){s=!0;try{for(;t;){const a=t;t=null;try{await e(a)}catch{}}}finally{s=!1,i()}}}return{push(a){t=a,r()},hush(){t=null,s||i()},get speaking(){return s},get waiting(){return t},settled(){return!s&&!t?Promise.resolve():new Promise(a=>{n.push(a)})}}}const jS="agentus.voice",kl={autoRead:!1,speakMode:"off",voiceURI:"",rate:1,lang:typeof navigator<"u"&&navigator.language?navigator.language:"en-US",serverTts:!1,stt:"auto"};function WN(){try{const e=localStorage.getItem(jS);if(!e)return{...kl};const t=JSON.parse(e),s=Number(t.rate);return{...kl,...t,rate:Number.isFinite(s)?Math.min(2,Math.max(.5,s)):kl.rate}}catch{return{...kl}}}function TS(e){try{localStorage.setItem(jS,JSON.stringify(e))}catch{}}const n_={provider:"browser",tts:{server:!1,model:null,voice:null},stt:{server:!1,streaming:!1,model:null,batchModel:null,language:null},hotwords:{fixed:0,dynamic:!1,limit:0}};let $o=null;const qp=new Set;async function Ch(e=!1){if($o&&!e)return $o;try{const t=await fetch("/api/voice",{credentials:"same-origin"});if(!t.ok)throw new Error(String(t.status));$o=await t.json()}catch{$o=n_}for(const t of qp)t();return $o}function li(){return $o??n_}function KN(e){return qp.add(e),()=>qp.delete(e)}const t0=80,AS=220,qN=2,VN=12,YN=3,s0=2,GN=400,af=0,JN=1,XN=4,ZN=400,QN=60;let lf=0;const Za=[];async function eR(e,t,s){lf>=YN&&await new Promise((n,i)=>{const r={priority:e,run:n};Za.push(r),Za.sort((l,c)=>l.priority-c.priority);const a=()=>{const l=Za.indexOf(r);l>=0&&Za.splice(l,1),i(new rn)};t&&(t.aborted?a():t.addEventListener("abort",a,{once:!0}))}),lf++;try{return await s()}finally{const n=Za.shift();n?n.run():lf--}}function n0(e,t=AS){const s=e.replace(/```[\s\S]*?```/g," code block ").replace(/[*_`#>|]/g," ").replace(/\s+/g," ").trim();if(!s)return[];const n=[];let i=s;for(;i.length>t;){const r=i.slice(0,t),a=Math.max(r.lastIndexOf(". "),r.lastIndexOf("。"),r.lastIndexOf("! "),r.lastIndexOf("? ")),l=Math.max(r.lastIndexOf(", "),r.lastIndexOf("; "),r.lastIndexOf(",")),c=a>t*.5?a+1:l>t*.5?l+1:r.lastIndexOf(" "),u=c>0?c:t;n.push(i.slice(0,u).trim()),i=i.slice(u).trim()}return i&&n.push(i),n.filter(Boolean)}let nn=null;function MS(){return window.AudioContext??window.webkitAudioContext??null}const Fl={echoCancellation:null,noiseSuppression:null};function tR(e,t){const s=e.getAudioTracks()[0],n=typeof s?.getSettings=="function"?s.getSettings():void 0;Fl.echoCancellation=typeof n?.echoCancellation=="boolean"?n.echoCancellation:t>0?!1:null,Fl.noiseSuppression=typeof n?.noiseSuppression=="boolean"?n.noiseSuppression:t>0?!1:null,Fl.echoCancellation===!1&&console.warn("[voice] microphone opened WITHOUT echo cancellation — the call may hear itself")}function i0(){return Fl.echoCancellation!==!1}function cf(){return{...Fl}}async function r0(e){const t=[e,{audio:{channelCount:1,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1}},{audio:!0}];let s=null;for(let n=0;n<t.length;n++)try{const i=await navigator.mediaDevices.getUserMedia(t[n]);return n>0&&console.warn("[voice] microphone opened only with degraded constraints",t[n]),tR(i,n),i}catch(i){s=i;const r=i?.name??"";if(r==="NotAllowedError"||r==="SecurityError")throw i;await new Promise(a=>setTimeout(a,250))}throw s instanceof Error?s:new Error(String(s))}async function sR(){const e=MS();if(!e)return!1;try{return nn=nn??new e,nn.state==="suspended"&&await nn.resume(),nn.state==="running"}catch{return!1}}const or={analyser:null};let cr=null;function o0(){const e=or.analyser;if(!e)return-1;const t=cr&&cr.length===e.fftSize?cr:new Float32Array(new ArrayBuffer(e.fftSize*4));cr=t,e.getFloatTimeDomainData(t);let s=0;for(let n=0;n<t.length;n++)s+=t[n]*t[n];return Math.min(1,Math.sqrt(s/t.length)*4)}function nR(){const e=or.analyser;if(!e)return-1;const t=cr&&cr.length===e.fftSize?cr:new Float32Array(new ArrayBuffer(e.fftSize*4));cr=t,e.getFloatTimeDomainData(t);let s=0;for(let n=0;n<t.length;n++)s+=t[n]*t[n];return Math.min(1,Math.sqrt(s/t.length))}function iR(e){const t=or.analyser;if(!t)return!1;const s=new Float32Array(new ArrayBuffer(t.fftSize*4));t.getFloatTimeDomainData(s);const n=Math.max(1,Math.floor(s.length/e.length));for(let i=0,r=0;i<e.length;i++,r+=n)e[i]=s[r]??0;return!0}class rn extends Error{constructor(){super("stopped"),this.name="SpeechStopped"}}async function DS(e,t){const s=MS();if(s)try{nn=nn??new s,nn.state==="suspended"&&await nn.resume();const i=await nn.decodeAudioData(await e.arrayBuffer());await new Promise((r,a)=>{const l=nn.createBufferSource();l.buffer=i;const c=nn.createAnalyser();c.fftSize=512,l.connect(c),c.connect(nn.destination),or.analyser=c,l.onended=()=>{or.analyser===c&&(or.analyser=null),r()};const u=()=>{or.analyser===c&&(or.analyser=null);try{l.stop()}catch{}a(new rn)};if(t){if(t.aborted)return u();t.addEventListener("abort",u,{once:!0})}l.start()});return}catch(i){if(i instanceof rn)throw i;if(t?.aborted)throw new rn}const n=URL.createObjectURL(e);try{await new Promise((i,r)=>{const a=new Audio(n),l=()=>{try{a.pause()}catch{}r(new rn)};a.onended=()=>{c(),i()},a.onerror=()=>{c(),r(new Error("audio playback failed"))};const c=()=>{t&&t.removeEventListener("abort",l)};if(t){if(t.aborted)return l();t.addEventListener("abort",l,{once:!0})}a.play().catch(u=>{c(),r(new Error(String(u?.message??u)))})})}finally{URL.revokeObjectURL(n)}}function Qa(){return typeof window<"u"&&"speechSynthesis"in window}class rR{#e={speakingId:null,speaking:!1,error:"",note:""};#l=new Set;#i=null;#s=0;#o=!1;#t=[];#n=new Set;subscribe=t=>(this.#l.add(t),()=>this.#l.delete(t));getSnapshot=()=>this.#e;#c(t){this.#e={...this.#e,...t};for(const s of this.#l)s()}subscribeVoices=t=>(this.#n.add(t),()=>this.#n.delete(t));voices=()=>this.#t;init(){if(!Qa())return;const t=()=>{const i=window.speechSynthesis.getVoices();if(i.length!==this.#t.length){this.#t=i;for(const r of this.#n)r()}};t(),window.speechSynthesis.addEventListener("voiceschanged",t);let s=0;const n=window.setInterval(()=>{s+=1,t(),(this.#t.length||s>40)&&window.clearInterval(n)},250);window.addEventListener("pointerdown",t,{once:!0})}pickVoice(t){const s=this.#t.length?this.#t:Qa()?window.speechSynthesis.getVoices():[];if(!s.length)return null;if(t.voiceURI){const r=s.find(a=>a.voiceURI===t.voiceURI);if(r)return r}const n=t.lang.toLowerCase(),i=n.split("-")[0];return s.find(r=>r.lang.toLowerCase()===n)??s.find(r=>r.lang.toLowerCase().startsWith(i))??s.find(r=>r.default)??s[0]}async speak(t,s,n){const i=String(t??"").trim();if(!i)return;this.stop();const r=++this.#s;this.#o=!1;const a=n.serverTts&&li().tts.server,l=n0(i,a?t0:AS);if(!l.length)return;const c=new AbortController;this.#i=c,this.#c({error:"",note:"",speakingId:s,speaking:!0});try{a?await this.#v(l,n,c.signal):await this.#h(l,n,c.signal)}catch(u){if(this.#o||r!==this.#s||u instanceof rn||u?.name==="AbortError")return;if(n.serverTts&&Qa()){this.#c({note:`服务端语音这一句失败了(${String(u?.message??u)}),已改用浏览器语音`});try{await this.#h(l,n,c.signal);return}catch(h){if(this.#o||h instanceof rn)return;this.#c({error:String(h?.message??h)})}}else this.#c({error:String(u?.message??u)})}finally{this.#i===c&&(this.#i=null),r===this.#s&&this.#c({speaking:!1,speakingId:null})}}async#h(t,s,n){if(!Qa())throw new Error("this browser has no speech synthesis");const i=window.speechSynthesis,r=this.pickVoice(s);for(const[a,l]of t.entries()){if(n?.aborted)throw new rn;if(await new Promise((c,u)=>{const h=new SpeechSynthesisUtterance(l);r?(h.voice=r,h.lang=r.lang):h.lang=s.lang,h.rate=s.rate,h.onend=()=>c(),h.onerror=d=>u(new Error(`speech error: ${d.error??"unknown"}`)),i.speak(h),a===0&&i.resume()}),n?.aborted)throw new rn;i.paused&&i.resume()}}#_(t,s,n,i){return eR(i,n,async()=>{const r=await fetch("/api/tts",{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},signal:n,body:JSON.stringify({text:t,speed:s.rate})});if(!r.ok){const a=await r.json().catch(()=>({error:`${r.status}`}));throw new Error(a.error??`tts ${r.status}`)}return await r.blob()})}async#p(t,s,n,i=af){let r=null;for(let a=0;a<=s0;a++){if(n?.aborted)throw new rn;try{return await this.#_(t,s,n,i)}catch(l){if(l instanceof rn||l?.name==="AbortError"||n?.aborted)throw l;r=l,a<s0&&await new Promise(c=>{window.setTimeout(c,GN*(a+1))})}}throw r instanceof Error?r:new Error(String(r))}#d=new Map;#f(t,s){return`${s.rate}|${li().tts.voice??""}|${t}`}prefetch(t,s){if(!(s.serverTts&&li().tts.server))return;const n=String(t??"").trim();if(n)for(const i of n0(n,t0)){const r=this.#f(i,s);if(this.#d.has(r))continue;const a=this.#p(i,s,void 0,JN);for(a.catch(()=>{}),this.#d.set(r,a);this.#d.size>VN;){const l=this.#d.keys().next().value;if(l===void 0)break;this.#d.delete(l)}}}async#v(t,s,n){const i=[],r=a=>{const l=this.#f(a,s),c=this.#d.get(l);if(c)return this.#d.delete(l),c.catch(()=>this.#p(a,s,n,af));const u=this.#p(a,s,n,af);return u.catch(()=>{}),u};for(let a=0;a<t.length;a++){if(n.aborted)throw new rn;for(;i.length<Math.min(qN,t.length-a);)i.push(r(t[a+i.length]));if(await DS(await i.shift(),n),n.aborted)throw new rn}}stop(){this.#o=!0,this.#i?.abort(),this.#i=null,Qa()&&window.speechSynthesis.cancel(),this.#e.speaking&&this.#c({speaking:!1,speakingId:null})}}const Ft=new rR;Ft.init();function dd(){return g.useSyncExternalStore(Ft.subscribe,Ft.getSnapshot)}const el=new Set,oR=1024,IS=UN(e=>Ft.speak(e.text,e.key,Hn));function uc(){IS.hush(),Ft.stop()}function aR(e){IS.push({key:e.key,text:e.text})}let i_=!1;function a0(e){i_=e}function Eh(){return i_}function lR(e,t,s){if(i_||!s||el.has(e))return!1;for(el.add(e);el.size>oR;){const n=el.values().next().value;if(n===void 0)break;el.delete(n)}return!0}function PS(){const e=window;return e.SpeechRecognition??e.webkitSpeechRecognition??null}function Vp(){return!!PS()}function LS(){const e=window.AgentusMic;return e&&typeof e.start=="function"&&typeof e.stop=="function"?e:null}function OS(){const e=LS();if(!e)return!1;try{return!!e.available()}catch{return!1}}function cR(){return OS()||typeof navigator.mediaDevices?.getUserMedia=="function"}function uR(){return typeof window<"u"&&!window.isSecureContext?"当前页面是明文 http,浏览器不允许网页录音。请改用 https 入口访问(在服务前放一层终结 TLS 的反代或隧道),或走本机 localhost;手机上也可以用 Agentus app。":"this browser cannot record audio"}function hR(){return new Promise(e=>{const t=document.createElement("input");t.type="file",t.accept="audio/*",t.setAttribute("capture","microphone"),t.style.position="fixed",t.style.left="-9999px";let s=!1;const n=i=>{s||(s=!0,t.remove(),e(i))};t.onchange=()=>n(t.files?.[0]??null),window.addEventListener("focus",()=>{window.setTimeout(()=>n(t.files?.[0]??null),600)},{once:!0}),document.body.appendChild(t),t.click()})}class dR{#e={status:"idle",text:"",interim:"",error:"",engine:null,seconds:0};#l=new Set;#i=null;#s=null;#o=[];#t=null;#n=null;#c=null;#h=null;#_=null;#p=null;#d="";#f=0;#v=0;#b=new Float32Array(256);#D=null;#x=!0;#I;#k=!1;#a=0;#m=[];#S=null;#C=0;#y="";#w=!1;#E=()=>{const t=globalThis.__asFeed;return t&&typeof t=="object"?t:null};level=()=>{const t=this.#E();if(!t)return this.#f;const s=Number(t.level);return Number.isFinite(s)?s:0};levelRms=()=>{const t=this.#E();if(!t)return this.#v;const s=Number(t.rms??(Number.isFinite(Number(t.level))?Number(t.level)/6:NaN));return Number.isFinite(s)?Math.max(0,s):0};wave=()=>this.#b;setVadTap=t=>{this.#D=t};setRelay(t){if(this.#x=t,!t){this.#w=!0,this.#$();return}this.#w=!1,this.#k&&this.#N()}#$(){this.#S!==null&&(window.clearTimeout(this.#S),this.#S=null);const t=this.#n;if(this.#n=null,this.#m.length=0,!!t){t.onmessage=null,t.onerror=null,t.onclose=null;try{t.close()}catch{}}}resetText(){this.#d="",this.#r({text:"",interim:""})}commitForTest(t){this.#d=`${this.#d}${t}`.replace(/\s+/g," ").trim(),this.#r({status:"idle",text:this.#d,interim:""})}#T(t){let s=0;for(let a=0;a<t.length;a++)s+=t[a]*t[a];const n=Math.sqrt(s/t.length),i=Math.min(1,n*6);this.#f=i>this.#f?this.#f+(i-this.#f)*.6:this.#f*.72+i*.28,this.#v=n>this.#v?this.#v+(n-this.#v)*.6:this.#v*.72+n*.28,this.#D?.(t);const r=Math.max(1,Math.floor(t.length/this.#b.length));for(let a=0,l=0;a<this.#b.length&&l<t.length;a++,l+=r)this.#b[a]=t[l]}subscribe=t=>(this.#l.add(t),()=>this.#l.delete(t));#P=null;getSnapshot=()=>{const t=this.#E();if(!t)return this.#e;const s=String(t.text??""),n=String(t.interim??""),i=this.#P;return i&&i.text===s&&i.interim===n&&i.status===this.#e.status&&i.error===this.#e.error&&i.engine===this.#e.engine&&i.seconds===this.#e.seconds?i:(this.#P={...this.#e,text:s,interim:n},this.#P)};#r(t){this.#e={...this.#e,...t};for(const s of this.#l)s()}async start(t,s){if(this.#e.status!=="idle"&&this.#e.status!=="error")return!1;uc();const n=++this.#a;this.#r({status:"idle",text:"",interim:"",error:"",seconds:0}),this.#d="";const i=this.#E();if(i)return this.#x=!0,this.#r({status:"listening",engine:"stream",error:"",text:String(i.text??""),interim:String(i.interim??"")}),!0;const r=t.stt,a=li().stt.server,l=li().stt.streaming,c=(r==="browser"||r==="auto")&&Vp();try{if(r==="stream"||r==="auto"&&l){if(!l)throw new Error("streaming STT is not configured on the server (settings → 语音)");return await this.#L(t,s,n),!0}return c?(this.#H(t),!0):a?(await this.#K(t,n),!0):(this.#r({status:"error",engine:null,error:(typeof window<"u"&&!window.isSecureContext&&!cR()?`${uR()} `:"")+(r==="server"||a?"no dictation available: this browser has no speech recognition and the server has no STT endpoint (AGENTUS_STT_BASE_URL)":"no dictation available in this browser — set the server STT endpoint or use Chromium/Edge")}),!1)}catch(u){return this.#R(n)||this.#r({status:"error",error:String(u?.message??u)}),!1}}#H(t){const s=PS();if(!s)throw new Error("speech recognition unavailable");const n=new s;n.lang=t.lang,n.continuous=!0,n.interimResults=!0,n.maxAlternatives=1;let i="";n.onstart=()=>this.#r({status:"listening",engine:"browser",error:""}),n.onresult=r=>{let a="";for(let l=r.resultIndex;l<r.results.length;l+=1){const c=r.results[l],u=c[0]?.transcript??"";c.isFinal?i+=u:a+=u}this.#r({text:i.trim(),interim:a.trim()})},n.onerror=r=>{const a=String(r?.error??"unknown");this.#r({status:"error",error:a==="not-allowed"||a==="service-not-allowed"?"microphone permission denied":a==="no-speech"?"heard nothing — try again closer to the microphone":`speech recognition failed: ${a}`})},n.onend=()=>{this.#e.status==="listening"&&this.#r({status:"idle",interim:""}),this.#i=null},this.#i=n,this.#r({status:"requesting",engine:"browser"});try{n.start()}catch(r){throw this.#i=null,new Error(String(r?.message??r))}}async#L(t,s,n){const i=OS()?LS():null;if(!i&&typeof navigator.mediaDevices?.getUserMedia!="function"){await this.#u(t);return}const r=window.AudioContext??window.webkitAudioContext;if(!i&&!r)throw new Error("this browser cannot process audio");this.#r({status:"requesting",engine:"stream",error:""}),this.#x=!0,this.#w=!1,this.#C=0,this.#y="",this.#I=s,this.#k=!0,this.#m.length=0,this.#N();const a=l=>this.#U(l);if(i?await this.#F(i,a,n):await this.#W(r,a,n),this.#R(n)){this.#A(),this.#O(),this.#r({status:"idle",interim:"",text:""});return}this.#r({status:"listening",engine:"stream",seconds:0}),this.#t=window.setInterval(()=>this.#r({seconds:this.#e.seconds+1}),1e3)}#U(t){const s=this.#n;s&&s.readyState===WebSocket.OPEN?s.send(t):this.#m.length<QN&&this.#m.push(t)}#N(){if(this.#n||!this.#k)return;const t=this.#I?`?sessionId=${encodeURIComponent(this.#I)}`:"",s=new WebSocket(`${location.protocol==="https:"?"wss":"ws"}://${location.host}/ws/asr${t}`);s.binaryType="arraybuffer",this.#n=s,s.onopen=()=>{this.#C=0,this.#y="";for(const n of this.#m)s.send(n);this.#m.length=0,this.#e.status!=="listening"&&this.#r({status:"listening",engine:"stream",error:""})},s.onmessage=n=>{let i;try{i=JSON.parse(String(n.data))}catch{return}i.t==="asr-partial"?this.#r({interim:String(i.text??"")}):i.t==="asr-final"?(this.#d=`${this.#d}${i.text??""}`.replace(/\s+/g," ").trim(),this.#r({text:this.#d,interim:""})):i.t==="asr-error"?this.#g(String(i.error??"streaming asr failed")):i.t==="asr-done"&&(this.#w||!this.#k||!this.#x?this.#j():this.#g("the recogniser ended the turn by itself"))},s.onerror=()=>this.#g("the streaming socket failed — is the server up?"),s.onclose=()=>{this.#n===s&&(this.#n=null),this.#g(this.#y||"the streaming socket failed — is the server up?")}}#g(t){if(!(!this.#k||this.#w||!this.#x)&&(this.#y||(this.#y=t),this.#S===null)){if(this.#C>=XN){this.#r({status:"error",error:this.#y}),this.#y="",this.#j();return}this.#C+=1,this.#S=window.setTimeout(()=>{this.#S=null,this.#N()},ZN*this.#C)}}async#W(t,s,n){const i=await r0({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}});if(this.#R(n)){for(const u of i.getTracks())u.stop();return}this.#_=i;const r=new t({sampleRate:16e3});this.#c=r;const a=r.createMediaStreamSource(i),l=r.createScriptProcessor(2048,1,1),c=r.createGain();c.gain.value=0,this.#h=l,l.onaudioprocess=u=>{const h=u.inputBuffer.getChannelData(0);if(this.#T(h),!this.#x)return;const d=BS(h,r.sampleRate,16e3);d.length&&s(d.buffer)},a.connect(l),l.connect(c),c.connect(r.destination)}async#F(t,s,n){let i="permission";for(let r=0;r<12&&(i=String(t.start(16e3)),!(i==="ok"||i==="already"));r++){if(i==="permission"){this.#r({status:"requesting",engine:"stream"}),await new Promise(a=>setTimeout(a,600));continue}throw new Error(`手机上的原生麦克风打不开(${i})`)}if(i!=="ok"&&i!=="already")throw new Error(`手机上的原生麦克风打不开(${i})`);if(this.#R(n)){try{t.stop()}catch{}return}this.#p=t,window.__asMic=r=>{const a=atob(r),l=a.length>>1,c=new Int16Array(l);for(let h=0;h<l;h++){const d=a.charCodeAt(2*h),p=a.charCodeAt(2*h+1);c[h]=(p<<8|d)<<16>>16}const u=new Float32Array(l);for(let h=0;h<l;h++)u[h]=c[h]/32768;this.#T(u),this.#x&&s(c.buffer)}}#O(){this.#$(),this.#k=!1,this.#w=!1,this.#C=0,this.#y="",this.#A(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#x=!0}#R(t){return t!==this.#a}#A(){if(this.#h){this.#h.onaudioprocess=null;try{this.#h.disconnect()}catch{}this.#h=null}if(this.#c&&(this.#c.close().catch(()=>{}),this.#c=null),this.#_){for(const t of this.#_.getTracks())t.stop();this.#_=null}if(this.#p){try{this.#p.stop()}catch{}this.#p=null}window.__asMic=void 0,this.#f=0,this.#b.fill(0)}#j(){this.#O(),this.#r({status:"idle",interim:""})}async#K(t,s){if(typeof navigator.mediaDevices?.getUserMedia!="function"){await this.#u(t);return}this.#r({status:"requesting",engine:"server",error:""});const n=await r0({audio:!0});if(this.#R(s)){for(const a of n.getTracks())a.stop();return}const i=MediaRecorder.isTypeSupported("audio/webm;codecs=opus")?"audio/webm;codecs=opus":"",r=new MediaRecorder(n,i?{mimeType:i}:void 0);this.#o=[],r.ondataavailable=a=>{a.data.size&&this.#o.push(a.data)},r.onstop=()=>{for(const a of n.getTracks())a.stop();this.#q(t)},this.#s=r,r.start(1e3),this.#r({status:"recording",engine:"server",seconds:0}),this.#t=window.setInterval(()=>this.#r({seconds:this.#e.seconds+1}),1e3)}async#u(t){this.#r({status:"requesting",engine:"server",error:""});const s=await hR();if(!s){this.#r({status:"idle",text:"",interim:"",error:""});return}await this.#M(t,s)}async#M(t,s){this.#r({status:"transcribing"});try{const n=await fetch(`/api/stt?language=${encodeURIComponent(t.lang)}`,{method:"POST",credentials:"same-origin",headers:{"content-type":s.type||"audio/webm"},body:s}),i=await n.json().catch(()=>({}));if(!n.ok)throw new Error(i.error??`stt ${n.status}`);this.#r({status:"idle",text:String(i.text??"").trim(),interim:""})}catch(n){this.#r({status:"error",error:String(n?.message??n)})}}async#q(t){this.#t&&(window.clearInterval(this.#t),this.#t=null);const s=new Blob(this.#o,{type:this.#o[0]?.type||"audio/webm"});if(this.#o=[],this.#s=null,!s.size){this.#r({status:"error",error:"nothing was recorded — check the microphone"});return}await this.#M(t,s)}stop(){if(this.#a+=1,this.#e.status==="requesting"){this.cancel();return}if(this.#i){try{this.#i.stop()}catch{}return}if(this.#n&&this.#n.readyState===WebSocket.OPEN){this.#A(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#w=!0,this.#r({status:"transcribing"});try{this.#n.send(JSON.stringify({t:"asr-stop"}))}catch{this.#j();return}window.setTimeout(()=>{this.#e.status==="transcribing"&&this.#j()},8e3);return}this.#s&&this.#s.state!=="inactive"&&this.#s.stop(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#e.status==="listening"&&this.#r({status:"idle",interim:""})}cancel(){if(this.#a+=1,this.#i){try{this.#i.abort()}catch{}this.#i=null}this.#s&&this.#s.state!=="inactive"&&(this.#s.onstop=null,this.#s.stop(),this.#s=null),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#O(),this.#d="",this.#o=[],this.#r({status:"idle",text:"",interim:"",error:"",seconds:0})}consume(){const t=this.#e.text.trim();return this.#r({status:"idle",text:"",interim:"",seconds:0}),t}setOwner(t){this.#z=t}owns(t){return this.#z===t}#z="chat"}function BS(e,t,s){if(t===s){const a=new Int16Array(e.length);for(let l=0;l<e.length;l+=1)a[l]=l0(e[l]);return a}const n=t/s,i=Math.max(0,Math.floor(e.length/n)),r=new Int16Array(i);for(let a=0;a<i;a+=1){const l=a*n,c=Math.floor(l),u=Math.min(c+1,e.length-1),h=l-c;r[a]=l0(e[c]*(1-h)+e[u]*h)}return r}function l0(e){const t=Math.round((Number.isFinite(e)?e:0)*32767);return t>32767?32767:t<-32768?-32768:t}const pe=new dR;typeof window<"u"&&(window.__asDictation=pe);function r_(){return g.useSyncExternalStore(pe.subscribe,pe.getSnapshot)}let Hn=WN();const Nh=new Set;async function $S(){try{const e=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({prefs:Hn})});return e.ok?"":(await e.json().catch(()=>({}))).error??`save failed (${e.status})`}catch(e){return String(e?.message??e)}}function c0(e){const t={...kl};if(!e||typeof e!="object")return t;const s=e;return{autoRead:typeof s.autoRead=="boolean"?s.autoRead:t.autoRead,speakMode:s.speakMode==="off"||s.speakMode==="reply"||s.speakMode==="brief"?s.speakMode:typeof s.autoRead=="boolean"&&s.autoRead?"reply":"off",voiceURI:typeof s.voiceURI=="string"?s.voiceURI:t.voiceURI,rate:Number.isFinite(Number(s.rate))?Math.min(2,Math.max(.5,Number(s.rate))):t.rate,lang:typeof s.lang=="string"&&s.lang?s.lang:t.lang,serverTts:typeof s.serverTts=="boolean"?s.serverTts:t.serverTts,stt:s.stt==="browser"||s.stt==="stream"||s.stt==="server"?s.stt:"auto"}}function fR(e){Hn=e,TS(Hn);for(const t of Nh)t()}async function pR(){try{const e=await fetch("/api/settings",{credentials:"same-origin"});if(!e.ok)return;const t=await e.json(),s=c0(t.prefs),n=c0(t.prefsDefaults);if(uf.every(r=>s[r]===n[r])&&uf.some(r=>Hn[r]!==s[r])){$S();return}uf.some(r=>Hn[r]!==s[r])&&fR(s)}catch{}}const uf=["speakMode","voiceURI","rate","lang","serverTts","stt"];function mR(e){const t={...Hn,...e},s=Number.isFinite(t.rate)?Math.min(2,Math.max(.5,t.rate)):1;Hn={...t,rate:s},TS(Hn);for(const n of Nh)n();$S()}function gR(){return Hn}function _o(){return[g.useSyncExternalStore(t=>(Nh.add(t),()=>Nh.delete(t)),()=>Hn),mR]}function _R(e,t,s){const[n]=_o(),i=(s??n.speakMode??(n.autoRead?"reply":"off"))==="reply",r=e?.length?e.map(a=>a.key).join(""):"";g.useEffect(()=>{if(!(!i||!t||!e?.length))for(const a of e)a.text.trim()&&lR(a.key,!0,i)&&aR(a)},[r,t,i])}function vR(e,t,s){const[n]=_o(),i=(s??n.speakMode??(n.autoRead?"reply":"off"))==="brief";g.useEffect(()=>{!i||!t||!e||!e.text.trim()||Ft.speak(e.text,e.key,n)},[e?.key,t,i])}const Fo=2,Yp="agentus.webnotify",tr={on:!0,sound:"chime",volume:.6};function yR(e){return e.available&&e.permission==="granted"&&e.enabled&&e.hidden}function bR(e,t,s,n){return e.sound!=="chime"||n||!s.enabled||!s.hidden?!1:t==="approval"||t==="agent_done"||t==="error"}function wR(e){return e==="approval"?[{freq:659.25,at:0,dur:.13},{freq:987.77,at:.15,dur:.28}]:e==="error"?[{freq:739.99,at:0,dur:.11},{freq:1046.5,at:.12,dur:.13},{freq:739.99,at:.27,dur:.26}]:[{freq:880,at:0,dur:.16},{freq:659.25,at:.2,dur:.3}]}function xR(e){try{return new URL(e,typeof location>"u"?"http://localhost/":location.href).searchParams.get("session")}catch{return null}}function SR(){try{const e=localStorage.getItem(Yp);if(!e)return{...tr,v:Fo};const t=JSON.parse(e),s={on:typeof t.on=="boolean"?t.on:tr.on,sound:t.sound==="chime"||t.sound==="silent"||t.sound==="default"?t.sound:tr.sound,volume:typeof t.volume=="number"&&Number.isFinite(t.volume)?Math.min(1,Math.max(0,t.volume)):tr.volume};if(t.v!==Fo&&s.sound==="default"&&(s.sound=tr.sound),t.v!==Fo){s.v=Fo;try{localStorage.setItem(Yp,JSON.stringify(s))}catch{}}return s}catch{return{...tr,v:Fo}}}function hu(){return typeof window>"u"||!("Notification"in window)?"no-api":window.isSecureContext?"ok":"insecure"}let hf=null;function FS(){if(typeof window>"u")return null;const e=window.AudioContext??window.webkitAudioContext;if(!e)return null;if(!hf)try{hf=new e}catch{return null}return hf}function ca(){const e=FS();e&&e.state==="suspended"&&e.resume()}function kR(e,t,s,n,i){const r=e.createOscillator(),a=e.createGain();r.type="sine",r.frequency.value=t,a.gain.setValueAtTime(1e-4,s),a.gain.linearRampToValueAtTime(i,s+.012),a.gain.exponentialRampToValueAtTime(1e-4,s+n),r.connect(a),a.connect(e.destination),r.start(s),r.stop(s+n+.02)}function Gp(e,t){const s=FS();if(!s)return;s.state==="suspended"&&s.resume();const n=s.currentTime+.01;for(const i of wR(t))kR(s,i.freq,n+i.at,i.dur,e)}const Jp=new Map;let Xp=0;async function zS(){if(typeof navigator>"u"||!("serviceWorker"in navigator))return null;try{return await navigator.serviceWorker.getRegistration()??null}catch{return null}}let Zp=null;function CR(e){Zp=e}function HS(e){if(!e)return;const t=xR(e);if(t&&Zp){Zp(t);return}location.assign(e)}const u0="/icons/icon-192.png";async function h0(e,t){const s={body:e.body,tag:e.noticeId,icon:u0,badge:u0,data:{open:e.open??null,noticeId:e.noticeId},renotify:!0,requireInteraction:!!e.sticky,silent:t.sound!=="default"},n=await zS();if(n&&typeof n.showNotification=="function")try{return await n.showNotification(e.title,s),Xp=Date.now(),!0}catch{}try{const i=new Notification(e.title,s);return i.onclick=()=>{HS(e.open),i.close()},Jp.set(e.noticeId,i),Xp=Date.now(),!0}catch{return!1}}async function d0(e){const t=Jp.get(e);t&&(t.close(),Jp.delete(e));const s=await zS();if(!(!s||typeof s.getNotifications!="function"))try{for(const n of await s.getNotifications({tag:e}))n.close()}catch{}}class ER{#e=tr;#l=null;#i=new Set;#s;constructor(){this.#e=typeof localStorage>"u"?{...tr}:SR(),this.#s=this.#o()}#o(){const t=hu();return{availability:t,permission:t==="ok"?Notification.permission:"unavailable",prefs:this.#e,last:this.#l}}#t(){this.#s=this.#o();for(const t of this.#i)t()}subscribe=t=>(this.#i.add(t),()=>this.#i.delete(t));getSnapshot=()=>this.#s;setPrefs(t){this.#e={...this.#e,...t},t.volume!==void 0&&(this.#e.volume=Math.min(1,Math.max(0,t.volume)));try{localStorage.setItem(Yp,JSON.stringify({...this.#e,v:Fo}))}catch{}this.#t()}async requestPermission(){if(hu()!=="ok")return"unavailable";ca();try{const t=await Notification.requestPermission();return this.#t(),this.#o().permission}catch{return this.#o().permission}}handle(t){if(t.op==="dismiss"){d0(t.noticeId);return}const s=hu(),n={available:s==="ok",permission:s==="ok"?Notification.permission:"unavailable",enabled:this.#e.on,hidden:typeof document>"u"?!1:document.hidden},i={enabled:this.#e.on,hidden:typeof document>"u"?!1:document.hidden};bR(this.#e,t.kind,i,Eh())&&Gp(this.#e.volume,t.kind),yR(n)&&h0(t,this.#e).then(r=>{this.#l={title:t.title,at:Date.now(),drawn:r},this.#t()})}async test(){if(hu()!=="ok")return!1;ca();const t={op:"upsert",noticeId:`test:${Date.now()}`,kind:"agent_done",title:"测试通知",body:"这条通知能弹出来,就说明这台设备没问题",open:null,at:Date.now()},s=await h0(t,this.#e);return this.#l={title:t.title,at:Date.now(),drawn:s},this.#t(),this.#e.sound==="chime"&&!Eh()&&Gp(this.#e.volume,"agent_done"),s}async closeAll(t){for(const s of t)await d0(s)}lastDrawnAt(){return Xp}}const Si=new ER;function NR(){typeof navigator>"u"||!("serviceWorker"in navigator)||navigator.serviceWorker.addEventListener("message",e=>{const t=e.data;t?.t==="agentus:notify-open"&&HS(t.open??null)})}function RR(){return g.useSyncExternalStore(Si.subscribe,Si.getSnapshot)}class df extends Error{constructor(){super("unauthorized"),this.name="AuthRequired"}}const Qp="agentus.unread",jR=8e3,TR=8e3;function AR(){try{const e=localStorage.getItem(Qp),t=e?JSON.parse(e):[];return Array.isArray(t)?t.filter(s=>typeof s=="string"):[]}catch{return[]}}function MR(e){try{const t=[...e];t.length?localStorage.setItem(Qp,JSON.stringify(t)):localStorage.removeItem(Qp)}catch{}}class DR{sessions=[];cold=[];archived=[];byId=new Map;activeId=null;conn="connecting";net="ok";netError="";auth="unknown";authInfo=null;authError="";authBusy=!1;blocked=null;lastSeq={};ws=null;#e=0;#l=null;#i=[];#s=new Map;#o=new Map;#t=new Set;#n=new Map;#c=new Set;#h=new Set(AR());#_=new Set;#p=new Map;#d=new Set;#f=null;#v;#b(t){try{t?localStorage.setItem("agentus.active",t):localStorage.removeItem("agentus.active")}catch{}}#D(){try{return new URL(location.href).searchParams.get("session")}catch{return null}}#x(t){try{const s=new URL(location.href),n=t??null;if((s.searchParams.get("session")??null)===n)return;n?s.searchParams.set("session",n):s.searchParams.delete("session"),history.replaceState(history.state,"",s.toString())}catch{}}followUrl(){const t=this.#D();!t||t===this.activeId||this.byId.has(t)&&this.setActive(t)}#I(){const t=this.#D();if(t)return this.#b(t),t;try{return localStorage.getItem("agentus.active")}catch{return null}}#k=0;constructor(){this.#v=this.#w()}async#a(t,s,n){const i=n?.timeoutMs??15e3,r=n?.retry===!1?1:2;let a=null;for(let l=0;l<r;l++){const c=new AbortController,u=setTimeout(()=>c.abort(),i);try{const h=await fetch(t,{...s,signal:c.signal});if(clearTimeout(u),h.status===401)throw this.#S("会话已过期,请重新登录"),new df;const d=h.status===204?null:await h.json().catch(()=>null);if(!h.ok){const p=d?.error??`HTTP ${h.status}`,f=new Error(p);throw f.httpStatus=h.status,f.httpBody=d,f}return this.#m(!0,""),d}catch(h){if(clearTimeout(u),h instanceof df||h.httpStatus!==void 0)throw h;a=h;const d=h?.name==="AbortError"?`请求超时 ${i/1e3}s`:String(h?.message??h);if(l===r-1)throw this.#m(!1,`${d} (${t})`),new Error(d);await new Promise(p=>setTimeout(p,600))}}throw a instanceof Error?a:new Error(String(a))}#m(t,s){const n=t?"ok":"degraded";this.net===n&&this.netError===s||(this.net=n,this.netError=s,this.bump())}#S(t){const s=this.auth==="in";if(this.auth="out",this.authError=s?t:this.authError,this.ws){const n=this.ws;this.ws=null,n.onclose=null;try{n.close()}catch{}}this.conn="offline",(s||this.sessions.length)&&(this.sessions=[],this.cold=[],this.archived=[],this.byId.clear(),this.activeId=null,this.#b(null)),this.bump()}async checkAuth(){try{const t=await this.#a("/api/auth/me",void 0,{retry:!1,timeoutMs:8e3});if(this.authInfo=t,t.authEnabled&&!t.authenticated){this.#S(""),this.authError="";return}this.#e=0,this.auth="in",this.authError="",this.bump(),this.connect(),this.refreshRows()}catch(t){if(t instanceof df)return;const s=`无法连接服务端:${String(t.message??t)}`;if(this.auth==="in"){this.#m(!1,s),this.#C(Math.min(1e4,800*2**this.#e++));return}this.auth="out",this.authError=s,this.bump()}}#C(t){this.#l||(this.#l=setTimeout(()=>{this.#l=null,this.checkAuth()},t))}async login(t,s){if(this.authBusy)return!1;this.authBusy=!0,this.authError="",this.bump();try{const n=await fetch("/api/auth/login",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({username:t,password:s})});if(n.status===401)return this.authError="用户名或密码不正确",!1;if(n.status===429){const r=await n.json().catch(()=>({})),a=Math.ceil((r.retryAfterMs??3e4)/1e3);return this.authError=`尝试次数过多,请 ${a} 秒后再试`,!1}if(!n.ok)return this.authError=`登录失败:HTTP ${n.status}`,!1;const i=await n.json();return this.authInfo={authEnabled:!0,authenticated:!0,kind:"session",username:i.username,expiresAt:i.expiresAt??null,usingDefaultPassword:!!i.usingDefaultPassword},this.auth="in",this.authError="",this.bump(),this.connect(),!0}catch(n){return this.authError=`登录请求失败:${String(n.message??n)}`,!1}finally{this.authBusy=!1,this.bump()}}async logout(){try{await fetch("/api/auth/logout",{method:"POST"})}catch{}this.#S(""),this.authError="",this.bump()}subscribe=t=>(this.#d.add(t),()=>this.#d.delete(t));getSnapshot=()=>this.#v;markPermAnswered(t,s,n=!0){this.#p.set(t,{label:s,at:Date.now(),armed:n}),this.bump()}permAnswer(t){const s=this.#p.get(t);if(s)return{label:s.label,at:s.at,lapsed:s.armed&&Date.now()-s.at>jR}}#y(){if(!this.#p.size)return;const t=new Set;for(const s of this.byId.values())for(const n of s.perms)t.add(n.requestId);for(const s of[...this.#p.keys()])t.has(s)||this.#p.delete(s)}#w(){return{sessions:this.sessions,cold:this.cold,archived:this.archived,activeId:this.activeId,active:this.activeId?this.byId.get(this.activeId):void 0,conn:this.conn,net:this.net,netError:this.netError,auth:this.auth,authInfo:this.authInfo,authError:this.authError,authBusy:this.authBusy,blocked:this.blocked,unread:new Set([...this.#c,...this.#h]),version:this.#k}}bump(){this.#k++,this.#f==null&&(typeof requestAnimationFrame=="function"?this.#f=requestAnimationFrame(()=>{this.#f=null,this.#E()}):typeof setTimeout=="function"?this.#f=setTimeout(()=>{this.#f=null,this.#E()},0):this.#E()),this.#$()}#E(){this.#f!=null&&(typeof cancelAnimationFrame=="function"?cancelAnimationFrame(this.#f):typeof clearTimeout=="function"&&clearTimeout(this.#f),this.#f=null);for(const t of this.byId.values())t.busy=t.info.status==="running";this.#v=this.#w();for(const t of this.#d)t()}#$(){typeof document>"u"||!document.hidden||this.#f!=null&&this.#E()}connect(){if(this.auth==="out")return;const t=location.protocol==="https:"?"wss":"ws",s=new WebSocket(`${t}://${location.host}/ws`);this.ws=s,s.onopen=()=>{for(this.conn="online",this.net="ok",this.netError="",this.#e=0,s.send(JSON.stringify({t:"resume",lastSeq:this.lastSeq}));this.#i.length;){const n=this.#i.shift();try{s.send(JSON.stringify(n))}catch{this.#i.unshift(n);break}}this.bump(),this.refreshRows(),window.setTimeout(()=>this.drainPersistedQueues(),700)},s.onmessage=n=>this.apply(JSON.parse(n.data)),s.onclose=()=>{if(this.conn="offline",this.bump(),this.auth==="out")return;const n=Math.min(1e4,800*2**this.#e++);this.#C(n)},s.onerror=()=>s.close()}sendPrompt(t,s,n=[]){!s.trim()&&!n.length||this.#T(t,{text:s,attachments:n})}#T(t,s){const n=`p-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,i={t:"prompt",sessionId:t,text:s.text,attachments:s.attachments,pid:n,...s.interrupt?{interrupt:!0}:{}};if(!this.send(i)){if(s.rowId){const l=this.#s.get(t)??[];this.#g(t,l.map(c=>c.id===s.rowId?{...c,inflight:!1}:c))}return}const a=setTimeout(()=>this.#H(n),TR);this.#n.set(n,{sessionId:t,pid:n,text:s.text,attachments:s.attachments,rowId:s.rowId,timer:a})}#P(t,s){const n=s?this.#n.get(s):[...this.#n.values()].find(r=>r.sessionId===t);if(!n)return;for(const r of[...this.#n.values()])r.sessionId===t&&(clearTimeout(r.timer),this.#n.delete(r.pid));clearTimeout(n.timer),this.#n.delete(n.pid);const i=this.#s.get(t)??[];i.some(r=>r.pid===n.pid)&&this.#g(t,i.filter(r=>r.pid!==n.pid))}#r(t){const s=this.#n.get(t);s&&(clearTimeout(s.timer),this.#n.delete(t))}#H(t){const s=this.#n.get(t);if(!s)return;this.#n.delete(t),this.#t.delete(s.sessionId);const n=this.#s.get(s.sessionId)??[];s.rowId&&n.some(i=>i.id===s.rowId)?this.#g(s.sessionId,n.map(i=>i.id===s.rowId?{...i,inflight:!1,unsure:!0}:i)):n.some(i=>i.pid===s.pid)||this.#g(s.sessionId,[...n,{id:`q-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,text:s.text,attachments:s.attachments,at:Date.now(),unsure:!0,pid:s.pid}]),this.#m(!1,"消息未确认送达 — 已放回队列,点 ↑ 重发")}send(t){return this.auth==="out"?(this.#m(!1,"未登录 — 请先登录再发送指令"),!1):this.ws?.readyState===WebSocket.OPEN?(this.ws.send(JSON.stringify(t)),!0):t.t==="prompt"?(this.enqueuePrompt(t.sessionId,t.text,t.attachments??[]),this.#m(!1,"连接已断开 — 消息已排队,重连后自动发送"),!1):t.t==="respond-permission"?(this.#i.push(t),this.#i.length>20&&this.#i.shift(),this.#m(!1,"连接已断开 — 指令已排队,重连后自动发送"),!1):(this.#m(!1,"连接已断开 — 该操作未能送达"),!1)}#L(t){return`agentus.queue.${t}`}#U(t){try{const s=localStorage.getItem(this.#L(t)),n=s?JSON.parse(s):[];return Array.isArray(n)?n.filter(i=>i&&typeof i.text=="string"&&i.text.trim()).map(i=>({id:String(i.id??`q-${i.at??Date.now()}`),text:i.text,attachments:i.attachments??[],at:i.at??Date.now(),...i.unsure?{unsure:!0,pid:typeof i.pid=="string"?i.pid:void 0}:{}})):[]}catch{return[]}}#N(t){const s=this.#s.get(t)??this.#U(t);return s.length&&this.#s.set(t,s),s}drainPersistedQueues(){try{for(let t=0;t<localStorage.length;t++){const s=localStorage.key(t);if(!s?.startsWith("agentus.queue."))continue;const n=s.slice(14);this.#N(n),this.drainQueue(n)}}catch{}}#g(t,s){s.length?this.#s.set(t,s):this.#s.delete(t);try{s.length?localStorage.setItem(this.#L(t),JSON.stringify(s)):localStorage.removeItem(this.#L(t))}catch{}const n=this.byId.get(t);n&&(n.queue=s),this.bump()}queueSetup(t,s){s.length&&this.#o.set(t,s)}#W(t){const s=this.#o.get(t);if(s?.length){this.#o.delete(t);for(const n of s)n.kind==="model"?this.send({t:"set-model",sessionId:t,modelId:n.value}):n.kind==="mode"?this.send({t:"set-mode",sessionId:t,modeId:n.value}):this.send({t:"set-config",sessionId:t,configId:n.id,value:n.value})}}enqueuePrompt(t,s,n=[]){const i=this.#s.get(t)??[];this.#g(t,[...i,{id:`q-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,text:s,attachments:n,at:Date.now()}])}sendToCold(t,s,n=[]){const i=this.#s.get(t)??this.#N(t),r=i[i.length-1],a=this.sessions.some(u=>u.id===t&&u.status==="ready"),l=!!(r&&r.text===s&&!a&&Date.now()-r.at<5e3),c=!s.trim()&&!n.length;!l&&!c&&this.enqueuePrompt(t,s,n),this.resume(t)}dropQueued(t,s){const n=this.#s.get(t)??[];this.#g(t,n.filter(i=>i.id!==s))}editQueued(t,s,n){const i=this.#s.get(t)??[],r=n.trim();this.#g(t,r?i.map(a=>a.id===s?{...a,text:r}:a):i.filter(a=>a.id!==s))}sendQueuedNow(t,s){const n=this.#s.get(t)??[],i=n.find(r=>r.id===s);i&&(this.#t.add(t),this.#g(t,n.map(r=>r.id===s?{...r,inflight:!0,unsure:!1}:r)),this.#T(t,{text:i.text,attachments:i.attachments,interrupt:!0,rowId:s}))}sendNow(t,s,n=[]){if(!s.trim()&&!n.length)return;this.#N(t),this.enqueuePrompt(t,s,n);const i=this.#s.get(t)??[],r=i[i.length-1];r&&this.sendQueuedNow(t,r.id)}drainQueue(t){const s=this.#s.get(t)??this.#N(t),n=s[0];!n||n.inflight||n.unsure||this.#t.has(t)||Qr(this.byId.get(t))||this.sessions.find(r=>r.id===t)?.status==="running"||(this.#g(t,s.map(r=>r.id===n.id?{...r,inflight:!0}:r)),this.#T(t,{text:n.text,attachments:n.attachments,interrupt:!0,rowId:n.id}))}#F(t){this.#t.delete(t);const s=this.#s.get(t)??[];s.some(n=>n.inflight)&&this.#g(t,s.filter(n=>!n.inflight))}#O(t){this.#t.delete(t);const s=this.#s.get(t)??[];s.some(n=>n.inflight)&&this.#g(t,s.map(n=>n.inflight?{...n,inflight:!1}:n))}setActive(t){this.activeId=t,this.#b(t),this.#x(t),this.clearUnread(t),this.#v=this.#w(),this.bump();const s=this.byId.get(t);s&&!s.loaded&&this.loadHistory(t)}markUnread(t){this.#c.has(t)||(this.#c=new Set(this.#c).add(t),this.bump())}clearUnread(t){if(!this.#c.has(t))return;const s=new Set(this.#c);s.delete(t),this.#c=s,this.bump()}isUnread(t){return this.#c.has(t)||this.#h.has(t)}toggleUnread(t){if(this.isUnread(t)){const s=new Set(this.#c);s.delete(t),this.#c=s;const n=new Set(this.#h);n.delete(t),this.#h=n}else this.#h=new Set(this.#h).add(t);MR(this.#h),this.bump()}async loadHistory(t){try{const{messages:s,hasOlder:n}=await this.#a(`/api/sessions/${t}/messages?tail=1`),i=this.#u(t);i.seen.clear(),i.msgs=[],i.blocks.clear(),i.minSeq=null,i.plan=null,i.turn=0,i.turnStart=0;for(const r of s)this.#B(i,r);i.loaded=!0,i.hasOlder=!!n,this.#M(i),this.#q(i),this.bump(),this.#K(i)}catch{}}async loadEarlier(t){const s=this.#u(t);if(s.loadingOlder||!s.hasOlder||s.minSeq==null)return 0;s.loadingOlder=!0,this.bump();try{const{messages:n,hasOlder:i}=await this.#a(`/api/sessions/${t}/messages?before=${s.minSeq}`),r=[],a=new Map;for(const c of n)this.#B(s,c,{list:r,index:a});const l=[];for(const c of r){const u=s.blocks.get(c.key),h=u===void 0?void 0:s.msgs[u];if(h&&h.kind===c.kind&&(c.kind==="agent"||c.kind==="thought")&&h.kind===c.kind){const d=h,p=c;if(p.text.length>d.text.length){const f=s.msgs.indexOf(d);f>=0&&(s.msgs[f]={...d,text:p.text})}continue}l.push(c)}return l.length&&(s.msgs=[...l,...s.msgs]),s.blocks=e0(s.msgs),s.hasOlder=!!i,l.length}catch{return-1}finally{s.loadingOlder=!1,this.bump()}}async loadBackends(){return await this.#a("/api/backends")}async createBackend(t){await this.#a("/api/backends",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}async updateBackend(t,s){await this.#a(`/api/backends/${encodeURIComponent(t)}`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(s)})}async deleteBackend(t){await this.#a(`/api/backends/${encodeURIComponent(t)}`,{method:"DELETE"})}async inspectBackend(t){return await this.#a(`/api/backends/${encodeURIComponent(t)}/inspect`,{method:"POST"},{timeoutMs:6e4,retry:!1})}async listEntries(t){return await this.#a(`/api/fs/dirs?files=1&path=${encodeURIComponent(t)}`)}async readFile(t){return await this.#a(`/api/fs/file?path=${encodeURIComponent(t)}`)}async statFile(t){return await this.#a(`/api/fs/stat?path=${encodeURIComponent(t)}`)}async writeFile(t,s,n){return await this.#a("/api/fs/file",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({path:t,content:s,...n?{ifHash:n}:{}})},{retry:!1})}async fork(t){const s=await this.#a(`/api/sessions/${t}/fork`,{method:"POST"},{timeoutMs:12e4,retry:!1});return this.sessions.some(n=>n.id===s.id)||(this.sessions=[s,...this.sessions]),this.cold=this.cold.filter(n=>n.id!==s.id),this.archived=this.archived.filter(n=>n.id!==s.id),this.setActive(s.id),s.id}async setModel(t,s){const n=await this.#a(`/api/sessions/${t}/model`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({modelId:s})},{timeoutMs:9e4,retry:!1}),i=this.byId.get(t);i&&(i.info={...i.info,...n});const r=this.sessions.findIndex(a=>a.id===t);return r>=0&&(this.sessions[r]={...this.sessions[r],...n}),this.bump(),n}async setContextLimit(t,s,n={}){const i=await this.#a(`/api/sessions/${t}/context-limit`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({limit:s,...n})}),r=this.byId.get(t);r&&(r.info={...r.info,...i});const a=this.sessions.findIndex(c=>c.id===t);a>=0&&(this.sessions[a]={...this.sessions[a],...i});const l=this.archived.findIndex(c=>c.id===t);l>=0&&(this.archived[l]={...this.archived[l],...i}),this.bump()}async setWorkspace(t,s){const n=await this.#a(`/api/sessions/${t}/workspace`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({path:s})}),i=this.byId.get(t);i&&(i.info={...i.info,...n});const r=this.sessions.findIndex(a=>a.id===t);r>=0&&(this.sessions[r]={...this.sessions[r],...n}),this.bump()}async createSession(t,s,n){const i=await this.#a("/api/sessions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({backend:t,cwd:s,title:n||void 0})},{retry:!1}),r=this.#u(i.id);return r.info={...r.info,...i},this.sessions.some(a=>a.id===i.id)||(this.sessions=[i,...this.sessions]),this.bump(),i.id}async refreshRows(){try{const{cold:t,archived:s}=await this.#a("/api/sessions");this.cold=t??[],this.archived=s??[],this.bump()}catch{}}async rename(t,s){const n=await this.#a(`/api/sessions/${t}/rename`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({title:s})}),i=this.byId.get(t);i&&(i.info={...i.info,...n});for(const r of[this.sessions,this.archived]){const a=r.findIndex(l=>l.id===t);a>=0&&(r[a]={...r[a],...n})}return this.bump(),n}async regenerateTitle(t){const s=await this.#a(`/api/sessions/${t}/title/regenerate`,{method:"POST"}),n=s.info,i=this.byId.get(t);i&&(i.info={...i.info,...n});for(const r of[this.sessions,this.cold,this.archived]){const a=r.findIndex(l=>l.id===t);a>=0&&(r[a]={...r[a],...n})}return this.bump(),s}async resume(t){if(this.#u(t),this.setActive(t),!this.#_.has(t)){this.#_.add(t),this.#u(t).resuming=!0,this.bump();try{const s=await this.#a(`/api/sessions/${t}/resume`,{method:"POST"},{timeoutMs:12e4,retry:!1});this.#u(t).info=s,this.sessions.some(n=>n.id===t)||(this.sessions=[s,...this.sessions]),this.cold=this.cold.filter(n=>n.id!==t),await this.loadHistory(t)}catch(s){const n=s.httpStatus,i=s.httpBody;if(n===409&&(i?.code==="home_mismatch"||i?.code==="context_missing")){const r=this.sessions.find(a=>a.id===t)??this.cold.find(a=>a.id===t)??this.archived.find(a=>a.id===t);this.blocked={id:t,title:r?.title??t,code:i.code,sessionHome:i.sessionHome??null,rowHome:i.rowHome??null},this.bump();return}this.#m(!1,`恢复失败:${String(s.message??s)}`)}finally{this.#_.delete(t),this.#u(t).resuming=!1,this.bump()}}}async restart(t){try{const s=await this.#a(`/api/sessions/${t}/restart`,{method:"POST"},{timeoutMs:12e4,retry:!1}),n=this.#u(t);n.info={...n.info,...s};for(const i of[this.sessions,this.cold,this.archived]){const r=i.findIndex(a=>a.id===t);r>=0&&(i[r]={...i[r],...s})}this.bump()}catch(s){const n=s.httpStatus,i=s.httpBody;if(n===409&&(i?.code==="home_mismatch"||i?.code==="context_missing")){const r=this.sessions.find(a=>a.id===t);this.blocked={id:t,title:r?.title??t,code:i.code,sessionHome:i.sessionHome??null,rowHome:i.rowHome??null},this.bump();return}this.#m(!1,`重启 agent 进程失败:${String(s.message??s)}`)}}dismissBlocked(){this.blocked=null,this.bump()}deleteBlocked(){const t=this.blocked;this.blocked=null,t&&this.purgeCold(t.id),this.bump()}purgeCold(t){this.sessions=this.sessions.filter(s=>s.id!==t),this.cold=this.cold.filter(s=>s.id!==t),this.archived=this.archived.filter(s=>s.id!==t),this.byId.delete(t),this.bump(),this.#a(`/api/sessions/${t}`,{method:"DELETE"}).catch(()=>this.refreshRows()).then(()=>this.refreshRows())}async setArchived(t,s){try{const n=await this.#a(`/api/sessions/${t}/${s?"archive":"unarchive"}`,{method:"POST"}),i=this.byId.get(t);return i&&(i.info={...i.info,...n}),s?(this.sessions=this.sessions.filter(r=>r.id!==t),this.cold=this.cold.filter(r=>r.id!==t),this.archived.some(r=>r.id===t)||(this.archived=[n,...this.archived]),this.activeId===t&&this.#R()):(this.archived=this.archived.filter(r=>r.id!==t),!this.sessions.some(r=>r.id===t)&&!this.cold.some(r=>r.id===t)&&(this.cold=[n,...this.cold])),this.bump(),n}catch(n){return this.#m(!1,`${s?"归档":"取消归档"}失败:${String(n.message??n)}`),null}}async unarchiveAndResume(t){await this.setArchived(t,!1),await this.resume(t)}#R(){const t=this.sessions[0]??this.cold[0]??this.archived[0]??null;this.activeId=t?.id??null,this.#b(this.activeId),t&&!this.sessions.some(s=>s.id===t.id)&&this.loadHistory(t.id)}#A(t,s,n,i,r,a){const l=t.plan;if(!l){t.plan={key:`plan-${t.turn}`,items:s,terminal:n,explanation:r,at:i,turn:t.turn,title:a??void 0};return}if(l.turn===t.turn){l.items=s,l.terminal=n,l.explanation=r,a!==void 0&&(l.title=a??void 0);return}const c=t.turnStart>0&&t.turnStart<=t.msgs.length?t.turnStart:t.msgs.length;t.msgs.splice(c,0,{key:l.key,kind:"plan",items:l.items,terminal:l.terminal,explanation:l.explanation,at:l.at,title:l.title}),t.blocks=e0(t.msgs),t.turnStart=Math.min(t.turnStart+1,t.msgs.length),t.plan={key:`plan-${t.turn}`,items:s,terminal:n,explanation:r,at:i,turn:t.turn,title:a??void 0}}#j(t,s){this.#A(t,s.items.map(n=>({content:n.content,status:n.status,priority:n.priority})),s.terminal??void 0,s.updatedAt,s.explanation??void 0,s.title?.trim()||null)}async#K(t){try{const{plan:s}=await this.#a(`/api/sessions/${t.info.id}/plan`);if(!s)return;this.#j(t,s),this.bump()}catch{}}#u(t){let s=this.byId.get(t);return s||(s={info:this.sessions.find(n=>n.id===t)??{id:t},msgs:[],notes:[],perms:[],busy:!1,busySince:null,loaded:!1,hasOlder:!1,loadingOlder:!1,minSeq:null,lastAt:Date.now(),rev:0,seen:new Set,blocks:new Map,plan:null,turn:0,turnStart:0,queue:this.#N(t)},this.byId.set(t,s)),s}apply(t){switch(t.t){case"hello":break;case"sessions":{this.sessions=t.sessions,t.cold&&(this.cold=t.cold),t.archived&&(this.archived=t.archived);const s=new Set([...t.sessions.map(n=>n.id),...this.cold.map(n=>n.id),...this.archived.map(n=>n.id)]);for(const n of[...t.sessions,...this.cold,...this.archived]){const i=this.#u(n.id);i.info={...i.info,...n}}if(t.background){const n=new Set(t.background.map(i=>i.sessionId));for(const i of t.background)this.#u(i.sessionId).background=i.tasks;for(const[i,r]of this.byId)!n.has(i)&&r.background?.length&&(r.background=[])}if(t.pending){const n=new Map;for(const i of t.pending){const r=n.get(i.sessionId);r?r.push(i):n.set(i.sessionId,[i])}for(const[i,r]of n)this.#u(i).perms=r;for(const i of this.byId.values())n.has(i.info.id)||(i.perms=[]);this.#y()}for(const n of[...this.byId.keys()])s.has(n)||this.byId.delete(n);if(this.activeId&&!s.has(this.activeId)&&(this.activeId=null,this.#b(null)),!this.activeId&&s.size){const n=this.#I(),i=n&&s.has(n)?n:t.sessions[0]?.id??this.cold[0]?.id??this.archived[0]?.id;i&&(this.activeId=i,this.loadHistory(i))}for(const n of this.sessions)n.status==="ready"&&this.#s.get(n.id)?.length&&this.drainQueue(n.id);break}case"session":{t.session.cold===!0?(this.sessions=this.sessions.filter(s=>s.id!==t.session.id),this.cold=this.cold.map(s=>s.id===t.session.id?t.session:s),this.cold.some(s=>s.id===t.session.id)||this.cold.push(t.session)):(this.sessions=this.sessions.map(s=>s.id===t.session.id?t.session:s),this.sessions.some(s=>s.id===t.session.id)||this.sessions.push(t.session),this.cold=this.cold.filter(s=>s.id!==t.session.id)),this.#u(t.session.id).info=t.session,t.session.status==="ready"&&this.#W(t.session.id),t.session.status==="ready"&&this.#s.get(t.session.id)?.length&&this.drainQueue(t.session.id);break}case"messages":{const s=this.#u(t.sessionId);if(t.partial){for(const n of t.messages)this.#B(s,n,{resync:!0});s.lastAt=Date.now();break}s.seen.clear(),s.msgs=[],s.blocks.clear(),s.plan=null,s.turn=0,s.turnStart=0,this.#M(s);for(const n of t.messages)this.#B(s,n);s.loaded=!0;break}case"message":{const s=this.#u(t.message.sessionId),n=t.message.payload?.rejectedPrompt,i=t.message.payload?.pid;typeof i=="string"&&this.#r(i),t.message.kind==="meta"&&typeof n=="string"&&n.trim()&&this.enqueuePrompt(t.message.sessionId,n),this.#B(s,t.message,{delta:t.delta,n:t.n}),s.lastAt=Date.now(),this.lastSeq[t.message.sessionId]=Math.max(this.lastSeq[t.message.sessionId]??0,t.message.seq);break}case"status":{const s=this.#u(t.sessionId),n=Date.now(),i=s.notes[s.notes.length-1],r=s.msgs.length?s.msgs[s.msgs.length-1].key:null;i&&t.statusKind&&i.kind===t.statusKind?(i.text=t.text,i.afterKey=r):(s.notes.push({key:`st-${n}-${s.notes.length}`,kind:t.statusKind,text:t.text,at:n,afterKey:r}),s.notes.length>200&&s.notes.splice(0,s.notes.length-200)),s.lastAt=n;break}case"background":{this.#u(t.sessionId).background=t.tasks;break}case"turn-start":{const s=this.#u(t.sessionId);s.busy=!0,s.busySince=Date.now(),s.lastAt=Date.now(),s.trace=t.trace??null,this.#F(t.sessionId),this.#P(t.sessionId,t.pid);break}case"plan":{const s=this.#u(t.sessionId);this.#j(s,t.plan),s.lastAt=Date.now();break}case"speak":{const s=this.#u(t.sessionId),n={id:t.id,text:t.text,kind:t.kind,priority:t.priority,at:Date.now()};s.speaks=[...s.speaks??[],n].slice(-10);break}case"usage":{const s=this.#u(t.sessionId);s.info={...s.info,usage:t.usage},s.lastAt=Date.now();break}case"turn-end":{const s=this.#u(t.sessionId);if(s.busy=!1,t.sessionId!==this.activeId&&this.markUnread(t.sessionId),s.busySince=null,this.#M(s),t.error&&s.msgs.push({key:`err-${Date.now()}`,kind:"meta",text:t.error}),t.error?this.#O(t.sessionId):this.#F(t.sessionId),!t.error){const n=t.sessionId;window.setTimeout(()=>this.drainQueue(n),250)}break}case"permission":this.#u(t.request.sessionId).perms.push(t.request);break;case"permission-resolved":for(const s of this.byId.values())s.perms=s.perms.filter(n=>n.requestId!==t.requestId);this.#y();break;case"permission-expired":for(const s of this.byId.values())s.perms=s.perms.filter(n=>n.requestId!==t.requestId);this.#y(),this.#u(t.sessionId).msgs.push({key:`perm-exp-${t.requestId}`,kind:"meta",text:"这条审批已经过期:agent 等不到答复、先自己放过了(或它已经放弃这一轮)。你的点击没有生效。"});break;case"config-rejected":{const s=this.#u(t.sessionId),n=t.name||t.configId;s.msgs.push({key:`cfg-rej-${t.configId}-${Date.now()}`,kind:"meta",text:`${n} 这一档没生效:agent 没有接受「${t.value}」${t.actual?`,实际仍是「${t.actual}」`:""}。(模型只认它公布的那几档;换档位或换模型再试。)`});break}case"notify":{Si.handle(t.notice);break}case"error":{this.activeId&&this.#u(this.activeId).msgs.push({key:`e-${Date.now()}`,kind:"meta",text:t.error});break}}this.bump()}#M(t){for(let s=0;s<t.msgs.length;s++){const n=t.msgs[s];(n.kind==="agent"||n.kind==="thought")&&n.open&&(t.msgs[s]={...n,open:!1})}}#q(t){const s=t.msgs[t.msgs.length-1];s&&(s.kind==="agent"||s.kind==="thought")&&t.busy&&!s.open&&(t.msgs[t.msgs.length-1]={...s,open:!0})}#z(t,s){for(let n=0;n<t.length;n++){const i=t[n];i.kind==="thought"&&i.open&&i.key!==s&&(t[n]={...i,open:!1})}}#B(t,s,n){const i=n?.list??t.msgs,r=n?.index??t.blocks,a=n?.delta,l=s.payload;let c=null;const u=a!==void 0,h=(s.kind==="agent"||s.kind==="thought")&&Qv(s.kind,l)!==null;if(!(n?.resync===!0&&(s.kind==="tool"||s.kind==="plan"||s.kind==="user"||s.kind==="meta"||h)||s.kind==="tool"||s.kind==="meta"||s.kind==="note"||s.kind==="approval"||s.kind==="project-skills"||s.seq<=0||u)){if(t.seen.has(s.seq))return;t.seen.add(s.seq)}s.seq>0&&(t.minSeq==null||s.seq<t.minSeq)&&(t.minSeq=s.seq);const f=s.payload,m=typeof s.createdAt=="number"?s.createdAt:Date.now(),b=IR(f);switch(i[i.length-1],s.kind){case"user":if(i.some(v=>v.key===`m${s.seq}`))break;const _=f.origin??null;i.push({key:`m${s.seq}`,kind:"user",text:String(f.text??""),at:m,..._&&typeof _.sessionId=="string"?{from:{id:_.sessionId,title:String(_.title??"").trim()||"另一个会话"}}:{},files:Array.isArray(f.attachments)?f.attachments.map(v=>({kind:String(v.kind??""),name:String(v.name??"file")})):[]}),n?.list||(t.turn+=1,t.turnStart=i.length-1);break;case"agent":case"thought":{const v=s.kind,y=Qv(v,f),{at:w}=BN(i,r,{key:y,kind:v,text:b,delta:a,n:n?.n},(S,N)=>({key:S,kind:N.kind,text:N.text,open:!0,at:m})),x=i[w];a!==void 0&&t.info.status==="running"&&x&&(x.kind==="agent"||x.kind==="thought")&&!x.open&&(i[w]={...x,open:!0}),v==="thought"&&(c=i[w]?.key??null);break}case"note":{const v=`n${s.seq}`,y=typeof f.hits=="number"?f.hits:void 0,w={key:v,kind:"note",category:String(f.category??""),text:typeof f.text=="string"?f.text:"",hits:y,at:m,items:Array.isArray(f.items)?f.items.filter(S=>S&&typeof S.text=="string"&&S.text.trim()):void 0,truncated:f.truncated===!0},x=r.get(v);x!==void 0&&i[x]?.kind==="note"?i[x]=w:(i.push(w),r.set(v,i.length-1));break}case"approval":{const v=`p${s.seq}`,y=f.decision,w={key:v,kind:"approval",requestId:String(f.requestId??""),title:String(f.toolCallTitle??"tool call"),kind2:String(f.kind??"other"),path:typeof f.path=="string"?f.path:null,diff:f.diff??null,options:Array.isArray(f.options)?f.options:[],decision:y??null,at:m},x=r.get(v);x!==void 0&&i[x]?.kind==="approval"?i[x]=w:(i.push(w),r.set(v,i.length-1));break}case"project-skills":{const v=`s${s.seq}`,y={key:v,kind:"project-skills",root:String(f.root??""),count:typeof f.count=="number"?f.count:0,text:String(f.text??""),state:String(f.state??"ask"),at:m},w=r.get(v);w!==void 0&&i[w]?.kind==="project-skills"?i[w]=y:(i.push(y),r.set(v,i.length-1));break}case"turn-usage":{const v=`u${s.seq}`,y=S=>typeof S=="number"&&Number.isFinite(S)?S:0,w=S=>typeof S=="number"&&Number.isFinite(S)?S:null,x={key:v,kind:"turn-usage",available:f.available!==!1,input:y(f.input),output:y(f.output),thought:y(f.thought),cacheRead:w(f.cacheRead),cacheWrite:w(f.cacheWrite),total:y(f.total),durationMs:typeof f.durationMs=="number"?f.durationMs:void 0,cacheHitPercent:typeof f.cacheHitPercent=="number"?f.cacheHitPercent:null,tps:typeof f.tps=="number"?f.tps:null,at:m};r.get(v)===void 0&&(i.push(x),r.set(v,i.length-1));break}case"tool":{const v=String(f.toolCallId??s.toolCallId??s.seq),y=i.find(E=>E.kind==="tool"&&E.toolCallId===v),w=PR(f),x=LR(f),S=new Set((y?.changes??[]).map(E=>`${E.path}\0${E.oldText??""}\0${E.newText??""}\0${E.diffText??""}`)),N=zN(f).filter(E=>!S.has(`${E.path}\0${E.oldText??""}\0${E.newText??""}\0${E.diffText??""}`)),R=N.length?[...y?.changes??[],...N]:y?.changes;if(y){const E=i.indexOf(y),M={...y,title:f.title?String(f.title):y.title,status:f.status?String(f.status):y.status,detail:w??y.detail,input:x??y.input,changes:R};E>=0&&(i[E]=M)}else i.push({key:`tc-${v}`,kind:"tool",toolCallId:v,at:m,title:String(f.title??"tool call"),status:String(f.status??"pending"),kind2:String(f.kind??""),detail:w,input:x,changes:R});break}case"plan":{const v=f._meta??{},y=(f.entries??[]).map(S=>({content:String(S?.content??""),status:String(S?.status??"pending"),priority:S?.priority})),w=typeof f._slotPlanTerminal=="string"?f._slotPlanTerminal:void 0,x=typeof v["agentus/explanation"]=="string"?String(v["agentus/explanation"]):void 0;if(n?.list){const S=i.find(N=>N.kind==="plan");if(S&&S.kind==="plan"){const N=i.indexOf(S);i[N]={...S,items:y,terminal:w,explanation:x}}else i.push({key:`m${s.seq}`,kind:"plan",items:y,terminal:w,explanation:x,at:m});break}this.#A(t,y,w,m,x);break}case"meta":if(i.some(v=>v.key===`m${s.seq}`))break;i.push({key:`m${s.seq}`,kind:"meta",text:b||JSON.stringify(f)});break}this.#z(i,c),this.lastSeq[t.info.id]=Math.max(this.lastSeq[t.info.id]??0,s.seq),t.rev+=1,t.lastAt=Date.now()}}function IR(e){const t=e.content;return t?.type==="text"&&typeof t.text=="string"?t.text:""}function PR(e){const s=r=>r.length>4e3?`${r.slice(0,4e3)}
43
+ `)){if(i.startsWith("+++ ")){const r=i.slice(4).trim().replace(/^b\//,"").replace(/\t.*$/,"");r&&r!=="/dev/null"&&(t=r);continue}i.startsWith("--- ")||(i.startsWith("+")?s++:i.startsWith("-")&&n++)}return t?{path:t,insertions:s,deletions:n}:null}function zN(e){const t=e??{},s=Array.isArray(t.content)?t.content:[],n=[],i=new Set,r=a=>{i.has(a.path)||(i.add(a.path),n.push(a))};for(const a of s){if(!a||typeof a!="object")continue;if(of(a.path)&&a.path&&(a.oldText!=null||a.newText!=null||a.type==="diff")){r({path:a.path,oldText:a.oldText??"",newText:a.newText??""});continue}const l=of(a.text)?a.text:of(a.content?.text)?a.content.text:"";if(!l)continue;const c=RS(l);c&&r({path:c.path,diffText:l})}return n}function HN(e){const t=[],s=new Map;for(const n of e){const i=s.get(n.path);if(!i){t.push(n.path),s.set(n.path,{first:n,last:n,edits:1,diffText:n.diffText});continue}i.last=n,i.edits++,n.oldText!=null||n.newText!=null?i.diffText=void 0:i.diffText||(i.diffText=n.diffText)}return t.map(n=>{const{first:i,last:r,edits:a,diffText:l}=s.get(n),c={path:n,name:FN(n),edits:a};if(i.oldText!=null||r.newText!=null){const u=i.oldText??"",h=r.newText??r.oldText??"",d=s_(u,h);return{...c,insertions:d.filter(p=>p.kind==="add").length,deletions:d.filter(p=>p.kind==="del").length,oldText:u,newText:h}}if(l){const u=RS(l);return{...c,insertions:u?.insertions??0,deletions:u?.deletions??0,oldText:"",newText:"",diffText:l}}return{...c,insertions:0,deletions:0,oldText:"",newText:""}})}function UN(e){let t=null,s=!1,n=[];function i(){const a=n;n=[];for(const l of a)l()}async function r(){if(!s){s=!0;try{for(;t;){const a=t;t=null;try{await e(a)}catch{}}}finally{s=!1,i()}}}return{push(a){t=a,r()},hush(){t=null,s||i()},get speaking(){return s},get waiting(){return t},settled(){return!s&&!t?Promise.resolve():new Promise(a=>{n.push(a)})}}}const jS="agentus.voice",kl={autoRead:!1,speakMode:"off",voiceURI:"",rate:1,lang:typeof navigator<"u"&&navigator.language?navigator.language:"en-US",serverTts:!1,stt:"auto"};function WN(){try{const e=localStorage.getItem(jS);if(!e)return{...kl};const t=JSON.parse(e),s=Number(t.rate);return{...kl,...t,rate:Number.isFinite(s)?Math.min(2,Math.max(.5,s)):kl.rate}}catch{return{...kl}}}function TS(e){try{localStorage.setItem(jS,JSON.stringify(e))}catch{}}const n_={provider:"browser",tts:{server:!1,model:null,voice:null},stt:{server:!1,streaming:!1,model:null,batchModel:null,language:null},hotwords:{fixed:0,dynamic:!1,limit:0}};let $o=null;const qp=new Set;async function Ch(e=!1){if($o&&!e)return $o;try{const t=await fetch("/api/voice",{credentials:"same-origin"});if(!t.ok)throw new Error(String(t.status));$o=await t.json()}catch{$o=n_}for(const t of qp)t();return $o}function li(){return $o??n_}function KN(e){return qp.add(e),()=>qp.delete(e)}const t0=80,AS=220,qN=2,VN=12,YN=3,s0=2,GN=400,af=0,JN=1,XN=4,ZN=400,QN=60;let lf=0;const Za=[];async function eR(e,t,s){lf>=YN&&await new Promise((n,i)=>{const r={priority:e,run:n};Za.push(r),Za.sort((l,c)=>l.priority-c.priority);const a=()=>{const l=Za.indexOf(r);l>=0&&Za.splice(l,1),i(new rn)};t&&(t.aborted?a():t.addEventListener("abort",a,{once:!0}))}),lf++;try{return await s()}finally{const n=Za.shift();n?n.run():lf--}}function n0(e,t=AS){const s=e.replace(/```[\s\S]*?```/g," code block ").replace(/[*_`#>|]/g," ").replace(/\s+/g," ").trim();if(!s)return[];const n=[];let i=s;for(;i.length>t;){const r=i.slice(0,t),a=Math.max(r.lastIndexOf(". "),r.lastIndexOf("。"),r.lastIndexOf("! "),r.lastIndexOf("? ")),l=Math.max(r.lastIndexOf(", "),r.lastIndexOf("; "),r.lastIndexOf(",")),c=a>t*.5?a+1:l>t*.5?l+1:r.lastIndexOf(" "),u=c>0?c:t;n.push(i.slice(0,u).trim()),i=i.slice(u).trim()}return i&&n.push(i),n.filter(Boolean)}let nn=null;function MS(){return window.AudioContext??window.webkitAudioContext??null}const Fl={echoCancellation:null,noiseSuppression:null};function tR(e,t){const s=e.getAudioTracks()[0],n=typeof s?.getSettings=="function"?s.getSettings():void 0;Fl.echoCancellation=typeof n?.echoCancellation=="boolean"?n.echoCancellation:t>0?!1:null,Fl.noiseSuppression=typeof n?.noiseSuppression=="boolean"?n.noiseSuppression:t>0?!1:null,Fl.echoCancellation===!1&&console.warn("[voice] microphone opened WITHOUT echo cancellation — the call may hear itself")}function i0(){return Fl.echoCancellation!==!1}function cf(){return{...Fl}}async function r0(e){const t=[e,{audio:{channelCount:1,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1}},{audio:!0}];let s=null;for(let n=0;n<t.length;n++)try{const i=await navigator.mediaDevices.getUserMedia(t[n]);return n>0&&console.warn("[voice] microphone opened only with degraded constraints",t[n]),tR(i,n),i}catch(i){s=i;const r=i?.name??"";if(r==="NotAllowedError"||r==="SecurityError")throw i;await new Promise(a=>setTimeout(a,250))}throw s instanceof Error?s:new Error(String(s))}async function sR(){const e=MS();if(!e)return!1;try{return nn=nn??new e,nn.state==="suspended"&&await nn.resume(),nn.state==="running"}catch{return!1}}const or={analyser:null};let cr=null;function o0(){const e=or.analyser;if(!e)return-1;const t=cr&&cr.length===e.fftSize?cr:new Float32Array(new ArrayBuffer(e.fftSize*4));cr=t,e.getFloatTimeDomainData(t);let s=0;for(let n=0;n<t.length;n++)s+=t[n]*t[n];return Math.min(1,Math.sqrt(s/t.length)*4)}function nR(){const e=or.analyser;if(!e)return-1;const t=cr&&cr.length===e.fftSize?cr:new Float32Array(new ArrayBuffer(e.fftSize*4));cr=t,e.getFloatTimeDomainData(t);let s=0;for(let n=0;n<t.length;n++)s+=t[n]*t[n];return Math.min(1,Math.sqrt(s/t.length))}function iR(e){const t=or.analyser;if(!t)return!1;const s=new Float32Array(new ArrayBuffer(t.fftSize*4));t.getFloatTimeDomainData(s);const n=Math.max(1,Math.floor(s.length/e.length));for(let i=0,r=0;i<e.length;i++,r+=n)e[i]=s[r]??0;return!0}class rn extends Error{constructor(){super("stopped"),this.name="SpeechStopped"}}async function DS(e,t){const s=MS();if(s)try{nn=nn??new s,nn.state==="suspended"&&await nn.resume();const i=await nn.decodeAudioData(await e.arrayBuffer());await new Promise((r,a)=>{const l=nn.createBufferSource();l.buffer=i;const c=nn.createAnalyser();c.fftSize=512,l.connect(c),c.connect(nn.destination),or.analyser=c,l.onended=()=>{or.analyser===c&&(or.analyser=null),r()};const u=()=>{or.analyser===c&&(or.analyser=null);try{l.stop()}catch{}a(new rn)};if(t){if(t.aborted)return u();t.addEventListener("abort",u,{once:!0})}l.start()});return}catch(i){if(i instanceof rn)throw i;if(t?.aborted)throw new rn}const n=URL.createObjectURL(e);try{await new Promise((i,r)=>{const a=new Audio(n),l=()=>{try{a.pause()}catch{}r(new rn)};a.onended=()=>{c(),i()},a.onerror=()=>{c(),r(new Error("audio playback failed"))};const c=()=>{t&&t.removeEventListener("abort",l)};if(t){if(t.aborted)return l();t.addEventListener("abort",l,{once:!0})}a.play().catch(u=>{c(),r(new Error(String(u?.message??u)))})})}finally{URL.revokeObjectURL(n)}}function Qa(){return typeof window<"u"&&"speechSynthesis"in window}class rR{#e={speakingId:null,speaking:!1,error:"",note:""};#l=new Set;#i=null;#s=0;#o=!1;#t=[];#n=new Set;subscribe=t=>(this.#l.add(t),()=>this.#l.delete(t));getSnapshot=()=>this.#e;#c(t){this.#e={...this.#e,...t};for(const s of this.#l)s()}subscribeVoices=t=>(this.#n.add(t),()=>this.#n.delete(t));voices=()=>this.#t;init(){if(!Qa())return;const t=()=>{const i=window.speechSynthesis.getVoices();if(i.length!==this.#t.length){this.#t=i;for(const r of this.#n)r()}};t(),window.speechSynthesis.addEventListener("voiceschanged",t);let s=0;const n=window.setInterval(()=>{s+=1,t(),(this.#t.length||s>40)&&window.clearInterval(n)},250);window.addEventListener("pointerdown",t,{once:!0})}pickVoice(t){const s=this.#t.length?this.#t:Qa()?window.speechSynthesis.getVoices():[];if(!s.length)return null;if(t.voiceURI){const r=s.find(a=>a.voiceURI===t.voiceURI);if(r)return r}const n=t.lang.toLowerCase(),i=n.split("-")[0];return s.find(r=>r.lang.toLowerCase()===n)??s.find(r=>r.lang.toLowerCase().startsWith(i))??s.find(r=>r.default)??s[0]}async speak(t,s,n){const i=String(t??"").trim();if(!i)return;this.stop();const r=++this.#s;this.#o=!1;const a=n.serverTts&&li().tts.server,l=n0(i,a?t0:AS);if(!l.length)return;const c=new AbortController;this.#i=c,this.#c({error:"",note:"",speakingId:s,speaking:!0});try{a?await this.#v(l,n,c.signal):await this.#h(l,n,c.signal)}catch(u){if(this.#o||r!==this.#s||u instanceof rn||u?.name==="AbortError")return;if(n.serverTts&&Qa()){this.#c({note:`服务端语音这一句失败了(${String(u?.message??u)}),已改用浏览器语音`});try{await this.#h(l,n,c.signal);return}catch(h){if(this.#o||h instanceof rn)return;this.#c({error:String(h?.message??h)})}}else this.#c({error:String(u?.message??u)})}finally{this.#i===c&&(this.#i=null),r===this.#s&&this.#c({speaking:!1,speakingId:null})}}async#h(t,s,n){if(!Qa())throw new Error("this browser has no speech synthesis");const i=window.speechSynthesis,r=this.pickVoice(s);for(const[a,l]of t.entries()){if(n?.aborted)throw new rn;if(await new Promise((c,u)=>{const h=new SpeechSynthesisUtterance(l);r?(h.voice=r,h.lang=r.lang):h.lang=s.lang,h.rate=s.rate,h.onend=()=>c(),h.onerror=d=>u(new Error(`speech error: ${d.error??"unknown"}`)),i.speak(h),a===0&&i.resume()}),n?.aborted)throw new rn;i.paused&&i.resume()}}#_(t,s,n,i){return eR(i,n,async()=>{const r=await fetch("/api/tts",{method:"POST",credentials:"same-origin",headers:{"content-type":"application/json"},signal:n,body:JSON.stringify({text:t,speed:s.rate})});if(!r.ok){const a=await r.json().catch(()=>({error:`${r.status}`}));throw new Error(a.error??`tts ${r.status}`)}return await r.blob()})}async#p(t,s,n,i=af){let r=null;for(let a=0;a<=s0;a++){if(n?.aborted)throw new rn;try{return await this.#_(t,s,n,i)}catch(l){if(l instanceof rn||l?.name==="AbortError"||n?.aborted)throw l;r=l,a<s0&&await new Promise(c=>{window.setTimeout(c,GN*(a+1))})}}throw r instanceof Error?r:new Error(String(r))}#d=new Map;#f(t,s){return`${s.rate}|${li().tts.voice??""}|${t}`}prefetch(t,s){if(!(s.serverTts&&li().tts.server))return;const n=String(t??"").trim();if(n)for(const i of n0(n,t0)){const r=this.#f(i,s);if(this.#d.has(r))continue;const a=this.#p(i,s,void 0,JN);for(a.catch(()=>{}),this.#d.set(r,a);this.#d.size>VN;){const l=this.#d.keys().next().value;if(l===void 0)break;this.#d.delete(l)}}}async#v(t,s,n){const i=[],r=a=>{const l=this.#f(a,s),c=this.#d.get(l);if(c)return this.#d.delete(l),c.catch(()=>this.#p(a,s,n,af));const u=this.#p(a,s,n,af);return u.catch(()=>{}),u};for(let a=0;a<t.length;a++){if(n.aborted)throw new rn;for(;i.length<Math.min(qN,t.length-a);)i.push(r(t[a+i.length]));if(await DS(await i.shift(),n),n.aborted)throw new rn}}stop(){this.#o=!0,this.#i?.abort(),this.#i=null,Qa()&&window.speechSynthesis.cancel(),this.#e.speaking&&this.#c({speaking:!1,speakingId:null})}}const Ft=new rR;Ft.init();function dd(){return g.useSyncExternalStore(Ft.subscribe,Ft.getSnapshot)}const el=new Set,oR=1024,IS=UN(e=>Ft.speak(e.text,e.key,Hn));function uc(){IS.hush(),Ft.stop()}function aR(e){IS.push({key:e.key,text:e.text})}let i_=!1;function a0(e){i_=e}function Eh(){return i_}function lR(e,t,s){if(i_||!s||el.has(e))return!1;for(el.add(e);el.size>oR;){const n=el.values().next().value;if(n===void 0)break;el.delete(n)}return!0}function PS(){const e=window;return e.SpeechRecognition??e.webkitSpeechRecognition??null}function Vp(){return!!PS()}function LS(){const e=window.AgentusMic;return e&&typeof e.start=="function"&&typeof e.stop=="function"?e:null}function OS(){const e=LS();if(!e)return!1;try{return!!e.available()}catch{return!1}}function cR(){return OS()||typeof navigator.mediaDevices?.getUserMedia=="function"}function uR(){return typeof window<"u"&&!window.isSecureContext?"当前页面是明文 http,浏览器不允许网页录音。请改用 https 入口访问(在服务前放一层终结 TLS 的反代或隧道),或走本机 localhost;手机上也可以用 Agentus app。":"this browser cannot record audio"}function hR(){return new Promise(e=>{const t=document.createElement("input");t.type="file",t.accept="audio/*",t.setAttribute("capture","microphone"),t.style.position="fixed",t.style.left="-9999px";let s=!1;const n=i=>{s||(s=!0,t.remove(),e(i))};t.onchange=()=>n(t.files?.[0]??null),window.addEventListener("focus",()=>{window.setTimeout(()=>n(t.files?.[0]??null),600)},{once:!0}),document.body.appendChild(t),t.click()})}class dR{#e={status:"idle",text:"",interim:"",error:"",engine:null,seconds:0};#l=new Set;#i=null;#s=null;#o=[];#t=null;#n=null;#c=null;#h=null;#_=null;#p=null;#d="";#f=0;#v=0;#b=new Float32Array(256);#D=null;#x=!0;#I;#k=!1;#a=0;#m=[];#S=null;#C=0;#y="";#w=!1;#E=()=>{const t=globalThis.__asFeed;return t&&typeof t=="object"?t:null};level=()=>{const t=this.#E();if(!t)return this.#f;const s=Number(t.level);return Number.isFinite(s)?s:0};levelRms=()=>{const t=this.#E();if(!t)return this.#v;const s=Number(t.rms??(Number.isFinite(Number(t.level))?Number(t.level)/6:NaN));return Number.isFinite(s)?Math.max(0,s):0};wave=()=>this.#b;setVadTap=t=>{this.#D=t};setRelay(t){if(this.#x=t,!t){this.#w=!0,this.#$();return}this.#w=!1,this.#k&&this.#N()}#$(){this.#S!==null&&(window.clearTimeout(this.#S),this.#S=null);const t=this.#n;if(this.#n=null,this.#m.length=0,!!t){t.onmessage=null,t.onerror=null,t.onclose=null;try{t.close()}catch{}}}resetText(){this.#d="",this.#r({text:"",interim:""})}commitForTest(t){this.#d=`${this.#d}${t}`.replace(/\s+/g," ").trim(),this.#r({status:"idle",text:this.#d,interim:""})}#T(t){let s=0;for(let a=0;a<t.length;a++)s+=t[a]*t[a];const n=Math.sqrt(s/t.length),i=Math.min(1,n*6);this.#f=i>this.#f?this.#f+(i-this.#f)*.6:this.#f*.72+i*.28,this.#v=n>this.#v?this.#v+(n-this.#v)*.6:this.#v*.72+n*.28,this.#D?.(t);const r=Math.max(1,Math.floor(t.length/this.#b.length));for(let a=0,l=0;a<this.#b.length&&l<t.length;a++,l+=r)this.#b[a]=t[l]}subscribe=t=>(this.#l.add(t),()=>this.#l.delete(t));#P=null;getSnapshot=()=>{const t=this.#E();if(!t)return this.#e;const s=String(t.text??""),n=String(t.interim??""),i=this.#P;return i&&i.text===s&&i.interim===n&&i.status===this.#e.status&&i.error===this.#e.error&&i.engine===this.#e.engine&&i.seconds===this.#e.seconds?i:(this.#P={...this.#e,text:s,interim:n},this.#P)};#r(t){this.#e={...this.#e,...t};for(const s of this.#l)s()}async start(t,s){if(this.#e.status!=="idle"&&this.#e.status!=="error")return!1;uc();const n=++this.#a;this.#r({status:"idle",text:"",interim:"",error:"",seconds:0}),this.#d="";const i=this.#E();if(i)return this.#x=!0,this.#r({status:"listening",engine:"stream",error:"",text:String(i.text??""),interim:String(i.interim??"")}),!0;const r=t.stt,a=li().stt.server,l=li().stt.streaming,c=(r==="browser"||r==="auto")&&Vp();try{if(r==="stream"||r==="auto"&&l){if(!l)throw new Error("streaming STT is not configured on the server (settings → 语音)");return await this.#L(t,s,n),!0}return c?(this.#H(t),!0):a?(await this.#K(t,n),!0):(this.#r({status:"error",engine:null,error:(typeof window<"u"&&!window.isSecureContext&&!cR()?`${uR()} `:"")+(r==="server"||a?"no dictation available: this browser has no speech recognition and the server has no STT endpoint (AGENTUS_STT_BASE_URL)":"no dictation available in this browser — set the server STT endpoint or use Chromium/Edge")}),!1)}catch(u){return this.#R(n)||this.#r({status:"error",error:String(u?.message??u)}),!1}}#H(t){const s=PS();if(!s)throw new Error("speech recognition unavailable");const n=new s;n.lang=t.lang,n.continuous=!0,n.interimResults=!0,n.maxAlternatives=1;let i="";n.onstart=()=>this.#r({status:"listening",engine:"browser",error:""}),n.onresult=r=>{let a="";for(let l=r.resultIndex;l<r.results.length;l+=1){const c=r.results[l],u=c[0]?.transcript??"";c.isFinal?i+=u:a+=u}this.#r({text:i.trim(),interim:a.trim()})},n.onerror=r=>{const a=String(r?.error??"unknown");this.#r({status:"error",error:a==="not-allowed"||a==="service-not-allowed"?"microphone permission denied":a==="no-speech"?"heard nothing — try again closer to the microphone":`speech recognition failed: ${a}`})},n.onend=()=>{this.#e.status==="listening"&&this.#r({status:"idle",interim:""}),this.#i=null},this.#i=n,this.#r({status:"requesting",engine:"browser"});try{n.start()}catch(r){throw this.#i=null,new Error(String(r?.message??r))}}async#L(t,s,n){const i=OS()?LS():null;if(!i&&typeof navigator.mediaDevices?.getUserMedia!="function"){await this.#u(t);return}const r=window.AudioContext??window.webkitAudioContext;if(!i&&!r)throw new Error("this browser cannot process audio");this.#r({status:"requesting",engine:"stream",error:""}),this.#x=!0,this.#w=!1,this.#C=0,this.#y="",this.#I=s,this.#k=!0,this.#m.length=0,this.#N();const a=l=>this.#U(l);if(i?await this.#F(i,a,n):await this.#W(r,a,n),this.#R(n)){this.#A(),this.#O(),this.#r({status:"idle",interim:"",text:""});return}this.#r({status:"listening",engine:"stream",seconds:0}),this.#t=window.setInterval(()=>this.#r({seconds:this.#e.seconds+1}),1e3)}#U(t){const s=this.#n;s&&s.readyState===WebSocket.OPEN?s.send(t):this.#m.length<QN&&this.#m.push(t)}#N(){if(this.#n||!this.#k)return;const t=this.#I?`?sessionId=${encodeURIComponent(this.#I)}`:"",s=new WebSocket(`${location.protocol==="https:"?"wss":"ws"}://${location.host}/ws/asr${t}`);s.binaryType="arraybuffer",this.#n=s,s.onopen=()=>{this.#C=0,this.#y="";for(const n of this.#m)s.send(n);this.#m.length=0,this.#e.status!=="listening"&&this.#r({status:"listening",engine:"stream",error:""})},s.onmessage=n=>{let i;try{i=JSON.parse(String(n.data))}catch{return}i.t==="asr-partial"?this.#r({interim:String(i.text??"")}):i.t==="asr-final"?(this.#d=`${this.#d}${i.text??""}`.replace(/\s+/g," ").trim(),this.#r({text:this.#d,interim:""})):i.t==="asr-error"?this.#g(String(i.error??"streaming asr failed")):i.t==="asr-done"&&(this.#w||!this.#k||!this.#x?this.#j():this.#g("the recogniser ended the turn by itself"))},s.onerror=()=>this.#g("the streaming socket failed — is the server up?"),s.onclose=()=>{this.#n===s&&(this.#n=null),this.#g(this.#y||"the streaming socket failed — is the server up?")}}#g(t){if(!(!this.#k||this.#w||!this.#x)&&(this.#y||(this.#y=t),this.#S===null)){if(this.#C>=XN){this.#r({status:"error",error:this.#y}),this.#y="",this.#j();return}this.#C+=1,this.#S=window.setTimeout(()=>{this.#S=null,this.#N()},ZN*this.#C)}}async#W(t,s,n){const i=await r0({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}});if(this.#R(n)){for(const u of i.getTracks())u.stop();return}this.#_=i;const r=new t({sampleRate:16e3});this.#c=r;const a=r.createMediaStreamSource(i),l=r.createScriptProcessor(2048,1,1),c=r.createGain();c.gain.value=0,this.#h=l,l.onaudioprocess=u=>{const h=u.inputBuffer.getChannelData(0);if(this.#T(h),!this.#x)return;const d=BS(h,r.sampleRate,16e3);d.length&&s(d.buffer)},a.connect(l),l.connect(c),c.connect(r.destination)}async#F(t,s,n){let i="permission";for(let r=0;r<12&&(i=String(t.start(16e3)),!(i==="ok"||i==="already"));r++){if(i==="permission"){this.#r({status:"requesting",engine:"stream"}),await new Promise(a=>setTimeout(a,600));continue}throw new Error(`手机上的原生麦克风打不开(${i})`)}if(i!=="ok"&&i!=="already")throw new Error(`手机上的原生麦克风打不开(${i})`);if(this.#R(n)){try{t.stop()}catch{}return}this.#p=t,window.__asMic=r=>{const a=atob(r),l=a.length>>1,c=new Int16Array(l);for(let h=0;h<l;h++){const d=a.charCodeAt(2*h),p=a.charCodeAt(2*h+1);c[h]=(p<<8|d)<<16>>16}const u=new Float32Array(l);for(let h=0;h<l;h++)u[h]=c[h]/32768;this.#T(u),this.#x&&s(c.buffer)}}#O(){this.#$(),this.#k=!1,this.#w=!1,this.#C=0,this.#y="",this.#A(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#x=!0}#R(t){return t!==this.#a}#A(){if(this.#h){this.#h.onaudioprocess=null;try{this.#h.disconnect()}catch{}this.#h=null}if(this.#c&&(this.#c.close().catch(()=>{}),this.#c=null),this.#_){for(const t of this.#_.getTracks())t.stop();this.#_=null}if(this.#p){try{this.#p.stop()}catch{}this.#p=null}window.__asMic=void 0,this.#f=0,this.#b.fill(0)}#j(){this.#O(),this.#r({status:"idle",interim:""})}async#K(t,s){if(typeof navigator.mediaDevices?.getUserMedia!="function"){await this.#u(t);return}this.#r({status:"requesting",engine:"server",error:""});const n=await r0({audio:!0});if(this.#R(s)){for(const a of n.getTracks())a.stop();return}const i=MediaRecorder.isTypeSupported("audio/webm;codecs=opus")?"audio/webm;codecs=opus":"",r=new MediaRecorder(n,i?{mimeType:i}:void 0);this.#o=[],r.ondataavailable=a=>{a.data.size&&this.#o.push(a.data)},r.onstop=()=>{for(const a of n.getTracks())a.stop();this.#q(t)},this.#s=r,r.start(1e3),this.#r({status:"recording",engine:"server",seconds:0}),this.#t=window.setInterval(()=>this.#r({seconds:this.#e.seconds+1}),1e3)}async#u(t){this.#r({status:"requesting",engine:"server",error:""});const s=await hR();if(!s){this.#r({status:"idle",text:"",interim:"",error:""});return}await this.#M(t,s)}async#M(t,s){this.#r({status:"transcribing"});try{const n=await fetch(`/api/stt?language=${encodeURIComponent(t.lang)}`,{method:"POST",credentials:"same-origin",headers:{"content-type":s.type||"audio/webm"},body:s}),i=await n.json().catch(()=>({}));if(!n.ok)throw new Error(i.error??`stt ${n.status}`);this.#r({status:"idle",text:String(i.text??"").trim(),interim:""})}catch(n){this.#r({status:"error",error:String(n?.message??n)})}}async#q(t){this.#t&&(window.clearInterval(this.#t),this.#t=null);const s=new Blob(this.#o,{type:this.#o[0]?.type||"audio/webm"});if(this.#o=[],this.#s=null,!s.size){this.#r({status:"error",error:"nothing was recorded — check the microphone"});return}await this.#M(t,s)}stop(){if(this.#a+=1,this.#e.status==="requesting"){this.cancel();return}if(this.#i){try{this.#i.stop()}catch{}return}if(this.#n&&this.#n.readyState===WebSocket.OPEN){this.#A(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#w=!0,this.#r({status:"transcribing"});try{this.#n.send(JSON.stringify({t:"asr-stop"}))}catch{this.#j();return}window.setTimeout(()=>{this.#e.status==="transcribing"&&this.#j()},8e3);return}this.#s&&this.#s.state!=="inactive"&&this.#s.stop(),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#e.status==="listening"&&this.#r({status:"idle",interim:""})}cancel(){if(this.#a+=1,this.#i){try{this.#i.abort()}catch{}this.#i=null}this.#s&&this.#s.state!=="inactive"&&(this.#s.onstop=null,this.#s.stop(),this.#s=null),this.#t&&(window.clearInterval(this.#t),this.#t=null),this.#O(),this.#d="",this.#o=[],this.#r({status:"idle",text:"",interim:"",error:"",seconds:0})}consume(){const t=this.#e.text.trim();return this.#r({status:"idle",text:"",interim:"",seconds:0}),t}setOwner(t){this.#z=t}owns(t){return this.#z===t}#z="chat"}function BS(e,t,s){if(t===s){const a=new Int16Array(e.length);for(let l=0;l<e.length;l+=1)a[l]=l0(e[l]);return a}const n=t/s,i=Math.max(0,Math.floor(e.length/n)),r=new Int16Array(i);for(let a=0;a<i;a+=1){const l=a*n,c=Math.floor(l),u=Math.min(c+1,e.length-1),h=l-c;r[a]=l0(e[c]*(1-h)+e[u]*h)}return r}function l0(e){const t=Math.round((Number.isFinite(e)?e:0)*32767);return t>32767?32767:t<-32768?-32768:t}const pe=new dR;typeof window<"u"&&(window.__asDictation=pe);function r_(){return g.useSyncExternalStore(pe.subscribe,pe.getSnapshot)}let Hn=WN();const Nh=new Set;async function $S(){try{const e=await fetch("/api/settings",{method:"PUT",credentials:"same-origin",headers:{"content-type":"application/json"},body:JSON.stringify({prefs:Hn})});return e.ok?"":(await e.json().catch(()=>({}))).error??`save failed (${e.status})`}catch(e){return String(e?.message??e)}}function c0(e){const t={...kl};if(!e||typeof e!="object")return t;const s=e;return{autoRead:typeof s.autoRead=="boolean"?s.autoRead:t.autoRead,speakMode:s.speakMode==="off"||s.speakMode==="reply"||s.speakMode==="brief"?s.speakMode:typeof s.autoRead=="boolean"&&s.autoRead?"reply":"off",voiceURI:typeof s.voiceURI=="string"?s.voiceURI:t.voiceURI,rate:Number.isFinite(Number(s.rate))?Math.min(2,Math.max(.5,Number(s.rate))):t.rate,lang:typeof s.lang=="string"&&s.lang?s.lang:t.lang,serverTts:typeof s.serverTts=="boolean"?s.serverTts:t.serverTts,stt:s.stt==="browser"||s.stt==="stream"||s.stt==="server"?s.stt:"auto"}}function fR(e){Hn=e,TS(Hn);for(const t of Nh)t()}async function pR(){try{const e=await fetch("/api/settings",{credentials:"same-origin"});if(!e.ok)return;const t=await e.json(),s=c0(t.prefs),n=c0(t.prefsDefaults);if(uf.every(r=>s[r]===n[r])&&uf.some(r=>Hn[r]!==s[r])){$S();return}uf.some(r=>Hn[r]!==s[r])&&fR(s)}catch{}}const uf=["speakMode","voiceURI","rate","lang","serverTts","stt"];function mR(e){const t={...Hn,...e},s=Number.isFinite(t.rate)?Math.min(2,Math.max(.5,t.rate)):1;Hn={...t,rate:s},TS(Hn);for(const n of Nh)n();$S()}function gR(){return Hn}function _o(){return[g.useSyncExternalStore(t=>(Nh.add(t),()=>Nh.delete(t)),()=>Hn),mR]}function _R(e,t,s){const[n]=_o(),i=(s??n.speakMode??(n.autoRead?"reply":"off"))==="reply",r=e?.length?e.map(a=>a.key).join(""):"";g.useEffect(()=>{if(!(!i||!t||!e?.length))for(const a of e)a.text.trim()&&lR(a.key,!0,i)&&aR(a)},[r,t,i])}function vR(e,t,s){const[n]=_o(),i=(s??n.speakMode??(n.autoRead?"reply":"off"))==="brief";g.useEffect(()=>{!i||!t||!e||!e.text.trim()||Ft.speak(e.text,e.key,n)},[e?.key,t,i])}const Fo=2,Yp="agentus.webnotify",tr={on:!0,sound:"chime",volume:.6};function yR(e){return e.available&&e.permission==="granted"&&e.enabled&&e.hidden}function bR(e,t,s,n){return e.sound!=="chime"||n||!s.enabled||!s.hidden?!1:t==="approval"||t==="agent_done"||t==="error"}function wR(e){return e==="approval"?[{freq:659.25,at:0,dur:.13},{freq:987.77,at:.15,dur:.28}]:e==="error"?[{freq:739.99,at:0,dur:.11},{freq:1046.5,at:.12,dur:.13},{freq:739.99,at:.27,dur:.26}]:[{freq:880,at:0,dur:.16},{freq:659.25,at:.2,dur:.3}]}function xR(e){try{return new URL(e,typeof location>"u"?"http://localhost/":location.href).searchParams.get("session")}catch{return null}}function SR(){try{const e=localStorage.getItem(Yp);if(!e)return{...tr,v:Fo};const t=JSON.parse(e),s={on:typeof t.on=="boolean"?t.on:tr.on,sound:t.sound==="chime"||t.sound==="silent"||t.sound==="default"?t.sound:tr.sound,volume:typeof t.volume=="number"&&Number.isFinite(t.volume)?Math.min(1,Math.max(0,t.volume)):tr.volume};if(t.v!==Fo&&s.sound==="default"&&(s.sound=tr.sound),t.v!==Fo){s.v=Fo;try{localStorage.setItem(Yp,JSON.stringify(s))}catch{}}return s}catch{return{...tr,v:Fo}}}function hu(){return typeof window>"u"||!("Notification"in window)?"no-api":window.isSecureContext?"ok":"insecure"}let hf=null;function FS(){if(typeof window>"u")return null;const e=window.AudioContext??window.webkitAudioContext;if(!e)return null;if(!hf)try{hf=new e}catch{return null}return hf}function ca(){const e=FS();e&&e.state==="suspended"&&e.resume()}function kR(e,t,s,n,i){const r=e.createOscillator(),a=e.createGain();r.type="sine",r.frequency.value=t,a.gain.setValueAtTime(1e-4,s),a.gain.linearRampToValueAtTime(i,s+.012),a.gain.exponentialRampToValueAtTime(1e-4,s+n),r.connect(a),a.connect(e.destination),r.start(s),r.stop(s+n+.02)}function Gp(e,t){const s=FS();if(!s)return;s.state==="suspended"&&s.resume();const n=s.currentTime+.01;for(const i of wR(t))kR(s,i.freq,n+i.at,i.dur,e)}const Jp=new Map;let Xp=0;async function zS(){if(typeof navigator>"u"||!("serviceWorker"in navigator))return null;try{return await navigator.serviceWorker.getRegistration()??null}catch{return null}}let Zp=null;function CR(e){Zp=e}function HS(e){if(!e)return;const t=xR(e);if(t&&Zp){Zp(t);return}location.assign(e)}const u0="/icons/icon-192.png";async function h0(e,t){const s={body:e.body,tag:e.noticeId,icon:u0,badge:u0,data:{open:e.open??null,noticeId:e.noticeId},renotify:!0,requireInteraction:!!e.sticky,silent:t.sound!=="default"},n=await zS();if(n&&typeof n.showNotification=="function")try{return await n.showNotification(e.title,s),Xp=Date.now(),!0}catch{}try{const i=new Notification(e.title,s);return i.onclick=()=>{HS(e.open),i.close()},Jp.set(e.noticeId,i),Xp=Date.now(),!0}catch{return!1}}async function d0(e){const t=Jp.get(e);t&&(t.close(),Jp.delete(e));const s=await zS();if(!(!s||typeof s.getNotifications!="function"))try{for(const n of await s.getNotifications({tag:e}))n.close()}catch{}}class ER{#e=tr;#l=null;#i=new Set;#s;constructor(){this.#e=typeof localStorage>"u"?{...tr}:SR(),this.#s=this.#o()}#o(){const t=hu();return{availability:t,permission:t==="ok"?Notification.permission:"unavailable",prefs:this.#e,last:this.#l}}#t(){this.#s=this.#o();for(const t of this.#i)t()}subscribe=t=>(this.#i.add(t),()=>this.#i.delete(t));getSnapshot=()=>this.#s;setPrefs(t){this.#e={...this.#e,...t},t.volume!==void 0&&(this.#e.volume=Math.min(1,Math.max(0,t.volume)));try{localStorage.setItem(Yp,JSON.stringify({...this.#e,v:Fo}))}catch{}this.#t()}async requestPermission(){if(hu()!=="ok")return"unavailable";ca();try{const t=await Notification.requestPermission();return this.#t(),this.#o().permission}catch{return this.#o().permission}}handle(t){if(t.op==="dismiss"){d0(t.noticeId);return}const s=hu(),n={available:s==="ok",permission:s==="ok"?Notification.permission:"unavailable",enabled:this.#e.on,hidden:typeof document>"u"?!1:document.hidden},i={enabled:this.#e.on,hidden:typeof document>"u"?!1:document.hidden};bR(this.#e,t.kind,i,Eh())&&Gp(this.#e.volume,t.kind),yR(n)&&h0(t,this.#e).then(r=>{this.#l={title:t.title,at:Date.now(),drawn:r},this.#t()})}async test(){if(hu()!=="ok")return!1;ca();const t={op:"upsert",noticeId:`test:${Date.now()}`,kind:"agent_done",title:"测试通知",body:"这条通知能弹出来,就说明这台设备没问题",open:null,at:Date.now()},s=await h0(t,this.#e);return this.#l={title:t.title,at:Date.now(),drawn:s},this.#t(),this.#e.sound==="chime"&&!Eh()&&Gp(this.#e.volume,"agent_done"),s}async closeAll(t){for(const s of t)await d0(s)}lastDrawnAt(){return Xp}}const Si=new ER;function NR(){typeof navigator>"u"||!("serviceWorker"in navigator)||navigator.serviceWorker.addEventListener("message",e=>{const t=e.data;t?.t==="agentus:notify-open"&&HS(t.open??null)})}function RR(){return g.useSyncExternalStore(Si.subscribe,Si.getSnapshot)}class df extends Error{constructor(){super("unauthorized"),this.name="AuthRequired"}}const Qp="agentus.unread",jR=8e3,TR=8e3;function AR(){try{const e=localStorage.getItem(Qp),t=e?JSON.parse(e):[];return Array.isArray(t)?t.filter(s=>typeof s=="string"):[]}catch{return[]}}function MR(e){try{const t=[...e];t.length?localStorage.setItem(Qp,JSON.stringify(t)):localStorage.removeItem(Qp)}catch{}}class DR{sessions=[];cold=[];archived=[];byId=new Map;activeId=null;conn="connecting";net="ok";netError="";auth="unknown";authInfo=null;authError="";authBusy=!1;blocked=null;lastSeq={};ws=null;#e=0;#l=null;#i=[];#s=new Map;#o=new Map;#t=new Set;#n=new Map;#c=new Set;#h=new Set(AR());#_=new Set;#p=new Map;#d=new Set;#f=null;#v;#b(t){try{t?localStorage.setItem("agentus.active",t):localStorage.removeItem("agentus.active")}catch{}}#D(){try{return new URL(location.href).searchParams.get("session")}catch{return null}}#x(t){try{const s=new URL(location.href),n=t??null;if((s.searchParams.get("session")??null)===n)return;n?s.searchParams.set("session",n):s.searchParams.delete("session"),history.replaceState(history.state,"",s.toString())}catch{}}followUrl(){const t=this.#D();!t||t===this.activeId||this.byId.has(t)&&this.setActive(t)}#I(){const t=this.#D();if(t)return this.#b(t),t;try{return localStorage.getItem("agentus.active")}catch{return null}}#k=0;constructor(){this.#v=this.#w()}async#a(t,s,n){const i=n?.timeoutMs??15e3,r=n?.retry===!1?1:2;let a=null;for(let l=0;l<r;l++){const c=new AbortController,u=setTimeout(()=>c.abort(),i);try{const h=await fetch(t,{...s,signal:c.signal});if(clearTimeout(u),h.status===401)throw this.#S("会话已过期,请重新登录"),new df;const d=h.status===204?null:await h.json().catch(()=>null);if(!h.ok){const p=d?.error??`HTTP ${h.status}`,f=new Error(p);throw f.httpStatus=h.status,f.httpBody=d,f}return this.#m(!0,""),d}catch(h){if(clearTimeout(u),h instanceof df||h.httpStatus!==void 0)throw h;a=h;const d=h?.name==="AbortError"?`请求超时 ${i/1e3}s`:String(h?.message??h);if(l===r-1)throw this.#m(!1,`${d} (${t})`),new Error(d);await new Promise(p=>setTimeout(p,600))}}throw a instanceof Error?a:new Error(String(a))}#m(t,s){const n=t?"ok":"degraded";this.net===n&&this.netError===s||(this.net=n,this.netError=s,this.bump())}#S(t){const s=this.auth==="in";if(this.auth="out",this.authError=s?t:this.authError,this.ws){const n=this.ws;this.ws=null,n.onclose=null;try{n.close()}catch{}}this.conn="offline",(s||this.sessions.length)&&(this.sessions=[],this.cold=[],this.archived=[],this.byId.clear(),this.activeId=null,this.#b(null)),this.bump()}async checkAuth(){try{const t=await this.#a("/api/auth/me",void 0,{retry:!1,timeoutMs:8e3});if(this.authInfo=t,t.authEnabled&&!t.authenticated){this.#S(""),this.authError="";return}this.#e=0,this.auth="in",this.authError="",this.bump(),this.connect(),this.refreshRows()}catch(t){if(t instanceof df)return;const s=`无法连接服务端:${String(t.message??t)}`;if(this.auth==="in"){this.#m(!1,s),this.#C(Math.min(1e4,800*2**this.#e++));return}this.auth="out",this.authError=s,this.bump()}}#C(t){this.#l||(this.#l=setTimeout(()=>{this.#l=null,this.checkAuth()},t))}async login(t,s){if(this.authBusy)return!1;this.authBusy=!0,this.authError="",this.bump();try{const n=await fetch("/api/auth/login",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({username:t,password:s})});if(n.status===401)return this.authError="用户名或密码不正确",!1;if(n.status===429){const r=await n.json().catch(()=>({})),a=Math.ceil((r.retryAfterMs??3e4)/1e3);return this.authError=`尝试次数过多,请 ${a} 秒后再试`,!1}if(!n.ok)return this.authError=`登录失败:HTTP ${n.status}`,!1;const i=await n.json();return this.authInfo={authEnabled:!0,authenticated:!0,kind:"session",username:i.username,expiresAt:i.expiresAt??null,usingDefaultPassword:!!i.usingDefaultPassword},this.auth="in",this.authError="",this.bump(),this.connect(),!0}catch(n){return this.authError=`登录请求失败:${String(n.message??n)}`,!1}finally{this.authBusy=!1,this.bump()}}async logout(){try{await fetch("/api/auth/logout",{method:"POST"})}catch{}this.#S(""),this.authError="",this.bump()}subscribe=t=>(this.#d.add(t),()=>this.#d.delete(t));getSnapshot=()=>this.#v;markPermAnswered(t,s,n=!0){this.#p.set(t,{label:s,at:Date.now(),armed:n}),this.bump()}permAnswer(t){const s=this.#p.get(t);if(s)return{label:s.label,at:s.at,lapsed:s.armed&&Date.now()-s.at>jR}}#y(){if(!this.#p.size)return;const t=new Set;for(const s of this.byId.values())for(const n of s.perms)t.add(n.requestId);for(const s of[...this.#p.keys()])t.has(s)||this.#p.delete(s)}#w(){return{sessions:this.sessions,cold:this.cold,archived:this.archived,activeId:this.activeId,active:this.activeId?this.byId.get(this.activeId):void 0,conn:this.conn,net:this.net,netError:this.netError,auth:this.auth,authInfo:this.authInfo,authError:this.authError,authBusy:this.authBusy,blocked:this.blocked,unread:new Set([...this.#c,...this.#h]),version:this.#k}}bump(){this.#k++,this.#f==null&&(typeof requestAnimationFrame=="function"?this.#f=requestAnimationFrame(()=>{this.#f=null,this.#E()}):typeof setTimeout=="function"?this.#f=setTimeout(()=>{this.#f=null,this.#E()},0):this.#E()),this.#$()}#E(){this.#f!=null&&(typeof cancelAnimationFrame=="function"?cancelAnimationFrame(this.#f):typeof clearTimeout=="function"&&clearTimeout(this.#f),this.#f=null);for(const t of this.byId.values())t.busy=t.info.status==="running";this.#v=this.#w();for(const t of this.#d)t()}#$(){typeof document>"u"||!document.hidden||this.#f!=null&&this.#E()}connect(){if(this.auth==="out")return;const t=location.protocol==="https:"?"wss":"ws",s=new WebSocket(`${t}://${location.host}/ws`);this.ws=s,s.onopen=()=>{for(this.conn="online",this.net="ok",this.netError="",this.#e=0,s.send(JSON.stringify({t:"resume",lastSeq:this.lastSeq}));this.#i.length;){const n=this.#i.shift();try{s.send(JSON.stringify(n))}catch{this.#i.unshift(n);break}}this.bump(),this.refreshRows(),window.setTimeout(()=>this.drainPersistedQueues(),700)},s.onmessage=n=>this.apply(JSON.parse(n.data)),s.onclose=()=>{if(this.conn="offline",this.bump(),this.auth==="out")return;const n=Math.min(1e4,800*2**this.#e++);this.#C(n)},s.onerror=()=>s.close()}sendPrompt(t,s,n=[]){!s.trim()&&!n.length||this.#T(t,{text:s,attachments:n})}#T(t,s){const n=`p-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,i={t:"prompt",sessionId:t,text:s.text,attachments:s.attachments,pid:n,...s.interrupt?{interrupt:!0}:{}};if(!this.send(i)){if(s.rowId){const l=this.#s.get(t)??[];this.#g(t,l.map(c=>c.id===s.rowId?{...c,inflight:!1}:c))}return}const a=setTimeout(()=>this.#H(n),TR);this.#n.set(n,{sessionId:t,pid:n,text:s.text,attachments:s.attachments,rowId:s.rowId,timer:a})}#P(t,s){const n=s?this.#n.get(s):[...this.#n.values()].find(r=>r.sessionId===t);if(!n)return;for(const r of[...this.#n.values()])r.sessionId===t&&(clearTimeout(r.timer),this.#n.delete(r.pid));clearTimeout(n.timer),this.#n.delete(n.pid);const i=this.#s.get(t)??[];i.some(r=>r.pid===n.pid)&&this.#g(t,i.filter(r=>r.pid!==n.pid))}#r(t){const s=this.#n.get(t);s&&(clearTimeout(s.timer),this.#n.delete(t))}#H(t){const s=this.#n.get(t);if(!s)return;this.#n.delete(t),this.#t.delete(s.sessionId);const n=this.#s.get(s.sessionId)??[];s.rowId&&n.some(i=>i.id===s.rowId)?this.#g(s.sessionId,n.map(i=>i.id===s.rowId?{...i,inflight:!1,unsure:!0}:i)):n.some(i=>i.pid===s.pid)||this.#g(s.sessionId,[...n,{id:`q-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,text:s.text,attachments:s.attachments,at:Date.now(),unsure:!0,pid:s.pid}]),this.#m(!1,"消息未确认送达 — 已放回队列,点 ↑ 重发")}send(t){return this.auth==="out"?(this.#m(!1,"未登录 — 请先登录再发送指令"),!1):this.ws?.readyState===WebSocket.OPEN?(this.ws.send(JSON.stringify(t)),!0):t.t==="prompt"?(this.enqueuePrompt(t.sessionId,t.text,t.attachments??[]),this.#m(!1,"连接已断开 — 消息已排队,重连后自动发送"),!1):t.t==="respond-permission"?(this.#i.push(t),this.#i.length>20&&this.#i.shift(),this.#m(!1,"连接已断开 — 指令已排队,重连后自动发送"),!1):(this.#m(!1,"连接已断开 — 该操作未能送达"),!1)}#L(t){return`agentus.queue.${t}`}#U(t){try{const s=localStorage.getItem(this.#L(t)),n=s?JSON.parse(s):[];return Array.isArray(n)?n.filter(i=>i&&typeof i.text=="string"&&i.text.trim()).map(i=>({id:String(i.id??`q-${i.at??Date.now()}`),text:i.text,attachments:i.attachments??[],at:i.at??Date.now(),...i.unsure?{unsure:!0,pid:typeof i.pid=="string"?i.pid:void 0}:{}})):[]}catch{return[]}}#N(t){const s=this.#s.get(t)??this.#U(t);return s.length&&this.#s.set(t,s),s}drainPersistedQueues(){try{for(let t=0;t<localStorage.length;t++){const s=localStorage.key(t);if(!s?.startsWith("agentus.queue."))continue;const n=s.slice(14);this.#N(n),this.drainQueue(n)}}catch{}}#g(t,s){s.length?this.#s.set(t,s):this.#s.delete(t);try{s.length?localStorage.setItem(this.#L(t),JSON.stringify(s)):localStorage.removeItem(this.#L(t))}catch{}const n=this.byId.get(t);n&&(n.queue=s),this.bump()}queueSetup(t,s){s.length&&this.#o.set(t,s)}#W(t){const s=this.#o.get(t);if(s?.length){this.#o.delete(t);for(const n of s)n.kind==="model"?this.send({t:"set-model",sessionId:t,modelId:n.value,fromReplay:!0}):n.kind==="mode"?this.send({t:"set-mode",sessionId:t,modeId:n.value}):this.send({t:"set-config",sessionId:t,configId:n.id,value:n.value})}}enqueuePrompt(t,s,n=[]){const i=this.#s.get(t)??[];this.#g(t,[...i,{id:`q-${Date.now()}-${Math.random().toString(36).slice(2,7)}`,text:s,attachments:n,at:Date.now()}])}sendToCold(t,s,n=[]){const i=this.#s.get(t)??this.#N(t),r=i[i.length-1],a=this.sessions.some(u=>u.id===t&&u.status==="ready"),l=!!(r&&r.text===s&&!a&&Date.now()-r.at<5e3),c=!s.trim()&&!n.length;!l&&!c&&this.enqueuePrompt(t,s,n),this.resume(t)}dropQueued(t,s){const n=this.#s.get(t)??[];this.#g(t,n.filter(i=>i.id!==s))}editQueued(t,s,n){const i=this.#s.get(t)??[],r=n.trim();this.#g(t,r?i.map(a=>a.id===s?{...a,text:r}:a):i.filter(a=>a.id!==s))}sendQueuedNow(t,s){const n=this.#s.get(t)??[],i=n.find(r=>r.id===s);i&&(this.#t.add(t),this.#g(t,n.map(r=>r.id===s?{...r,inflight:!0,unsure:!1}:r)),this.#T(t,{text:i.text,attachments:i.attachments,interrupt:!0,rowId:s}))}sendNow(t,s,n=[]){if(!s.trim()&&!n.length)return;this.#N(t),this.enqueuePrompt(t,s,n);const i=this.#s.get(t)??[],r=i[i.length-1];r&&this.sendQueuedNow(t,r.id)}drainQueue(t){const s=this.#s.get(t)??this.#N(t),n=s[0];!n||n.inflight||n.unsure||this.#t.has(t)||Qr(this.byId.get(t))||this.sessions.find(r=>r.id===t)?.status==="running"||(this.#g(t,s.map(r=>r.id===n.id?{...r,inflight:!0}:r)),this.#T(t,{text:n.text,attachments:n.attachments,interrupt:!0,rowId:n.id}))}#F(t){this.#t.delete(t);const s=this.#s.get(t)??[];s.some(n=>n.inflight)&&this.#g(t,s.filter(n=>!n.inflight))}#O(t){this.#t.delete(t);const s=this.#s.get(t)??[];s.some(n=>n.inflight)&&this.#g(t,s.map(n=>n.inflight?{...n,inflight:!1}:n))}setActive(t){this.activeId=t,this.#b(t),this.#x(t),this.clearUnread(t),this.#v=this.#w(),this.bump();const s=this.byId.get(t);s&&!s.loaded&&this.loadHistory(t)}markUnread(t){this.#c.has(t)||(this.#c=new Set(this.#c).add(t),this.bump())}clearUnread(t){if(!this.#c.has(t))return;const s=new Set(this.#c);s.delete(t),this.#c=s,this.bump()}isUnread(t){return this.#c.has(t)||this.#h.has(t)}toggleUnread(t){if(this.isUnread(t)){const s=new Set(this.#c);s.delete(t),this.#c=s;const n=new Set(this.#h);n.delete(t),this.#h=n}else this.#h=new Set(this.#h).add(t);MR(this.#h),this.bump()}async loadHistory(t){try{const{messages:s,hasOlder:n}=await this.#a(`/api/sessions/${t}/messages?tail=1`),i=this.#u(t);i.seen.clear(),i.msgs=[],i.blocks.clear(),i.minSeq=null,i.plan=null,i.turn=0,i.turnStart=0;for(const r of s)this.#B(i,r);i.loaded=!0,i.hasOlder=!!n,this.#M(i),this.#q(i),this.bump(),this.#K(i)}catch{}}async loadEarlier(t){const s=this.#u(t);if(s.loadingOlder||!s.hasOlder||s.minSeq==null)return 0;s.loadingOlder=!0,this.bump();try{const{messages:n,hasOlder:i}=await this.#a(`/api/sessions/${t}/messages?before=${s.minSeq}`),r=[],a=new Map;for(const c of n)this.#B(s,c,{list:r,index:a});const l=[];for(const c of r){const u=s.blocks.get(c.key),h=u===void 0?void 0:s.msgs[u];if(h&&h.kind===c.kind&&(c.kind==="agent"||c.kind==="thought")&&h.kind===c.kind){const d=h,p=c;if(p.text.length>d.text.length){const f=s.msgs.indexOf(d);f>=0&&(s.msgs[f]={...d,text:p.text})}continue}l.push(c)}return l.length&&(s.msgs=[...l,...s.msgs]),s.blocks=e0(s.msgs),s.hasOlder=!!i,l.length}catch{return-1}finally{s.loadingOlder=!1,this.bump()}}async loadBackends(){return await this.#a("/api/backends")}async createBackend(t){await this.#a("/api/backends",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}async updateBackend(t,s){await this.#a(`/api/backends/${encodeURIComponent(t)}`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(s)})}async deleteBackend(t){await this.#a(`/api/backends/${encodeURIComponent(t)}`,{method:"DELETE"})}async inspectBackend(t){return await this.#a(`/api/backends/${encodeURIComponent(t)}/inspect`,{method:"POST"},{timeoutMs:6e4,retry:!1})}async listEntries(t){return await this.#a(`/api/fs/dirs?files=1&path=${encodeURIComponent(t)}`)}async readFile(t){return await this.#a(`/api/fs/file?path=${encodeURIComponent(t)}`)}async statFile(t){return await this.#a(`/api/fs/stat?path=${encodeURIComponent(t)}`)}async writeFile(t,s,n){return await this.#a("/api/fs/file",{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify({path:t,content:s,...n?{ifHash:n}:{}})},{retry:!1})}async fork(t){const s=await this.#a(`/api/sessions/${t}/fork`,{method:"POST"},{timeoutMs:12e4,retry:!1});return this.sessions.some(n=>n.id===s.id)||(this.sessions=[s,...this.sessions]),this.cold=this.cold.filter(n=>n.id!==s.id),this.archived=this.archived.filter(n=>n.id!==s.id),this.setActive(s.id),s.id}async setModel(t,s){const n=await this.#a(`/api/sessions/${t}/model`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({modelId:s})},{timeoutMs:9e4,retry:!1}),i=this.byId.get(t);i&&(i.info={...i.info,...n});const r=this.sessions.findIndex(a=>a.id===t);return r>=0&&(this.sessions[r]={...this.sessions[r],...n}),this.bump(),n}async setContextLimit(t,s,n={}){const i=await this.#a(`/api/sessions/${t}/context-limit`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({limit:s,...n})}),r=this.byId.get(t);r&&(r.info={...r.info,...i});const a=this.sessions.findIndex(c=>c.id===t);a>=0&&(this.sessions[a]={...this.sessions[a],...i});const l=this.archived.findIndex(c=>c.id===t);l>=0&&(this.archived[l]={...this.archived[l],...i}),this.bump()}async setWorkspace(t,s){const n=await this.#a(`/api/sessions/${t}/workspace`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({path:s})}),i=this.byId.get(t);i&&(i.info={...i.info,...n});const r=this.sessions.findIndex(a=>a.id===t);r>=0&&(this.sessions[r]={...this.sessions[r],...n}),this.bump()}async createSession(t,s,n){const i=await this.#a("/api/sessions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({backend:t,cwd:s,title:n||void 0})},{retry:!1}),r=this.#u(i.id);return r.info={...r.info,...i},this.sessions.some(a=>a.id===i.id)||(this.sessions=[i,...this.sessions]),this.bump(),i.id}async refreshRows(){try{const{cold:t,archived:s}=await this.#a("/api/sessions");this.cold=t??[],this.archived=s??[],this.bump()}catch{}}async rename(t,s){const n=await this.#a(`/api/sessions/${t}/rename`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({title:s})}),i=this.byId.get(t);i&&(i.info={...i.info,...n});for(const r of[this.sessions,this.archived]){const a=r.findIndex(l=>l.id===t);a>=0&&(r[a]={...r[a],...n})}return this.bump(),n}async regenerateTitle(t){const s=await this.#a(`/api/sessions/${t}/title/regenerate`,{method:"POST"}),n=s.info,i=this.byId.get(t);i&&(i.info={...i.info,...n});for(const r of[this.sessions,this.cold,this.archived]){const a=r.findIndex(l=>l.id===t);a>=0&&(r[a]={...r[a],...n})}return this.bump(),s}async resume(t){if(this.#u(t),this.setActive(t),!this.#_.has(t)){this.#_.add(t),this.#u(t).resuming=!0,this.bump();try{const s=await this.#a(`/api/sessions/${t}/resume`,{method:"POST"},{timeoutMs:12e4,retry:!1});this.#u(t).info=s,this.sessions.some(n=>n.id===t)||(this.sessions=[s,...this.sessions]),this.cold=this.cold.filter(n=>n.id!==t),await this.loadHistory(t)}catch(s){const n=s.httpStatus,i=s.httpBody;if(n===409&&(i?.code==="home_mismatch"||i?.code==="context_missing")){const r=this.sessions.find(a=>a.id===t)??this.cold.find(a=>a.id===t)??this.archived.find(a=>a.id===t);this.blocked={id:t,title:r?.title??t,code:i.code,sessionHome:i.sessionHome??null,rowHome:i.rowHome??null},this.bump();return}this.#m(!1,`恢复失败:${String(s.message??s)}`)}finally{this.#_.delete(t),this.#u(t).resuming=!1,this.bump()}}}async restart(t){try{const s=await this.#a(`/api/sessions/${t}/restart`,{method:"POST"},{timeoutMs:12e4,retry:!1}),n=this.#u(t);n.info={...n.info,...s};for(const i of[this.sessions,this.cold,this.archived]){const r=i.findIndex(a=>a.id===t);r>=0&&(i[r]={...i[r],...s})}this.bump()}catch(s){const n=s.httpStatus,i=s.httpBody;if(n===409&&(i?.code==="home_mismatch"||i?.code==="context_missing")){const r=this.sessions.find(a=>a.id===t);this.blocked={id:t,title:r?.title??t,code:i.code,sessionHome:i.sessionHome??null,rowHome:i.rowHome??null},this.bump();return}this.#m(!1,`重启 agent 进程失败:${String(s.message??s)}`)}}dismissBlocked(){this.blocked=null,this.bump()}deleteBlocked(){const t=this.blocked;this.blocked=null,t&&this.purgeCold(t.id),this.bump()}purgeCold(t){this.sessions=this.sessions.filter(s=>s.id!==t),this.cold=this.cold.filter(s=>s.id!==t),this.archived=this.archived.filter(s=>s.id!==t),this.byId.delete(t),this.bump(),this.#a(`/api/sessions/${t}`,{method:"DELETE"}).catch(()=>this.refreshRows()).then(()=>this.refreshRows())}async setArchived(t,s){try{const n=await this.#a(`/api/sessions/${t}/${s?"archive":"unarchive"}`,{method:"POST"}),i=this.byId.get(t);return i&&(i.info={...i.info,...n}),s?(this.sessions=this.sessions.filter(r=>r.id!==t),this.cold=this.cold.filter(r=>r.id!==t),this.archived.some(r=>r.id===t)||(this.archived=[n,...this.archived]),this.activeId===t&&this.#R()):(this.archived=this.archived.filter(r=>r.id!==t),!this.sessions.some(r=>r.id===t)&&!this.cold.some(r=>r.id===t)&&(this.cold=[n,...this.cold])),this.bump(),n}catch(n){return this.#m(!1,`${s?"归档":"取消归档"}失败:${String(n.message??n)}`),null}}async unarchiveAndResume(t){await this.setArchived(t,!1),await this.resume(t)}#R(){const t=this.sessions[0]??this.cold[0]??this.archived[0]??null;this.activeId=t?.id??null,this.#b(this.activeId),t&&!this.sessions.some(s=>s.id===t.id)&&this.loadHistory(t.id)}#A(t,s,n,i,r,a){const l=t.plan;if(!l){t.plan={key:`plan-${t.turn}`,items:s,terminal:n,explanation:r,at:i,turn:t.turn,title:a??void 0};return}if(l.turn===t.turn){l.items=s,l.terminal=n,l.explanation=r,a!==void 0&&(l.title=a??void 0);return}const c=t.turnStart>0&&t.turnStart<=t.msgs.length?t.turnStart:t.msgs.length;t.msgs.splice(c,0,{key:l.key,kind:"plan",items:l.items,terminal:l.terminal,explanation:l.explanation,at:l.at,title:l.title}),t.blocks=e0(t.msgs),t.turnStart=Math.min(t.turnStart+1,t.msgs.length),t.plan={key:`plan-${t.turn}`,items:s,terminal:n,explanation:r,at:i,turn:t.turn,title:a??void 0}}#j(t,s){this.#A(t,s.items.map(n=>({content:n.content,status:n.status,priority:n.priority})),s.terminal??void 0,s.updatedAt,s.explanation??void 0,s.title?.trim()||null)}async#K(t){try{const{plan:s}=await this.#a(`/api/sessions/${t.info.id}/plan`);if(!s)return;this.#j(t,s),this.bump()}catch{}}#u(t){let s=this.byId.get(t);return s||(s={info:this.sessions.find(n=>n.id===t)??{id:t},msgs:[],notes:[],perms:[],busy:!1,busySince:null,loaded:!1,hasOlder:!1,loadingOlder:!1,minSeq:null,lastAt:Date.now(),rev:0,seen:new Set,blocks:new Map,plan:null,turn:0,turnStart:0,queue:this.#N(t)},this.byId.set(t,s)),s}apply(t){switch(t.t){case"hello":break;case"sessions":{this.sessions=t.sessions,t.cold&&(this.cold=t.cold),t.archived&&(this.archived=t.archived);const s=new Set([...t.sessions.map(n=>n.id),...this.cold.map(n=>n.id),...this.archived.map(n=>n.id)]);for(const n of[...t.sessions,...this.cold,...this.archived]){const i=this.#u(n.id);i.info={...i.info,...n}}if(t.background){const n=new Set(t.background.map(i=>i.sessionId));for(const i of t.background)this.#u(i.sessionId).background=i.tasks;for(const[i,r]of this.byId)!n.has(i)&&r.background?.length&&(r.background=[])}if(t.pending){const n=new Map;for(const i of t.pending){const r=n.get(i.sessionId);r?r.push(i):n.set(i.sessionId,[i])}for(const[i,r]of n)this.#u(i).perms=r;for(const i of this.byId.values())n.has(i.info.id)||(i.perms=[]);this.#y()}for(const n of[...this.byId.keys()])s.has(n)||this.byId.delete(n);if(this.activeId&&!s.has(this.activeId)&&(this.activeId=null,this.#b(null)),!this.activeId&&s.size){const n=this.#I(),i=n&&s.has(n)?n:t.sessions[0]?.id??this.cold[0]?.id??this.archived[0]?.id;i&&(this.activeId=i,this.loadHistory(i))}for(const n of this.sessions)n.status==="ready"&&this.#s.get(n.id)?.length&&this.drainQueue(n.id);break}case"session":{t.session.cold===!0?(this.sessions=this.sessions.filter(s=>s.id!==t.session.id),this.cold=this.cold.map(s=>s.id===t.session.id?t.session:s),this.cold.some(s=>s.id===t.session.id)||this.cold.push(t.session)):(this.sessions=this.sessions.map(s=>s.id===t.session.id?t.session:s),this.sessions.some(s=>s.id===t.session.id)||this.sessions.push(t.session),this.cold=this.cold.filter(s=>s.id!==t.session.id)),this.#u(t.session.id).info=t.session,t.session.status==="ready"&&this.#W(t.session.id),t.session.status==="ready"&&this.#s.get(t.session.id)?.length&&this.drainQueue(t.session.id);break}case"messages":{const s=this.#u(t.sessionId);if(t.partial){for(const n of t.messages)this.#B(s,n,{resync:!0});s.lastAt=Date.now();break}s.seen.clear(),s.msgs=[],s.blocks.clear(),s.plan=null,s.turn=0,s.turnStart=0,this.#M(s);for(const n of t.messages)this.#B(s,n);s.loaded=!0;break}case"message":{const s=this.#u(t.message.sessionId),n=t.message.payload?.rejectedPrompt,i=t.message.payload?.pid;typeof i=="string"&&this.#r(i),t.message.kind==="meta"&&typeof n=="string"&&n.trim()&&this.enqueuePrompt(t.message.sessionId,n),this.#B(s,t.message,{delta:t.delta,n:t.n}),s.lastAt=Date.now(),this.lastSeq[t.message.sessionId]=Math.max(this.lastSeq[t.message.sessionId]??0,t.message.seq);break}case"status":{const s=this.#u(t.sessionId),n=Date.now(),i=s.notes[s.notes.length-1],r=s.msgs.length?s.msgs[s.msgs.length-1].key:null;i&&t.statusKind&&i.kind===t.statusKind?(i.text=t.text,i.afterKey=r):(s.notes.push({key:`st-${n}-${s.notes.length}`,kind:t.statusKind,text:t.text,at:n,afterKey:r}),s.notes.length>200&&s.notes.splice(0,s.notes.length-200)),s.lastAt=n;break}case"background":{this.#u(t.sessionId).background=t.tasks;break}case"turn-start":{const s=this.#u(t.sessionId);s.busy=!0,s.busySince=Date.now(),s.lastAt=Date.now(),s.trace=t.trace??null,this.#F(t.sessionId),this.#P(t.sessionId,t.pid);break}case"plan":{const s=this.#u(t.sessionId);this.#j(s,t.plan),s.lastAt=Date.now();break}case"speak":{const s=this.#u(t.sessionId),n={id:t.id,text:t.text,kind:t.kind,priority:t.priority,at:Date.now()};s.speaks=[...s.speaks??[],n].slice(-10);break}case"usage":{const s=this.#u(t.sessionId);s.info={...s.info,usage:t.usage},s.lastAt=Date.now();break}case"turn-end":{const s=this.#u(t.sessionId);if(s.busy=!1,t.sessionId!==this.activeId&&this.markUnread(t.sessionId),s.busySince=null,this.#M(s),t.error&&s.msgs.push({key:`err-${Date.now()}`,kind:"meta",text:t.error}),t.error?this.#O(t.sessionId):this.#F(t.sessionId),!t.error){const n=t.sessionId;window.setTimeout(()=>this.drainQueue(n),250)}break}case"permission":this.#u(t.request.sessionId).perms.push(t.request);break;case"permission-resolved":for(const s of this.byId.values())s.perms=s.perms.filter(n=>n.requestId!==t.requestId);this.#y();break;case"permission-expired":for(const s of this.byId.values())s.perms=s.perms.filter(n=>n.requestId!==t.requestId);this.#y(),this.#u(t.sessionId).msgs.push({key:`perm-exp-${t.requestId}`,kind:"meta",text:"这条审批已经过期:agent 等不到答复、先自己放过了(或它已经放弃这一轮)。你的点击没有生效。"});break;case"config-rejected":{const s=this.#u(t.sessionId),n=t.name||t.configId;s.msgs.push({key:`cfg-rej-${t.configId}-${Date.now()}`,kind:"meta",text:`${n} 这一档没生效:agent 没有接受「${t.value}」${t.actual?`,实际仍是「${t.actual}」`:""}。(模型只认它公布的那几档;换档位或换模型再试。)`});break}case"notify":{Si.handle(t.notice);break}case"error":{this.activeId&&this.#u(this.activeId).msgs.push({key:`e-${Date.now()}`,kind:"meta",text:t.error});break}}this.bump()}#M(t){for(let s=0;s<t.msgs.length;s++){const n=t.msgs[s];(n.kind==="agent"||n.kind==="thought")&&n.open&&(t.msgs[s]={...n,open:!1})}}#q(t){const s=t.msgs[t.msgs.length-1];s&&(s.kind==="agent"||s.kind==="thought")&&t.busy&&!s.open&&(t.msgs[t.msgs.length-1]={...s,open:!0})}#z(t,s){for(let n=0;n<t.length;n++){const i=t[n];i.kind==="thought"&&i.open&&i.key!==s&&(t[n]={...i,open:!1})}}#B(t,s,n){const i=n?.list??t.msgs,r=n?.index??t.blocks,a=n?.delta,l=s.payload;let c=null;const u=a!==void 0,h=(s.kind==="agent"||s.kind==="thought")&&Qv(s.kind,l)!==null;if(!(n?.resync===!0&&(s.kind==="tool"||s.kind==="plan"||s.kind==="user"||s.kind==="meta"||h)||s.kind==="tool"||s.kind==="meta"||s.kind==="note"||s.kind==="approval"||s.kind==="project-skills"||s.seq<=0||u)){if(t.seen.has(s.seq))return;t.seen.add(s.seq)}s.seq>0&&(t.minSeq==null||s.seq<t.minSeq)&&(t.minSeq=s.seq);const f=s.payload,m=typeof s.createdAt=="number"?s.createdAt:Date.now(),b=IR(f);switch(i[i.length-1],s.kind){case"user":if(i.some(v=>v.key===`m${s.seq}`))break;const _=f.origin??null;i.push({key:`m${s.seq}`,kind:"user",text:String(f.text??""),at:m,..._&&typeof _.sessionId=="string"?{from:{id:_.sessionId,title:String(_.title??"").trim()||"另一个会话"}}:{},files:Array.isArray(f.attachments)?f.attachments.map(v=>({kind:String(v.kind??""),name:String(v.name??"file")})):[]}),n?.list||(t.turn+=1,t.turnStart=i.length-1);break;case"agent":case"thought":{const v=s.kind,y=Qv(v,f),{at:w}=BN(i,r,{key:y,kind:v,text:b,delta:a,n:n?.n},(S,N)=>({key:S,kind:N.kind,text:N.text,open:!0,at:m})),x=i[w];a!==void 0&&t.info.status==="running"&&x&&(x.kind==="agent"||x.kind==="thought")&&!x.open&&(i[w]={...x,open:!0}),v==="thought"&&(c=i[w]?.key??null);break}case"note":{const v=`n${s.seq}`,y=typeof f.hits=="number"?f.hits:void 0,w={key:v,kind:"note",category:String(f.category??""),text:typeof f.text=="string"?f.text:"",hits:y,at:m,items:Array.isArray(f.items)?f.items.filter(S=>S&&typeof S.text=="string"&&S.text.trim()):void 0,truncated:f.truncated===!0},x=r.get(v);x!==void 0&&i[x]?.kind==="note"?i[x]=w:(i.push(w),r.set(v,i.length-1));break}case"approval":{const v=`p${s.seq}`,y=f.decision,w={key:v,kind:"approval",requestId:String(f.requestId??""),title:String(f.toolCallTitle??"tool call"),kind2:String(f.kind??"other"),path:typeof f.path=="string"?f.path:null,diff:f.diff??null,options:Array.isArray(f.options)?f.options:[],decision:y??null,at:m},x=r.get(v);x!==void 0&&i[x]?.kind==="approval"?i[x]=w:(i.push(w),r.set(v,i.length-1));break}case"project-skills":{const v=`s${s.seq}`,y={key:v,kind:"project-skills",root:String(f.root??""),count:typeof f.count=="number"?f.count:0,text:String(f.text??""),state:String(f.state??"ask"),at:m},w=r.get(v);w!==void 0&&i[w]?.kind==="project-skills"?i[w]=y:(i.push(y),r.set(v,i.length-1));break}case"turn-usage":{const v=`u${s.seq}`,y=S=>typeof S=="number"&&Number.isFinite(S)?S:0,w=S=>typeof S=="number"&&Number.isFinite(S)?S:null,x={key:v,kind:"turn-usage",available:f.available!==!1,input:y(f.input),output:y(f.output),thought:y(f.thought),cacheRead:w(f.cacheRead),cacheWrite:w(f.cacheWrite),total:y(f.total),durationMs:typeof f.durationMs=="number"?f.durationMs:void 0,cacheHitPercent:typeof f.cacheHitPercent=="number"?f.cacheHitPercent:null,tps:typeof f.tps=="number"?f.tps:null,at:m};r.get(v)===void 0&&(i.push(x),r.set(v,i.length-1));break}case"tool":{const v=String(f.toolCallId??s.toolCallId??s.seq),y=i.find(E=>E.kind==="tool"&&E.toolCallId===v),w=PR(f),x=LR(f),S=new Set((y?.changes??[]).map(E=>`${E.path}\0${E.oldText??""}\0${E.newText??""}\0${E.diffText??""}`)),N=zN(f).filter(E=>!S.has(`${E.path}\0${E.oldText??""}\0${E.newText??""}\0${E.diffText??""}`)),R=N.length?[...y?.changes??[],...N]:y?.changes;if(y){const E=i.indexOf(y),M={...y,title:f.title?String(f.title):y.title,status:f.status?String(f.status):y.status,detail:w??y.detail,input:x??y.input,changes:R};E>=0&&(i[E]=M)}else i.push({key:`tc-${v}`,kind:"tool",toolCallId:v,at:m,title:String(f.title??"tool call"),status:String(f.status??"pending"),kind2:String(f.kind??""),detail:w,input:x,changes:R});break}case"plan":{const v=f._meta??{},y=(f.entries??[]).map(S=>({content:String(S?.content??""),status:String(S?.status??"pending"),priority:S?.priority})),w=typeof f._slotPlanTerminal=="string"?f._slotPlanTerminal:void 0,x=typeof v["agentus/explanation"]=="string"?String(v["agentus/explanation"]):void 0;if(n?.list){const S=i.find(N=>N.kind==="plan");if(S&&S.kind==="plan"){const N=i.indexOf(S);i[N]={...S,items:y,terminal:w,explanation:x}}else i.push({key:`m${s.seq}`,kind:"plan",items:y,terminal:w,explanation:x,at:m});break}this.#A(t,y,w,m,x);break}case"meta":if(i.some(v=>v.key===`m${s.seq}`))break;i.push({key:`m${s.seq}`,kind:"meta",text:b||JSON.stringify(f)});break}this.#z(i,c),this.lastSeq[t.info.id]=Math.max(this.lastSeq[t.info.id]??0,s.seq),t.rev+=1,t.lastAt=Date.now()}}function IR(e){const t=e.content;return t?.type==="text"&&typeof t.text=="string"?t.text:""}function PR(e){const s=r=>r.length>4e3?`${r.slice(0,4e3)}
44
44
  … (${r.length-4e3} more chars)`:r,n=e.rawOutput;if(typeof n=="string"&&n.trim())return s(n);if(n&&typeof n=="object")try{return s(JSON.stringify(n,null,1))}catch{}const i=e.content;if(Array.isArray(i)){const r=[];for(const a of i){const l=String(a?.type??"");if(l==="content"){const c=a.content;c?.type==="text"&&c.text&&r.push(String(c.text))}else if(l==="diff"){const c=String(a.path??"file"),u=typeof a.newText=="string"?a.newText:"";r.push(`--- ${c}
45
45
  ${u.slice(0,1500)}`)}else if(l==="terminal"){const c=a.output;c&&r.push(String(c))}}if(r.length)return s(r.join(`
46
46
  `))}return""}function LR(e){const t=e.rawInput;if(typeof t=="string"&&t.trim())return t.slice(0,1200);if(t&&typeof t=="object")try{return JSON.stringify(t,null,1).slice(0,1200)}catch{return""}return""}const ee=new DR;if(typeof window<"u"){const e=window;e.__agentusOpenSession=t=>{const s=String(t??"").trim();if(!s||!ee.byId.has(s))return!1;ee.setActive(s);const n=ee.byId.get(s);return n&&!n.loaded&&ee.resume(s).catch(()=>{}),!0},window.addEventListener("popstate",()=>ee.followUrl())}function Qr(e){return!!(e&&(e.busy||e.info.status==="running"))}function Rh(e){return`/api/fs/raw?path=${encodeURIComponent(e)}`}async function fd(e){try{if(navigator.clipboard?.writeText)return await navigator.clipboard.writeText(e),!0}catch{}try{const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.top="-1000px",t.style.opacity="0",document.body.appendChild(t),t.select(),t.setSelectionRange(0,t.value.length);const s=document.execCommand("copy");return t.remove(),s}catch{return!1}}const em=new Set;function OR(e){return em.add(e),()=>{em.delete(e)}}function US(e){for(const t of[...em])try{t(e)}catch{}}const tm="data-agentus-table",BR=4,sm="⇕",$R={asc:"▲",desc:"▼",none:sm};function nm(e){if(!e)return"";const t=e.querySelector(".md-table-sort");return t?(t.querySelector(".md-table-sort-label")?.textContent??"").trim():(e.textContent??"").trim()}function FR(e,t,s){const n=e.tBodies[0];if(!n)return;const i=Array.from(n.rows).filter(a=>a.parentElement===n),r=a=>Number(a.dataset.mdRow??0);i.sort((a,l)=>{if(s==="none")return r(a)-r(l);const c=nm(a.cells[t]).localeCompare(nm(l.cells[t]),void 0,{numeric:!0,sensitivity:"base"});return c!==0?s==="asc"?c:-c:r(a)-r(l)});for(const a of i)n.appendChild(a)}function zR(e){const t=e.cloneNode(!0);t.removeAttribute(tm);for(const s of Array.from(t.querySelectorAll(".md-table-sort"))){const n=s.querySelector(".md-table-sort-label"),i=s.parentElement;i&&n&&(i.textContent=n.textContent??"",i.removeAttribute("aria-sort"))}return t}function HR(e){if(document.querySelector(".md-table-overlay"))return;const t=document.createElement("div");t.className="md-table-overlay",t.setAttribute("role","dialog"),t.setAttribute("aria-modal","true"),t.setAttribute("aria-label","table");const s=document.createElement("div");s.className="md-table-bar";const n=document.createElement("button");n.type="button",n.className="md-table-btn",n.textContent="rotate";const i=document.createElement("span");i.className="head-spacer";const r=document.createElement("button");r.type="button",r.className="md-table-btn",r.textContent="copy";const a=document.createElement("button");a.type="button",a.className="md-table-btn",a.textContent="close",a.setAttribute("aria-label","close table"),s.append(n,i,r,a);const l=document.createElement("div");l.className="md-table-stage";const c=document.createElement("div");c.className="md-table-zoom md";const u=zR(e);c.appendChild(u),l.appendChild(c),t.append(s,l),document.body.appendChild(t),o_(c);const h=window.innerHeight>window.innerWidth;c.classList.toggle("rot",h);const d=()=>{t.remove(),window.removeEventListener("keydown",p)},p=f=>{f.key==="Escape"&&d()};window.addEventListener("keydown",p),n.addEventListener("click",()=>c.classList.toggle("rot")),a.addEventListener("click",d),t.addEventListener("click",f=>{(f.target===t||f.target===l)&&d()}),r.addEventListener("click",()=>{const f=Array.from(u.rows).map(m=>Array.from(m.cells).map(b=>nm(b).replace(/\s+/g," ")).join(" "));fd(f.join(`
@@ -14,7 +14,7 @@
14
14
  <link rel="icon" href="/icons/favicon.ico" sizes="any" />
15
15
  <link rel="apple-touch-icon" href="/icons/apple-touch-icon-180.png" />
16
16
  <title>Agentus</title>
17
- <script type="module" crossorigin src="/assets/index-B7y5yEpo.js"></script>
17
+ <script type="module" crossorigin src="/assets/index-DSN1oxqH.js"></script>
18
18
  <link rel="stylesheet" crossorigin href="/assets/index-DW9ejasQ.css">
19
19
  </head>
20
20
  <body>