dsh-provider-proxy 0.8.0 → 0.9.0
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 +79 -5
- package/lib/client.js +1532 -185
- package/lib/client.js.map +4 -4
- package/lib/index.js +443 -32
- package/lib/index.js.map +4 -4
- package/package.json +1 -1
package/lib/client.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/client.css", "../src/client.ts", "../src/host-rules.ts", "../src/proxy-address.ts"],
|
|
4
|
-
"sourcesContent": ["\nvar __dshMap = {\"root\":\"1c0df77c_root\",\"lead\":\"5d248416_lead\",\"empty\":\"1710aef8_empty\",\"card\":\"b4a56347_card\",\"cardActive\":\"5d17f1d6_cardActive\",\"cardRejected\":\"0b12be1b_cardRejected\",\"defaultCard\":\"4dc8a19a_defaultCard\",\"defaultLead\":\"593693ac_defaultLead\",\"cardHead\":\"0c3d7976_cardHead\",\"cardTitles\":\"ba5490f7_cardTitles\",\"name\":\"fc223200_name\",\"id\":\"b54fcb50_id\",\"pillOn\":\"2d0e393c_pillOn\",\"pillLive\":\"ed98388d_pillLive\",\"pillOff\":\"07959fb6_pillOff\",\"pillRejected\":\"23916369_pillRejected\",\"toggle\":\"44052e5b_toggle\",\"field\":\"7826b254_field\",\"label\":\"fd3de42a_label\",\"hint\":\"9c1dd04c_hint\",\"input\":\"0cb12e78_input\",\"passwordToggle\":\"e7ed8e99_passwordToggle\",\"testButton\":\"3ea31502_testButton\",\"diag\":\"8093bbdb_diag\",\"diagSummary\":\"bb056060_diagSummary\",\"diagList\":\"643d5158_diagList\",\"chipRow\":\"cf7604fc_chipRow\",\"chip\":\"69584a20_chip\",\"chipActive\":\"9e9e3b3e_chipActive\",\"formGrid\":\"07283bc3_formGrid\",\"formGridFull\":\"31635992_formGridFull\",\"compactRow\":\"10f37453_compactRow\",\"compactRowActive\":\"b8d0ab91_compactRowActive\",\"compactRowRejected\":\"518f0c81_compactRowRejected\",\"copyButton\":\"4b86d627_copyButton\"};\nvar __dshStyles = (globalThis.__dshPluginStyles || (globalThis.__dshPluginStyles = new Set()));\nif (!__dshStyles.has(\"dsh-provider-proxy/client.css\")) {\n __dshStyles.add(\"dsh-provider-proxy/client.css\");\n var __dshStyle = document.createElement('style');\n __dshStyle.setAttribute('data-plugin-css', \"dsh-provider-proxy/client.css\");\n __dshStyle.textContent = \"/* dsh-provider-proxy \u2014 provider proxy settings page.\\r\\n Tokens only: no literal colours, matching the shared --dsw-* system. */\\r\\n\\r\\n.1c0df77c_root {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n gap: 12px;\\r\\n max-width: 640px;\\r\\n}\\r\\n\\r\\n.5d248416_lead {\\r\\n margin: 0 0 4px;\\r\\n font-size: 12px;\\r\\n line-height: 1.6;\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n.1710aef8_empty {\\r\\n margin: 0;\\r\\n padding: 16px;\\r\\n border: 1px dashed var(--dsw-alias-border-l1);\\r\\n border-radius: 8px;\\r\\n font-size: 12px;\\r\\n text-align: center;\\r\\n color: var(--dsw-alias-state-idle-primary);\\r\\n}\\r\\n\\r\\n/* ---- provider card ---- */\\r\\n\\r\\n.b4a56347_card,\\r\\n.5d17f1d6_cardActive,\\r\\n.0b12be1b_cardRejected {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n gap: 10px;\\r\\n padding: 12px 14px;\\r\\n border: 1px solid var(--dsw-alias-border-l1);\\r\\n border-radius: 10px;\\r\\n background: var(--dsw-alias-bg-layer-1);\\r\\n}\\r\\n\\r\\n.5d17f1d6_cardActive {\\r\\n border-color: var(--dsw-alias-state-success-primary);\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n}\\r\\n\\r\\n/* An enabled route the Host refused: never dress it as active. */\\r\\n.0b12be1b_cardRejected {\\r\\n border-color: var(--dsw-alias-state-error-primary, #f85149);\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n}\\r\\n\\r\\n/* ---- shared default endpoint ---- */\\r\\n\\r\\n/* A distinct outer layer, so it reads as \\\"one setting for the page\\\" rather than\\r\\n as one more provider card. */\\r\\n.4dc8a19a_defaultCard {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n gap: 10px;\\r\\n padding: 14px 16px;\\r\\n border: 1px solid var(--dsw-alias-border-l2);\\r\\n border-radius: 10px;\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n}\\r\\n\\r\\n.593693ac_defaultLead {\\r\\n margin: -2px 0 0;\\r\\n font-size: 11px;\\r\\n line-height: 1.5;\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n.0c3d7976_cardHead {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n gap: 12px;\\r\\n}\\r\\n\\r\\n.ba5490f7_cardTitles {\\r\\n display: flex;\\r\\n align-items: baseline;\\r\\n gap: 8px;\\r\\n min-width: 0;\\r\\n}\\r\\n\\r\\n.fc223200_name {\\r\\n overflow: hidden;\\r\\n font-size: 13px;\\r\\n font-weight: 600;\\r\\n white-space: nowrap;\\r\\n text-overflow: ellipsis;\\r\\n color: var(--dsw-alias-label-primary);\\r\\n}\\r\\n\\r\\n.b54fcb50_id {\\r\\n flex: none;\\r\\n padding: 1px 6px;\\r\\n border-radius: 4px;\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n font-family: ui-monospace, monospace;\\r\\n font-size: 11px;\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n/* ---- status pill ---- */\\r\\n\\r\\n.2d0e393c_pillOn,\\r\\n.ed98388d_pillLive,\\r\\n.07959fb6_pillOff,\\r\\n.23916369_pillRejected {\\r\\n flex: none;\\r\\n padding: 2px 8px;\\r\\n border-radius: 999px;\\r\\n font-size: 11px;\\r\\n font-weight: 500;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.2d0e393c_pillOn {\\r\\n background: var(--dsw-alias-state-success-primary);\\r\\n color: var(--dsw-alias-bg-base);\\r\\n}\\r\\n\\r\\n.ed98388d_pillLive {\\r\\n border: 1px solid var(--dsw-alias-border-l2);\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n.07959fb6_pillOff {\\r\\n color: var(--dsw-alias-state-idle-primary);\\r\\n}\\r\\n\\r\\n.23916369_pillRejected {\\r\\n border: 1px solid var(--dsw-alias-state-error-primary, #f85149);\\r\\n color: var(--dsw-alias-state-error-primary, #f85149);\\r\\n}\\r\\n\\r\\n/* ---- toggle ---- */\\r\\n\\r\\n.44052e5b_toggle {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 8px;\\r\\n padding-top: 2px;\\r\\n font-size: 12px;\\r\\n color: var(--dsw-alias-label-primary);\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n.44052e5b_toggle input {\\r\\n accent-color: var(--dsw-alias-brand-primary);\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n/* ---- fields ---- */\\r\\n\\r\\n.7826b254_field {\\r\\n display: grid;\\r\\n grid-template-columns: 76px 1fr;\\r\\n align-items: center;\\r\\n gap: 8px;\\r\\n font-size: 12px;\\r\\n min-width: 0;\\r\\n}\\r\\n\\r\\n.fd3de42a_label {\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n.9c1dd04c_hint {\\r\\n grid-column: 1 / -1;\\r\\n margin-top: 2px;\\r\\n font-size: 11px;\\r\\n color: var(--dsw-alias-state-warn-primary, #d29922);\\r\\n}\\r\\n\\r\\n.0cb12e78_input {\\r\\n box-sizing: border-box;\\r\\n width: 100%;\\r\\n min-width: 0;\\r\\n padding: 5px 8px;\\r\\n border: 1px solid var(--dsw-alias-border-l1);\\r\\n border-radius: 6px;\\r\\n outline: none;\\r\\n background: var(--dsw-alias-bg-layer-1);\\r\\n color: var(--dsw-alias-label-primary);\\r\\n font: inherit;\\r\\n font-size: 12px;\\r\\n transition: border-color 120ms ease, background 120ms ease;\\r\\n}\\r\\n\\r\\n/* The base look of every input is INLINE too, so these three state rules only\\r\\n ever take effect as author-important declarations \u2014 same reason as the\\r\\n self-check button above. `cursor` has no inline base and needs none, and the\\r\\n hover border uses `l3` because `l1`\u2192`l2` is a 4%\u219210% black step nobody can\\r\\n see. */\\r\\n\\r\\n.0cb12e78_input:hover:not(:disabled) {\\r\\n border-color: var(--dsw-alias-border-l3) !important;\\r\\n}\\r\\n\\r\\n.0cb12e78_input:focus {\\r\\n border-color: var(--dsw-alias-brand-primary) !important;\\r\\n}\\r\\n\\r\\n.0cb12e78_input:disabled {\\r\\n color: var(--dsw-alias-state-idle-primary) !important;\\r\\n background: var(--dsw-alias-bg-layer-2) !important;\\r\\n cursor: not-allowed;\\r\\n}\\r\\n\\r\\n/* The icon sits inside the input, so its hover/focus feedback must be local\\r\\n and must outrank the transparent inline base. */\\r\\n.e7ed8e99_passwordToggle {\\r\\n transition: background 120ms ease, color 120ms ease;\\r\\n}\\r\\n\\r\\n.e7ed8e99_passwordToggle:hover:not(:disabled) {\\r\\n background: var(--dsw-alias-interactive-bg-hover) !important;\\r\\n color: var(--dsw-alias-label-primary) !important;\\r\\n}\\r\\n\\r\\n.e7ed8e99_passwordToggle:focus-visible {\\r\\n outline: 2px solid var(--dsw-alias-brand-primary);\\r\\n outline-offset: 1px;\\r\\n}\\r\\n\\r\\n/* ---- self-check ---- */\\r\\n\\r\\n/* The hover state is the one thing an inline style cannot express, which is why\\r\\n this element carries a class at all. Layout stays inline.\\r\\n\\r\\n Two traps, both hit before this comment existed:\\r\\n - `!important` is load-bearing: the base border and background are INLINE, and\\r\\n the cascade sorts a style attribute after every author rule, so a plain\\r\\n declaration here would ship, match, and still lose.\\r\\n - the TOKENS must be visible ones. `bg-layer-1/2/3` all resolve to\\r\\n `neutral-bluish-00` in the light theme, so a layer swap is a no-op there, and\\r\\n `border-l1`\u2192`l2` is 4%\u219210% black on a 1px line. The app's own hovers use\\r\\n `interactive-bg-hover`; using it here is what makes the feedback exist. */\\r\\n.3ea31502_testButton {\\r\\n transition: border-color 120ms ease, background 120ms ease;\\r\\n}\\r\\n\\r\\n.3ea31502_testButton:hover:not(:disabled) {\\r\\n border-color: var(--dsw-alias-border-l3) !important;\\r\\n background: var(--dsw-alias-interactive-bg-hover) !important;\\r\\n}\\r\\n\\r\\n/* ---- diagnostics ---- */\\r\\n\\r\\n.8093bbdb_diag {\\r\\n margin-top: 2px;\\r\\n padding: 8px 10px;\\r\\n border: 1px solid var(--dsw-alias-border-l1);\\r\\n border-radius: 8px;\\r\\n font-size: 11px;\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n.bb056060_diagSummary {\\r\\n cursor: pointer;\\r\\n color: var(--dsw-alias-state-warn-primary);\\r\\n}\\r\\n\\r\\n.643d5158_diagList {\\r\\n margin: 6px 0 0;\\r\\n padding-left: 18px;\\r\\n font-family: ui-monospace, monospace;\\r\\n word-break: break-all;\\r\\n}\\r\\n\\r\\n/* ---- v0.8.0 N9 additions: status filter chips ---- */\\r\\n\\r\\n.cf7604fc_chipRow {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 6px;\\r\\n flex-wrap: wrap;\\r\\n}\\r\\n\\r\\n.69584a20_chip {\\r\\n transition: border-color 120ms ease, background 120ms ease, color 120ms ease;\\r\\n}\\r\\n\\r\\n.69584a20_chip:hover:not(:disabled) {\\r\\n border-color: var(--dsw-alias-border-l3) !important;\\r\\n background: var(--dsw-alias-interactive-bg-hover) !important;\\r\\n color: var(--dsw-alias-label-primary) !important;\\r\\n}\\r\\n\\r\\n.9e9e3b3e_chipActive {\\r\\n border-color: var(--dsw-alias-brand-primary) !important;\\r\\n background: var(--dsw-alias-interactive-bg-hover) !important;\\r\\n color: var(--dsw-alias-brand-primary) !important;\\r\\n}\\r\\n\\r\\n/* ---- v0.8.0 N11 additions: form grid ---- */\\r\\n\\r\\n.07283bc3_formGrid {\\r\\n display: grid;\\r\\n grid-template-columns: repeat(2, minmax(0, 1fr));\\r\\n align-items: start;\\r\\n gap: 10px 14px;\\r\\n}\\r\\n\\r\\n.31635992_formGridFull {\\r\\n grid-column: 1 / -1;\\r\\n}\\r\\n\\r\\n@media (max-width: 520px) {\\r\\n .07283bc3_formGrid {\\r\\n grid-template-columns: 1fr !important;\\r\\n }\\r\\n .31635992_formGridFull {\\r\\n grid-column: auto !important;\\r\\n }\\r\\n}\\r\\n\\r\\n/* ---- v0.8.0 N10 additions: compact view ---- */\\r\\n\\r\\n.10f37453_compactRow,\\r\\n.b8d0ab91_compactRowActive,\\r\\n.518f0c81_compactRowRejected {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n gap: 10px;\\r\\n padding: 10px 14px;\\r\\n border: 1px solid var(--dsw-alias-border-l1);\\r\\n border-radius: 8px;\\r\\n background: var(--dsw-alias-bg-layer-1);\\r\\n margin-bottom: 8px;\\r\\n}\\r\\n\\r\\n.b8d0ab91_compactRowActive {\\r\\n border-color: var(--dsw-alias-state-success-primary);\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n}\\r\\n\\r\\n.518f0c81_compactRowRejected {\\r\\n border-color: var(--dsw-alias-state-error-primary, #f85149);\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n}\\r\\n\\r\\n/* ---- v0.8.0 N13 additions: quick copy ---- */\\r\\n.4b86d627_copyButton {\\r\\n transition: background 120ms ease, color 120ms ease;\\r\\n}\\r\\n\\r\\n.4b86d627_copyButton:hover:not(:disabled) {\\r\\n background: var(--dsw-alias-interactive-bg-hover) !important;\\r\\n color: var(--dsw-alias-label-primary) !important;\\r\\n}\\r\\n\";\n document.head.appendChild(__dshStyle);\n}\nmodule.exports = __dshMap;\nmodule.exports.default = __dshMap;\nmodule.exports.__esModule = true;\n", "/**\r\n * dsh-provider-proxy \u2014 browser half.\r\n *\r\n * Contributes ONE settings page (a `settings.section` list entry) that lists\r\n * every known provider with its proxy switch, type, host, port and username.\r\n *\r\n * This replaces an earlier attempt to render into each provider card on the\r\n * Models page (`settings.models.provider-card`). That seat is keyed and\r\n * dispatched per provider namespace, and a third-party registration never\r\n * matched it on this build: no error, no request, simply no output. A\r\n * `settings.section` entry is a plain list contribution with an `id`, which is\r\n * the shape the shipped `dsh-llm-retry-settings` plugin uses successfully in\r\n * this same desktop profile.\r\n *\r\n * The whole bundle runs inside the client module system's lazy-CJS factory:\r\n * executing the script only REGISTERS the factory, and every side effect\r\n * (including the CSS injection) happens at materialization.\r\n */\r\n\r\n// The CSS-Modules build turns this sheet into a hashed class map AND injects it\r\n// at materialization. The binding is what the component reads; importing it for\r\n// side effects only would leave `styles` undefined at render time.\r\nimport styles from './client.css'\r\nimport { deadRuleEntries } from './host-rules.js'\r\nimport { defaultProxyProblem, proxyHostProblem } from './proxy-address.js'\r\n\r\ntype Protocol = 'http' | 'https' | 'socks5'\r\n\r\ntype RouteValue = {\r\n enabled: boolean\r\n useDefault: boolean\r\n protocol: Protocol\r\n host: string\r\n port: number\r\n username: string\r\n password: string\r\n onlyHosts: string\r\n bypassHosts: string\r\n testTarget: string\r\n}\r\n\r\n/** The provider rows we know about, and which of them are actually live. */\r\ntype ProviderRow = { id: string; name: string; live: boolean }\r\n\r\n/**\r\n * React, resolved from the client module table.\r\n *\r\n * React is NOT a Cordis service and is not reachable from `ctx` \u2014 reading it\r\n * there produced a silently null component. The module table is the only route:\r\n * the build leaves `react` external, so this compiles to a `require(\"react\")`\r\n * inside the factory closure, answered from the shell-seeded baseline.\r\n *\r\n * Resolved lazily on first render so merely REGISTERING the bundle \u2014 which is\r\n * all a script evaluation does \u2014 never materializes React.\r\n */\r\nlet ReactCache: unknown\r\n\r\nfunction react(): any {\r\n if (ReactCache === undefined) {\r\n ReactCache = ((): unknown => {\r\n try {\r\n return require('react')\r\n } catch {\r\n return (globalThis as Record<string, unknown>).React\r\n }\r\n })()\r\n }\r\n return ReactCache\r\n}\r\n\r\nconst PROTOCOLS: Protocol[] = ['http', 'https', 'socks5']\r\n\r\n/** Our own settings namespace; the profile entry id created by the bundle patch. */\r\nconst NAMESPACE = 'provider-proxy'\r\n\r\n/**\r\n * Cordis services this half needs.\r\n *\r\n * ONLY `slots` is declared. That is the complete set this release actually\r\n * offers on a client fiber: `layout, locale, sessions, slots, theme, timer,\r\n * uiWorkspace, workspaces`.\r\n *\r\n * A declared service that never arrives leaves the fiber PENDING forever, and\r\n * that is NOT a client-only failure \u2014 it is reported as\r\n * web boot: 1 entry did not activate\r\n * dsh-provider-proxy: pending (waiting for service: settingsScope)\r\n * which fails the whole Desktop boot. `settingsScope` and `configForms` were\r\n * both guessed and both are absent here, so neither may be declared.\r\n *\r\n * Settings are therefore reached through `ctx.get(name)` \u2014 the framework's own\r\n * non-throwing lookup \u2014 and the page degrades to read-only when it is absent.\r\n */\r\nconst PLUGINS = ['slots']\r\n\r\nexport const inject = PLUGINS\r\n\r\nexport function apply(ctx: any): void {\r\n // The settings shell declares `settings.section` on its own fiber, so\r\n // `slots.inject` waits for that declaration and the contribution is removed\r\n // when the panel is torn down.\r\n ctx.slots.inject('settings.section', () =>\r\n ctx.slots.register(\r\n {\r\n name: 'settings.section',\r\n id: NAMESPACE,\r\n order: 20,\r\n label: () => 'Provider \u4EE3\u7406',\r\n },\r\n () => renderPage(ctx),\r\n ),\r\n )\r\n}\r\n\r\n/**\r\n * Pick the dictionary.\r\n *\r\n * Chinese is the default, not English: this plugin is written for a\r\n * Chinese-speaking operator, and a page that renders in the wrong language is\r\n * worse than one that never matches the shell's locale.\r\n *\r\n * `ctx.locale` is not injected \u2014 declaring a service that this release does not\r\n * provide left the fiber PENDING and failed the whole Desktop boot \u2014 so the\r\n * locale is probed with the non-throwing `ctx.get`, then the browser's own\r\n * language, and only then English.\r\n */\r\nfunction localeOf(ctx: any): string {\r\n try {\r\n const service = optionalService(ctx, 'locale')\r\n const snapshot = service?.getSnapshot?.() ?? service?.getLocale?.()\r\n const id = typeof snapshot?.locale === 'string' ? snapshot.locale : undefined\r\n if (id !== undefined) return id.toLowerCase().startsWith('zh') ? 'zh' : 'en'\r\n } catch {\r\n // fall through to the browser language\r\n }\r\n const browser = globalThis.navigator?.language\r\n if (typeof browser === 'string' && browser.toLowerCase().startsWith('zh')) return 'zh'\r\n return browser === undefined ? 'zh' : 'en'\r\n}\r\n\r\n/**\r\n * Look a service up WITHOUT declaring it in `inject`.\r\n *\r\n * `ctx.get(name)` is the framework's own optional lookup: it returns undefined\r\n * instead of throwing, and \u2014 unlike a declared service \u2014 it cannot leave the\r\n * fiber PENDING. That is what makes an optional integration safe here: this\r\n * release has no settings service at all, so the page simply shows its fields\r\n * and reports that saving is unavailable.\r\n */\r\nfunction optionalService(ctx: any, ...names: string[]): any {\r\n for (const name of names) {\r\n try {\r\n const found = typeof ctx?.get === 'function' ? ctx.get(name) : undefined\r\n if (found !== undefined && found !== null) return found\r\n } catch {\r\n // try the next spelling\r\n }\r\n }\r\n return undefined\r\n}\r\n\r\n/** The settings form for this plugin's namespace, when one exists. */\r\nfunction formOf(ctx: any): any {\r\n const forms = optionalService(ctx, 'configForms', 'settingsScope')\r\n if (forms === undefined) return undefined\r\n try {\r\n if (typeof forms.get === 'function') return forms.get(NAMESPACE)\r\n // A settingsScope-style service is already bound to one namespace.\r\n if (typeof forms.getSnapshot === 'function' || typeof forms.bind === 'function') return forms\r\n } catch {\r\n return undefined\r\n }\r\n return undefined\r\n}\r\n\r\nfunction readConfig(ctx: any): { value: any; revision: number } {\r\n const form = formOf(ctx)\r\n if (form === undefined) return { value: {}, revision: 0 }\r\n try {\r\n const snapshot = form.getSnapshot?.()\r\n return {\r\n value: snapshot?.value ?? snapshot?.user ?? {},\r\n revision: snapshot?.revision ?? 0,\r\n }\r\n } catch {\r\n return { value: {}, revision: 0 }\r\n }\r\n}\r\n\r\nasync function writeConfig(ctx: any, ops: readonly unknown[]): Promise<void> {\r\n const form = formOf(ctx)\r\n if (typeof form?.mutate !== 'function') {\r\n throw new Error('dsh-provider-proxy: settings transport unavailable')\r\n }\r\n await form.mutate(ops as any[], readConfig(ctx).revision)\r\n}\r\n\r\n/**\r\n * The provider rows, read from the Host.\r\n *\r\n * This release exposes no client-facing LLM service, so the page cannot ask for\r\n * the directory itself. The Host serves it at this same-origin endpoint, where\r\n * `ctx.llm.listProviders()` / `listConfigurableProviders()` actually live. The\r\n * list is therefore automatic \u2014 the user never types a route id.\r\n *\r\n * Only ACTIVE routes are shown. A provider this deployment merely *offers* \u2014\r\n * declared but not registered, so nothing would ever be sent through it \u2014 is\r\n * not the user's business on this page, and listing it only invites them to\r\n * configure a proxy for a route that cannot be selected. A provider that is\r\n * already configured is kept regardless, so a saved setting never silently\r\n * disappears from view.\r\n */\r\nfunction knownProviders(configured: Record<string, RouteValue>, published: ProviderRow[]): ProviderRow[] {\r\n const rows = new Map<string, ProviderRow>()\r\n const byId = new Map<string, ProviderRow>()\r\n for (const row of published) {\r\n byId.set(row.id, row)\r\n if (row.live) rows.set(row.id, row)\r\n }\r\n for (const id of Object.keys(configured)) {\r\n if (rows.has(id)) continue\r\n // A saved route must stay visible, but switching the proxy ON does not make\r\n // its provider live. `live` comes from the Host catalogue exclusively; using\r\n // `route.enabled` here made a card flip between \"offline\" and \"proxied\" as\r\n // the user toggled the switch, while no provider became available at all.\r\n const known = byId.get(id)\r\n rows.set(id, { id, name: known?.name ?? id, live: known?.live === true })\r\n }\r\n return [...rows.values()].sort(byName)\r\n}\r\n\r\n/**\r\n * Where the Host publishes the live provider catalogue.\r\n */\r\nconst CATALOG_PATH = '/dsh-provider-proxy/providers'\r\n\r\n/** Where the Host runs a per-provider connection self-check. */\r\nconst TEST_PATH = '/dsh-provider-proxy/test'\r\n\r\n/**\r\n * Latency bands for the self-check result, in milliseconds.\r\n *\r\n * The colour is decoration, never information: the numeric value is always\r\n * printed, so an unknown theme token (which resolves to `unset`) costs colour,\r\n * never the reading. The `var(..., fallback)` form keeps the colours visible even\r\n * if the theme renames the token.\r\n */\r\nconst LATENCY_FAST_MS = 500\r\nconst LATENCY_SLOW_MS = 1500\r\n/** The schema default for `testUrl`; also what \"Restore default\" writes. */\r\nconst DEFAULT_TEST_URL = 'https://api.ipify.org?format=json'\r\nconst MAX_TEST_URLS = 5\r\n\r\nfunction latencyColor(ms: unknown): string {\r\n if (typeof ms !== 'number' || !Number.isFinite(ms)) return 'var(--dsw-alias-label-secondary)'\r\n if (ms <= LATENCY_FAST_MS) return 'var(--dsw-alias-state-success-primary, #2ea043)'\r\n if (ms <= LATENCY_SLOW_MS) return 'var(--dsw-alias-state-warn-primary, #d29922)'\r\n return 'var(--dsw-alias-state-error-primary, #f85149)'\r\n}\r\n\r\n/** Normalize the Host's self-check payload into the shape the card renders. */\r\nfunction testResultFrom(body: any, strings: Record<string, string>): Record<string, unknown> {\r\n const ok = body?.ok === true\r\n return {\r\n pending: false,\r\n ok,\r\n ms: typeof body?.ms === 'number' && Number.isFinite(body.ms) ? body.ms : undefined,\r\n ip: typeof body?.exitIp === 'string' && body.exitIp.length > 0 ? body.exitIp : undefined,\r\n status:\r\n typeof body?.status === 'number' && Number.isInteger(body.status) ? body.status : undefined,\r\n target: typeof body?.target === 'string' && body.target.length > 0 ? body.target : undefined,\r\n targetSource:\r\n body?.targetSource === 'route' || body?.targetSource === 'upstream'\r\n ? body.targetSource\r\n : body?.targetSource === 'testUrl'\r\n ? 'testUrl'\r\n : undefined,\r\n cached: body?.cached === true,\r\n // The Host probes a target the way routing would: a loopback/private upstream\r\n // (or a bypassHosts match) is reached DIRECT, not through the proxy. The card\r\n // says so, so a green check is not read as \"the proxy works\".\r\n direct: body?.viaProxy === false,\r\n error: ok\r\n ? undefined\r\n : typeof body?.error === 'string' && body.error.length > 0\r\n ? body.error\r\n : strings.testFailed,\r\n }\r\n}\r\n\r\n/** Split `testUrl` the same way the Host does: commas or whitespace. */\r\nfunction splitTestUrls(raw: string): string[] {\r\n return raw\r\n .split(/[,\\s]+/)\r\n .map(entry => entry.trim())\r\n .filter(entry => entry.length > 0)\r\n}\r\n\r\n/**\r\n * Hint-only validation for `testUrl`.\r\n *\r\n * The Host does not refuse malformed candidates; it simply fails that check.\r\n * The page therefore warns without blocking the write, so a user can still save\r\n * a value the Host accepts (including an empty string, which means \"use the\r\n * built-in default\").\r\n */\r\nfunction testUrlHint(raw: string, t: Record<string, string>): string | undefined {\r\n const entries = splitTestUrls(raw)\r\n if (entries.length === 0) return t.testUrlEmptyHint\r\n const invalid = entries.filter(entry => !isAbsoluteHttpUrl(entry))\r\n if (invalid.length > 0) return t.testUrlInvalidHint\r\n if (entries.length > MAX_TEST_URLS) return t.testUrlTooManyHint\r\n return undefined\r\n}\r\n\r\nfunction isAbsoluteHttpUrl(value: string): boolean {\r\n try {\r\n const url = new URL(value)\r\n return (url.protocol === 'http:' || url.protocol === 'https:') && url.hostname.length > 0\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\n/**\r\n * Where the check's target came from, in the card's own words.\r\n *\r\n * The target is NOT always the top-level `testUrl`: a route's own\r\n * `testTarget` wins, then the provider's REAL upstream, and only a provider\r\n * that publishes none falls back to `testUrl`. Saying so is what explains why\r\n * editing `testUrl` changed one card and not another.\r\n */\r\nfunction targetSourceSuffix(\r\n result: { targetSource?: unknown },\r\n t: Record<string, string>,\r\n): string {\r\n switch (result.targetSource) {\r\n case 'route':\r\n return t.targetSourceRoute\r\n case 'upstream':\r\n return t.targetSourceUpstream\r\n case 'testUrl':\r\n return t.targetSourceTestUrl\r\n default:\r\n return ''\r\n }\r\n}\r\n\r\n/**\r\n * Remove values and URL credentials from text that will be shown to the user.\r\n *\r\n * Settings errors may quote the rejected value. A password field must never\r\n * echo that value, even inside an otherwise useful error message, so exact\r\n * known secrets are replaced before anything is rendered or written to the\r\n * diagnostics panel.\r\n */\r\nfunction redactSensitiveText(text: string, secrets: readonly unknown[] = []): string {\r\n let safe = text\r\n for (const secret of secrets) {\r\n if (typeof secret !== 'string' || secret.length === 0) continue\r\n safe = safe.split(secret).join('***')\r\n }\r\n // A URL in an error may carry userinfo and query/fragment values even when\r\n // the individual secret is not known to this call.\r\n safe = safe.replace(/\\b([a-z][a-z0-9+.-]*:\\/\\/)[^/@\\s]+@/gi, '$1')\r\n safe = safe.replace(/([?&#])[^\\s\"'<>]*/g, '$1')\r\n return safe.length > 500 ? `${safe.slice(0, 500)}\u2026` : safe\r\n}\r\n\r\n/** Values that may be echoed by a failed multi-field write. */\r\nfunction secretsFromOps(ops: readonly any[]): string[] {\r\n const out: string[] = []\r\n for (const op of ops) {\r\n const field = op?.path?.[op.path.length - 1]\r\n if (field === 'password' && typeof op?.value === 'string' && op.value.length > 0) {\r\n out.push(op.value)\r\n }\r\n }\r\n return out\r\n}\r\n\r\n/**\r\n * The setter the lazy catalogue initializer resolves through.\r\n *\r\n * It is republished after every render, so the newest one always wins, and a\r\n * promise that settles after an unmount writes to a harmless no-op.\r\n */\r\nlet catalogueSetter: ((catalog: Catalog) => void) | undefined = () => {}\r\n\r\n/** How one provider's last proxied request ended, as the Host recorded it. */\r\ntype LastUse = {\r\n /** When the most recent proxied request BEGAN. */\r\n startedAt?: number\r\n /** When the last request that FINISHED ended; paired with `ok`/`code`. */\r\n at?: number\r\n ok?: boolean\r\n code?: string\r\n}\r\n\r\n/** What the Host endpoint publishes: provider rows, hit counts, rejected routes. */\r\ntype Catalog = {\r\n rows: ProviderRow[]\r\n /**\r\n * Exactly what the Host published, before `knownProviders` merges saved\r\n * routes in. N7 must compare against this set: comparing against `rows`\r\n * would make every saved provider look published.\r\n */\r\n publishedRows: ProviderRow[]\r\n hits: Record<string, number>\r\n problems: Record<string, string>\r\n lastUse: Record<string, LastUse>\r\n /** Set when the FIRST read failed; a later successful poll clears it. */\r\n error?: string\r\n}\r\n\r\n/**\r\n * A coarse \"how long ago\", for the last-use line.\r\n *\r\n * Deliberately coarse: the page only re-reads the catalogue every 10 s, so a\r\n * second-precision string would look stale on its own and mean nothing.\r\n */\r\nfunction relativeTime(at: number, t: Record<string, string>): string {\r\n const seconds = Math.max(0, Math.round((Date.now() - at) / 1000))\r\n if (seconds < 60) return t.justNow\r\n const minutes = Math.floor(seconds / 60)\r\n if (minutes < 60) return `${minutes}${t.minutesAgo}`\r\n const hours = Math.floor(minutes / 60)\r\n if (hours < 24) return `${hours}${t.hoursAgo}`\r\n return `${Math.floor(hours / 24)}${t.daysAgo}`\r\n}\r\n\r\n/** Read the Host's provider catalogue. Same-origin, so no token is needed. */\r\nasync function fetchCatalog(): Promise<Catalog> {\r\n const response = await globalThis.fetch(CATALOG_PATH, { headers: { accept: 'application/json' } })\r\n if (!response.ok) throw new Error(`Host answered ${response.status}`)\r\n const body = await response.json()\r\n const list = Array.isArray(body?.providers) ? body.providers : []\r\n const rows = list\r\n .filter((row: any) => typeof row?.id === 'string' && row.id.length > 0)\r\n .map((row: any) => ({\r\n id: row.id,\r\n name: typeof row.name === 'string' && row.name.length > 0 ? row.name : row.id,\r\n live: row.live === true,\r\n }))\r\n // The Host counts requests it routed through each provider's proxy. Anything\r\n // malformed is dropped rather than rendered, so a bad payload cannot put a\r\n // non-numeric string on the page.\r\n const hits: Record<string, number> = {}\r\n const published = body?.hits\r\n if (published !== null && typeof published === 'object') {\r\n for (const [id, count] of Object.entries(published)) {\r\n if (typeof count === 'number' && Number.isFinite(count)) hits[id] = count\r\n }\r\n }\r\n // A route the Host REFUSED (a bad port, half-filled credentials) is absent from\r\n // the provider list entirely, so this map is the only place that says why it is\r\n // missing. The Host already stripped the log prefix from it.\r\n const problems: Record<string, string> = {}\r\n const rejected = body?.problems\r\n if (rejected !== null && typeof rejected === 'object') {\r\n for (const [id, message] of Object.entries(rejected)) {\r\n if (typeof message === 'string' && message.length > 0) problems[id] = message\r\n }\r\n }\r\n // The last-use record: when each provider's most recent proxied request\r\n // began, and \u2014 separately \u2014 how the last request that FINISHED ended. Anything\r\n // malformed is dropped rather than rendered, so a bad payload cannot put a\r\n // non-numeric timestamp on the page. An entry carrying only `startedAt` is\r\n // kept: it is a request still in flight, and the page says when it was started.\r\n const lastUse: Record<string, LastUse> = {}\r\n const publishedLastUse = body?.lastUse\r\n if (publishedLastUse !== null && typeof publishedLastUse === 'object') {\r\n for (const [id, raw] of Object.entries(publishedLastUse)) {\r\n const entry = raw as LastUse | undefined\r\n if (entry === null || typeof entry !== 'object') continue\r\n const at = typeof entry.at === 'number' && Number.isFinite(entry.at) ? entry.at : undefined\r\n const startedAt =\r\n typeof entry.startedAt === 'number' && Number.isFinite(entry.startedAt)\r\n ? entry.startedAt\r\n : undefined\r\n if (at === undefined && startedAt === undefined) continue\r\n lastUse[id] = {\r\n ...(startedAt === undefined ? {} : { startedAt }),\r\n ...(at === undefined ? {} : { at }),\r\n ...(typeof entry.ok === 'boolean' ? { ok: entry.ok } : {}),\r\n ...(typeof entry.code === 'string' && entry.code.length > 0 ? { code: entry.code } : {}),\r\n }\r\n }\r\n }\r\n return { rows, publishedRows: rows, hits, problems, lastUse }\r\n}\r\n\r\n/**\r\n * Catalogue polling while the page is open.\r\n *\r\n * The catalogue (published rows, hit counts, rejected routes) is fetched once at\r\n * mount and would otherwise stay a snapshot for the page's lifetime: the hit\r\n * counter never moves, and a route the Host starts or stops refusing stays\r\n * invisible. One shared interval re-fetches it every CATALOG_REFRESH_MS.\r\n *\r\n * `touchCatalogPolling` runs on every render. Writing the module-level timestamp\r\n * there is deliberately not treated as a render side effect: it is idempotent,\r\n * re-enters nothing (unlike a setState during render), and it is the only signal\r\n * that the page is still alive. A page that stops rendering \u2014 a closed panel \u2014\r\n * goes stale, and the next tick cancels the interval instead of fetching for\r\n * nobody. A failed poll is swallowed: the page keeps its last data, and the\r\n * mount-time fetch already reports a broken endpoint in the diagnostics.\r\n */\r\nconst CATALOG_REFRESH_MS = 10_000\r\nlet catalogPoll: ReturnType<typeof setInterval> | undefined\r\nlet catalogTouchedAt = 0\r\n\r\nfunction touchCatalogPolling(): void {\r\n catalogTouchedAt = Date.now()\r\n if (catalogPoll !== undefined) return\r\n catalogPoll = setInterval(() => {\r\n if (Date.now() - catalogTouchedAt > CATALOG_REFRESH_MS * 2 + 1_000) {\r\n clearInterval(catalogPoll)\r\n catalogPoll = undefined\r\n return\r\n }\r\n void fetchCatalog()\r\n .then(catalog => catalogueSetter?.(catalog))\r\n .catch(() => undefined)\r\n }, CATALOG_REFRESH_MS)\r\n}\r\n\r\nconst byName = (a: ProviderRow, b: ProviderRow): number => a.name.localeCompare(b.name)\r\n\r\nfunction view(route: Partial<RouteValue> | undefined): RouteValue {\r\n return {\r\n enabled: route?.enabled === true,\r\n useDefault: route?.useDefault === true,\r\n protocol: PROTOCOLS.includes(route?.protocol as Protocol) ? (route!.protocol as Protocol) : 'http',\r\n host: route?.host ?? '',\r\n port: route?.port ?? 0,\r\n username: route?.username ?? '',\r\n password: route?.password ?? '',\r\n onlyHosts: route?.onlyHosts ?? '',\r\n bypassHosts: route?.bypassHosts ?? '',\r\n testTarget: route?.testTarget ?? '',\r\n }\r\n}\r\n\r\n/** Drop the brackets WHATWG URL keeps on an IPv6 literal host. */\r\nfunction unbracket(hostname: string): string {\r\n return hostname.startsWith('[') && hostname.endsWith(']') ? hostname.slice(1, -1) : hostname\r\n}\r\n\r\n/**\r\n * Split a pasted full proxy URL into route fields, or `undefined` when the text\r\n * is not one.\r\n *\r\n * `socks5` is a NON-special scheme, so WHATWG URL still parses its userinfo and\r\n * port (verified), but three quirks are handled here:\r\n * - the userinfo is NOT percent-decoded by the parser, so it is decoded here;\r\n * - an IPv6 literal comes back bracketed, and the host field wants it bare;\r\n * - a DEFAULT port is stripped by WHATWG for http/https; the original text is\r\n * consulted so an explicitly written :80/:443 is preserved, while an absent\r\n * port still stays 0 (\"not configured\") instead of being invented.\r\n */\r\nfunction explicitPortOf(text: string): number {\r\n const authority = text.slice(text.indexOf('://') + 3).split(/[/?#]/, 1)[0]\r\n const hostPort = authority.slice(authority.lastIndexOf('@') + 1)\r\n const match = /^\\[[^\\]]+\\]:(\\d+)$/.exec(hostPort) ?? /^[^:]+:(\\d+)$/.exec(hostPort)\r\n if (match === null) return 0\r\n const port = Number.parseInt(match[1], 10)\r\n return Number.isNaN(port) ? 0 : port\r\n}\r\n\r\nfunction splitProxyUrl(text: string): Partial<RouteValue> | undefined {\r\n const trimmed = text.trim()\r\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(trimmed)) return undefined\r\n let url: URL\r\n try {\r\n url = new URL(trimmed)\r\n } catch {\r\n return undefined\r\n }\r\n const scheme = url.protocol.slice(0, -1).toLowerCase()\r\n // `socks://` is a common spelling this plugin does not accept on its own;\r\n // normalizing it here means a pasted alias still lands on the supported\r\n // transport instead of being rejected later.\r\n const protocol = scheme === 'socks' ? 'socks5' : scheme\r\n if (!PROTOCOLS.includes(protocol as Protocol)) return undefined\r\n if (url.hostname.length === 0) return undefined\r\n const decode = (value: string): string => {\r\n try {\r\n return decodeURIComponent(value)\r\n } catch {\r\n return value\r\n }\r\n }\r\n const parsedPort = url.port.length > 0\r\n ? Number.parseInt(url.port, 10)\r\n : explicitPortOf(trimmed)\r\n return {\r\n protocol: protocol as Protocol,\r\n host: unbracket(url.hostname),\r\n port: Number.isNaN(parsedPort) ? 0 : parsedPort,\r\n username: decode(url.username),\r\n password: decode(url.password),\r\n }\r\n}\r\n\r\n/**\r\n * Pending writes, one debounced timer per provider+field.\r\n *\r\n * Every keystroke of an input fires `bind`, and the Host rebuilds its whole\r\n * proxy table on each settings write (`loader/volatile-update` \u2192 `rebuild()`).\r\n * Writing per keystroke therefore churns a dispatcher generation per character \u2014\r\n * and, worse, a half-typed credential (\"username without a password\") hits the\r\n * Host guards between keystrokes, so the route is refused for an instant and a\r\n * misleading problem is recorded. Only the LAST value of a burst needs to reach\r\n * the Host; the draft already gives the control its instant feedback.\r\n *\r\n * Module-level, so the timers survive a re-render (each pass rebuilds `save`)\r\n * and a page unmount: a write that was already promised still lands.\r\n */\r\nconst WRITE_DELAY_MS = 300\r\ntype PendingWrite = { timer?: ReturnType<typeof setTimeout>; flush: () => Promise<void> }\r\nconst pendingWrites = new Map<string, PendingWrite>()\r\n\r\n/**\r\n * Writes are serialized so a test can await every write it flushed without\r\n * racing the settings revision fence. A run handles its own failures, so the\r\n * tail never rejects the next write.\r\n */\r\nlet writeQueue: Promise<void> = Promise.resolve()\r\nfunction enqueueWrite(run: () => Promise<void>): Promise<void> {\r\n const next = writeQueue.then(run, run)\r\n writeQueue = next.catch(() => undefined)\r\n return next\r\n}\r\n\r\n/** Schedule one debounced write; `flush` runs it immediately and only once. */\r\nfunction scheduleWrite(key: string, run: () => Promise<void>): void {\r\n const pending = pendingWrites.get(key)\r\n if (pending?.timer !== undefined) clearTimeout(pending.timer)\r\n const entry: PendingWrite = {\r\n flush: () => {\r\n if (entry.timer !== undefined) clearTimeout(entry.timer)\r\n pendingWrites.delete(key)\r\n return enqueueWrite(run)\r\n },\r\n }\r\n entry.timer = setTimeout(() => { void entry.flush() }, WRITE_DELAY_MS)\r\n pendingWrites.set(key, entry)\r\n}\r\n\r\n/**\r\n * A self-check result belongs to the configuration it was measured against.\r\n * Every relevant edit bumps this counter; a response that started under an older\r\n * generation is discarded instead of being pasted onto the new settings.\r\n */\r\nconst testGeneration = new Map<string, number>()\r\nconst TEST_RELEVANT_FIELDS = new Set([\r\n 'protocol',\r\n 'host',\r\n 'port',\r\n 'username',\r\n 'password',\r\n 'onlyHosts',\r\n 'bypassHosts',\r\n 'testTarget',\r\n 'useDefault',\r\n])\r\n\r\n/** The provider directory, cached module-side. See renderPage. */\r\nlet directoryCache: ProviderRow[] | undefined\r\n\r\n/**\r\n * Everything the page learned about its own wiring, rendered verbatim.\r\n *\r\n * The browser side of a plugin has no other diagnostic channel \u2014 the Host log\r\n * never sees it \u2014 so a silent failure had to be diagnosed by inference. This\r\n * panel is what proved that `remote.settings` and `remote.llm` do not exist in\r\n * this release, and that the catalogue had to come from the Host endpoint.\r\n *\r\n * Cleared at the start of every render so the panel shows the CURRENT state\r\n * rather than an ever-growing log of the session.\r\n */\r\nlet diagnostics: string[] = []\r\n\r\nfunction note(message: string): void {\r\n if (!diagnostics.includes(message)) diagnostics.push(message)\r\n}\r\n\r\n/**\r\n * Layout constants, applied as INLINE styles.\r\n *\r\n * The page is rendered into the settings panel, and the CSS-Modules pipeline\r\n * that feeds the stylesheet has broken twice in ways that were invisible from\r\n * the source: the class map failed to bind at all, and a shared class prefix\r\n * silently merged two rules. Both left the page readable but laid out as one\r\n * unstyled block.\r\n *\r\n * Structure is therefore expressed as inline styles, which cannot be lost by\r\n * the bundle, and the stylesheet is kept for the purely decorative parts. A\r\n * theme token that is not defined simply resolves to `unset`, so an unknown\r\n * token costs colour, never layout.\r\n */\r\nconst S = {\r\n root: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '12px',\r\n maxWidth: '720px',\r\n },\r\n card: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '12px',\r\n padding: '14px 16px',\r\n marginBottom: '12px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '10px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n },\r\n cardActive: {\r\n borderColor: 'var(--dsw-alias-state-success-primary)',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n /** An enabled route the Host refused: active-looking styling would be a lie. */\r\n cardRejected: {\r\n borderColor: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n head: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n gap: '12px',\r\n },\r\n titles: { display: 'flex', alignItems: 'baseline', gap: '8px', minWidth: '0' },\r\n name: {\r\n fontSize: '14px',\r\n fontWeight: '600',\r\n color: 'var(--dsw-alias-label-primary)',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n whiteSpace: 'nowrap',\r\n },\r\n id: {\r\n flex: 'none',\r\n padding: '1px 6px',\r\n borderRadius: '4px',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n fontFamily: 'ui-monospace, monospace',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n hits: {\r\n flex: 'none',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n whiteSpace: 'nowrap',\r\n },\r\n testRow: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '10px',\r\n flexWrap: 'wrap',\r\n },\r\n testButton: {\r\n padding: '5px 12px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '6px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-label-primary)',\r\n font: 'inherit',\r\n fontSize: '12px',\r\n cursor: 'pointer',\r\n },\r\n /** The reveal/hide control sits inside the password field's right edge. */\r\n passwordControl: {\r\n position: 'relative',\r\n minWidth: '0',\r\n },\r\n passwordToggle: {\r\n position: 'absolute',\r\n top: '50%',\r\n right: '4px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n width: '26px',\r\n height: '26px',\r\n padding: '0',\r\n border: '0',\r\n borderRadius: '6px',\r\n background: 'transparent',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n lineHeight: '1',\r\n transform: 'translateY(-50%)',\r\n cursor: 'pointer',\r\n },\r\n testResult: {\r\n // A flex row so the target can drop onto its own line: the container was a\r\n // plain span, where `flexBasis: 100%` does nothing and the target ran into\r\n // the \"cached\" label.\r\n display: 'flex',\r\n flexWrap: 'wrap',\r\n alignItems: 'baseline',\r\n columnGap: '6px',\r\n rowGap: '2px',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n wordBreak: 'break-all',\r\n },\r\n /**\r\n * A failed check is the answer, not decoration: it takes the error colour and\r\n * a heavier weight, unlike the latency band colour which only tints a number\r\n * that is printed anyway.\r\n */\r\n testFailure: {\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n fontWeight: '500',\r\n },\r\n /** A rejected route is a failure of the settings, not a warning about them. */\r\n diagProblem: {\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n },\r\n /** Informational catalogue mismatch: not a rejected route, so no error red. */\r\n diagNote: {\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n advanced: {\r\n marginTop: '4px',\r\n fontSize: '12px',\r\n },\r\n advancedSummary: {\r\n cursor: 'pointer',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n pill: {\r\n flex: 'none',\r\n padding: '2px 10px',\r\n borderRadius: '999px',\r\n fontSize: '11px',\r\n fontWeight: '500',\r\n whiteSpace: 'nowrap',\r\n },\r\n pillOn: {\r\n background: 'var(--dsw-alias-state-success-primary)',\r\n color: 'var(--dsw-alias-bg-base)',\r\n },\r\n pillLive: {\r\n border: '1px solid var(--dsw-alias-border-l2)',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n pillOff: { color: 'var(--dsw-alias-state-idle-primary)' },\r\n pillRejected: {\r\n border: '1px solid var(--dsw-alias-state-error-primary, #f85149)',\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n },\r\n /**\r\n * The shared default endpoint sits on its own layer so it reads as global\r\n * rather than as one more provider card \u2014 the mistake it exists to prevent is\r\n * a user typing the same address into every card.\r\n */\r\n defaultCard: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '10px',\r\n padding: '14px 16px',\r\n border: '1px solid var(--dsw-alias-border-l2)',\r\n borderRadius: '10px',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n defaultLead: {\r\n margin: '-2px 0 0',\r\n fontSize: '11px',\r\n lineHeight: '1.5',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n inheritNote: {\r\n margin: '0',\r\n fontSize: '11px',\r\n lineHeight: '1.5',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n /** The default is not configured: an answer, so it takes the error colour. */\r\n inheritWarning: {\r\n margin: '0',\r\n fontSize: '11px',\r\n lineHeight: '1.5',\r\n fontWeight: '500',\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n },\r\n toggle: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n fontSize: '12px',\r\n color: 'var(--dsw-alias-label-primary)',\r\n },\r\n field: {\r\n display: 'grid',\r\n gridTemplateColumns: '76px 1fr',\r\n alignItems: 'center',\r\n gap: '8px',\r\n fontSize: '12px',\r\n minWidth: '0',\r\n },\r\n label: { color: 'var(--dsw-alias-label-secondary)' },\r\n input: {\r\n boxSizing: 'border-box',\r\n width: '100%',\r\n minWidth: '0',\r\n padding: '6px 8px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '6px',\r\n outline: 'none',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-label-primary)',\r\n font: 'inherit',\r\n fontSize: '12px',\r\n },\r\n diag: {\r\n marginTop: '4px',\r\n padding: '8px 10px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '8px',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n hint: {\r\n gridColumn: '1 / -1',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-state-warn-primary, #d29922)',\r\n },\r\n chipRow: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n flexWrap: 'wrap',\r\n marginBottom: '2px',\r\n },\r\n chip: {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n padding: '3px 10px',\r\n borderRadius: '999px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n fontSize: '11px',\r\n fontWeight: '500',\r\n cursor: 'pointer',\r\n userSelect: 'none',\r\n },\r\n chipActive: {\r\n borderColor: 'var(--dsw-alias-brand-primary)',\r\n background: 'var(--dsw-alias-interactive-bg-hover)',\r\n color: 'var(--dsw-alias-brand-primary)',\r\n fontWeight: '600',\r\n },\r\n compactRow: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n gap: '10px',\r\n padding: '10px 14px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '8px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n marginBottom: '8px',\r\n },\r\n compactRowActive: {\r\n borderColor: 'var(--dsw-alias-state-success-primary)',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n compactRowRejected: {\r\n borderColor: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n compactEndpoint: {\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n whiteSpace: 'nowrap',\r\n maxWidth: '180px',\r\n },\r\n formGrid: {\r\n display: 'grid',\r\n gridTemplateColumns: 'repeat(2, minmax(0, 1fr))',\r\n alignItems: 'start',\r\n gap: '10px 14px',\r\n },\r\n formGridFull: {\r\n gridColumn: '1 / -1',\r\n },\r\n copyButton: {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n padding: '2px 4px',\r\n border: 'none',\r\n borderRadius: '4px',\r\n background: 'transparent',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n cursor: 'pointer',\r\n fontSize: '11px',\r\n lineHeight: '1',\r\n },\r\n} as const\r\n\r\nfunction renderPage(ctx: any): unknown {\r\n const React = react()\r\n if (React === undefined || typeof React.createElement !== 'function') return null\r\n\r\n const h = React.createElement\r\n const t = stringsFor(ctx)\r\n diagnostics = []\r\n\r\n // `useState` is only reached after the React check, so the early return above\r\n // cannot desync the hooks order.\r\n let snapshot: { value: any; revision: number }\r\n try {\r\n snapshot = readConfig(ctx)\r\n } catch {\r\n snapshot = { value: {}, revision: 0 }\r\n }\r\n const configured = (snapshot.value?.providers ?? {}) as Record<string, RouteValue>\r\n note(\r\n formOf(ctx) === undefined\r\n ? '\u8BBE\u7F6E\uFF1A\u672A\u627E\u5230 configForms \u670D\u52A1\uFF0C\u53EA\u80FD\u663E\u793A\u3001\u65E0\u6CD5\u4FDD\u5B58'\r\n : `\u8BBE\u7F6E\uFF1A\u6B63\u5E38\uFF08\u4FEE\u8BA2\u53F7 ${snapshot.revision}\uFF0C${Object.keys(configured).length} \u4E2A provider\uFF09`,\r\n )\r\n\r\n // The provider catalogue comes from the Host over a same-origin endpoint, so\r\n // it arrives asynchronously. The initial state is a LAZY initializer, so the\r\n // fetch starts from `useState(() => \u2026)` instead of by calling a setter during\r\n // render: a render must have no side effects, and doing so also shifted the\r\n // hook order between passes.\r\n const [state, setState] = (React.useState ?? ((fn: any) => [fn(), () => {}]))(() => {\r\n void fetchCatalog()\r\n .then(catalog => catalogueSetter?.(catalog))\r\n .catch((error: any) => {\r\n catalogueSetter?.({\r\n rows: [],\r\n publishedRows: [],\r\n hits: {},\r\n problems: {},\r\n lastUse: {},\r\n error: String(error?.message ?? error),\r\n })\r\n })\r\n return {\r\n rows: undefined as ProviderRow[] | undefined,\r\n publishedRows: undefined as ProviderRow[] | undefined,\r\n hits: {} as Record<string, number>,\r\n problems: {} as Record<string, string>,\r\n lastUse: {} as Record<string, LastUse>,\r\n error: undefined as string | undefined,\r\n pending: true,\r\n }\r\n })\r\n // The setter is published right after the hook so the initializer's promise\r\n // can reach it. It is re-published on every render, so the latest wins.\r\n catalogueSetter = catalog =>\r\n setState({\r\n rows: catalog.rows,\r\n publishedRows: catalog.publishedRows,\r\n hits: catalog.hits,\r\n problems: catalog.problems,\r\n lastUse: catalog.lastUse,\r\n error: catalog.error,\r\n pending: false,\r\n })\r\n // Keeps the catalogue (rows, hit counts, rejected routes) current while the\r\n // page is open; see the function's own notes for the staleness handling.\r\n touchCatalogPolling()\r\n\r\n const published = state.rows ?? []\r\n const publishedRows = state.publishedRows ?? []\r\n const hits = state.hits ?? {}\r\n const lastUse = state.lastUse ?? {}\r\n\r\n /**\r\n * The one-line last-use summary for a card, or `undefined` when the route has\r\n * never carried a request. `hits` says the route HAS been used; this says\r\n * whether it still works \u2014 the question a silently stalled proxy raises.\r\n *\r\n * A success or failure uses `at`, the time the last request FINISHED \u2014 the\r\n * time its outcome belongs to. A request that has only STARTED uses\r\n * `startedAt`, so a still-in-flight call cannot make the page claim an outcome\r\n * it does not have yet.\r\n */\r\n const lastUseText = (id: string): string | undefined => {\r\n const use = lastUse[id]\r\n if (use === undefined) return undefined\r\n if (use.ok === true) return `${t.recentOk}${relativeTime(use.at ?? use.startedAt ?? Date.now(), t)}`\r\n if (use.ok === false) return `${t.recentFail}${use.code ?? 'ERROR'}`\r\n return `${t.recentStarted}${relativeTime(use.startedAt ?? use.at ?? Date.now(), t)}`\r\n }\r\n // Rendered straight from state rather than through `note()`: `diagnostics` is\r\n // cleared at the start of every render, so a note written when the catalog\r\n // arrives would not survive to the next pass.\r\n const problems = state.problems ?? {}\r\n const problemLines = Object.entries(problems).map(([id, message]) =>\r\n h('li', { key: `p:${id}`, style: S.diagProblem }, `${id}\uFF1A${message}`),\r\n )\r\n const publishedIds = new Set(publishedRows.map((row: ProviderRow) => row.id))\r\n const missingFromCatalog =\r\n state.pending === true || state.error !== undefined\r\n ? []\r\n : Object.keys(configured)\r\n .filter(id => !publishedIds.has(id))\r\n .sort()\r\n const catalogueMismatchLine =\r\n missingFromCatalog.length === 0\r\n ? undefined\r\n : h(\r\n 'li',\r\n { key: 'catalogue-mismatch', style: S.diagNote },\r\n `${t.catalogueMismatch}${missingFromCatalog.join('\u3001')}${t.catalogueMismatchSuffix}`,\r\n )\r\n const problemCount = problemLines.length + (catalogueMismatchLine === undefined ? 0 : 1)\r\n note(\r\n `provider \u5217\u8868\uFF1A\u6765\u81EA Host \u5171 ${published.length} \u4E2A\uFF08${published.map((r: ProviderRow) => r.id).join('\u3001') || '\u65E0'}\uFF09`,\r\n )\r\n // Local draft, layered over the stored config.\r\n //\r\n // Without it a checkbox does not change until the panel remounts: the value\r\n // is read from the settings store, which only updates when the page is\r\n // rebuilt. The draft makes the control respond immediately, then reconciles\r\n // with the store so a refused write is visible rather than silently lost.\r\n const [draft, setDraft] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const edit = (id: string, field: string, value: unknown) =>\r\n setDraft((current: any) => ({ ...current, [id]: { ...current[id], [field]: value } }))\r\n\r\n /**\r\n * The shared default endpoint gets its own draft for the same reason a card\r\n * does: its controls must show an edit before the debounced write lands.\r\n *\r\n * It is deliberately NOT stored under a sentinel key inside `draft`:\r\n * `knownProviders` unions the stored config with the draft to build the card\r\n * list, so such a key would surface as a phantom provider with no name.\r\n */\r\n const [defaultDraft, setDefaultDraft] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const editDefault = (field: string, value: unknown) =>\r\n setDefaultDraft((current: any) => ({ ...current, [field]: value }))\r\n\r\n /**\r\n * Whether each password input is temporarily shown as plain text.\r\n *\r\n * Provider cards are keyed by id; the shared default has its own state so a\r\n * real provider named `default` cannot collide with it. This is view state\r\n * only: it is deliberately not persisted and never written to the settings.\r\n */\r\n const [passwordVisible, setPasswordVisible] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const [defaultPasswordVisible, setDefaultPasswordVisible] = (React.useState ?? ((v: any) => [v, () => {}]))(false)\r\n const togglePassword = (id: string): void =>\r\n setPasswordVisible((current: any) => ({ ...current, [id]: current[id] !== true }))\r\n const toggleDefaultPassword = (): void =>\r\n setDefaultPasswordVisible((current: boolean) => current !== true)\r\n const passwordToggle = (visible: boolean, onToggle: () => void): unknown =>\r\n h(\r\n 'button',\r\n {\r\n className: styles.passwordToggle,\r\n style: S.passwordToggle,\r\n type: 'button',\r\n 'aria-label': visible ? t.hidePassword : t.showPassword,\r\n 'aria-pressed': visible,\r\n title: visible ? t.hidePassword : t.showPassword,\r\n onClick: onToggle,\r\n },\r\n h(\r\n 'svg',\r\n {\r\n width: 16,\r\n height: 16,\r\n viewBox: '0 0 24 24',\r\n fill: 'none',\r\n stroke: 'currentColor',\r\n strokeWidth: 2,\r\n strokeLinecap: 'round',\r\n strokeLinejoin: 'round',\r\n 'aria-hidden': 'true',\r\n focusable: 'false',\r\n },\r\n h('path', {\r\n key: 'eye',\r\n d: 'M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z',\r\n }),\r\n h('circle', { key: 'pupil', cx: 12, cy: 12, r: 3 }),\r\n visible ? h('path', { key: 'slash', d: 'm3 3 18 18' }) : null,\r\n ),\r\n )\r\n\r\n /**\r\n * The advanced global fields live outside `draft` on purpose: `draft` is keyed\r\n * by provider id, and a sentinel would surface as a phantom provider row.\r\n */\r\n const [globalDraft, setGlobalDraft] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const editGlobal = (field: string, value: unknown) =>\r\n setGlobalDraft((current: any) => ({ ...current, [field]: value }))\r\n\r\n /** The latest refused write, shown above the cards instead of in the fold. */\r\n const [saveError, setSaveError] = (React.useState ?? ((v: any) => [v, () => {}]))(undefined)\r\n /** The latest accepted write, rendered in the diagnostics on the next pass. */\r\n const [savedNote, setSavedNote] = (React.useState ?? ((v: any) => [v, () => {}]))(undefined)\r\n\r\n // Self-check outcomes keyed by provider id: `{ pending: true }` while the Host\r\n // is testing, then the normalized result the card renders.\r\n const [tests, setTests] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n\r\n /** Drop results for these providers and invalidate any response in flight. */\r\n const invalidateTests = (ids: readonly string[]): void => {\r\n if (ids.length === 0) return\r\n for (const id of ids) {\r\n testGeneration.set(id, (testGeneration.get(id) ?? 0) + 1)\r\n }\r\n setTests((current: any) => {\r\n let changed = false\r\n const next = { ...current }\r\n for (const id of ids) {\r\n if (next[id] === undefined) continue\r\n delete next[id]\r\n changed = true\r\n }\r\n return changed ? next : current\r\n })\r\n }\r\n\r\n /**\r\n * The list filter. Purely a view concern: it hides cards, it never touches a\r\n * saved setting, so a page with no filter one day still shows every route.\r\n */\r\n const [filter, setFilter] = (React.useState ?? ((v: any) => [v, () => {}]))('')\r\n const [statusFilter, setStatusFilter] = (React.useState ?? ((v: any) => [v, () => {}]))('all') as [\r\n 'all' | 'proxied' | 'direct' | 'rejected',\r\n (v: any) => void,\r\n ]\r\n const [viewMode, setViewMode] = (React.useState ?? ((v: any) => [v, () => {}]))('card') as [\r\n 'card' | 'compact',\r\n (v: any) => void,\r\n ]\r\n const [expandedCards, setExpandedCards] = (React.useState ?? ((v: any) => [v, () => {}]))({}) as [\r\n Record<string, boolean>,\r\n (v: any) => void,\r\n ]\r\n const [batchProgress, setBatchProgress] = (React.useState ?? ((v: any) => [v, () => {}]))(null) as [\r\n { done: number; total: number } | null,\r\n (v: any) => void,\r\n ]\r\n const [copiedKey, setCopiedKey] = (React.useState ?? ((v: any) => [v, () => {}]))(undefined) as [\r\n string | undefined,\r\n (v: any) => void,\r\n ]\r\n\r\n const copyToClipboard = (key: string, text: string): void => {\r\n try {\r\n if (typeof globalThis.navigator?.clipboard?.writeText === 'function') {\r\n void globalThis.navigator.clipboard.writeText(text).then(() => {\r\n setCopiedKey(key)\r\n setTimeout(() => setCopiedKey((prev: any) => (prev === key ? undefined : prev)), 1500)\r\n }).catch(() => undefined)\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n const copyButton = (key: string, text: string, ariaLabel: string): unknown =>\r\n h(\r\n 'button',\r\n {\r\n className: styles.copyButton,\r\n style: S.copyButton,\r\n type: 'button',\r\n 'aria-label': ariaLabel,\r\n title: copiedKey === key ? t.copied : ariaLabel,\r\n onClick: (e: any) => {\r\n e.stopPropagation?.()\r\n copyToClipboard(key, text)\r\n },\r\n },\r\n copiedKey === key\r\n ? h(\r\n 'svg',\r\n {\r\n width: 12,\r\n height: 12,\r\n viewBox: '0 0 24 24',\r\n fill: 'none',\r\n stroke: 'var(--dsw-alias-state-success-primary, #2ea043)',\r\n strokeWidth: 2,\r\n strokeLinecap: 'round',\r\n strokeLinejoin: 'round',\r\n 'aria-hidden': 'true',\r\n },\r\n h('path', { d: 'M20 6 9 17l-5-5' }),\r\n )\r\n : h(\r\n 'svg',\r\n {\r\n width: 12,\r\n height: 12,\r\n viewBox: '0 0 24 24',\r\n fill: 'none',\r\n stroke: 'currentColor',\r\n strokeWidth: 2,\r\n strokeLinecap: 'round',\r\n strokeLinejoin: 'round',\r\n 'aria-hidden': 'true',\r\n },\r\n h('rect', { width: 14, height: 14, x: 8, y: 8, rx: 2, ry: 2 }),\r\n h('path', { d: 'M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2' }),\r\n ),\r\n copiedKey === key\r\n ? h('span', { style: { marginLeft: '3px', fontSize: '10px', color: 'var(--dsw-alias-state-success-primary, #2ea043)' } }, t.copied)\r\n : null,\r\n )\r\n\r\n /**\r\n * Run the Host's self-check for one provider.\r\n *\r\n * The check is not routed traffic, so it never changes the hit count; the count\r\n * on the card is read at mount and stays put until the page reloads.\r\n *\r\n * Pending writes for this provider (and the shared default it may inherit) are\r\n * flushed before the request: the Host reads the saved settings, not the draft,\r\n * so testing inside the 300 ms debounce would otherwise test the old endpoint.\r\n */\r\n const runTest = (id: string): Promise<void> => {\r\n const generation = (testGeneration.get(id) ?? 0) + 1\r\n testGeneration.set(id, generation)\r\n setTests((current: any) => ({ ...current, [id]: { pending: true } }))\r\n return (async () => {\r\n try {\r\n for (const [key, entry] of [...pendingWrites]) {\r\n if (\r\n key.startsWith(`${id}\\u0000`) ||\r\n key.startsWith('\\u0000default\\u0000') ||\r\n key.startsWith('\\u0000global\\u0000')\r\n ) {\r\n void entry.flush()\r\n }\r\n }\r\n await writeQueue\r\n if (testGeneration.get(id) !== generation) return\r\n const response = await globalThis.fetch(TEST_PATH, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json', accept: 'application/json' },\r\n body: JSON.stringify({ provider: id }),\r\n })\r\n const body = await response.json()\r\n if (testGeneration.get(id) !== generation) return\r\n setTests((current: any) => ({ ...current, [id]: testResultFrom(body, t) }))\r\n } catch (error: any) {\r\n if (testGeneration.get(id) !== generation) return\r\n setTests((current: any) => ({\r\n ...current,\r\n [id]: { pending: false, ok: false, error: String(error?.message ?? error) },\r\n }))\r\n }\r\n })()\r\n }\r\n\r\n const runBatchTest = (): void => {\r\n const activeIds = rows\r\n .filter(row => view({ ...configured[row.id], ...draft[row.id] }).enabled)\r\n .map(row => row.id)\r\n if (activeIds.length === 0 || batchProgress !== null) return\r\n setBatchProgress({ done: 0, total: activeIds.length })\r\n\r\n void (async () => {\r\n let index = 0\r\n let completed = 0\r\n const concurrency = Math.min(3, activeIds.length)\r\n const worker = async (): Promise<void> => {\r\n while (index < activeIds.length) {\r\n const id = activeIds[index++]\r\n await runTest(id)\r\n completed++\r\n setBatchProgress({ done: completed, total: activeIds.length })\r\n }\r\n }\r\n await Promise.all(Array.from({ length: concurrency }, () => worker()))\r\n setTimeout(() => {\r\n setBatchProgress(null)\r\n }, 2000)\r\n })()\r\n }\r\n\r\n const rows = knownProviders({ ...configured, ...draft }, published)\r\n\r\n /** Cards whose effective endpoint comes from the shared default. */\r\n const inheritingIds = (): string[] =>\r\n rows\r\n .filter(row => view({ ...configured[row.id], ...draft[row.id] }).useDefault === true)\r\n .map(row => row.id)\r\n\r\n /**\r\n * Persist one field, debounced per `key`: a burst of edits to the same control\r\n * collapses into ONE write carrying the last value. The control already shows\r\n * the new value via the draft, so this only has to succeed quietly; a refusal\r\n * is reported in the diagnostics and undone by `onRefused`.\r\n */\r\n const save = (\r\n key: string,\r\n path: unknown[],\r\n label: string,\r\n value: unknown,\r\n onRefused: () => void,\r\n ) => {\r\n const field = path[path.length - 1]\r\n const secret = field === 'password' && typeof value === 'string' ? value : undefined\r\n const safeLabel = secret === undefined ? label : `${label}\uFF08\u503C\u5DF2\u9690\u85CF\uFF09`\r\n scheduleWrite(key, () =>\r\n writeConfig(ctx, [{ op: 'set', path, value }])\r\n .then(() => {\r\n setSaveError(undefined)\r\n setSavedNote(secret === undefined ? `\u5DF2\u4FDD\u5B58 ${label}` : `\u5DF2\u4FDD\u5B58 ${safeLabel}`)\r\n })\r\n .catch((error: any) => {\r\n const message = redactSensitiveText(String(error?.message ?? error), [\r\n ...(secret === undefined ? [] : [secret]),\r\n ])\r\n setSavedNote(undefined)\r\n setSaveError({ label: safeLabel, message })\r\n onRefused()\r\n }),\r\n )\r\n }\r\n\r\n /**\r\n * Undo ONE refused field in a card's draft.\r\n *\r\n * Only that field is dropped. Other fields of the same provider may hold edits\r\n * that are still pending or already accepted \u2014 dropping the whole draft entry\r\n * would throw away values the Host never objected to. An entry left empty by\r\n * the removal is dropped entirely, so it cannot keep a phantom row alive.\r\n */\r\n const rollbackRouteField = (id: string, field: string): void => {\r\n setDraft((current: any) => {\r\n const entry = current[id]\r\n if (entry === undefined || entry[field] === undefined) return current\r\n const nextEntry = { ...entry }\r\n delete nextEntry[field]\r\n const next = { ...current }\r\n if (Object.keys(nextEntry).length === 0) delete next[id]\r\n else next[id] = nextEntry\r\n return next\r\n })\r\n }\r\n\r\n /** One card control: update the draft instantly, persist in the background. */\r\n const bind = (id: string, field: string) => (value: unknown) => {\r\n edit(id, field, value)\r\n if (TEST_RELEVANT_FIELDS.has(field)) invalidateTests([id])\r\n save(`${id}\\u0000${field}`, ['providers', id, field], `${id}.${field}`, value, () =>\r\n rollbackRouteField(id, field),\r\n )\r\n }\r\n\r\n /** One default-block control: same contract, addressed at `defaultProxy`. */\r\n const bindDefault = (field: string) => (value: unknown) => {\r\n editDefault(field, value)\r\n invalidateTests(inheritingIds())\r\n save(`\\u0000default\\u0000${field}`, ['defaultProxy', field], `defaultProxy.${field}`, value, () => {\r\n // Same rule as a card field: drop only this field, and only if the draft\r\n // still holds it, so an already-accepted sibling edit is never discarded.\r\n setDefaultDraft((current: any) => {\r\n if (current[field] === undefined) return current\r\n const next = { ...current }\r\n delete next[field]\r\n return next\r\n })\r\n })\r\n }\r\n\r\n /** One advanced global control: draft, invalidate every check, persist. */\r\n const bindGlobal = (field: 'testUrl' | 'localDirect') => (value: unknown) => {\r\n editGlobal(field, value)\r\n invalidateTests(rows.map(row => row.id))\r\n save(`\\u0000global\\u0000${field}`, [field], field, value, () => {\r\n setGlobalDraft((current: any) => {\r\n if (current[field] === undefined) return current\r\n const next = { ...current }\r\n delete next[field]\r\n return next\r\n })\r\n })\r\n }\r\n\r\n /**\r\n * One debounced write carrying SEVERAL edits at once.\r\n *\r\n * Used for a pasted proxy URL: five separate writes would each rebuild the\r\n * Host's whole proxy table, and a half-applied paste (credentials without the\r\n * host, say) would hit the credential guards mid-burst \u2014 the same trap the\r\n * per-field debounce exists to avoid.\r\n */\r\n const saveMany = (key: string, ops: unknown[], label: string, onRefused: () => void) => {\r\n const secrets = secretsFromOps(ops as any[])\r\n const hidesValues = (ops as any[]).some(op => op?.path?.[op.path.length - 1] === 'password')\r\n const safeLabel = hidesValues ? `${label}\uFF08\u503C\u5DF2\u9690\u85CF\uFF09` : label\r\n scheduleWrite(key, () =>\r\n writeConfig(ctx, ops)\r\n .then(() => {\r\n setSaveError(undefined)\r\n setSavedNote(`\u5DF2\u4FDD\u5B58 ${safeLabel}`)\r\n })\r\n .catch((error: any) => {\r\n const message = redactSensitiveText(String(error?.message ?? error), secrets)\r\n setSavedNote(undefined)\r\n setSaveError({ label: safeLabel, message })\r\n onRefused()\r\n }),\r\n )\r\n }\r\n\r\n /** Undo one set of pasted fields in a card's draft. */\r\n const rollbackRouteFields = (id: string, fields: readonly string[]): void => {\r\n setDraft((current: any) => {\r\n const entry = current[id]\r\n if (entry === undefined) return current\r\n const nextEntry = { ...entry }\r\n for (const field of fields) delete nextEntry[field]\r\n const next = { ...current }\r\n if (Object.keys(nextEntry).length === 0) delete next[id]\r\n else next[id] = nextEntry\r\n return next\r\n })\r\n }\r\n\r\n /** Apply a parsed proxy URL to one card: one draft update, one write. */\r\n const applyCardUrl = (id: string, parts: Record<string, unknown>): void => {\r\n setDraft((current: any) => ({ ...current, [id]: { ...current[id], ...parts } }))\r\n invalidateTests([id])\r\n const fields = Object.keys(parts)\r\n saveMany(\r\n `${id}\\u0000*paste`,\r\n fields.map(field => ({ op: 'set', path: ['providers', id, field], value: parts[field] })),\r\n `${id}.*\uFF08\u7C98\u8D34\u4EE3\u7406 URL\uFF09`,\r\n () => rollbackRouteFields(id, fields),\r\n )\r\n }\r\n\r\n /** Apply a parsed proxy URL to the shared default endpoint. */\r\n const applyDefaultUrl = (parts: Record<string, unknown>): void => {\r\n setDefaultDraft((current: any) => ({ ...current, ...parts }))\r\n invalidateTests(inheritingIds())\r\n const fields = Object.keys(parts)\r\n saveMany(\r\n '\\u0000default\\u0000*paste',\r\n fields.map(field => ({ op: 'set', path: ['defaultProxy', field], value: parts[field] })),\r\n '\u9ED8\u8BA4\u4EE3\u7406\uFF08\u7C98\u8D34\u4EE3\u7406 URL\uFF09',\r\n () => {\r\n setDefaultDraft((current: any) => {\r\n const next = { ...current }\r\n for (const field of fields) delete next[field]\r\n return next\r\n })\r\n },\r\n )\r\n }\r\n\r\n /**\r\n * Promote a card's own endpoint to the shared default.\r\n *\r\n * The reduced form of \"copy this card to another\": once the endpoint lives in\r\n * the default block, every other card opts in with one switch, so a\r\n * multi-select picker would be a second way to do the same thing.\r\n */\r\n const promoteToDefault = (id: string): void => {\r\n if (\r\n defaultComplete &&\r\n inheritingIds().length > 0 &&\r\n globalThis.window?.confirm?.(t.confirmPromoteToDefault) !== true\r\n ) {\r\n return\r\n }\r\n const route = view({ ...configured[id], ...draft[id] })\r\n applyDefaultUrl({\r\n protocol: route.protocol,\r\n host: route.host.trim(),\r\n port: route.port,\r\n username: route.username,\r\n password: route.password,\r\n })\r\n }\r\n\r\n /** Point every card at the default endpoint, in one write. */\r\n const applyDefaultToAll = (): void => {\r\n const ids = rows.map(row => row.id)\r\n if (ids.length === 0) return\r\n setDraft((current: any) => {\r\n const next = { ...current }\r\n for (const id of ids) next[id] = { ...next[id], useDefault: true }\r\n return next\r\n })\r\n invalidateTests(ids)\r\n saveMany(\r\n '\\u0000default\\u0000applyAll',\r\n ids.map(id => ({ op: 'set', path: ['providers', id, 'useDefault'], value: true })),\r\n `\u6240\u6709 provider \u7684 useDefault\uFF08${ids.length} \u4E2A\uFF09`,\r\n () =>\r\n setDraft((current: any) => {\r\n const next = { ...current }\r\n for (const id of ids) {\r\n const entry = next[id]\r\n if (entry === undefined || entry.useDefault === undefined) continue\r\n const nextEntry = { ...entry }\r\n delete nextEntry.useDefault\r\n if (Object.keys(nextEntry).length === 0) delete next[id]\r\n else next[id] = nextEntry\r\n }\r\n return next\r\n }),\r\n )\r\n }\r\n\r\n /**\r\n * A paste handler for any proxy-address field.\r\n *\r\n * Only a RECOGNISED proxy URL is intercepted; anything else falls through to\r\n * the browser so a pasted bare host still lands in the field normally.\r\n */\r\n const onProxyUrlPaste =\r\n (apply: (parts: Record<string, unknown>) => void) =>\r\n (event: any): void => {\r\n const text = event?.clipboardData?.getData?.('text')\r\n if (typeof text !== 'string') return\r\n const parts = splitProxyUrl(text)\r\n if (parts === undefined) return\r\n event.preventDefault?.()\r\n apply(parts)\r\n }\r\n\r\n const field = (\r\n label: string,\r\n control: unknown,\r\n hint?: string,\r\n hintError?: boolean,\r\n fullWidth?: boolean,\r\n ): unknown =>\r\n h(\r\n 'label',\r\n {\r\n className: `${styles.field}${fullWidth ? ` ${styles.formGridFull}` : ''}`,\r\n style: {\r\n ...S.field,\r\n ...(fullWidth ? S.formGridFull : {}),\r\n },\r\n key: label,\r\n },\r\n h('span', { className: styles.label, style: S.label }, label),\r\n control,\r\n hint === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n {\r\n className: styles.hint,\r\n style: {\r\n ...S.hint,\r\n marginTop: '2px',\r\n // A warning that a value can never work is an answer, not\r\n // decoration \u2014 same rule as the failed self-check text.\r\n ...(hintError === true\r\n ? { color: 'var(--dsw-alias-state-error-primary, #f85149)' }\r\n : {}),\r\n },\r\n },\r\n hint,\r\n ),\r\n )\r\n\r\n /**\r\n * The shared endpoint block, always rendered.\r\n *\r\n * It is the only place the address can be entered, so hiding it until some\r\n * card opts in would leave no way to configure it in the first place.\r\n */\r\n const storedDefault = (snapshot.value?.defaultProxy ?? {}) as Partial<RouteValue>\r\n const defaultView = view({ ...storedDefault, ...defaultDraft })\r\n // The SAME predicate the Host applies, imported rather than re-written: a\r\n // browser copy that only checked \"host non-empty and port in range\" called\r\n // `https://1.2.3.4` complete and enabled the bulk button, while the Host refused\r\n // every route pointed at it.\r\n //\r\n // The REASON is kept as well as the verdict: the block refuses for several\r\n // reasons (no host, a scheme-carrying host, a bad port, a half-filled\r\n // credential), and a card that said \"missing host or port\" for all of them sent\r\n // the user to the one field that was already correct.\r\n const defaultWhy = defaultProxyProblem(defaultView)\r\n // An empty optional block is \"not configured\", not a typed mistake. Only an\r\n // invalid NON-empty host gets the error colour under the input.\r\n const defaultHostWhy = defaultView.host.trim().length === 0\r\n ? undefined\r\n : proxyHostProblem(defaultView.host)\r\n const defaultComplete = defaultWhy === undefined\r\n const defaultOrigin = `${defaultView.protocol}://${defaultView.host}:${defaultView.port}`\r\n const defaultBlock = h(\r\n 'div',\r\n { className: styles.defaultCard, style: S.defaultCard, key: 'default-proxy' },\r\n h(\r\n 'header',\r\n { className: styles.cardHead, style: S.head },\r\n h(\r\n 'div',\r\n { className: styles.cardTitles, style: S.titles },\r\n h('span', { className: styles.name, style: S.name }, t.defaultTitle),\r\n ),\r\n h(\r\n 'span',\r\n {\r\n className: defaultComplete ? styles.pillOn : styles.pillOff,\r\n style: { ...S.pill, ...(defaultComplete ? S.pillOn : S.pillOff) },\r\n },\r\n defaultComplete ? t.complete : t.notConfigured,\r\n ),\r\n ),\r\n h('p', { className: styles.defaultLead, style: S.defaultLead }, t.defaultLead),\r\n h(\r\n 'div',\r\n { className: styles.formGrid, style: S.formGrid, key: 'default:form-grid' },\r\n field(\r\n t.protocol,\r\n h(\r\n 'select',\r\n {\r\n className: styles.input,\r\n style: S.input,\r\n value: defaultView.protocol,\r\n onChange: (event: any) => bindDefault('protocol')(event.target.value),\r\n },\r\n ...PROTOCOLS.map(protocol =>\r\n h('option', { key: protocol, value: protocol }, protocol.toUpperCase()),\r\n ),\r\n ),\r\n ),\r\n field(\r\n t.host,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: '127.0.0.1',\r\n value: defaultView.host,\r\n onChange: (event: any) => bindDefault('host')(event.target.value),\r\n // Same convenience as the cards: a full URL fills the whole block.\r\n onPaste: onProxyUrlPaste(applyDefaultUrl),\r\n }),\r\n defaultHostWhy ?? t.hostHint,\r\n defaultHostWhy !== undefined,\r\n ),\r\n field(\r\n t.port,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n type: 'number',\r\n min: 1,\r\n max: 65535,\r\n placeholder: '7890',\r\n value: defaultView.port === 0 ? '' : String(defaultView.port),\r\n onChange: (event: any) => {\r\n const parsed = Number.parseInt(event.target.value, 10)\r\n bindDefault('port')(Number.isNaN(parsed) ? 0 : parsed)\r\n },\r\n }),\r\n ),\r\n field(\r\n t.username,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n autoComplete: 'off',\r\n value: defaultView.username,\r\n onChange: (event: any) => bindDefault('username')(event.target.value),\r\n }),\r\n ),\r\n field(\r\n t.password,\r\n h(\r\n 'div',\r\n { style: S.passwordControl },\r\n h('input', {\r\n className: styles.input,\r\n style: { ...S.input, paddingRight: '36px' },\r\n type: defaultPasswordVisible === true ? 'text' : 'password',\r\n autoComplete: 'off',\r\n value: defaultView.password,\r\n onChange: (event: any) => bindDefault('password')(event.target.value),\r\n }),\r\n passwordToggle(defaultPasswordVisible === true, toggleDefaultPassword),\r\n ),\r\n t.passwordHintProxy,\r\n false,\r\n true,\r\n ),\r\n ),\r\n // Bulk opt-in, in ONE write: a per-card walk would rebuild the table N times.\r\n // Disabled while the default configuration is incomplete, because pointing every card at an\r\n // empty endpoint would just refuse them all.\r\n h(\r\n 'div',\r\n { style: S.testRow, key: 'default:apply' },\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n disabled: !defaultComplete || rows.length === 0,\r\n onClick: applyDefaultToAll,\r\n },\r\n `${t.applyDefaultAll}\uFF08${rows.length}\uFF09`,\r\n ),\r\n ),\r\n )\r\n\r\n const storedTestUrl =\r\n typeof snapshot.value?.testUrl === 'string' ? snapshot.value.testUrl : DEFAULT_TEST_URL\r\n const storedLocalDirect = snapshot.value?.localDirect !== false\r\n const globalTestUrl = typeof globalDraft.testUrl === 'string' ? globalDraft.testUrl : storedTestUrl\r\n const globalLocalDirect =\r\n typeof globalDraft.localDirect === 'boolean' ? globalDraft.localDirect : storedLocalDirect\r\n const globalTestUrlHint = testUrlHint(globalTestUrl, t)\r\n const globalBlock = h(\r\n 'details',\r\n {\r\n className: styles.diag,\r\n style: {\r\n ...S.diag,\r\n marginTop: '0',\r\n },\r\n key: 'global-settings',\r\n },\r\n h('summary', { className: styles.diagSummary }, t.globalTitle),\r\n h('p', { className: styles.defaultLead, style: S.defaultLead }, t.globalLead),\r\n h(\r\n 'label',\r\n { className: styles.field, style: S.field },\r\n h('span', { className: styles.label, style: S.label }, t.testUrl),\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n value: globalTestUrl,\r\n onChange: (event: any) => bindGlobal('testUrl')(event.target.value),\r\n }),\r\n globalTestUrlHint === undefined\r\n ? h('span', { className: styles.hint, style: S.hint }, t.testUrlHint)\r\n : h(\r\n 'span',\r\n {\r\n className: styles.hint,\r\n style: {\r\n ...S.hint,\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n },\r\n },\r\n globalTestUrlHint,\r\n ),\r\n ),\r\n h(\r\n 'div',\r\n { style: S.testRow },\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n onClick: () => bindGlobal('testUrl')(DEFAULT_TEST_URL),\r\n },\r\n t.restoreDefaultTestUrl,\r\n ),\r\n ),\r\n h(\r\n 'label',\r\n { className: styles.toggle, style: S.toggle },\r\n h('input', {\r\n type: 'checkbox',\r\n checked: globalLocalDirect,\r\n onChange: (event: any) => bindGlobal('localDirect')(event.target.checked === true),\r\n }),\r\n h('span', null, t.localDirect),\r\n ),\r\n h(\r\n 'p',\r\n { className: styles.hint, style: { ...S.hint, margin: '2px 0 0' } },\r\n globalLocalDirect ? t.localDirectOnHint : t.localDirectOffHint,\r\n ),\r\n )\r\n\r\n const routeStateOf = (row: ProviderRow): 'proxied' | 'direct' | 'rejected' => {\r\n const route = view({ ...configured[row.id], ...draft[row.id] })\r\n const recorded = problems[row.id]\r\n const useDefault = route.useDefault === true\r\n const problemText = recorded !== undefined\r\n ? recorded\r\n : useDefault\r\n ? (defaultComplete ? undefined : `${t.defaultMissing}${defaultWhy}`)\r\n : (route.enabled ? defaultProxyProblem(route) : undefined)\r\n if (route.enabled && problemText !== undefined) return 'rejected'\r\n if (route.enabled) return 'proxied'\r\n return 'direct'\r\n }\r\n\r\n const query = filter.trim().toLowerCase()\r\n const matchedKeywordRows =\r\n query.length === 0\r\n ? rows\r\n : rows.filter(row => `${row.id} ${row.name}`.toLowerCase().includes(query))\r\n\r\n const countActive = matchedKeywordRows.filter(r => routeStateOf(r) === 'proxied').length\r\n const countDirect = matchedKeywordRows.filter(r => routeStateOf(r) === 'direct').length\r\n const countRejected = matchedKeywordRows.filter(r => routeStateOf(r) === 'rejected').length\r\n\r\n const shown = matchedKeywordRows.filter(row => {\r\n if (statusFilter === 'all') return true\r\n return routeStateOf(row) === statusFilter\r\n })\r\n\r\n const chipRow =\r\n rows.length === 0\r\n ? null\r\n : h(\r\n 'div',\r\n { className: styles.chipRow, style: S.chipRow, key: 'status-chips' },\r\n ([\r\n { id: 'all', label: `${t.filterStatusAll} (${matchedKeywordRows.length})` },\r\n { id: 'proxied', label: `${t.filterStatusProxied} (${countActive})` },\r\n { id: 'direct', label: `${t.filterStatusDirect} (${countDirect})` },\r\n { id: 'rejected', label: `${t.filterStatusRejected} (${countRejected})` },\r\n ] as const).map(({ id, label }) =>\r\n h(\r\n 'button',\r\n {\r\n key: id,\r\n type: 'button',\r\n className: statusFilter === id ? styles.chipActive : styles.chip,\r\n style: {\r\n ...S.chip,\r\n ...(statusFilter === id ? S.chipActive : {}),\r\n },\r\n onClick: () => setStatusFilter(id),\r\n },\r\n label,\r\n ),\r\n ),\r\n )\r\n\r\n const filterRow =\r\n rows.length === 0\r\n ? null\r\n : field(\r\n t.filterLabel,\r\n h(\r\n 'div',\r\n { style: { display: 'flex', alignItems: 'center', gap: '8px' } },\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: t.filterPlaceholder,\r\n value: filter,\r\n onChange: (event: any) => setFilter(event.target.value),\r\n }),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, flex: 'none', whiteSpace: 'nowrap' },\r\n type: 'button',\r\n disabled: countActive === 0 || batchProgress !== null,\r\n onClick: runBatchTest,\r\n },\r\n batchProgress !== null\r\n ? `${t.batchTesting} (${batchProgress.done}/${batchProgress.total})`\r\n : `${t.batchTest} (${countActive})`,\r\n ),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, flex: 'none', whiteSpace: 'nowrap' },\r\n type: 'button',\r\n onClick: () => setViewMode((m: any) => (m === 'card' ? 'compact' : 'card')),\r\n },\r\n viewMode === 'card' ? t.viewCompact : t.viewCard,\r\n ),\r\n ),\r\n )\r\n\r\n // The empty slot answers three different questions: still loading, the read\r\n // failed, or truly nothing to show. Only the last is the empty message.\r\n // With saved cards present, a failed first read is reported above them instead.\r\n const catalogueStatus = rows.length === 0\r\n ? state.pending\r\n ? { text: t.catalogueLoading, error: false }\r\n : state.error !== undefined\r\n ? { text: `${t.catalogueError}${state.error}`, error: true }\r\n : undefined\r\n : undefined\r\n const catalogueNotice =\r\n state.error !== undefined && rows.length > 0\r\n ? h(\r\n 'p',\r\n { key: 'catalogue-error', style: S.inheritWarning },\r\n `${t.catalogueStale}${state.error}`,\r\n )\r\n : null\r\n\r\n // ALWAYS an array: a single element is not iterable, and spreading one threw\r\n // \"Spread syntax requires ...iterable[Symbol.iterator]\" on an empty list.\r\n const body: unknown[] = shown.length === 0\r\n ? [\r\n h(\r\n 'p',\r\n {\r\n className: styles.empty,\r\n key: 'empty',\r\n style: {\r\n margin: '0',\r\n padding: '16px',\r\n border: '1px dashed var(--dsw-alias-border-l1)',\r\n borderRadius: '8px',\r\n fontSize: '12px',\r\n textAlign: 'center',\r\n color: catalogueStatus?.error === true\r\n ? 'var(--dsw-alias-state-error-primary, #f85149)'\r\n : 'var(--dsw-alias-state-idle-primary)',\r\n ...(catalogueStatus?.error === true ? { fontWeight: '500' } : {}),\r\n },\r\n },\r\n catalogueStatus?.text ?? (query.length > 0 ? t.noMatch : t.empty),\r\n ),\r\n ]\r\n : shown.map(row => {\r\n // The MERGED value, so a just-typed value shows immediately.\r\n const route = view({ ...configured[row.id], ...draft[row.id] })\r\n // The endpoint controls are editable whether or not the route is on: the\r\n // point of the self-check below is to verify a setting BEFORE switching\r\n // it on, which is impossible if the fields can only be typed into while\r\n // traffic is already flowing through them. `enabled` gates routing only.\r\n // The line exists only once a route has actually carried a request, so an\r\n // ENABLED route with no record yet says so \u2014 otherwise a missing line is\r\n // indistinguishable from the feature not existing. A disabled route stays\r\n // silent: it cannot have a record, and saying so on every off card is noise.\r\n const lastText = lastUseText(row.id) ?? (route.enabled ? t.noRecord : undefined)\r\n const result = tests[row.id]\r\n // Rule entries that can never match: flagged under the input instead of\r\n // failing silently \u2014 a dead `onlyHosts` entry means fail-closed sends\r\n // the traffic DIRECT while the user believes it is proxied.\r\n const onlyDead = deadRuleEntries(route.onlyHosts)\r\n const bypassDead = deadRuleEntries(route.bypassHosts)\r\n const useDefault = route.useDefault === true\r\n // Whether this card has an endpoint worth checking: an inheriting card\r\n // depends on the shared default being configured, an own-endpoint card on\r\n // its host and port being complete. Mirrors the Host's own build gate.\r\n const endpointStored = route.useDefault\r\n ? defaultComplete\r\n : route.host.trim().length > 0 &&\r\n Number.isInteger(route.port) &&\r\n route.port >= 1 &&\r\n route.port <= 65535\r\n const showTest = route.enabled || endpointStored\r\n // The Host's recorded problem is authoritative (it also covers dispatcher\r\n // construction); until the next catalogue poll, the shared predicate can\r\n // already prove the common endpoint mistakes. An unused route is never\r\n // \"rejected\" \u2014 it has not asked for anything yet.\r\n const problemText = ((): string | undefined => {\r\n const recorded = problems[row.id]\r\n if (recorded !== undefined) return recorded\r\n if (useDefault) return defaultComplete ? undefined : `${t.defaultMissing}${defaultWhy}`\r\n return route.enabled ? defaultProxyProblem(route) : undefined\r\n })()\r\n const rejected = route.enabled && problemText !== undefined\r\n // Built once and either rendered (this route carries its own address) or\r\n // replaced by a one-line note (it inherits the shared default), so a card\r\n // can never show an input that does not apply to it.\r\n const endpointFields = [\r\n field(\r\n t.protocol,\r\n h(\r\n 'select',\r\n {\r\n className: styles.input,\r\n style: S.input,\r\n value: route.protocol,\r\n onChange: (event: any) => bind(row.id, 'protocol')(event.target.value),\r\n },\r\n ...PROTOCOLS.map(protocol =>\r\n h('option', { key: protocol, value: protocol }, protocol.toUpperCase()),\r\n ),\r\n ),\r\n route.protocol === 'socks5' ? t.socks5Hint : undefined,\r\n ),\r\n field(\r\n t.host,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: '127.0.0.1',\r\n value: route.host,\r\n onChange: (event: any) => bind(row.id, 'host')(event.target.value),\r\n // A pasted full proxy URL fills every transport field at once.\r\n onPaste: onProxyUrlPaste(parts => applyCardUrl(row.id, parts)),\r\n }),\r\n t.hostHint,\r\n ),\r\n field(\r\n t.port,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n type: 'number',\r\n min: 1,\r\n max: 65535,\r\n placeholder: '7890',\r\n value: route.port === 0 ? '' : String(route.port),\r\n onChange: (event: any) => {\r\n const parsed = Number.parseInt(event.target.value, 10)\r\n bind(row.id, 'port')(Number.isNaN(parsed) ? 0 : parsed)\r\n },\r\n }),\r\n ),\r\n field(\r\n t.username,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n autoComplete: 'off',\r\n value: route.username,\r\n onChange: (event: any) => bind(row.id, 'username')(event.target.value),\r\n }),\r\n ),\r\n // Every transport accepts a password: SOCKS5 hands it to\r\n // Socks5ProxyAgent as an option, HTTP/HTTPS embed it in the proxy URL\r\n // userinfo (undici turns that into Proxy-Authorization). It is stored on\r\n // the route, so it lands in the settings file with the rest of the\r\n // config; the diagnostics only ever surface a credential-free origin.\r\n field(\r\n t.password,\r\n h(\r\n 'div',\r\n { style: S.passwordControl },\r\n h('input', {\r\n className: styles.input,\r\n style: { ...S.input, paddingRight: '36px' },\r\n type: passwordVisible[row.id] === true ? 'text' : 'password',\r\n autoComplete: 'off',\r\n value: route.password,\r\n onChange: (event: any) => bind(row.id, 'password')(event.target.value),\r\n }),\r\n passwordToggle(passwordVisible[row.id] === true, () => togglePassword(row.id)),\r\n ),\r\n route.protocol === 'socks5' ? t.passwordHint : t.passwordHintProxy,\r\n false,\r\n true,\r\n ),\r\n ]\r\n // The pill describes the ROUTE, never provider availability: a saved\r\n // route can outlive the Host directory, and whether that directory lists\r\n // it must not make the proxy switch read as \"offline\" or \"proxied\".\r\n const pill = rejected\r\n ? { className: styles.pillRejected, style: { ...S.pill, ...S.pillRejected }, text: t.rejected }\r\n : route.enabled\r\n ? { className: styles.pillOn, style: { ...S.pill, ...S.pillOn }, text: t.on }\r\n : { className: styles.pillLive, style: { ...S.pill, ...S.pillLive }, text: t.off }\r\n const cardSection = h(\r\n 'section',\r\n {\r\n className: rejected ? styles.cardRejected : route.enabled ? styles.cardActive : styles.card,\r\n style: rejected\r\n ? { ...S.card, ...S.cardRejected }\r\n : route.enabled\r\n ? { ...S.card, ...S.cardActive }\r\n : S.card,\r\n key: row.id,\r\n },\r\n h(\r\n 'header',\r\n { className: styles.cardHead, style: S.head },\r\n h(\r\n 'div',\r\n { className: styles.cardTitles, style: S.titles },\r\n h('span', { className: styles.name, style: S.name }, row.name),\r\n h('span', { className: styles.id, style: S.id }, row.id),\r\n // A disabled route can never have hits, so \"0\" there would only add\r\n // noise; the count shows once the route is on (or has counted).\r\n route.enabled || (hits[row.id] ?? 0) > 0\r\n ? h(\r\n 'span',\r\n { style: S.hits },\r\n `${t.hitCountPrefix}${hits[row.id] ?? 0}${t.hitCountSuffix}`,\r\n )\r\n : null,\r\n // The last-use line. A failure takes the error colour, same rule as\r\n // a failed self-check: it is an answer, not decoration.\r\n lastText === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n {\r\n style: {\r\n ...S.hits,\r\n ...(lastUse[row.id]?.ok === false ? S.inheritWarning : {}),\r\n },\r\n },\r\n lastText,\r\n ),\r\n ),\r\n h('span', { className: pill.className, style: pill.style }, pill.text),\r\n ),\r\n h(\r\n 'label',\r\n { className: styles.toggle, style: S.toggle },\r\n h('input', {\r\n type: 'checkbox',\r\n checked: route.enabled,\r\n onChange: (event: any) => bind(row.id, 'enabled')(event.target.checked === true),\r\n }),\r\n h('span', null, t.useProxy),\r\n ),\r\n // Opting into the shared endpoint. The card then shows the address it\r\n // will actually use \u2014 or, when the default is not configured, why the\r\n // route is refused \u2014 instead of a set of empty inputs the user never\r\n // filled and cannot interpret.\r\n h(\r\n 'label',\r\n { className: styles.toggle, style: S.toggle, key: `${row.id}:usedefault` },\r\n h('input', {\r\n type: 'checkbox',\r\n checked: useDefault,\r\n onChange: (event: any) => bind(row.id, 'useDefault')(event.target.checked === true),\r\n }),\r\n h('span', null, t.useDefault),\r\n ),\r\n problemText !== undefined\r\n ? h('p', { key: `${row.id}:problem`, style: S.inheritWarning }, problemText)\r\n : useDefault\r\n ? h(\r\n 'p',\r\n { key: `${row.id}:inherit`, style: S.inheritNote },\r\n `${t.inheritingDefault}${defaultOrigin}`,\r\n )\r\n : null,\r\n ...(useDefault\r\n ? []\r\n : [h('div', { className: styles.formGrid, style: S.formGrid, key: `${row.id}:form-grid` }, ...endpointFields)]),\r\n // The self-check is offered whenever there is something to check: an\r\n // enabled route (the Host's table carries it, and a rejected one still\r\n // reports WHY), or a disabled one whose endpoint is already complete \u2014\r\n // the Host builds that one for the check alone. A disabled route with\r\n // no endpoint has nothing to test and would only answer \"not enabled\".\r\n showTest\r\n ? h(\r\n 'div',\r\n { style: S.testRow, key: `${row.id}:test` },\r\n // A check on a route that is still off is a trial run, and it says\r\n // so \u2014 otherwise the result reads as though the route were live.\r\n route.enabled ? null : h('span', { style: S.testResult }, t.testDisabledNote),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n disabled: result?.pending === true,\r\n onClick: () => runTest(row.id),\r\n },\r\n result?.pending === true ? t.testRunning : t.testButton,\r\n ),\r\n result?.pending === false\r\n ? h(\r\n 'div',\r\n { style: S.testResult },\r\n result.ok === true\r\n ? [\r\n // The band colour belongs to the LATENCY alone. The\r\n // status sits beside it in the plain label colour:\r\n // colouring the whole line made a successful check\r\n // over 1500 ms read as a failure.\r\n h(\r\n 'span',\r\n { key: 'lat', style: { color: latencyColor(result.ms) } },\r\n `\u2713 ${typeof result.ms === 'number' ? result.ms : '\u2014'} ms`,\r\n ),\r\n typeof result.status === 'number'\r\n ? h(\r\n 'span',\r\n { key: 'status' },\r\n `HTTP ${result.status}`,\r\n )\r\n : null,\r\n result.ip === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n { key: 'ip', style: { display: 'inline-flex', alignItems: 'center', gap: '3px' } },\r\n `${t.exitIpLabel}${result.ip}`,\r\n copyButton(`${row.id}:ip`, result.ip, t.copy),\r\n ),\r\n result.direct === true\r\n ? h('span', { key: 'direct' }, t.directLabel)\r\n : null,\r\n result.cached === true\r\n ? h('span', { key: 'cached' }, t.cachedLabel)\r\n : null,\r\n result.target === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n {\r\n key: 'target',\r\n style: {\r\n flexBasis: '100%',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n wordBreak: 'break-all',\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n gap: '3px',\r\n },\r\n },\r\n `${t.testTargetLabel}${result.target}${targetSourceSuffix(result, t)}`,\r\n copyButton(`${row.id}:target`, result.target, t.copy),\r\n ),\r\n ]\r\n : [\r\n h(\r\n 'span',\r\n { key: 'err', style: { ...S.testFailure, display: 'inline-flex', alignItems: 'center', gap: '3px' } },\r\n `\u2717 ${result.error}`,\r\n copyButton(`${row.id}:err`, String(result.error), t.copy),\r\n ),\r\n typeof result.status === 'number'\r\n ? h('span', { key: 'status' }, `HTTP ${result.status}`)\r\n : null,\r\n result.target === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n {\r\n key: 'target',\r\n style: {\r\n flexBasis: '100%',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n wordBreak: 'break-all',\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n gap: '3px',\r\n },\r\n },\r\n `${t.testTargetLabel}${result.target}${targetSourceSuffix(result, t)}`,\r\n copyButton(`${row.id}:target`, result.target, t.copy),\r\n ),\r\n ],\r\n )\r\n : null,\r\n // Promote this card's endpoint to the shared default. Offered only\r\n // when the card carries its OWN endpoint: an inheriting card would\r\n // just be copying the default onto itself.\r\n endpointStored && !useDefault\r\n ? h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n onClick: () => promoteToDefault(row.id),\r\n },\r\n t.setAsDefault,\r\n )\r\n : null,\r\n )\r\n : null,\r\n // Target-host rules, collapsed so the common case stays one short card.\r\n h(\r\n 'details',\r\n { style: S.advanced, key: `${row.id}:rules` },\r\n h('summary', { style: S.advancedSummary }, t.advanced),\r\n field(\r\n t.onlyHosts,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: 'api.example.com',\r\n value: route.onlyHosts,\r\n onChange: (event: any) => bind(row.id, 'onlyHosts')(event.target.value),\r\n }),\r\n onlyDead.length === 0 ? t.onlyHostsHint : `${t.ruleDeadHint}${onlyDead.join('\u3001')}`,\r\n onlyDead.length > 0,\r\n ),\r\n field(\r\n t.bypassHosts,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: 'localhost',\r\n value: route.bypassHosts,\r\n onChange: (event: any) => bind(row.id, 'bypassHosts')(event.target.value),\r\n }),\r\n bypassDead.length === 0 ? t.bypassHostsHint : `${t.ruleDeadHint}${bypassDead.join('\u3001')}`,\r\n bypassDead.length > 0,\r\n ),\r\n // The self-check target: empty uses the top-level testUrl, set makes\r\n // this card's Test request this URL \u2014 a real upstream proves the whole\r\n // path, not just the proxy hop.\r\n field(\r\n t.testTarget,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: 'https://api.example.com',\r\n value: route.testTarget,\r\n onChange: (event: any) => bind(row.id, 'testTarget')(event.target.value),\r\n }),\r\n t.testTargetHint,\r\n ),\r\n ),\r\n )\r\n\r\n const isExpanded = expandedCards[row.id] === true\r\n const compactRowElement = h(\r\n 'section',\r\n {\r\n className: rejected ? styles.compactRowRejected : route.enabled ? styles.compactRowActive : styles.compactRow,\r\n style: rejected\r\n ? { ...S.compactRow, ...S.compactRowRejected }\r\n : route.enabled\r\n ? { ...S.compactRow, ...S.compactRowActive }\r\n : S.compactRow,\r\n key: `compact:${row.id}`,\r\n },\r\n h(\r\n 'div',\r\n { style: { display: 'flex', alignItems: 'center', gap: '8px', minWidth: '0' } },\r\n h('input', {\r\n type: 'checkbox',\r\n checked: route.enabled,\r\n onChange: (event: any) => bind(row.id, 'enabled')(event.target.checked === true),\r\n }),\r\n h('span', { className: styles.name, style: { ...S.name, maxWidth: '140px' } }, row.name),\r\n h('span', { className: styles.id, style: S.id }, row.id),\r\n useDefault\r\n ? h('span', { style: S.compactEndpoint }, `${t.useDefault}: ${defaultOrigin}`)\r\n : h('span', { style: S.compactEndpoint }, `${route.protocol.toUpperCase()}://${route.host || '\u2014'}:${route.port || '\u2014'}`),\r\n ),\r\n h(\r\n 'div',\r\n { style: { display: 'flex', alignItems: 'center', gap: '8px', flex: 'none' } },\r\n result?.pending === true\r\n ? h('span', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary)' } }, t.testRunning)\r\n : result?.ok === true\r\n ? h('span', { style: { fontSize: '11px', color: latencyColor(result.ms), fontWeight: '500' } }, `\u2713 ${result.ms ?? '\u2014'} ms`)\r\n : result?.ok === false\r\n ? h('span', { style: { fontSize: '11px', color: 'var(--dsw-alias-state-error-primary, #f85149)', fontWeight: '500' } }, `\u2717 ${result.error}`)\r\n : lastText !== undefined\r\n ? h('span', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary)' } }, lastText)\r\n : null,\r\n h('span', { className: pill.className, style: pill.style }, pill.text),\r\n showTest\r\n ? h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, padding: '3px 8px', fontSize: '11px' },\r\n type: 'button',\r\n disabled: result?.pending === true,\r\n onClick: () => runTest(row.id),\r\n },\r\n result?.pending === true ? t.testRunning : t.testButton,\r\n )\r\n : null,\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, padding: '3px 8px', fontSize: '11px' },\r\n type: 'button',\r\n onClick: () => setExpandedCards((curr: any) => ({ ...curr, [row.id]: !curr[row.id] })),\r\n },\r\n isExpanded ? t.collapseDetails : t.expandDetails,\r\n ),\r\n ),\r\n )\r\n\r\n if (viewMode === 'compact') {\r\n return isExpanded\r\n ? h('div', { key: `compact-wrap:${row.id}` }, compactRowElement, cardSection)\r\n : compactRowElement\r\n }\r\n return cardSection\r\n })\r\n\r\n return h(\r\n 'div',\r\n { className: styles.root, style: S.root },\r\n h('p', { className: styles.lead, style: { margin: '0 0 4px', fontSize: '12px', lineHeight: '1.6', color: 'var(--dsw-alias-label-secondary)' } }, t.lead),\r\n saveError === undefined\r\n ? null\r\n : h(\r\n 'div',\r\n {\r\n role: 'alert',\r\n key: 'save-error',\r\n style: {\r\n display: 'flex',\r\n alignItems: 'flex-start',\r\n justifyContent: 'space-between',\r\n gap: '10px',\r\n padding: '8px 10px',\r\n border: '1px solid var(--dsw-alias-state-error-primary, #f85149)',\r\n borderRadius: '8px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n fontSize: '12px',\r\n fontWeight: '500',\r\n wordBreak: 'break-all',\r\n },\r\n },\r\n h('span', null, `${t.saveFailedPrefix}${saveError.label} \u2014 ${saveError.message}`),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, flex: 'none' },\r\n type: 'button',\r\n onClick: () => setSaveError(undefined),\r\n },\r\n t.close,\r\n ),\r\n ),\r\n defaultBlock,\r\n globalBlock,\r\n catalogueNotice,\r\n chipRow,\r\n filterRow,\r\n ...body,\r\n h(\r\n 'details',\r\n {\r\n className: styles.diag,\r\n key: 'diag',\r\n style: {\r\n marginTop: '4px',\r\n padding: '8px 10px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '8px',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n },\r\n // The count is the only visible signal while the panel is collapsed: a\r\n // rejected route is not a page that refuses to render, it is one that\r\n // quietly does nothing.\r\n h(\r\n 'summary',\r\n { className: styles.diagSummary },\r\n problemCount === 0 ? t.diagnostics : `${t.diagnostics} (${problemCount})`,\r\n ),\r\n h(\r\n 'ul',\r\n { className: styles.diagList, style: { margin: '6px 0 0', paddingLeft: '18px' } },\r\n ...(problemCount === 0 && diagnostics.length === 0 && savedNote === undefined\r\n ? [h('li', { key: 'none' }, t.diagPending)]\r\n : [\r\n ...problemLines,\r\n ...(catalogueMismatchLine === undefined ? [] : [catalogueMismatchLine]),\r\n ...(savedNote === undefined ? [] : [h('li', { key: 'saved' }, savedNote)]),\r\n ...diagnostics.map((line, index) => h('li', { key: `d${index}` }, line)),\r\n ]),\r\n ),\r\n ),\r\n )\r\n}\r\n\r\nconst EN = {\r\n lead: 'Route selected model providers through your own forward proxy. Other providers stay direct. Requests to loopback or private addresses (localhost, 127.x, private ranges) go direct by default; set the top-level localDirect to false to proxy them instead \u2014 a forward proxy normally cannot reach your own machine.',\r\n empty: 'No providers found yet.',\r\n catalogueLoading: 'Loading providers\u2026',\r\n catalogueError: 'Could not load the provider list: ',\r\n catalogueStale: 'Could not load the provider list; showing the saved configuration: ',\r\n useProxy: 'Use a proxy for this provider',\r\n useDefault: 'Use the default proxy',\r\n defaultTitle: 'Default proxy',\r\n defaultLead: 'One endpoint, reused by every provider that turns on \"Use the default proxy\". The status only reports configuration completeness; use the Test button on a card to verify reachability.',\r\n inheritingDefault: 'Using the default proxy: ',\r\n defaultMissing: 'The default proxy configuration is incomplete, so this provider is not proxied: ',\r\n filterLabel: 'Filter',\r\n filterPlaceholder: 'Filter by name or id\u2026',\r\n filterStatusAll: 'All',\r\n filterStatusProxied: 'Proxied',\r\n filterStatusDirect: 'Direct',\r\n filterStatusRejected: 'Rejected',\r\n noMatch: 'No provider matches the filter.',\r\n setAsDefault: 'Set as the default proxy',\r\n applyDefaultAll: 'Use the default proxy for all providers',\r\n protocol: 'Type',\r\n host: 'IP / host',\r\n port: 'Port',\r\n username: 'Username',\r\n password: 'Password',\r\n showPassword: 'Show',\r\n hidePassword: 'Hide',\r\n confirmPromoteToDefault:\r\n 'The default proxy is already in use by one or more providers. Replace it with this card\\'s endpoint?',\r\n hostHint: 'IP or domain only; paste full URL supported',\r\n passwordHint: 'Sent to the SOCKS5 proxy for authentication; stored with this setting.',\r\n passwordHintProxy: 'Sent to the proxy as an authentication password; stored with this setting.',\r\n hitCountPrefix: '',\r\n hitCountSuffix: ' proxied',\r\n recentOk: 'last ok ',\r\n recentFail: 'last failure ',\r\n recentStarted: 'last call ',\r\n noRecord: 'no proxied request yet',\r\n justNow: 'just now',\r\n minutesAgo: ' min ago',\r\n hoursAgo: ' h ago',\r\n daysAgo: ' d ago',\r\n viewCard: 'Card view',\r\n viewCompact: 'Compact view',\r\n expandDetails: 'Edit',\r\n collapseDetails: 'Collapse',\r\n batchTest: 'Test active',\r\n batchTesting: 'Testing',\r\n testButton: 'Test',\r\n testRunning: 'Testing\u2026',\r\n testDisabledNote: 'Not enabled \u2014 test only: ',\r\n testFailed: 'Test failed',\r\n exitIpLabel: 'exit IP ',\r\n directLabel: 'direct (not through the proxy)',\r\n cachedLabel: 'cached',\r\n testTargetLabel: 'Target: ',\r\n targetSourceRoute: \" (this card's own target)\",\r\n targetSourceUpstream: \" (this provider's real upstream)\",\r\n targetSourceTestUrl: ' (global self-check URL)',\r\n globalTitle: 'Global settings (advanced)',\r\n globalLead: 'These fields are saved with the plugin rather than per provider. Leave testUrl empty to use the built-in default; comma/space separated candidates are tried in order and only the first 5 are used. localDirect is on by default; turn it off only when the proxy itself is a loopback or private target.',\r\n testUrl: 'Self-check URL',\r\n testUrlHint: 'Comma/space separated; http(s) URLs in the order they should be tried.',\r\n testUrlEmptyHint: 'Empty means the Host uses its built-in default URL.',\r\n testUrlInvalidHint: 'Some candidates are not absolute http(s) URLs. They are saved, but those checks will fail.',\r\n testUrlTooManyHint: 'More than 5 candidates are listed; only the first 5 take effect.',\r\n restoreDefaultTestUrl: 'Restore default',\r\n localDirect: 'Loopback / private targets go direct',\r\n localDirectOnHint: 'On: localhost, 127.x and private ranges bypass the proxy.',\r\n localDirectOffHint: 'Off: loopback/private targets also use the proxy. Enable only when the proxy itself is the target.',\r\n advanced: 'Advanced: target host rules',\r\n onlyHosts: 'Proxy only',\r\n onlyHostsHint: 'Comma/space separated; when set, only requests to these hosts are proxied (suffix match, * for all).',\r\n bypassHosts: 'Bypass',\r\n bypassHostsHint: 'Comma/space separated; requests to these hosts go direct, taking priority.',\r\n ruleDeadHint: 'These entries never match \u2014 use bare host names (no port, scheme or path); a wildcard must be `*` or start with `*.`: ',\r\n testTarget: 'Self-check target',\r\n testTargetHint: 'Empty uses the top-level testUrl; when set, this card\\'s Test requests this URL instead \u2014 point it at a real upstream to verify the end-to-end path.',\r\n socks5Hint: 'SOCKS5 tunnels the connection; the proxy resolves the target host name.',\r\n on: 'proxied',\r\n rejected: 'config rejected',\r\n off: 'direct',\r\n complete: 'complete',\r\n notConfigured: 'not configured',\r\n diagnostics: 'Connection diagnostics',\r\n diagPending: '(collecting\u2026)',\r\n catalogueMismatch: 'Saved but not listed by the Host catalogue: ',\r\n catalogueMismatchSuffix: '. Their proxy settings are kept.',\r\n saveFailedPrefix: 'Save failed: ',\r\n close: 'Close',\r\n copy: 'Copy',\r\n copied: 'Copied',\r\n}\r\n\r\nconst ZH = {\r\n lead: '\u8BA9\u6307\u5B9A\u7684 provider \u8D70\u4F60\u81EA\u5DF1\u7684\u6B63\u5411\u4EE3\u7406\uFF0C\u5176\u5B83 provider \u4FDD\u6301\u76F4\u8FDE\u3002\u6307\u5411\u672C\u673A\u6216\u5185\u7F51\u5730\u5740\uFF08localhost\u3001127.x\u3001\u79C1\u6709\u7F51\u6BB5\uFF09\u7684\u8BF7\u6C42\u9ED8\u8BA4\u76F4\u8FDE\uFF0C\u9876\u5C42 localDirect \u8BBE\u4E3A false \u65F6\u6062\u590D\u8D70\u4EE3\u7406\u2014\u2014\u6B63\u5411\u4EE3\u7406\u901A\u5E38\u591F\u4E0D\u5230\u4F60\u81EA\u5DF1\u7684\u673A\u5668\u3002',\r\n empty: '\u6CA1\u6709\u68C0\u6D4B\u5230\u4EFB\u4F55 provider\u3002',\r\n catalogueLoading: '\u6B63\u5728\u8BFB\u53D6 provider \u5217\u8868\u2026',\r\n catalogueError: '\u8BFB\u53D6 provider \u5217\u8868\u5931\u8D25\uFF1A',\r\n catalogueStale: 'provider \u5217\u8868\u8BFB\u53D6\u5931\u8D25\uFF0C\u4E0B\u9762\u663E\u793A\u7684\u662F\u5DF2\u4FDD\u5B58\u7684\u914D\u7F6E\uFF1A',\r\n useProxy: '\u4E3A\u8BE5 provider \u542F\u7528\u4EE3\u7406',\r\n useDefault: '\u4F7F\u7528\u9ED8\u8BA4\u4EE3\u7406',\r\n defaultTitle: '\u9ED8\u8BA4\u4EE3\u7406',\r\n defaultLead: '\u4E3A\u52FE\u9009\u300C\u4F7F\u7528\u9ED8\u8BA4\u4EE3\u7406\u300D\u7684 provider \u590D\u7528\u7684\u7AEF\u70B9\uFF0C\u53EA\u586B\u4E00\u6B21\u3002\u72B6\u6001\u53EA\u8868\u793A\u914D\u7F6E\u662F\u5426\u5B8C\u6574\uFF1B\u4EE3\u7406\u662F\u5426\u53EF\u8FBE\u8BF7\u7528\u5361\u7247\u4E0A\u7684\u300C\u6D4B\u8BD5\u300D\u9A8C\u8BC1\u3002',\r\n inheritingDefault: '\u4F7F\u7528\u9ED8\u8BA4\u4EE3\u7406\uFF1A',\r\n defaultMissing: '\u9876\u5C42\u9ED8\u8BA4\u4EE3\u7406\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF0C\u8BE5 provider \u4E0D\u4F1A\u8D70\u4EE3\u7406\uFF1A',\r\n filterLabel: '\u8FC7\u6EE4',\r\n filterPlaceholder: '\u6309\u540D\u79F0\u6216 id \u8FC7\u6EE4\u2026',\r\n filterStatusAll: '\u5168\u90E8',\r\n filterStatusProxied: '\u8D70\u4EE3\u7406',\r\n filterStatusDirect: '\u76F4\u8FDE',\r\n filterStatusRejected: '\u914D\u7F6E\u88AB\u62D2',\r\n noMatch: '\u6CA1\u6709\u5339\u914D\u7684 provider\u3002',\r\n setAsDefault: '\u8BBE\u4E3A\u9ED8\u8BA4\u4EE3\u7406',\r\n applyDefaultAll: '\u6240\u6709 provider \u4F7F\u7528\u9ED8\u8BA4\u4EE3\u7406',\r\n protocol: '\u7C7B\u578B',\r\n host: 'IP / \u4E3B\u673A',\r\n port: '\u7AEF\u53E3',\r\n username: '\u7528\u6237\u540D',\r\n password: '\u5BC6\u7801',\r\n showPassword: '\u663E\u793A',\r\n hidePassword: '\u9690\u85CF',\r\n confirmPromoteToDefault: '\u5DF2\u6709 provider \u6B63\u5728\u4F7F\u7528\u9ED8\u8BA4\u4EE3\u7406\u3002\u8981\u7528\u8FD9\u5F20\u5361\u7247\u7684\u7AEF\u70B9\u8986\u76D6\u5B83\u5417\uFF1F',\r\n hostHint: '\u4EC5\u9650 IP \u6216\u57DF\u540D\uFF0C\u652F\u6301\u7C98\u8D34\u5B8C\u6574\u4EE3\u7406 URL',\r\n passwordHint: '\u4EC5\u4F5C\u4E3A SOCKS5 \u8BA4\u8BC1\u53E3\u4EE4\u53D1\u9001\u7ED9\u4EE3\u7406\uFF1B\u968F\u8BE5\u8BBE\u7F6E\u4E00\u8D77\u4FDD\u5B58\u3002',\r\n passwordHintProxy: '\u4F5C\u4E3A\u4EE3\u7406\u8BA4\u8BC1\u53E3\u4EE4\u53D1\u9001\u7ED9\u4EE3\u7406\uFF1B\u968F\u8BE5\u8BBE\u7F6E\u4E00\u8D77\u4FDD\u5B58\u3002',\r\n hitCountPrefix: '\u5DF2\u4EE3\u7406 ',\r\n hitCountSuffix: ' \u6B21',\r\n recentOk: '\u6700\u8FD1\u6210\u529F ',\r\n recentFail: '\u6700\u8FD1\u5931\u8D25 ',\r\n recentStarted: '\u6700\u8FD1\u8C03\u7528 ',\r\n noRecord: '\u5C1A\u65E0\u4EE3\u7406\u8BB0\u5F55',\r\n justNow: '\u521A\u521A',\r\n minutesAgo: ' \u5206\u949F\u524D',\r\n hoursAgo: ' \u5C0F\u65F6\u524D',\r\n daysAgo: ' \u5929\u524D',\r\n viewCard: '\u5361\u7247\u89C6\u56FE',\r\n viewCompact: '\u7D27\u51D1\u89C6\u56FE',\r\n expandDetails: '\u7F16\u8F91',\r\n collapseDetails: '\u6536\u8D77',\r\n batchTest: '\u6D4B\u8BD5\u5DF2\u542F\u7528',\r\n batchTesting: '\u6B63\u5728\u6D4B\u8BD5',\r\n testButton: '\u6D4B\u8BD5',\r\n testRunning: '\u6D4B\u8BD5\u4E2D\u2026',\r\n testDisabledNote: '\u672A\u542F\u7528\uFF0C\u4EC5\u6D4B\u8BD5\uFF1A',\r\n testFailed: '\u6D4B\u8BD5\u5931\u8D25',\r\n exitIpLabel: '\u51FA\u53E3 IP ',\r\n directLabel: '\u76F4\u8FDE\uFF08\u672A\u7ECF\u8FC7\u4EE3\u7406\uFF09',\r\n cachedLabel: '\u7F13\u5B58',\r\n testTargetLabel: '\u76EE\u6807 ',\r\n targetSourceRoute: '\uFF08\u672C\u5361\u7247\u81EA\u68C0\u76EE\u6807\uFF09',\r\n targetSourceUpstream: '\uFF08\u8BE5 provider \u7684\u771F\u5B9E\u4E0A\u6E38\uFF09',\r\n targetSourceTestUrl: '\uFF08\u5168\u5C40\u81EA\u68C0\u5730\u5740\uFF09',\r\n globalTitle: '\u5168\u5C40\u8BBE\u7F6E\uFF08\u9AD8\u7EA7\uFF09',\r\n globalLead: '\u8FD9\u91CC\u7684\u4E24\u9879\u5C5E\u4E8E\u63D2\u4EF6\u5168\u5C40\u8BBE\u7F6E\u3002testUrl \u7559\u7A7A\u65F6 Host \u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u503C\uFF1B\u591A\u4E2A\u5019\u9009\u7528\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF0C\u6309\u987A\u5E8F\u56DE\u9000\uFF0C\u53EA\u6709\u524D 5 \u4E2A\u751F\u6548\u3002localDirect \u9ED8\u8BA4\u5F00\u542F\uFF1B\u53EA\u6709\u4EE3\u7406\u672C\u8EAB\u5C31\u662F\u672C\u673A\u6216\u5185\u7F51\u76EE\u6807\u65F6\u624D\u9700\u8981\u5173\u95ED\u3002',\r\n testUrl: '\u81EA\u68C0\u5730\u5740',\r\n testUrlHint: '\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u6309\u987A\u5E8F\u5C1D\u8BD5\u7684 http(s) URL\u3002',\r\n testUrlEmptyHint: '\u7559\u7A7A\u65F6 Host \u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u5730\u5740\u3002',\r\n testUrlInvalidHint: '\u90E8\u5206\u5019\u9009\u4E0D\u662F\u7EDD\u5BF9\u7684 http(s) URL\u3002\u4ECD\u4F1A\u4FDD\u5B58\uFF0C\u4F46\u8FD9\u4E9B\u5019\u9009\u4F1A\u6D4B\u8BD5\u5931\u8D25\u3002',\r\n testUrlTooManyHint: '\u5019\u9009\u8D85\u8FC7 5 \u4E2A\uFF0C\u53EA\u6709\u524D 5 \u4E2A\u751F\u6548\u3002',\r\n restoreDefaultTestUrl: '\u6062\u590D\u9ED8\u8BA4',\r\n localDirect: '\u672C\u673A / \u5185\u7F51\u76EE\u6807\u76F4\u8FDE',\r\n localDirectOnHint: '\u5F00\u542F\uFF1Alocalhost\u3001127.x \u4E0E\u79C1\u6709\u7F51\u6BB5\u7ED5\u8FC7\u4EE3\u7406\u3002',\r\n localDirectOffHint: '\u5173\u95ED\uFF1A\u672C\u673A / \u5185\u7F51\u76EE\u6807\u4E5F\u8D70\u4EE3\u7406\uFF1B\u4EC5\u5728\u4EE3\u7406\u672C\u8EAB\u5C31\u662F\u76EE\u6807\u65F6\u4F7F\u7528\u3002',\r\n advanced: '\u9AD8\u7EA7\uFF1A\u76EE\u6807\u57DF\u540D\u89C4\u5219',\r\n onlyHosts: '\u4EC5\u8D70\u4EE3\u7406',\r\n onlyHostsHint: '\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u975E\u7A7A\u65F6\u53EA\u6709\u5339\u914D\u8FD9\u4E9B\u4E3B\u673A\u7684\u8BF7\u6C42\u8D70\u4EE3\u7406\uFF08\u540E\u7F00\u5339\u914D\uFF0C* \u8868\u793A\u5168\u90E8\uFF09\u3002',\r\n bypassHosts: '\u76F4\u8FDE',\r\n bypassHostsHint: '\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u5339\u914D\u8FD9\u4E9B\u4E3B\u673A\u7684\u8BF7\u6C42\u76F4\u8FDE\uFF0C\u4F18\u5148\u4E8E\u4E0A\u4E00\u9879\u3002',\r\n ruleDeadHint: '\u4EE5\u4E0B\u6761\u76EE\u6C38\u8FDC\u5339\u914D\u4E0D\u4E0A\u2014\u2014\u89C4\u5219\u53EA\u8BA4\u4E3B\u673A\u540D\uFF08\u4E0D\u8981\u5E26\u7AEF\u53E3\u3001\u534F\u8BAE\u524D\u7F00\u6216\u8DEF\u5F84\uFF09\uFF0C\u901A\u914D\u7B26\u53EA\u80FD\u662F\u5355\u72EC\u7684 * \u6216\u4EE5 *. \u5F00\u5934\uFF1A',\r\n testTarget: '\u81EA\u68C0\u76EE\u6807',\r\n testTargetHint: '\u7559\u7A7A\u7528\u9876\u5C42 testUrl\uFF1B\u586B\u5199\u540E\u8BE5\u5361\u7247\u7684\u300C\u6D4B\u8BD5\u300D\u6539\u4E3A\u8BF7\u6C42\u8FD9\u4E2A\u5730\u5740\uFF0C\u53EF\u62FF\u771F\u5B9E\u4E0A\u6E38\u9A8C\u8BC1\u7AEF\u5230\u7AEF\u8DEF\u5F84\u3002',\r\n socks5Hint: 'SOCKS5 \u4F1A\u5EFA\u7ACB\u96A7\u9053\uFF0C\u76EE\u6807\u57DF\u540D\u7531\u4EE3\u7406\u7AEF\u89E3\u6790\u3002',\r\n on: '\u8D70\u4EE3\u7406',\r\n rejected: '\u914D\u7F6E\u88AB\u62D2',\r\n off: '\u76F4\u8FDE',\r\n complete: '\u914D\u7F6E\u5B8C\u6574',\r\n notConfigured: '\u672A\u914D\u7F6E',\r\n diagnostics: '\u8FDE\u63A5\u8BCA\u65AD',\r\n diagPending: '\uFF08\u6B63\u5728\u6536\u96C6\u2026\uFF09',\r\n catalogueMismatch: '\u5DF2\u4FDD\u5B58\u4F46\u672A\u51FA\u73B0\u5728 Host \u76EE\u5F55\u4E2D\u7684 provider\uFF1A',\r\n catalogueMismatchSuffix: '\u3002\u4EE3\u7406\u914D\u7F6E\u4ECD\u4F1A\u4FDD\u7559\u3002',\r\n saveFailedPrefix: '\u4FDD\u5B58\u5931\u8D25\uFF1A',\r\n close: '\u5173\u95ED',\r\n copy: '\u590D\u5236',\r\n copied: '\u5DF2\u590D\u5236',\r\n}\r\n\r\n/**\r\n * Pick the dictionary for this render.\r\n *\r\n * The shell's own locale dictionary wins when it carries a translated entry, so\r\n * the page follows the application language instead of second-guessing it.\r\n * Chinese is the fallback because that is the operator's language.\r\n */\r\nfunction stringsFor(ctx: any): Record<string, string> {\r\n const language = localeOf(ctx)\r\n const bundled = language === 'zh' ? ZH : EN\r\n const translated = ((): Record<string, string> | undefined => {\r\n try {\r\n const service = optionalService(ctx, 'locale')\r\n const bound = service?.bind?.('dshProviderProxy')\r\n const value = typeof bound === 'function' ? bound('title') : undefined\r\n if (typeof value === 'string' && value.length > 0) return { title: value } as never\r\n } catch {\r\n // no locale dictionary available\r\n }\r\n return undefined\r\n })()\r\n return { ...bundled, ...(translated ?? {}) }\r\n}\r\n\r\n/**\r\n * The client module system's resolver.\r\n *\r\n * The loader calls `factory(require)` and that parameter shadows Node's\r\n * `require` inside the emitted CJS, so this describes the module-table\r\n * resolver, not Node's.\r\n */\r\ndeclare function require(specifier: string): unknown\r\n", "/**\r\n * Target-host rule parsing shared by the Host matcher and the settings page.\r\n *\r\n * This module deliberately has no undici import: the browser bundle imports it\r\n * too, and the two halves must agree on what an entry means before either can\r\n * safely warn about an entry that will never match.\r\n */\r\n\r\n/** Split a host-rule string into raw, non-empty tokens. */\r\nexport function splitHostRules(raw: string): string[] {\r\n return raw\r\n .split(/[,\\s]+/)\r\n .map(entry => entry.trim())\r\n .filter(entry => entry.length > 0)\r\n}\r\n\r\n/**\r\n * Normalize one raw rule for suffix matching.\r\n *\r\n * A leading `.` or `*.` is dropped: both spellings mean \"this host and its\r\n * subdomains\". Lower-casing belongs here as well, because the Host compares\r\n * against a WHATWG hostname that is already lower-cased.\r\n */\r\nexport function normalizeHostRule(raw: string): string {\r\n return raw.trim().replace(/^\\*?\\./, '').toLowerCase()\r\n}\r\n\r\n/** Split and normalize a host-rule string into matchable entries. */\r\nexport function parseHostList(raw: string): string[] {\r\n return splitHostRules(raw)\r\n .map(normalizeHostRule)\r\n .filter(entry => entry.length > 0)\r\n}\r\n\r\n/**\r\n * Whether a host is covered by one rule list.\r\n *\r\n * `*` matches everything; otherwise a rule matches the host itself or any\r\n * subdomain of it (`example.com` covers `api.example.com`).\r\n */\r\nexport function hostMatches(host: string, rules: readonly string[]): boolean {\r\n for (const rule of rules) {\r\n if (rule === '*') return true\r\n if (host === rule || host.endsWith(`.${rule}`)) return true\r\n }\r\n return false\r\n}\r\n\r\n/** Whether a raw token is a bracketed IPv6 literal, e.g. `[::1]`. */\r\nfunction isBracketedIpv6(token: string): boolean {\r\n return /^\\[[0-9a-f:.]+\\]$/i.test(token)\r\n}\r\n\r\n/** Whether a raw token can never match the Host's hostname comparison. */\r\nexport function hostRuleProblem(raw: string): string | undefined {\r\n const token = raw.trim()\r\n if (token.length === 0) return undefined\r\n // A bare `*.` normalizes to an empty string and disappears from the match\r\n // list entirely; report it rather than silently accepting a no-op.\r\n if (token === '*.' || normalizeHostRule(token).length === 0) return '\u7A7A\u901A\u914D\u7B26'\r\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(token)) return '\u5E26\u534F\u8BAE\u524D\u7F00'\r\n if (token.includes('/')) return '\u5E26\u8DEF\u5F84'\r\n // Host compares hostnames, never `host:port`; a bracketed IPv6 literal is the\r\n // one legitimate colon in a hostname.\r\n if (token.includes(':') && !isBracketedIpv6(token)) return '\u5E26\u7AEF\u53E3\u6216\u975E\u6CD5\u5192\u53F7'\r\n // Host strips only a leading `.`/`*.`; any other `*` cannot be a hostname.\r\n const withoutLeadingWildcard = token.replace(/^\\*\\./, '')\r\n if (withoutLeadingWildcard.includes('*') && token !== '*') return '\u6742\u6563\u901A\u914D\u7B26'\r\n return undefined\r\n}\r\n\r\n/** Every raw token that will never match, in the order it was typed. */\r\nexport function deadRuleEntries(raw: string): string[] {\r\n return splitHostRules(raw).filter(entry => hostRuleProblem(entry) !== undefined)\r\n}\r\n", "/**\n * The proxy-endpoint usability predicate, in ONE place.\n *\n * This lives in its own module \u2014 free of Node and schemastery imports \u2014 so the\n * BROWSER half can import the very same rule the Host applies. It exists because\n * the browser used to keep its own weaker copy that checked only \"host non-empty\n * and port in range\": against `https://1.2.3.4` that copy lit the default block\n * green and enabled the bulk \"use the default\" button, while the Host refused\n * every route that pointed at it (a host carrying a scheme or path is rejected by\n * `normalizeRoute`). One predicate, imported by both halves, cannot disagree\n * with itself.\n */\nexport interface ProxyEndpoint {\n /**\n * Proxy host or IP, without scheme, port, or path.\n *\n * Optional because the browser calls this with whatever the settings document\n * currently holds, which mid-edit is not yet a complete endpoint.\n */\n host?: string\n /** Proxy port. 0 means \"not configured\". */\n port?: number\n /**\n * Credential parts, if the endpoint carries any. A HALF-filled pair is a\n * problem, the same way it is on the route itself \u2014 see below.\n */\n username?: string\n password?: string\n}\n\nconst PROXY_HOST_INVALID = '\u4EE3\u7406\u5730\u5740\u53EA\u80FD\u586B IPv4\u3001IPv6 \u6216\u57DF\u540D'\nconst IPV4 = /^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/\nconst DOMAIN = /^(?=.*[a-z])(?=.{1,253}$)(?!.*\\.\\d+$)[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?)*$/i\nconst IPV6_CHARS = /^[0-9a-f:.]+$/i\n\n/**\n * Accept exactly one of: IPv4, IPv6, or a DNS host name. The field carries the\n * proxy address only; a port, scheme, path, credential, or other URL text belongs\n * in its own field and is rejected here.\n */\nexport function proxyHostProblem(rawHost?: string): string | undefined {\n const host = (rawHost ?? '').trim().replace(/\\.$/, '')\n if (host.length === 0) return '\u672A\u586B\u5199\u4EE3\u7406\u5730\u5740'\n if (IPV4.test(host)) return undefined\n\n // A colon or bracket means the value is claiming to be IPv6. Validate it as\n // an IPv6 literal; never fall back to accepting the text as a host name.\n if (host.includes(':') || host.startsWith('[')) {\n const literal = host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host\n if (!IPV6_CHARS.test(literal)) return PROXY_HOST_INVALID\n try {\n new URL(`http://[${literal}]:1`)\n return undefined\n } catch {\n return PROXY_HOST_INVALID\n }\n }\n\n return DOMAIN.test(host) ? undefined : PROXY_HOST_INVALID\n}\n\n/**\n * Why this endpoint cannot carry a request, or `undefined` when it can.\n *\n * The host and port checks mirror `normalizeRoute` exactly, so the browser's\n * verdict and the Host's are the same verdict. The credential pairing check\n * mirrors the guards in `buildRouteEntry`, which is what makes this predicate a\n * truthful preview of whether a route that opts into the default will actually be\n * built: without it, a default carrying `alice` and no password lit the block\n * green and enabled the bulk button, and every card it pointed at was then\n * refused by the credential guard with `entries.size === 0`.\n *\n * Tolerates a partial object (`{}`, `host: undefined`) rather than throwing: the\n * browser calls this with whatever the settings document currently holds, which\n * during a half-typed edit is not yet a complete endpoint.\n */\nexport function defaultProxyProblem(endpoint: ProxyEndpoint): string | undefined {\n const hostProblem = proxyHostProblem(endpoint.host)\n if (hostProblem !== undefined) return hostProblem\n // `?? 0` rather than a throw: an absent port is \"not configured\", which is the\n // same thing 0 already means everywhere else in this plugin.\n const port = endpoint.port ?? 0\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n return '\u4EE3\u7406\u7AEF\u53E3\u65E0\u6548\uFF08\u9700\u4E3A 1-65535 \u7684\u6574\u6570\uFF09'\n }\n // \"Both or neither\", exactly as `buildRouteEntry` enforces per transport. The\n // wording stays transport-neutral here because the default block carries a\n // protocol the user may still change; the route-level guards spell out the\n // protocol-specific reason once it is pinned. The Host trims the username\n // before its guards, so this predicate must trim it too; the password is not\n // trimmed by either side.\n const hasUser = (endpoint.username ?? '').trim().length > 0\n const hasPassword = (endpoint.password ?? '').length > 0\n if (hasUser !== hasPassword) {\n return hasUser\n ? '\u914D\u7F6E\u4E86\u4EE3\u7406\u7528\u6237\u540D\u4F46\u6CA1\u6709\u5BC6\u7801\uFF1B\u8BF7\u8865\u5168\u5BC6\u7801\u6216\u6E05\u7A7A\u7528\u6237\u540D'\n : '\u914D\u7F6E\u4E86\u4EE3\u7406\u5BC6\u7801\u4F46\u6CA1\u6709\u7528\u6237\u540D\uFF1B\u8BF7\u8865\u5168\u7528\u6237\u540D\u6216\u6E05\u7A7A\u5BC6\u7801'\n }\n return undefined\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["module", "field", "styles", "body", "apply"]
|
|
3
|
+
"sources": ["../src/client.css", "../src/client.ts", "../src/host-rules.ts", "../src/proxy-address.ts", "../src/presets.ts", "../src/proxy-clients.ts", "../src/backup.ts"],
|
|
4
|
+
"sourcesContent": ["\nvar __dshMap = {\"root\":\"53783ebc_root\",\"lead\":\"87ded16f_lead\",\"empty\":\"f139472e_empty\",\"card\":\"99d44a8a_card\",\"cardActive\":\"6bfd1d28_cardActive\",\"cardRejected\":\"ea4afe84_cardRejected\",\"defaultCard\":\"6c49773c_defaultCard\",\"defaultLead\":\"8e32da71_defaultLead\",\"cardHead\":\"d2cf61e5_cardHead\",\"cardTitles\":\"c6ef43cd_cardTitles\",\"name\":\"6dad9d13_name\",\"id\":\"dd160a22_id\",\"pillOn\":\"4b27b813_pillOn\",\"pillLive\":\"6e7a5d11_pillLive\",\"pillOff\":\"7951c4c2_pillOff\",\"pillRejected\":\"4756f162_pillRejected\",\"toggle\":\"7c4f39f6_toggle\",\"field\":\"ebe8e1a3_field\",\"label\":\"d6a07995_label\",\"hint\":\"5b4fb148_hint\",\"input\":\"30a51506_input\",\"passwordToggle\":\"fcfbab02_passwordToggle\",\"testButton\":\"b3231562_testButton\",\"diag\":\"184b2d06_diag\",\"diagSummary\":\"49005df6_diagSummary\",\"diagList\":\"7f1b6335_diagList\",\"chipRow\":\"406f7239_chipRow\",\"chip\":\"446f9f30_chip\",\"chipActive\":\"152509e7_chipActive\",\"formGrid\":\"6fb245a3_formGrid\",\"formGridFull\":\"c89ac7ba_formGridFull\",\"controlRow\":\"763cfc36_controlRow\",\"toolbarRow\":\"97a483ad_toolbarRow\",\"compactRow\":\"342803fe_compactRow\",\"compactRowActive\":\"b8cadbfb_compactRowActive\",\"compactRowRejected\":\"9ccd93bd_compactRowRejected\",\"copyButton\":\"dcf70ff1_copyButton\",\"profileCard\":\"9889cd73_profileCard\",\"panel\":\"64d062a3_panel\"};\nvar __dshStyles = (globalThis.__dshPluginStyles || (globalThis.__dshPluginStyles = new Set()));\nif (!__dshStyles.has(\"dsh-provider-proxy/client.css\")) {\n __dshStyles.add(\"dsh-provider-proxy/client.css\");\n var __dshStyle = document.createElement('style');\n __dshStyle.setAttribute('data-plugin-css', \"dsh-provider-proxy/client.css\");\n __dshStyle.textContent = \"/* dsh-provider-proxy \u2014 provider proxy settings page.\\r\\n Tokens only: no literal colours, matching the shared --dsw-* system. */\\r\\n\\r\\n.53783ebc_root {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n gap: 14px;\\r\\n max-width: 760px;\\r\\n}\\r\\n\\r\\n.87ded16f_lead {\\r\\n margin: 0 0 4px;\\r\\n font-size: 12px;\\r\\n line-height: 1.6;\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n.f139472e_empty {\\r\\n margin: 0;\\r\\n padding: 16px;\\r\\n border: 1px dashed var(--dsw-alias-border-l1);\\r\\n border-radius: 8px;\\r\\n font-size: 12px;\\r\\n text-align: center;\\r\\n color: var(--dsw-alias-state-idle-primary);\\r\\n}\\r\\n\\r\\n/* ---- provider card ---- */\\r\\n\\r\\n.99d44a8a_card,\\r\\n.6bfd1d28_cardActive,\\r\\n.ea4afe84_cardRejected {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n gap: 12px;\\r\\n padding: 14px 16px;\\r\\n border: 1px solid var(--dsw-alias-border-l1);\\r\\n border-radius: 10px;\\r\\n background: var(--dsw-alias-bg-layer-1);\\r\\n}\\r\\n\\r\\n.6bfd1d28_cardActive {\\r\\n border-color: var(--dsw-alias-state-success-primary);\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n}\\r\\n\\r\\n/* An enabled route the Host refused: never dress it as active. */\\r\\n.ea4afe84_cardRejected {\\r\\n border-color: var(--dsw-alias-state-error-primary, #f85149);\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n}\\r\\n\\r\\n/* ---- shared default endpoint ---- */\\r\\n\\r\\n/* A distinct outer layer, so it reads as \\\"one setting for the page\\\" rather than\\r\\n as one more provider card. */\\r\\n.6c49773c_defaultCard {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n gap: 12px;\\r\\n padding: 14px 16px;\\r\\n border: 1px solid var(--dsw-alias-border-l2);\\r\\n border-radius: 10px;\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n}\\r\\n\\r\\n.8e32da71_defaultLead {\\r\\n margin: -2px 0 0;\\r\\n font-size: 11px;\\r\\n line-height: 1.5;\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n.d2cf61e5_cardHead {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n gap: 12px;\\r\\n}\\r\\n\\r\\n.c6ef43cd_cardTitles {\\r\\n display: flex;\\r\\n align-items: baseline;\\r\\n gap: 8px;\\r\\n min-width: 0;\\r\\n}\\r\\n\\r\\n.6dad9d13_name {\\r\\n overflow: hidden;\\r\\n font-size: 13px;\\r\\n font-weight: 600;\\r\\n white-space: nowrap;\\r\\n text-overflow: ellipsis;\\r\\n color: var(--dsw-alias-label-primary);\\r\\n}\\r\\n\\r\\n.dd160a22_id {\\r\\n flex: none;\\r\\n padding: 1px 6px;\\r\\n border-radius: 4px;\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n font-family: ui-monospace, monospace;\\r\\n font-size: 11px;\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n/* ---- status pill ---- */\\r\\n\\r\\n.4b27b813_pillOn,\\r\\n.6e7a5d11_pillLive,\\r\\n.7951c4c2_pillOff,\\r\\n.4756f162_pillRejected {\\r\\n flex: none;\\r\\n padding: 2px 8px;\\r\\n border-radius: 999px;\\r\\n font-size: 11px;\\r\\n font-weight: 500;\\r\\n white-space: nowrap;\\r\\n}\\r\\n\\r\\n.4b27b813_pillOn {\\r\\n background: var(--dsw-alias-state-success-primary);\\r\\n color: var(--dsw-alias-bg-base);\\r\\n}\\r\\n\\r\\n.6e7a5d11_pillLive {\\r\\n border: 1px solid var(--dsw-alias-border-l2);\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n.7951c4c2_pillOff {\\r\\n color: var(--dsw-alias-state-idle-primary);\\r\\n}\\r\\n\\r\\n.4756f162_pillRejected {\\r\\n border: 1px solid var(--dsw-alias-state-error-primary, #f85149);\\r\\n color: var(--dsw-alias-state-error-primary, #f85149);\\r\\n}\\r\\n\\r\\n/* ---- toggle ---- */\\r\\n\\r\\n.7c4f39f6_toggle {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 8px;\\r\\n padding-top: 2px;\\r\\n font-size: 12px;\\r\\n color: var(--dsw-alias-label-primary);\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n.7c4f39f6_toggle input {\\r\\n accent-color: var(--dsw-alias-brand-primary);\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n/* ---- fields ---- */\\r\\n\\r\\n.ebe8e1a3_field {\\r\\n display: grid;\\r\\n grid-template-columns: 76px 1fr;\\r\\n align-items: center;\\r\\n gap: 8px;\\r\\n font-size: 12px;\\r\\n min-width: 0;\\r\\n}\\r\\n\\r\\n.d6a07995_label {\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n.5b4fb148_hint {\\r\\n grid-column: 1 / -1;\\r\\n margin-top: 2px;\\r\\n font-size: 11px;\\r\\n color: var(--dsw-alias-state-warn-primary, #d29922);\\r\\n}\\r\\n\\r\\n.30a51506_input {\\r\\n box-sizing: border-box;\\r\\n width: 100%;\\r\\n min-width: 0;\\r\\n padding: 5px 8px;\\r\\n border: 1px solid var(--dsw-alias-border-l1);\\r\\n border-radius: 6px;\\r\\n outline: none;\\r\\n background: var(--dsw-alias-bg-layer-1);\\r\\n color: var(--dsw-alias-label-primary);\\r\\n font: inherit;\\r\\n font-size: 12px;\\r\\n transition: border-color 120ms ease, background 120ms ease;\\r\\n}\\r\\n\\r\\n/* The base look of every input is INLINE too, so these three state rules only\\r\\n ever take effect as author-important declarations \u2014 same reason as the\\r\\n self-check button above. `cursor` has no inline base and needs none, and the\\r\\n hover border uses `l3` because `l1`\u2192`l2` is a 4%\u219210% black step nobody can\\r\\n see. */\\r\\n\\r\\n.30a51506_input:hover:not(:disabled) {\\r\\n border-color: var(--dsw-alias-border-l3) !important;\\r\\n}\\r\\n\\r\\n.30a51506_input:focus {\\r\\n border-color: var(--dsw-alias-brand-primary) !important;\\r\\n}\\r\\n\\r\\n.30a51506_input:disabled {\\r\\n color: var(--dsw-alias-state-idle-primary) !important;\\r\\n background: var(--dsw-alias-bg-layer-2) !important;\\r\\n cursor: not-allowed;\\r\\n}\\r\\n\\r\\n/* The icon sits inside the input, so its hover/focus feedback must be local\\r\\n and must outrank the transparent inline base. */\\r\\n.fcfbab02_passwordToggle {\\r\\n transition: background 120ms ease, color 120ms ease;\\r\\n}\\r\\n\\r\\n.fcfbab02_passwordToggle:hover:not(:disabled) {\\r\\n background: var(--dsw-alias-interactive-bg-hover) !important;\\r\\n color: var(--dsw-alias-label-primary) !important;\\r\\n}\\r\\n\\r\\n.fcfbab02_passwordToggle:focus-visible {\\r\\n outline: 2px solid var(--dsw-alias-brand-primary);\\r\\n outline-offset: 1px;\\r\\n}\\r\\n\\r\\n/* ---- self-check ---- */\\r\\n\\r\\n/* The hover state is the one thing an inline style cannot express, which is why\\r\\n this element carries a class at all. Layout stays inline.\\r\\n\\r\\n Two traps, both hit before this comment existed:\\r\\n - `!important` is load-bearing: the base border and background are INLINE, and\\r\\n the cascade sorts a style attribute after every author rule, so a plain\\r\\n declaration here would ship, match, and still lose.\\r\\n - the TOKENS must be visible ones. `bg-layer-1/2/3` all resolve to\\r\\n `neutral-bluish-00` in the light theme, so a layer swap is a no-op there, and\\r\\n `border-l1`\u2192`l2` is 4%\u219210% black on a 1px line. The app's own hovers use\\r\\n `interactive-bg-hover`; using it here is what makes the feedback exist. */\\r\\n.b3231562_testButton {\\r\\n transition: border-color 120ms ease, background 120ms ease;\\r\\n}\\r\\n\\r\\n.b3231562_testButton:hover:not(:disabled) {\\r\\n border-color: var(--dsw-alias-border-l3) !important;\\r\\n background: var(--dsw-alias-interactive-bg-hover) !important;\\r\\n}\\r\\n\\r\\n/* ---- diagnostics ---- */\\r\\n\\r\\n.184b2d06_diag {\\r\\n padding: 10px 14px;\\r\\n border: 1px solid var(--dsw-alias-border-l1);\\r\\n border-radius: 10px;\\r\\n font-size: 11px;\\r\\n color: var(--dsw-alias-label-secondary);\\r\\n}\\r\\n\\r\\n.49005df6_diagSummary {\\r\\n cursor: pointer;\\r\\n color: var(--dsw-alias-state-warn-primary);\\r\\n}\\r\\n\\r\\n.7f1b6335_diagList {\\r\\n margin: 6px 0 0;\\r\\n padding-left: 18px;\\r\\n font-family: ui-monospace, monospace;\\r\\n word-break: break-all;\\r\\n}\\r\\n\\r\\n/* ---- v0.8.0 N9 additions: status filter chips ---- */\\r\\n\\r\\n.406f7239_chipRow {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 6px;\\r\\n flex-wrap: wrap;\\r\\n}\\r\\n\\r\\n.446f9f30_chip {\\r\\n transition: border-color 120ms ease, background 120ms ease, color 120ms ease;\\r\\n}\\r\\n\\r\\n/* Hover is a HINT, never a selection.\\r\\n\\r\\n Two earlier versions of this rule were wrong in the same direction:\\r\\n it painted the active background (any hovered chip looked selected), and\\r\\n then it painted an outline (a deselected chip still looked framed). An\\r\\n unselected chip is bare text; hovering gives it a faint surface, nothing\\r\\n more. Selection is the only state allowed a border and a solid fill. */\\r\\n.446f9f30_chip:hover:not(:disabled) {\\r\\n border-color: transparent !important;\\r\\n background: var(--dsw-alias-interactive-bg-hover) !important;\\r\\n color: var(--dsw-alias-label-primary) !important;\\r\\n}\\r\\n\\r\\n/* The selected chip, driven by STATE rather than by class precedence, so it\\r\\n cannot be outranked by `:hover` on a sibling. */\\r\\n.152509e7_chipActive,\\r\\n.446f9f30_chip[aria-pressed='true'] {\\r\\n border-color: var(--dsw-alias-brand-primary) !important;\\r\\n background: var(--dsw-alias-brand-primary) !important;\\r\\n color: var(--dsw-alias-bg-base) !important;\\r\\n font-weight: 600;\\r\\n}\\r\\n\\r\\n/* A selected chip keeps its own surface while hovered: the pointer is on it,\\r\\n which must not read as \\\"about to become something else\\\". */\\r\\n.152509e7_chipActive:hover:not(:disabled),\\r\\n.446f9f30_chip[aria-pressed='true']:hover:not(:disabled) {\\r\\n border-color: var(--dsw-alias-brand-primary) !important;\\r\\n background: var(--dsw-alias-brand-primary) !important;\\r\\n color: var(--dsw-alias-bg-base) !important;\\r\\n}\\r\\n\\r\\n/* ---- v0.8.0 N11 additions: form grid ---- */\\r\\n\\r\\n.6fb245a3_formGrid {\\r\\n display: grid;\\r\\n grid-template-columns: repeat(2, minmax(0, 1fr));\\r\\n align-items: start;\\r\\n gap: 10px 14px;\\r\\n}\\r\\n\\r\\n.c89ac7ba_formGridFull {\\r\\n grid-column: 1 / -1;\\r\\n}\\r\\n\\r\\n@media (max-width: 520px) {\\r\\n .6fb245a3_formGrid {\\r\\n grid-template-columns: 1fr !important;\\r\\n }\\r\\n .c89ac7ba_formGridFull {\\r\\n grid-column: auto !important;\\r\\n }\\r\\n /* The endpoint-source picker and the enable switch stack too, instead of\\r\\n shrinking the picker until its option text is unreadable. */\\r\\n .763cfc36_controlRow {\\r\\n grid-template-columns: 1fr !important;\\r\\n }\\r\\n /* The list toolbar's buttons drop below the search box at this width. */\\r\\n .97a483ad_toolbarRow > * {\\r\\n flex: 1 1 100% !important;\\r\\n }\\r\\n}\\r\\n\\r\\n/* ---- v0.8.0 N10 additions: compact view ---- */\\r\\n\\r\\n.342803fe_compactRow,\\r\\n.b8cadbfb_compactRowActive,\\r\\n.9ccd93bd_compactRowRejected {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n align-items: stretch;\\r\\n gap: 8px;\\r\\n padding: 12px 16px;\\r\\n border: 1px solid var(--dsw-alias-border-l1);\\r\\n border-radius: 10px;\\r\\n background: var(--dsw-alias-bg-layer-1);\\r\\n}\\r\\n\\r\\n.b8cadbfb_compactRowActive {\\r\\n border-color: var(--dsw-alias-state-success-primary);\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n}\\r\\n\\r\\n.9ccd93bd_compactRowRejected {\\r\\n border-color: var(--dsw-alias-state-error-primary, #f85149);\\r\\n background: var(--dsw-alias-bg-layer-2);\\r\\n}\\r\\n\\r\\n/* ---- v0.8.0 N13 additions: quick copy ---- */\\r\\n.dcf70ff1_copyButton {\\r\\n transition: background 120ms ease, color 120ms ease;\\r\\n}\\r\\n\\r\\n.dcf70ff1_copyButton:hover:not(:disabled) {\\r\\n background: var(--dsw-alias-interactive-bg-hover) !important;\\r\\n color: var(--dsw-alias-label-primary) !important;\\r\\n}\\r\\n\\r\\n/* ---- v0.9.0 N14 additions: named proxy presets ----\\r\\n The manager reuses the diagnostics/details shell, so only the per-preset row\\r\\n needs its own rules: an inset card whose border lights up while it is being\\r\\n edited, which is the only way to tell several identical rows apart. */\\r\\n\\r\\n.9889cd73_profileCard {\\r\\n display: flex;\\r\\n flex-direction: column;\\r\\n gap: 8px;\\r\\n padding: 12px 14px;\\r\\n border: 1px solid var(--dsw-alias-border-l1);\\r\\n border-radius: 10px;\\r\\n background: var(--dsw-alias-bg-layer-1);\\r\\n transition: border-color 120ms ease;\\r\\n}\\r\\n\\r\\n.9889cd73_profileCard:focus-within {\\r\\n border-color: var(--dsw-alias-brand-primary) !important;\\r\\n}\\r\\n\\r\\n/* ---- v0.9.0 N19 additions: one layout scale ----\\r\\n These classes exist only so the narrow-screen rules above can reach the\\r\\n containers. Their visible properties stay inline, for the same reason every\\r\\n other box on this page does: the stylesheet has silently failed to bind here\\r\\n before, and layout must survive that. */\\r\\n\\r\\n.763cfc36_controlRow,\\r\\n.97a483ad_toolbarRow,\\r\\n.64d062a3_panel {\\r\\n min-width: 0;\\r\\n}\\r\\n\";\n document.head.appendChild(__dshStyle);\n}\nmodule.exports = __dshMap;\nmodule.exports.default = __dshMap;\nmodule.exports.__esModule = true;\n", "/**\r\n * dsh-provider-proxy \u2014 browser half.\r\n *\r\n * Contributes ONE settings page (a `settings.section` list entry) that lists\r\n * every known provider with its proxy switch, type, host, port and username.\r\n *\r\n * This replaces an earlier attempt to render into each provider card on the\r\n * Models page (`settings.models.provider-card`). That seat is keyed and\r\n * dispatched per provider namespace, and a third-party registration never\r\n * matched it on this build: no error, no request, simply no output. A\r\n * `settings.section` entry is a plain list contribution with an `id`, which is\r\n * the shape the shipped `dsh-llm-retry-settings` plugin uses successfully in\r\n * this same desktop profile.\r\n *\r\n * The whole bundle runs inside the client module system's lazy-CJS factory:\r\n * executing the script only REGISTERS the factory, and every side effect\r\n * (including the CSS injection) happens at materialization.\r\n */\r\n\r\n// The CSS-Modules build turns this sheet into a hashed class map AND injects it\r\n// at materialization. The binding is what the component reads; importing it for\r\n// side effects only would leave `styles` undefined at render time.\r\nimport styles from './client.css'\r\nimport { appendHostRules, deadRuleEntries, providerHostTemplate } from './host-rules.js'\r\nimport { defaultProxyProblem, proxyHostProblem } from './proxy-address.js'\r\nimport {\r\n DEFAULT_PROFILE_LABEL,\r\n DEFAULT_PROFILE_BINDING,\r\n bindingFields,\r\n endpointAddress,\r\n endpointSummary,\r\n profileNameProblem,\r\n profileNames,\r\n routeBindingOf,\r\n routesBoundTo,\r\n} from './presets.js'\r\nimport { PROXY_CLIENT_PRESETS, proxyClientPreset } from './proxy-clients.js'\r\nimport { backupCounts, backupFileName, backupOps, buildBackup, parseBackup } from './backup.js'\r\n\r\ntype Protocol = 'http' | 'https' | 'socks5'\r\n\r\ntype RouteValue = {\r\n enabled: boolean\r\n /** Non-empty binds the route's transport fields to one named preset. */\r\n profileId: string\r\n useDefault: boolean\r\n protocol: Protocol\r\n host: string\r\n port: number\r\n username: string\r\n password: string\r\n onlyHosts: string\r\n bypassHosts: string\r\n testTarget: string\r\n}\r\n\r\n/** One named preset, as the page holds it. */\r\ntype ProfileValue = {\r\n protocol: Protocol\r\n host: string\r\n port: number\r\n username: string\r\n password: string\r\n}\r\n\r\n/** The provider rows we know about, and which of them are actually live. */\r\ntype ProviderRow = { id: string; name: string; live: boolean }\r\n\r\n/**\r\n * React, resolved from the client module table.\r\n *\r\n * React is NOT a Cordis service and is not reachable from `ctx` \u2014 reading it\r\n * there produced a silently null component. The module table is the only route:\r\n * the build leaves `react` external, so this compiles to a `require(\"react\")`\r\n * inside the factory closure, answered from the shell-seeded baseline.\r\n *\r\n * Resolved lazily on first render so merely REGISTERING the bundle \u2014 which is\r\n * all a script evaluation does \u2014 never materializes React.\r\n */\r\nlet ReactCache: unknown\r\n\r\nfunction react(): any {\r\n if (ReactCache === undefined) {\r\n ReactCache = ((): unknown => {\r\n try {\r\n return require('react')\r\n } catch {\r\n return (globalThis as Record<string, unknown>).React\r\n }\r\n })()\r\n }\r\n return ReactCache\r\n}\r\n\r\nconst PROTOCOLS: Protocol[] = ['http', 'https', 'socks5']\r\n\r\n/** Our own settings namespace; the profile entry id created by the bundle patch. */\r\nconst NAMESPACE = 'provider-proxy'\r\n\r\n/**\r\n * Cordis services this half needs.\r\n *\r\n * ONLY `slots` is declared. That is the complete set this release actually\r\n * offers on a client fiber: `layout, locale, sessions, slots, theme, timer,\r\n * uiWorkspace, workspaces`.\r\n *\r\n * A declared service that never arrives leaves the fiber PENDING forever, and\r\n * that is NOT a client-only failure \u2014 it is reported as\r\n * web boot: 1 entry did not activate\r\n * dsh-provider-proxy: pending (waiting for service: settingsScope)\r\n * which fails the whole Desktop boot. `settingsScope` and `configForms` were\r\n * both guessed and both are absent here, so neither may be declared.\r\n *\r\n * Settings are therefore reached through `ctx.get(name)` \u2014 the framework's own\r\n * non-throwing lookup \u2014 and the page degrades to read-only when it is absent.\r\n */\r\nconst PLUGINS = ['slots']\r\n\r\nexport const inject = PLUGINS\r\n\r\nexport function apply(ctx: any): void {\r\n // The settings shell declares `settings.section` on its own fiber, so\r\n // `slots.inject` waits for that declaration and the contribution is removed\r\n // when the panel is torn down.\r\n ctx.slots.inject('settings.section', () =>\r\n ctx.slots.register(\r\n {\r\n name: 'settings.section',\r\n id: NAMESPACE,\r\n order: 20,\r\n label: () => 'Provider \u4EE3\u7406',\r\n },\r\n () => renderPage(ctx),\r\n ),\r\n )\r\n}\r\n\r\n/**\r\n * Pick the dictionary.\r\n *\r\n * Chinese is the default, not English: this plugin is written for a\r\n * Chinese-speaking operator, and a page that renders in the wrong language is\r\n * worse than one that never matches the shell's locale.\r\n *\r\n * `ctx.locale` is not injected \u2014 declaring a service that this release does not\r\n * provide left the fiber PENDING and failed the whole Desktop boot \u2014 so the\r\n * locale is probed with the non-throwing `ctx.get`, then the browser's own\r\n * language, and only then English.\r\n */\r\nfunction localeOf(ctx: any): string {\r\n try {\r\n const service = optionalService(ctx, 'locale')\r\n const snapshot = service?.getSnapshot?.() ?? service?.getLocale?.()\r\n const id = typeof snapshot?.locale === 'string' ? snapshot.locale : undefined\r\n if (id !== undefined) return id.toLowerCase().startsWith('zh') ? 'zh' : 'en'\r\n } catch {\r\n // fall through to the browser language\r\n }\r\n const browser = globalThis.navigator?.language\r\n if (typeof browser === 'string' && browser.toLowerCase().startsWith('zh')) return 'zh'\r\n return browser === undefined ? 'zh' : 'en'\r\n}\r\n\r\n/**\r\n * Look a service up WITHOUT declaring it in `inject`.\r\n *\r\n * `ctx.get(name)` is the framework's own optional lookup: it returns undefined\r\n * instead of throwing, and \u2014 unlike a declared service \u2014 it cannot leave the\r\n * fiber PENDING. That is what makes an optional integration safe here: this\r\n * release has no settings service at all, so the page simply shows its fields\r\n * and reports that saving is unavailable.\r\n */\r\nfunction optionalService(ctx: any, ...names: string[]): any {\r\n for (const name of names) {\r\n try {\r\n const found = typeof ctx?.get === 'function' ? ctx.get(name) : undefined\r\n if (found !== undefined && found !== null) return found\r\n } catch {\r\n // try the next spelling\r\n }\r\n }\r\n return undefined\r\n}\r\n\r\n/** The settings form for this plugin's namespace, when one exists. */\r\nfunction formOf(ctx: any): any {\r\n const forms = optionalService(ctx, 'configForms', 'settingsScope')\r\n if (forms === undefined) return undefined\r\n try {\r\n if (typeof forms.get === 'function') return forms.get(NAMESPACE)\r\n // A settingsScope-style service is already bound to one namespace.\r\n if (typeof forms.getSnapshot === 'function' || typeof forms.bind === 'function') return forms\r\n } catch {\r\n return undefined\r\n }\r\n return undefined\r\n}\r\n\r\nfunction readConfig(ctx: any): { value: any; revision: number } {\r\n const form = formOf(ctx)\r\n if (form === undefined) return { value: {}, revision: 0 }\r\n try {\r\n const snapshot = form.getSnapshot?.()\r\n return {\r\n value: snapshot?.value ?? snapshot?.user ?? {},\r\n revision: snapshot?.revision ?? 0,\r\n }\r\n } catch {\r\n return { value: {}, revision: 0 }\r\n }\r\n}\r\n\r\nasync function writeConfig(ctx: any, ops: readonly unknown[]): Promise<void> {\r\n const form = formOf(ctx)\r\n if (typeof form?.mutate !== 'function') {\r\n throw new Error('dsh-provider-proxy: settings transport unavailable')\r\n }\r\n await form.mutate(ops as any[], readConfig(ctx).revision)\r\n}\r\n\r\n/**\r\n * The provider rows, read from the Host.\r\n *\r\n * This release exposes no client-facing LLM service, so the page cannot ask for\r\n * the directory itself. The Host serves it at this same-origin endpoint, where\r\n * `ctx.llm.listProviders()` / `listConfigurableProviders()` actually live. The\r\n * list is therefore automatic \u2014 the user never types a route id.\r\n *\r\n * Only ACTIVE routes are shown. A provider this deployment merely *offers* \u2014\r\n * declared but not registered, so nothing would ever be sent through it \u2014 is\r\n * not the user's business on this page, and listing it only invites them to\r\n * configure a proxy for a route that cannot be selected. A provider that is\r\n * already configured is kept regardless, so a saved setting never silently\r\n * disappears from view.\r\n */\r\nfunction knownProviders(configured: Record<string, RouteValue>, published: ProviderRow[]): ProviderRow[] {\r\n const rows = new Map<string, ProviderRow>()\r\n const byId = new Map<string, ProviderRow>()\r\n for (const row of published) {\r\n byId.set(row.id, row)\r\n if (row.live) rows.set(row.id, row)\r\n }\r\n for (const id of Object.keys(configured)) {\r\n if (rows.has(id)) continue\r\n // A saved route must stay visible, but switching the proxy ON does not make\r\n // its provider live. `live` comes from the Host catalogue exclusively; using\r\n // `route.enabled` here made a card flip between \"offline\" and \"proxied\" as\r\n // the user toggled the switch, while no provider became available at all.\r\n const known = byId.get(id)\r\n rows.set(id, { id, name: known?.name ?? id, live: known?.live === true })\r\n }\r\n return [...rows.values()].sort(byName)\r\n}\r\n\r\n/**\r\n * Where the Host publishes the live provider catalogue.\r\n */\r\nconst CATALOG_PATH = '/dsh-provider-proxy/providers'\r\n\r\n/** Where the Host runs a per-provider connection self-check. */\r\nconst TEST_PATH = '/dsh-provider-proxy/test'\r\n\r\n/**\r\n * Latency bands for the self-check result, in milliseconds.\r\n *\r\n * The colour is decoration, never information: the numeric value is always\r\n * printed, so an unknown theme token (which resolves to `unset`) costs colour,\r\n * never the reading. The `var(..., fallback)` form keeps the colours visible even\r\n * if the theme renames the token.\r\n */\r\nconst LATENCY_FAST_MS = 500\r\nconst LATENCY_SLOW_MS = 1500\r\n/** The schema default for `testUrl`; also what \"Restore default\" writes. */\r\nconst DEFAULT_TEST_URL = 'https://api.ipify.org?format=json'\r\nconst MAX_TEST_URLS = 5\r\n\r\nfunction latencyColor(ms: unknown): string {\r\n if (typeof ms !== 'number' || !Number.isFinite(ms)) return 'var(--dsw-alias-label-secondary)'\r\n if (ms <= LATENCY_FAST_MS) return 'var(--dsw-alias-state-success-primary, #2ea043)'\r\n if (ms <= LATENCY_SLOW_MS) return 'var(--dsw-alias-state-warn-primary, #d29922)'\r\n return 'var(--dsw-alias-state-error-primary, #f85149)'\r\n}\r\n\r\n/** Normalize the Host's self-check payload into the shape the card renders. */\r\nfunction testResultFrom(body: any, strings: Record<string, string>): Record<string, unknown> {\r\n const ok = body?.ok === true\r\n return {\r\n pending: false,\r\n ok,\r\n ms: typeof body?.ms === 'number' && Number.isFinite(body.ms) ? body.ms : undefined,\r\n ip: typeof body?.exitIp === 'string' && body.exitIp.length > 0 ? body.exitIp : undefined,\r\n status:\r\n typeof body?.status === 'number' && Number.isInteger(body.status) ? body.status : undefined,\r\n target: typeof body?.target === 'string' && body.target.length > 0 ? body.target : undefined,\r\n targetSource:\r\n body?.targetSource === 'route' || body?.targetSource === 'upstream'\r\n ? body.targetSource\r\n : body?.targetSource === 'testUrl'\r\n ? 'testUrl'\r\n : undefined,\r\n cached: body?.cached === true,\r\n // The Host probes a target the way routing would: a loopback/private upstream\r\n // (or a bypassHosts match) is reached DIRECT, not through the proxy. The card\r\n // says so, so a green check is not read as \"the proxy works\".\r\n direct: body?.viaProxy === false,\r\n error: ok\r\n ? undefined\r\n : typeof body?.error === 'string' && body.error.length > 0\r\n ? body.error\r\n : strings.testFailed,\r\n }\r\n}\r\n\r\n/** Split `testUrl` the same way the Host does: commas or whitespace. */\r\nfunction splitTestUrls(raw: string): string[] {\r\n return raw\r\n .split(/[,\\s]+/)\r\n .map(entry => entry.trim())\r\n .filter(entry => entry.length > 0)\r\n}\r\n\r\n/**\r\n * Hint-only validation for `testUrl`.\r\n *\r\n * The Host does not refuse malformed candidates; it simply fails that check.\r\n * The page therefore warns without blocking the write, so a user can still save\r\n * a value the Host accepts (including an empty string, which means \"use the\r\n * built-in default\").\r\n */\r\nfunction testUrlHint(raw: string, t: Record<string, string>): string | undefined {\r\n const entries = splitTestUrls(raw)\r\n if (entries.length === 0) return t.testUrlEmptyHint\r\n const invalid = entries.filter(entry => !isAbsoluteHttpUrl(entry))\r\n if (invalid.length > 0) return t.testUrlInvalidHint\r\n if (entries.length > MAX_TEST_URLS) return t.testUrlTooManyHint\r\n return undefined\r\n}\r\n\r\nfunction isAbsoluteHttpUrl(value: string): boolean {\r\n try {\r\n const url = new URL(value)\r\n return (url.protocol === 'http:' || url.protocol === 'https:') && url.hostname.length > 0\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\n/**\r\n * Where the check's target came from, in the card's own words.\r\n *\r\n * The target is NOT always the top-level `testUrl`: a route's own\r\n * `testTarget` wins, then the provider's REAL upstream, and only a provider\r\n * that publishes none falls back to `testUrl`. Saying so is what explains why\r\n * editing `testUrl` changed one card and not another.\r\n */\r\nfunction targetSourceSuffix(\r\n result: { targetSource?: unknown },\r\n t: Record<string, string>,\r\n): string {\r\n switch (result.targetSource) {\r\n case 'route':\r\n return t.targetSourceRoute\r\n case 'upstream':\r\n return t.targetSourceUpstream\r\n case 'testUrl':\r\n return t.targetSourceTestUrl\r\n default:\r\n return ''\r\n }\r\n}\r\n\r\n/**\r\n * Remove values and URL credentials from text that will be shown to the user.\r\n *\r\n * Settings errors may quote the rejected value. A password field must never\r\n * echo that value, even inside an otherwise useful error message, so exact\r\n * known secrets are replaced before anything is rendered or written to the\r\n * diagnostics panel.\r\n */\r\nfunction redactSensitiveText(text: string, secrets: readonly unknown[] = []): string {\r\n let safe = text\r\n for (const secret of secrets) {\r\n if (typeof secret !== 'string' || secret.length === 0) continue\r\n safe = safe.split(secret).join('***')\r\n }\r\n // A URL in an error may carry userinfo and query/fragment values even when\r\n // the individual secret is not known to this call.\r\n safe = safe.replace(/\\b([a-z][a-z0-9+.-]*:\\/\\/)[^/@\\s]+@/gi, '$1')\r\n safe = safe.replace(/([?&#])[^\\s\"'<>]*/g, '$1')\r\n return safe.length > 500 ? `${safe.slice(0, 500)}\u2026` : safe\r\n}\r\n\r\n/** Values that may be echoed by a failed multi-field write. */\r\nfunction secretsFromOps(ops: readonly any[]): string[] {\r\n const out: string[] = []\r\n for (const op of ops) {\r\n const field = op?.path?.[op.path.length - 1]\r\n if (field === 'password' && typeof op?.value === 'string' && op.value.length > 0) {\r\n out.push(op.value)\r\n }\r\n }\r\n return out\r\n}\r\n\r\n/**\r\n * The setter the lazy catalogue initializer resolves through.\r\n *\r\n * It is republished after every render, so the newest one always wins, and a\r\n * promise that settles after an unmount writes to a harmless no-op.\r\n */\r\nlet catalogueSetter: ((catalog: Catalog) => void) | undefined = () => {}\r\n\r\n/** How one provider's last proxied request ended, as the Host recorded it. */\r\ntype LastUse = {\r\n /** When the most recent proxied request BEGAN. */\r\n startedAt?: number\r\n /** When the last request that FINISHED ended; paired with `ok`/`code`. */\r\n at?: number\r\n ok?: boolean\r\n code?: string\r\n}\r\n\r\n/** What the Host endpoint publishes: provider rows, hit counts, rejected routes. */\r\ntype Catalog = {\r\n rows: ProviderRow[]\r\n /**\r\n * Exactly what the Host published, before `knownProviders` merges saved\r\n * routes in. N7 must compare against this set: comparing against `rows`\r\n * would make every saved provider look published.\r\n */\r\n publishedRows: ProviderRow[]\r\n hits: Record<string, number>\r\n problems: Record<string, string>\r\n lastUse: Record<string, LastUse>\r\n /**\r\n * The forward proxy the Host inherited from its environment, if any. The\r\n * Host already dropped the credentials; `hadCredentials` says the variable\r\n * carried some, so the page can ask the user to re-enter them.\r\n */\r\n environmentProxy?: DetectedProxy | null\r\n /** Set when the FIRST read failed; a later successful poll clears it. */\r\n error?: string\r\n}\r\n\r\n/** One proxy detected in the Host's environment (see `src/proxy-env.ts`). */\r\ntype DetectedProxy = {\r\n source: string\r\n protocol: Protocol\r\n host: string\r\n port: number\r\n hadCredentials: boolean\r\n}\r\n\r\n/**\r\n * A coarse \"how long ago\", for the last-use line.\r\n *\r\n * Deliberately coarse: the page only re-reads the catalogue every 10 s, so a\r\n * second-precision string would look stale on its own and mean nothing.\r\n */\r\nfunction relativeTime(at: number, t: Record<string, string>): string {\r\n const seconds = Math.max(0, Math.round((Date.now() - at) / 1000))\r\n if (seconds < 60) return t.justNow\r\n const minutes = Math.floor(seconds / 60)\r\n if (minutes < 60) return `${minutes}${t.minutesAgo}`\r\n const hours = Math.floor(minutes / 60)\r\n if (hours < 24) return `${hours}${t.hoursAgo}`\r\n return `${Math.floor(hours / 24)}${t.daysAgo}`\r\n}\r\n\r\n/** Read the Host's provider catalogue. Same-origin, so no token is needed. */\r\nasync function fetchCatalog(): Promise<Catalog> {\r\n const response = await globalThis.fetch(CATALOG_PATH, { headers: { accept: 'application/json' } })\r\n if (!response.ok) throw new Error(`Host answered ${response.status}`)\r\n const body = await response.json()\r\n const list = Array.isArray(body?.providers) ? body.providers : []\r\n const rows = list\r\n .filter((row: any) => typeof row?.id === 'string' && row.id.length > 0)\r\n .map((row: any) => ({\r\n id: row.id,\r\n name: typeof row.name === 'string' && row.name.length > 0 ? row.name : row.id,\r\n live: row.live === true,\r\n }))\r\n // The Host counts requests it routed through each provider's proxy. Anything\r\n // malformed is dropped rather than rendered, so a bad payload cannot put a\r\n // non-numeric string on the page.\r\n const hits: Record<string, number> = {}\r\n const published = body?.hits\r\n if (published !== null && typeof published === 'object') {\r\n for (const [id, count] of Object.entries(published)) {\r\n if (typeof count === 'number' && Number.isFinite(count)) hits[id] = count\r\n }\r\n }\r\n // A route the Host REFUSED (a bad port, half-filled credentials) is absent from\r\n // the provider list entirely, so this map is the only place that says why it is\r\n // missing. The Host already stripped the log prefix from it.\r\n const problems: Record<string, string> = {}\r\n const rejected = body?.problems\r\n if (rejected !== null && typeof rejected === 'object') {\r\n for (const [id, message] of Object.entries(rejected)) {\r\n if (typeof message === 'string' && message.length > 0) problems[id] = message\r\n }\r\n }\r\n // The last-use record: when each provider's most recent proxied request\r\n // began, and \u2014 separately \u2014 how the last request that FINISHED ended. Anything\r\n // malformed is dropped rather than rendered, so a bad payload cannot put a\r\n // non-numeric timestamp on the page. An entry carrying only `startedAt` is\r\n // kept: it is a request still in flight, and the page says when it was started.\r\n const lastUse: Record<string, LastUse> = {}\r\n const publishedLastUse = body?.lastUse\r\n if (publishedLastUse !== null && typeof publishedLastUse === 'object') {\r\n for (const [id, raw] of Object.entries(publishedLastUse)) {\r\n const entry = raw as LastUse | undefined\r\n if (entry === null || typeof entry !== 'object') continue\r\n const at = typeof entry.at === 'number' && Number.isFinite(entry.at) ? entry.at : undefined\r\n const startedAt =\r\n typeof entry.startedAt === 'number' && Number.isFinite(entry.startedAt)\r\n ? entry.startedAt\r\n : undefined\r\n if (at === undefined && startedAt === undefined) continue\r\n lastUse[id] = {\r\n ...(startedAt === undefined ? {} : { startedAt }),\r\n ...(at === undefined ? {} : { at }),\r\n ...(typeof entry.ok === 'boolean' ? { ok: entry.ok } : {}),\r\n ...(typeof entry.code === 'string' && entry.code.length > 0 ? { code: entry.code } : {}),\r\n }\r\n }\r\n }\r\n // The environment probe is OPTIONAL decoration: a missing or malformed value\r\n // only costs the \"detect from environment\" option, never a render.\r\n const environmentProxy = ((): DetectedProxy | null => {\r\n const raw = (body?.environment as { proxy?: unknown } | undefined)?.proxy\r\n if (raw === null || typeof raw !== 'object') return null\r\n const candidate = raw as Record<string, unknown>\r\n const protocol = candidate.protocol\r\n if (protocol !== 'http' && protocol !== 'https' && protocol !== 'socks5') return null\r\n if (typeof candidate.host !== 'string' || candidate.host.length === 0) return null\r\n const port = candidate.port\r\n if (typeof port !== 'number' || !Number.isInteger(port) || port < 1 || port > 65535) return null\r\n return {\r\n source: typeof candidate.source === 'string' ? candidate.source : 'environment',\r\n protocol,\r\n host: candidate.host,\r\n port,\r\n hadCredentials: candidate.hadCredentials === true,\r\n }\r\n })()\r\n return { rows, publishedRows: rows, hits, problems, lastUse, environmentProxy }\r\n}\r\n\r\n/**\r\n * Catalogue polling while the page is open.\r\n *\r\n * The catalogue (published rows, hit counts, rejected routes) is fetched once at\r\n * mount and would otherwise stay a snapshot for the page's lifetime: the hit\r\n * counter never moves, and a route the Host starts or stops refusing stays\r\n * invisible. One shared interval re-fetches it every CATALOG_REFRESH_MS.\r\n *\r\n * `touchCatalogPolling` runs on every render. Writing the module-level timestamp\r\n * there is deliberately not treated as a render side effect: it is idempotent,\r\n * re-enters nothing (unlike a setState during render), and it is the only signal\r\n * that the page is still alive. A page that stops rendering \u2014 a closed panel \u2014\r\n * goes stale, and the next tick cancels the interval instead of fetching for\r\n * nobody. A failed poll is swallowed: the page keeps its last data, and the\r\n * mount-time fetch already reports a broken endpoint in the diagnostics.\r\n */\r\nconst CATALOG_REFRESH_MS = 10_000\r\nlet catalogPoll: ReturnType<typeof setInterval> | undefined\r\nlet catalogTouchedAt = 0\r\n\r\nfunction touchCatalogPolling(): void {\r\n catalogTouchedAt = Date.now()\r\n if (catalogPoll !== undefined) return\r\n catalogPoll = setInterval(() => {\r\n if (Date.now() - catalogTouchedAt > CATALOG_REFRESH_MS * 2 + 1_000) {\r\n clearInterval(catalogPoll)\r\n catalogPoll = undefined\r\n return\r\n }\r\n void fetchCatalog()\r\n .then(catalog => catalogueSetter?.(catalog))\r\n .catch(() => undefined)\r\n }, CATALOG_REFRESH_MS)\r\n}\r\n\r\nconst byName = (a: ProviderRow, b: ProviderRow): number => a.name.localeCompare(b.name)\r\n\r\nfunction view(route: Partial<RouteValue> | undefined): RouteValue {\r\n return {\r\n enabled: route?.enabled === true,\r\n profileId: typeof route?.profileId === 'string' ? route.profileId : '',\r\n useDefault: route?.useDefault === true,\r\n protocol: PROTOCOLS.includes(route?.protocol as Protocol) ? (route!.protocol as Protocol) : 'http',\r\n host: route?.host ?? '',\r\n port: route?.port ?? 0,\r\n username: route?.username ?? '',\r\n password: route?.password ?? '',\r\n onlyHosts: route?.onlyHosts ?? '',\r\n bypassHosts: route?.bypassHosts ?? '',\r\n testTarget: route?.testTarget ?? '',\r\n }\r\n}\r\n\r\n/** Schema defaults for one preset, so a half-filled one still renders. */\r\nfunction profileView(profile: Partial<ProfileValue> | undefined): ProfileValue {\r\n return {\r\n protocol: PROTOCOLS.includes(profile?.protocol as Protocol)\r\n ? (profile!.protocol as Protocol)\r\n : 'http',\r\n host: typeof profile?.host === 'string' ? profile.host : '',\r\n port: typeof profile?.port === 'number' ? profile.port : 0,\r\n username: typeof profile?.username === 'string' ? profile.username : '',\r\n password: typeof profile?.password === 'string' ? profile.password : '',\r\n }\r\n}\r\n\r\n/** Drop the brackets WHATWG URL keeps on an IPv6 literal host. */\r\nfunction unbracket(hostname: string): string {\r\n return hostname.startsWith('[') && hostname.endsWith(']') ? hostname.slice(1, -1) : hostname\r\n}\r\n\r\n/**\r\n * Split a pasted full proxy URL into route fields, or `undefined` when the text\r\n * is not one.\r\n *\r\n * `socks5` is a NON-special scheme, so WHATWG URL still parses its userinfo and\r\n * port (verified), but three quirks are handled here:\r\n * - the userinfo is NOT percent-decoded by the parser, so it is decoded here;\r\n * - an IPv6 literal comes back bracketed, and the host field wants it bare;\r\n * - a DEFAULT port is stripped by WHATWG for http/https; the original text is\r\n * consulted so an explicitly written :80/:443 is preserved, while an absent\r\n * port still stays 0 (\"not configured\") instead of being invented.\r\n */\r\nfunction explicitPortOf(text: string): number {\r\n const authority = text.slice(text.indexOf('://') + 3).split(/[/?#]/, 1)[0]\r\n const hostPort = authority.slice(authority.lastIndexOf('@') + 1)\r\n const match = /^\\[[^\\]]+\\]:(\\d+)$/.exec(hostPort) ?? /^[^:]+:(\\d+)$/.exec(hostPort)\r\n if (match === null) return 0\r\n const port = Number.parseInt(match[1], 10)\r\n return Number.isNaN(port) ? 0 : port\r\n}\r\n\r\nfunction splitProxyUrl(text: string): Partial<RouteValue> | undefined {\r\n const trimmed = text.trim()\r\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(trimmed)) return undefined\r\n let url: URL\r\n try {\r\n url = new URL(trimmed)\r\n } catch {\r\n return undefined\r\n }\r\n const scheme = url.protocol.slice(0, -1).toLowerCase()\r\n // `socks://` is a common spelling this plugin does not accept on its own;\r\n // normalizing it here means a pasted alias still lands on the supported\r\n // transport instead of being rejected later.\r\n const protocol = scheme === 'socks' ? 'socks5' : scheme\r\n if (!PROTOCOLS.includes(protocol as Protocol)) return undefined\r\n if (url.hostname.length === 0) return undefined\r\n const decode = (value: string): string => {\r\n try {\r\n return decodeURIComponent(value)\r\n } catch {\r\n return value\r\n }\r\n }\r\n const parsedPort = url.port.length > 0\r\n ? Number.parseInt(url.port, 10)\r\n : explicitPortOf(trimmed)\r\n return {\r\n protocol: protocol as Protocol,\r\n host: unbracket(url.hostname),\r\n port: Number.isNaN(parsedPort) ? 0 : parsedPort,\r\n username: decode(url.username),\r\n password: decode(url.password),\r\n }\r\n}\r\n\r\n/**\r\n * Pending writes, one debounced timer per provider+field.\r\n *\r\n * Every keystroke of an input fires `bind`, and the Host rebuilds its whole\r\n * proxy table on each settings write (`loader/volatile-update` \u2192 `rebuild()`).\r\n * Writing per keystroke therefore churns a dispatcher generation per character \u2014\r\n * and, worse, a half-typed credential (\"username without a password\") hits the\r\n * Host guards between keystrokes, so the route is refused for an instant and a\r\n * misleading problem is recorded. Only the LAST value of a burst needs to reach\r\n * the Host; the draft already gives the control its instant feedback.\r\n *\r\n * Module-level, so the timers survive a re-render (each pass rebuilds `save`)\r\n * and a page unmount: a write that was already promised still lands.\r\n */\r\nconst WRITE_DELAY_MS = 300\r\ntype PendingWrite = { timer?: ReturnType<typeof setTimeout>; flush: () => Promise<void> }\r\nconst pendingWrites = new Map<string, PendingWrite>()\r\n\r\n/**\r\n * Where the page remembers its own VIEW preferences.\r\n *\r\n * The settings page is torn down and remounted whenever the user navigates\r\n * away, so anything held in `useState` alone resets: a user who prefers the\r\n * compact list had to switch back on every visit. These are preferences about\r\n * how to LOOK at the page, never about what it configures, so they live in\r\n * `localStorage` rather than in the plugin's settings file \u2014 writing them to\r\n * `cordis.patch.yml` would make a display toggle look like configuration, and\r\n * a failed settings write would silently discard it.\r\n */\r\nconst VIEW_PREFS_KEY = 'dsh-provider-proxy:view'\r\n\r\ntype ViewPrefs = {\r\n viewMode?: 'card' | 'compact'\r\n statusFilter?: 'all' | 'proxied' | 'direct' | 'rejected'\r\n}\r\n\r\n/** Stored preferences, or `{}` when storage is missing or unreadable. */\r\nfunction readViewPrefs(): ViewPrefs {\r\n try {\r\n const raw = globalThis.localStorage?.getItem(VIEW_PREFS_KEY)\r\n if (typeof raw !== 'string' || raw.length === 0) return {}\r\n const parsed = JSON.parse(raw) as ViewPrefs\r\n if (parsed === null || typeof parsed !== 'object') return {}\r\n const out: ViewPrefs = {}\r\n if (parsed.viewMode === 'card' || parsed.viewMode === 'compact') out.viewMode = parsed.viewMode\r\n if (\r\n parsed.statusFilter === 'all' ||\r\n parsed.statusFilter === 'proxied' ||\r\n parsed.statusFilter === 'direct' ||\r\n parsed.statusFilter === 'rejected'\r\n ) {\r\n out.statusFilter = parsed.statusFilter\r\n }\r\n return out\r\n } catch {\r\n // Private mode, a quota error, or a corrupt value: the page still works,\r\n // it just forgets the preference.\r\n return {}\r\n }\r\n}\r\n\r\n/** Persist one preference, merging with what is already stored. */\r\nfunction writeViewPrefs(patch: ViewPrefs): void {\r\n try {\r\n const next = { ...readViewPrefs(), ...patch }\r\n globalThis.localStorage?.setItem(VIEW_PREFS_KEY, JSON.stringify(next))\r\n } catch {\r\n // A view preference that cannot be saved must never break the page.\r\n }\r\n}\r\n\r\n/**\r\n * Writes are serialized so a test can await every write it flushed without\r\n * racing the settings revision fence. A run handles its own failures, so the\r\n * tail never rejects the next write.\r\n */\r\nlet writeQueue: Promise<void> = Promise.resolve()\r\nfunction enqueueWrite(run: () => Promise<void>): Promise<void> {\r\n const next = writeQueue.then(run, run)\r\n writeQueue = next.catch(() => undefined)\r\n return next\r\n}\r\n\r\n/** Schedule one debounced write; `flush` runs it immediately and only once. */\r\nfunction scheduleWrite(key: string, run: () => Promise<void>): void {\r\n const pending = pendingWrites.get(key)\r\n if (pending?.timer !== undefined) clearTimeout(pending.timer)\r\n const entry: PendingWrite = {\r\n flush: () => {\r\n if (entry.timer !== undefined) clearTimeout(entry.timer)\r\n pendingWrites.delete(key)\r\n return enqueueWrite(run)\r\n },\r\n }\r\n entry.timer = setTimeout(() => { void entry.flush() }, WRITE_DELAY_MS)\r\n pendingWrites.set(key, entry)\r\n}\r\n\r\n/**\r\n * A self-check result belongs to the configuration it was measured against.\r\n * Every relevant edit bumps this counter; a response that started under an older\r\n * generation is discarded instead of being pasted onto the new settings.\r\n */\r\nconst testGeneration = new Map<string, number>()\r\nconst TEST_RELEVANT_FIELDS = new Set([\r\n 'protocol',\r\n 'host',\r\n 'port',\r\n 'username',\r\n 'password',\r\n 'onlyHosts',\r\n 'bypassHosts',\r\n 'testTarget',\r\n 'useDefault',\r\n])\r\n\r\n/** The provider directory, cached module-side. See renderPage. */\r\nlet directoryCache: ProviderRow[] | undefined\r\n\r\n/**\r\n * Everything the page learned about its own wiring, rendered verbatim.\r\n *\r\n * The browser side of a plugin has no other diagnostic channel \u2014 the Host log\r\n * never sees it \u2014 so a silent failure had to be diagnosed by inference. This\r\n * panel is what proved that `remote.settings` and `remote.llm` do not exist in\r\n * this release, and that the catalogue had to come from the Host endpoint.\r\n *\r\n * Cleared at the start of every render so the panel shows the CURRENT state\r\n * rather than an ever-growing log of the session.\r\n */\r\nlet diagnostics: string[] = []\r\n\r\nfunction note(message: string): void {\r\n if (!diagnostics.includes(message)) diagnostics.push(message)\r\n}\r\n\r\n/**\r\n * Layout constants, applied as INLINE styles.\r\n *\r\n * The page is rendered into the settings panel, and the CSS-Modules pipeline\r\n * that feeds the stylesheet has broken twice in ways that were invisible from\r\n * the source: the class map failed to bind at all, and a shared class prefix\r\n * silently merged two rules. Both left the page readable but laid out as one\r\n * unstyled block.\r\n *\r\n * Structure is therefore expressed as inline styles, which cannot be lost by\r\n * the bundle, and the stylesheet is kept for the purely decorative parts. A\r\n * theme token that is not defined simply resolves to `unset`, so an unknown\r\n * token costs colour, never layout.\r\n */\r\nconst S = {\r\n root: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '14px',\r\n maxWidth: '760px',\r\n },\r\n /**\r\n * One vertical group of page-level blocks.\r\n *\r\n * Page settings (default endpoint, presets, backup, advanced) are one visual\r\n * unit; the provider list is another. Without the grouping every block was a\r\n * sibling at the same level, so the list controls ended up four blocks below\r\n * the list they operate on.\r\n */\r\n group: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '10px',\r\n minWidth: '0',\r\n },\r\n /** A small heading that separates the page's groups. */\r\n groupTitle: {\r\n margin: '6px 0 -2px',\r\n fontSize: '11px',\r\n fontWeight: '600',\r\n letterSpacing: '0.04em',\r\n textTransform: 'uppercase',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n card: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '12px',\r\n padding: '14px 16px',\r\n // Longhands, for the same reason as `chip`: `cardActive`/`cardRejected`\r\n // override ONLY `borderColor`, and a shorthand here would lose its colour\r\n // the moment a card went back to the resting state.\r\n borderWidth: '1px',\r\n borderStyle: 'solid',\r\n borderColor: 'var(--dsw-alias-border-l1)',\r\n borderRadius: '10px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n },\r\n cardActive: {\r\n borderColor: 'var(--dsw-alias-state-success-primary)',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n /** An enabled route the Host refused: active-looking styling would be a lie. */\r\n cardRejected: {\r\n borderColor: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n head: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n gap: '12px',\r\n },\r\n titles: { display: 'flex', alignItems: 'baseline', gap: '8px', minWidth: '0' },\r\n name: {\r\n fontSize: '14px',\r\n fontWeight: '600',\r\n color: 'var(--dsw-alias-label-primary)',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n whiteSpace: 'nowrap',\r\n },\r\n id: {\r\n flex: 'none',\r\n padding: '1px 6px',\r\n borderRadius: '4px',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n fontFamily: 'ui-monospace, monospace',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n hits: {\r\n flex: 'none',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n whiteSpace: 'nowrap',\r\n },\r\n testRow: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '10px',\r\n flexWrap: 'wrap',\r\n },\r\n testButton: {\r\n padding: '5px 12px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '6px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-label-primary)',\r\n font: 'inherit',\r\n fontSize: '12px',\r\n cursor: 'pointer',\r\n },\r\n /** The reveal/hide control sits inside the password field's right edge. */\r\n passwordControl: {\r\n position: 'relative',\r\n minWidth: '0',\r\n },\r\n passwordToggle: {\r\n position: 'absolute',\r\n top: '50%',\r\n right: '4px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n width: '26px',\r\n height: '26px',\r\n padding: '0',\r\n border: '0',\r\n borderRadius: '6px',\r\n background: 'transparent',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n lineHeight: '1',\r\n transform: 'translateY(-50%)',\r\n cursor: 'pointer',\r\n },\r\n testResult: {\r\n // A flex row so the target can drop onto its own line: the container was a\r\n // plain span, where `flexBasis: 100%` does nothing and the target ran into\r\n // the \"cached\" label.\r\n display: 'flex',\r\n flexWrap: 'wrap',\r\n alignItems: 'baseline',\r\n columnGap: '6px',\r\n rowGap: '2px',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n wordBreak: 'break-all',\r\n },\r\n /**\r\n * A failed check is the answer, not decoration: it takes the error colour and\r\n * a heavier weight, unlike the latency band colour which only tints a number\r\n * that is printed anyway.\r\n */\r\n testFailure: {\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n fontWeight: '500',\r\n },\r\n /** A rejected route is a failure of the settings, not a warning about them. */\r\n diagProblem: {\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n },\r\n /** Informational catalogue mismatch: not a rejected route, so no error red. */\r\n diagNote: {\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n advanced: {\r\n marginTop: '4px',\r\n fontSize: '12px',\r\n },\r\n advancedSummary: {\r\n cursor: 'pointer',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n pill: {\r\n flex: 'none',\r\n padding: '2px 10px',\r\n borderRadius: '999px',\r\n fontSize: '11px',\r\n fontWeight: '500',\r\n whiteSpace: 'nowrap',\r\n },\r\n pillOn: {\r\n background: 'var(--dsw-alias-state-success-primary)',\r\n color: 'var(--dsw-alias-bg-base)',\r\n },\r\n pillLive: {\r\n border: '1px solid var(--dsw-alias-border-l2)',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n pillOff: { color: 'var(--dsw-alias-state-idle-primary)' },\r\n pillRejected: {\r\n border: '1px solid var(--dsw-alias-state-error-primary, #f85149)',\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n },\r\n /**\r\n * The shared default endpoint sits on its own layer so it reads as global\r\n * rather than as one more provider card \u2014 the mistake it exists to prevent is\r\n * a user typing the same address into every card.\r\n */\r\n defaultCard: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '12px',\r\n padding: '14px 16px',\r\n border: '1px solid var(--dsw-alias-border-l2)',\r\n borderRadius: '10px',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n defaultLead: {\r\n margin: '-2px 0 0',\r\n fontSize: '11px',\r\n lineHeight: '1.5',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n inheritNote: {\r\n margin: '0',\r\n fontSize: '11px',\r\n lineHeight: '1.5',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n /** The default is not configured: an answer, so it takes the error colour. */\r\n inheritWarning: {\r\n margin: '0',\r\n fontSize: '11px',\r\n lineHeight: '1.5',\r\n fontWeight: '500',\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n },\r\n toggle: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '8px',\r\n fontSize: '12px',\r\n color: 'var(--dsw-alias-label-primary)',\r\n },\r\n field: {\r\n display: 'grid',\r\n gridTemplateColumns: '76px 1fr',\r\n alignItems: 'center',\r\n gap: '8px',\r\n fontSize: '12px',\r\n minWidth: '0',\r\n },\r\n /** A row of peer controls, each with its own label above it. */\r\n controlRow: {\r\n display: 'grid',\r\n gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))',\r\n alignItems: 'end',\r\n gap: '10px 14px',\r\n },\r\n /** One cell of `controlRow`: a small label over its control. */\r\n controlCell: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '4px',\r\n fontSize: '12px',\r\n minWidth: '0',\r\n },\r\n label: { color: 'var(--dsw-alias-label-secondary)' },\r\n input: {\r\n boxSizing: 'border-box',\r\n width: '100%',\r\n minWidth: '0',\r\n padding: '6px 8px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '6px',\r\n outline: 'none',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-label-primary)',\r\n font: 'inherit',\r\n fontSize: '12px',\r\n },\r\n diag: {\r\n padding: '10px 14px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '10px',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n },\r\n hint: {\r\n gridColumn: '1 / -1',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-state-warn-primary, #d29922)',\r\n },\r\n /** The shared shell of every collapsible panel on the page. */\r\n panelBody: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '10px',\r\n marginTop: '8px',\r\n },\r\n /** The bordered block of list controls, directly above the list. */\r\n toolbar: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '8px',\r\n padding: '10px 12px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '10px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n },\r\n toolbarRow: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n flexWrap: 'wrap',\r\n gap: '8px',\r\n minWidth: '0',\r\n },\r\n /** The backup bar: explanation on the left, its two actions on the right. */\r\n backupBar: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n flexWrap: 'wrap',\r\n gap: '10px',\r\n padding: '10px 12px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '10px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n },\r\n chipRow: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: '6px',\r\n flexWrap: 'wrap',\r\n marginBottom: '2px',\r\n },\r\n chip: {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n padding: '3px 10px',\r\n borderRadius: '999px',\r\n // An UNSELECTED chip is bare text: no outline, no fill.\r\n //\r\n // It used to carry a faint 1px border, which is the same shape as the\r\n // selected chip's outline \u2014 so after switching filters the old chip still\r\n // read as \"selected, just with dimmer text\". The border is kept in the\r\n // declaration as `transparent` rather than removed, so selecting a chip\r\n // cannot shift the row by a pixel.\r\n //\r\n // WRITTEN AS THREE LONGHANDS, NOT AS THE `border` SHORTHAND. This is not\r\n // style: React diffs inline styles key by key, and `chipActive` only\r\n // overrides `borderColor`. Deselecting a chip therefore DELETES the\r\n // `borderColor` key, React writes `style.borderColor = ''`, and the\r\n // shorthand's transparent value is NOT restored \u2014 the border falls back to\r\n // the CSS initial value `currentColor`, leaving a text-coloured outline on\r\n // a chip that is supposed to have none. Keeping all three longhands present\r\n // in every state means only the VALUE changes, never the key.\r\n borderWidth: '1px',\r\n borderStyle: 'solid',\r\n borderColor: 'transparent',\r\n background: 'transparent',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n fontSize: '11px',\r\n fontWeight: '500',\r\n cursor: 'pointer',\r\n userSelect: 'none',\r\n },\r\n /** The one selected chip: a solid fill, unmistakable at a glance. */\r\n chipActive: {\r\n borderColor: 'var(--dsw-alias-brand-primary)',\r\n background: 'var(--dsw-alias-brand-primary)',\r\n color: 'var(--dsw-alias-bg-base)',\r\n fontWeight: '600',\r\n },\r\n compactRow: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '8px',\r\n padding: '12px 16px',\r\n borderWidth: '1px',\r\n borderStyle: 'solid',\r\n borderColor: 'var(--dsw-alias-border-l1)',\r\n borderRadius: '10px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n },\r\n /** Row 1 of a compact entry: identity and the proxy it uses. */\r\n compactLine: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n flexWrap: 'wrap',\r\n gap: '8px',\r\n minWidth: '0',\r\n },\r\n /** Row 2 of a compact entry: every control, right-aligned. */\r\n compactActions: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n flexWrap: 'wrap',\r\n gap: '8px',\r\n minWidth: '0',\r\n },\r\n /**\r\n * Row 3 of a compact entry: the self-check outcome.\r\n *\r\n * Its own line, so a running or failing check never shifts the picker or the\r\n * buttons, and a long failure message gets the full width instead of being\r\n * squeezed between two controls.\r\n */\r\n compactResultLine: {\r\n display: 'flex',\r\n alignItems: 'baseline',\r\n flexWrap: 'wrap',\r\n gap: '6px',\r\n paddingTop: '6px',\r\n borderTop: '1px solid var(--dsw-alias-border-l1)',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n minWidth: '0',\r\n wordBreak: 'break-all',\r\n },\r\n compactRowActive: {\r\n borderColor: 'var(--dsw-alias-state-success-primary)',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n compactRowRejected: {\r\n borderColor: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n background: 'var(--dsw-alias-bg-layer-2)',\r\n },\r\n compactEndpoint: {\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n overflow: 'hidden',\r\n textOverflow: 'ellipsis',\r\n whiteSpace: 'nowrap',\r\n maxWidth: '180px',\r\n },\r\n formGrid: {\r\n display: 'grid',\r\n gridTemplateColumns: 'repeat(2, minmax(0, 1fr))',\r\n alignItems: 'start',\r\n gap: '10px 14px',\r\n },\r\n formGridFull: {\r\n gridColumn: '1 / -1',\r\n },\r\n copyButton: {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n padding: '2px 4px',\r\n border: 'none',\r\n borderRadius: '4px',\r\n background: 'transparent',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n cursor: 'pointer',\r\n fontSize: '11px',\r\n lineHeight: '1',\r\n },\r\n} as const\r\n\r\nfunction renderPage(ctx: any): unknown {\r\n const React = react()\r\n if (React === undefined || typeof React.createElement !== 'function') return null\r\n\r\n const h = React.createElement\r\n const t = stringsFor(ctx)\r\n diagnostics = []\r\n\r\n // `useState` is only reached after the React check, so the early return above\r\n // cannot desync the hooks order.\r\n let snapshot: { value: any; revision: number }\r\n try {\r\n snapshot = readConfig(ctx)\r\n } catch {\r\n snapshot = { value: {}, revision: 0 }\r\n }\r\n const configured = (snapshot.value?.providers ?? {}) as Record<string, RouteValue>\r\n note(\r\n formOf(ctx) === undefined\r\n ? '\u8BBE\u7F6E\uFF1A\u672A\u627E\u5230 configForms \u670D\u52A1\uFF0C\u53EA\u80FD\u663E\u793A\u3001\u65E0\u6CD5\u4FDD\u5B58'\r\n : `\u8BBE\u7F6E\uFF1A\u6B63\u5E38\uFF08\u4FEE\u8BA2\u53F7 ${snapshot.revision}\uFF0C${Object.keys(configured).length} \u4E2A provider\uFF09`,\r\n )\r\n\r\n // The provider catalogue comes from the Host over a same-origin endpoint, so\r\n // it arrives asynchronously. The initial state is a LAZY initializer, so the\r\n // fetch starts from `useState(() => \u2026)` instead of by calling a setter during\r\n // render: a render must have no side effects, and doing so also shifted the\r\n // hook order between passes.\r\n const [state, setState] = (React.useState ?? ((fn: any) => [fn(), () => {}]))(() => {\r\n void fetchCatalog()\r\n .then(catalog => catalogueSetter?.(catalog))\r\n .catch((error: any) => {\r\n catalogueSetter?.({\r\n rows: [],\r\n publishedRows: [],\r\n hits: {},\r\n problems: {},\r\n lastUse: {},\r\n error: String(error?.message ?? error),\r\n })\r\n })\r\n return {\r\n rows: undefined as ProviderRow[] | undefined,\r\n publishedRows: undefined as ProviderRow[] | undefined,\r\n hits: {} as Record<string, number>,\r\n problems: {} as Record<string, string>,\r\n lastUse: {} as Record<string, LastUse>,\r\n environmentProxy: null as DetectedProxy | null,\r\n error: undefined as string | undefined,\r\n pending: true,\r\n }\r\n })\r\n // The setter is published right after the hook so the initializer's promise\r\n // can reach it. It is re-published on every render, so the latest wins.\r\n catalogueSetter = catalog =>\r\n setState({\r\n rows: catalog.rows,\r\n publishedRows: catalog.publishedRows,\r\n hits: catalog.hits,\r\n problems: catalog.problems,\r\n lastUse: catalog.lastUse,\r\n environmentProxy: catalog.environmentProxy ?? null,\r\n error: catalog.error,\r\n pending: false,\r\n })\r\n // Keeps the catalogue (rows, hit counts, rejected routes) current while the\r\n // page is open; see the function's own notes for the staleness handling.\r\n touchCatalogPolling()\r\n\r\n const published = state.rows ?? []\r\n const publishedRows = state.publishedRows ?? []\r\n const hits = state.hits ?? {}\r\n const lastUse = state.lastUse ?? {}\r\n\r\n /**\r\n * The one-line last-use summary for a card, or `undefined` when the route has\r\n * never carried a request. `hits` says the route HAS been used; this says\r\n * whether it still works \u2014 the question a silently stalled proxy raises.\r\n *\r\n * A success or failure uses `at`, the time the last request FINISHED \u2014 the\r\n * time its outcome belongs to. A request that has only STARTED uses\r\n * `startedAt`, so a still-in-flight call cannot make the page claim an outcome\r\n * it does not have yet.\r\n */\r\n const lastUseText = (id: string): string | undefined => {\r\n const use = lastUse[id]\r\n if (use === undefined) return undefined\r\n if (use.ok === true) return `${t.recentOk}${relativeTime(use.at ?? use.startedAt ?? Date.now(), t)}`\r\n if (use.ok === false) return `${t.recentFail}${use.code ?? 'ERROR'}`\r\n return `${t.recentStarted}${relativeTime(use.startedAt ?? use.at ?? Date.now(), t)}`\r\n }\r\n // Rendered straight from state rather than through `note()`: `diagnostics` is\r\n // cleared at the start of every render, so a note written when the catalog\r\n // arrives would not survive to the next pass.\r\n const problems = state.problems ?? {}\r\n const problemLines = Object.entries(problems).map(([id, message]) =>\r\n h('li', { key: `p:${id}`, style: S.diagProblem }, `${id}\uFF1A${message}`),\r\n )\r\n const publishedIds = new Set(publishedRows.map((row: ProviderRow) => row.id))\r\n const missingFromCatalog =\r\n state.pending === true || state.error !== undefined\r\n ? []\r\n : Object.keys(configured)\r\n .filter(id => !publishedIds.has(id))\r\n .sort()\r\n const catalogueMismatchLine =\r\n missingFromCatalog.length === 0\r\n ? undefined\r\n : h(\r\n 'li',\r\n { key: 'catalogue-mismatch', style: S.diagNote },\r\n `${t.catalogueMismatch}${missingFromCatalog.join('\u3001')}${t.catalogueMismatchSuffix}`,\r\n )\r\n const problemCount = problemLines.length + (catalogueMismatchLine === undefined ? 0 : 1)\r\n note(\r\n `provider \u5217\u8868\uFF1A\u6765\u81EA Host \u5171 ${published.length} \u4E2A\uFF08${published.map((r: ProviderRow) => r.id).join('\u3001') || '\u65E0'}\uFF09`,\r\n )\r\n // Local draft, layered over the stored config.\r\n //\r\n // Without it a checkbox does not change until the panel remounts: the value\r\n // is read from the settings store, which only updates when the page is\r\n // rebuilt. The draft makes the control respond immediately, then reconciles\r\n // with the store so a refused write is visible rather than silently lost.\r\n const [draft, setDraft] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const edit = (id: string, field: string, value: unknown) =>\r\n setDraft((current: any) => ({ ...current, [id]: { ...current[id], [field]: value } }))\r\n\r\n /**\r\n * The shared default endpoint gets its own draft for the same reason a card\r\n * does: its controls must show an edit before the debounced write lands.\r\n *\r\n * It is deliberately NOT stored under a sentinel key inside `draft`:\r\n * `knownProviders` unions the stored config with the draft to build the card\r\n * list, so such a key would surface as a phantom provider with no name.\r\n */\r\n const [defaultDraft, setDefaultDraft] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const editDefault = (field: string, value: unknown) =>\r\n setDefaultDraft((current: any) => ({ ...current, [field]: value }))\r\n\r\n /**\r\n * Named presets: their own draft, keyed by preset name.\r\n *\r\n * Kept separate from `draft` (keyed by provider id) so a preset can never be\r\n * mistaken for a provider row, and separate from `defaultDraft` because the\r\n * built-in default preset is edited in its own block.\r\n */\r\n const [profileDraft, setProfileDraft] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const editProfile = (name: string, field: string, value: unknown) =>\r\n setProfileDraft((current: any) => ({\r\n ...current,\r\n [name]: { ...current[name], [field]: value },\r\n }))\r\n\r\n /**\r\n * The preset manager's own edit state.\r\n *\r\n * `window.prompt` is NOT usable here: Electron does not implement it, so the\r\n * call throws and a button wired to it does nothing at all \u2014 exactly the\r\n * symptom \"clicking Add preset has no effect\". Naming is therefore an inline\r\n * input, which also works in a web build.\r\n */\r\n const [newProfileName, setNewProfileName] = (React.useState ?? ((v: any) => [v, () => {}]))('')\r\n const [renamingProfile, setRenamingProfile] = (React.useState ?? ((v: any) => [v, () => {}]))(\r\n undefined as string | undefined,\r\n )\r\n const [renameDraft, setRenameDraft] = (React.useState ?? ((v: any) => [v, () => {}]))('')\r\n /**\r\n * Whether the preset manager is expanded.\r\n *\r\n * A controlled `<details>`: adding a preset must open the block that contains\r\n * it, otherwise the new row appears inside a collapsed section and the click\r\n * still reads as \"nothing happened\".\r\n */\r\n const [profileManagerOpen, setProfileManagerOpen] = (React.useState ?? ((v: any) => [v, () => {}]))(\r\n false,\r\n )\r\n\r\n /**\r\n * Whether each password input is temporarily shown as plain text.\r\n *\r\n * Provider cards are keyed by id; the shared default has its own state so a\r\n * real provider named `default` cannot collide with it. This is view state\r\n * only: it is deliberately not persisted and never written to the settings.\r\n */\r\n const [passwordVisible, setPasswordVisible] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const [defaultPasswordVisible, setDefaultPasswordVisible] = (React.useState ?? ((v: any) => [v, () => {}]))(false)\r\n const togglePassword = (id: string): void =>\r\n setPasswordVisible((current: any) => ({ ...current, [id]: current[id] !== true }))\r\n const toggleDefaultPassword = (): void =>\r\n setDefaultPasswordVisible((current: boolean) => current !== true)\r\n const passwordToggle = (visible: boolean, onToggle: () => void): unknown =>\r\n h(\r\n 'button',\r\n {\r\n className: styles.passwordToggle,\r\n style: S.passwordToggle,\r\n type: 'button',\r\n 'aria-label': visible ? t.hidePassword : t.showPassword,\r\n 'aria-pressed': visible,\r\n title: visible ? t.hidePassword : t.showPassword,\r\n onClick: onToggle,\r\n },\r\n h(\r\n 'svg',\r\n {\r\n width: 16,\r\n height: 16,\r\n viewBox: '0 0 24 24',\r\n fill: 'none',\r\n stroke: 'currentColor',\r\n strokeWidth: 2,\r\n strokeLinecap: 'round',\r\n strokeLinejoin: 'round',\r\n 'aria-hidden': 'true',\r\n focusable: 'false',\r\n },\r\n h('path', {\r\n key: 'eye',\r\n d: 'M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12Z',\r\n }),\r\n h('circle', { key: 'pupil', cx: 12, cy: 12, r: 3 }),\r\n visible ? h('path', { key: 'slash', d: 'm3 3 18 18' }) : null,\r\n ),\r\n )\r\n\r\n /**\r\n * The advanced global fields live outside `draft` on purpose: `draft` is keyed\r\n * by provider id, and a sentinel would surface as a phantom provider row.\r\n */\r\n const [globalDraft, setGlobalDraft] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n const editGlobal = (field: string, value: unknown) =>\r\n setGlobalDraft((current: any) => ({ ...current, [field]: value }))\r\n\r\n /** The latest refused write, shown above the cards instead of in the fold. */\r\n const [saveError, setSaveError] = (React.useState ?? ((v: any) => [v, () => {}]))(undefined)\r\n /** The latest accepted write, rendered in the diagnostics on the next pass. */\r\n const [savedNote, setSavedNote] = (React.useState ?? ((v: any) => [v, () => {}]))(undefined)\r\n\r\n // Self-check outcomes keyed by provider id: `{ pending: true }` while the Host\r\n // is testing, then the normalized result the card renders.\r\n const [tests, setTests] = (React.useState ?? ((v: any) => [v, () => {}]))({})\r\n\r\n /** Drop results for these providers and invalidate any response in flight. */\r\n const invalidateTests = (ids: readonly string[]): void => {\r\n if (ids.length === 0) return\r\n for (const id of ids) {\r\n testGeneration.set(id, (testGeneration.get(id) ?? 0) + 1)\r\n }\r\n setTests((current: any) => {\r\n let changed = false\r\n const next = { ...current }\r\n for (const id of ids) {\r\n if (next[id] === undefined) continue\r\n delete next[id]\r\n changed = true\r\n }\r\n return changed ? next : current\r\n })\r\n }\r\n\r\n /**\r\n * The list filter. Purely a view concern: it hides cards, it never touches a\r\n * saved setting, so a page with no filter one day still shows every route.\r\n */\r\n const [filter, setFilter] = (React.useState ?? ((v: any) => [v, () => {}]))('')\r\n /**\r\n * View preferences are seeded from storage, so a remount restores the view the\r\n * user left behind instead of snapping back to the card layout.\r\n *\r\n * The initializer is LAZY for the same reason the catalogue fetch is: reading\r\n * storage during render would be a side effect. `useState(fn)` runs it once\r\n * per mount, which is exactly the \"remember across visits\" semantic wanted.\r\n */\r\n const [statusFilter, setStatusFilter] = (React.useState ?? ((v: any) => [v, () => {}]))(\r\n () => readViewPrefs().statusFilter ?? 'all',\r\n ) as [\r\n 'all' | 'proxied' | 'direct' | 'rejected',\r\n (v: any) => void,\r\n ]\r\n const [viewMode, setViewMode] = (React.useState ?? ((v: any) => [v, () => {}]))(\r\n () => readViewPrefs().viewMode ?? 'card',\r\n ) as ['card' | 'compact', (v: any) => void]\r\n const [expandedCards, setExpandedCards] = (React.useState ?? ((v: any) => [v, () => {}]))({}) as [\r\n Record<string, boolean>,\r\n (v: any) => void,\r\n ]\r\n const [batchProgress, setBatchProgress] = (React.useState ?? ((v: any) => [v, () => {}]))(null) as [\r\n { done: number; total: number } | null,\r\n (v: any) => void,\r\n ]\r\n const [copiedKey, setCopiedKey] = (React.useState ?? ((v: any) => [v, () => {}]))(undefined) as [\r\n string | undefined,\r\n (v: any) => void,\r\n ]\r\n\r\n const copyToClipboard = (key: string, text: string): void => {\r\n try {\r\n if (typeof globalThis.navigator?.clipboard?.writeText === 'function') {\r\n void globalThis.navigator.clipboard.writeText(text).then(() => {\r\n setCopiedKey(key)\r\n setTimeout(() => setCopiedKey((prev: any) => (prev === key ? undefined : prev)), 1500)\r\n }).catch(() => undefined)\r\n }\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n\r\n const copyButton = (key: string, text: string, ariaLabel: string): unknown =>\r\n h(\r\n 'button',\r\n {\r\n className: styles.copyButton,\r\n style: S.copyButton,\r\n type: 'button',\r\n 'aria-label': ariaLabel,\r\n title: copiedKey === key ? t.copied : ariaLabel,\r\n onClick: (e: any) => {\r\n e.stopPropagation?.()\r\n copyToClipboard(key, text)\r\n },\r\n },\r\n copiedKey === key\r\n ? h(\r\n 'svg',\r\n {\r\n width: 12,\r\n height: 12,\r\n viewBox: '0 0 24 24',\r\n fill: 'none',\r\n stroke: 'var(--dsw-alias-state-success-primary, #2ea043)',\r\n strokeWidth: 2,\r\n strokeLinecap: 'round',\r\n strokeLinejoin: 'round',\r\n 'aria-hidden': 'true',\r\n },\r\n h('path', { d: 'M20 6 9 17l-5-5' }),\r\n )\r\n : h(\r\n 'svg',\r\n {\r\n width: 12,\r\n height: 12,\r\n viewBox: '0 0 24 24',\r\n fill: 'none',\r\n stroke: 'currentColor',\r\n strokeWidth: 2,\r\n strokeLinecap: 'round',\r\n strokeLinejoin: 'round',\r\n 'aria-hidden': 'true',\r\n },\r\n h('rect', { width: 14, height: 14, x: 8, y: 8, rx: 2, ry: 2 }),\r\n h('path', { d: 'M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2' }),\r\n ),\r\n copiedKey === key\r\n ? h('span', { style: { marginLeft: '3px', fontSize: '10px', color: 'var(--dsw-alias-state-success-primary, #2ea043)' } }, t.copied)\r\n : null,\r\n )\r\n\r\n /**\r\n * Run the Host's self-check for one provider.\r\n *\r\n * The check is not routed traffic, so it never changes the hit count; the count\r\n * on the card is read at mount and stays put until the page reloads.\r\n *\r\n * Pending writes for this provider (and the shared default it may inherit) are\r\n * flushed before the request: the Host reads the saved settings, not the draft,\r\n * so testing inside the 300 ms debounce would otherwise test the old endpoint.\r\n */\r\n const runTest = (id: string): Promise<void> => {\r\n const generation = (testGeneration.get(id) ?? 0) + 1\r\n testGeneration.set(id, generation)\r\n setTests((current: any) => ({ ...current, [id]: { pending: true } }))\r\n return (async () => {\r\n try {\r\n for (const [key, entry] of [...pendingWrites]) {\r\n if (\r\n key.startsWith(`${id}\\u0000`) ||\r\n key.startsWith('\\u0000default\\u0000') ||\r\n key.startsWith('\\u0000global\\u0000')\r\n ) {\r\n void entry.flush()\r\n }\r\n }\r\n await writeQueue\r\n if (testGeneration.get(id) !== generation) return\r\n const response = await globalThis.fetch(TEST_PATH, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json', accept: 'application/json' },\r\n body: JSON.stringify({ provider: id }),\r\n })\r\n const body = await response.json()\r\n if (testGeneration.get(id) !== generation) return\r\n setTests((current: any) => ({ ...current, [id]: testResultFrom(body, t) }))\r\n } catch (error: any) {\r\n if (testGeneration.get(id) !== generation) return\r\n setTests((current: any) => ({\r\n ...current,\r\n [id]: { pending: false, ok: false, error: String(error?.message ?? error) },\r\n }))\r\n }\r\n })()\r\n }\r\n\r\n const runBatchTest = (): void => {\r\n const activeIds = rows\r\n .filter(row => view({ ...configured[row.id], ...draft[row.id] }).enabled)\r\n .map(row => row.id)\r\n if (activeIds.length === 0 || batchProgress !== null) return\r\n setBatchProgress({ done: 0, total: activeIds.length })\r\n\r\n void (async () => {\r\n let index = 0\r\n let completed = 0\r\n const concurrency = Math.min(3, activeIds.length)\r\n const worker = async (): Promise<void> => {\r\n while (index < activeIds.length) {\r\n const id = activeIds[index++]\r\n await runTest(id)\r\n completed++\r\n setBatchProgress({ done: completed, total: activeIds.length })\r\n }\r\n }\r\n await Promise.all(Array.from({ length: concurrency }, () => worker()))\r\n setTimeout(() => {\r\n setBatchProgress(null)\r\n }, 2000)\r\n })()\r\n }\r\n\r\n const rows = knownProviders({ ...configured, ...draft }, published)\r\n\r\n /** Cards whose effective endpoint comes from the shared default. */\r\n const inheritingIds = (): string[] =>\r\n rows\r\n .filter(row => view({ ...configured[row.id], ...draft[row.id] }).useDefault === true)\r\n .map(row => row.id)\r\n\r\n /**\r\n * Persist one field, debounced per `key`: a burst of edits to the same control\r\n * collapses into ONE write carrying the last value. The control already shows\r\n * the new value via the draft, so this only has to succeed quietly; a refusal\r\n * is reported in the diagnostics and undone by `onRefused`.\r\n */\r\n const save = (\r\n key: string,\r\n path: unknown[],\r\n label: string,\r\n value: unknown,\r\n onRefused: () => void,\r\n ) => {\r\n const field = path[path.length - 1]\r\n const secret = field === 'password' && typeof value === 'string' ? value : undefined\r\n const safeLabel = secret === undefined ? label : `${label}\uFF08\u503C\u5DF2\u9690\u85CF\uFF09`\r\n scheduleWrite(key, () =>\r\n writeConfig(ctx, [{ op: 'set', path, value }])\r\n .then(() => {\r\n setSaveError(undefined)\r\n setSavedNote(secret === undefined ? `\u5DF2\u4FDD\u5B58 ${label}` : `\u5DF2\u4FDD\u5B58 ${safeLabel}`)\r\n })\r\n .catch((error: any) => {\r\n const message = redactSensitiveText(String(error?.message ?? error), [\r\n ...(secret === undefined ? [] : [secret]),\r\n ])\r\n setSavedNote(undefined)\r\n setSaveError({ label: safeLabel, message })\r\n onRefused()\r\n }),\r\n )\r\n }\r\n\r\n /**\r\n * Undo ONE refused field in a card's draft.\r\n *\r\n * Only that field is dropped. Other fields of the same provider may hold edits\r\n * that are still pending or already accepted \u2014 dropping the whole draft entry\r\n * would throw away values the Host never objected to. An entry left empty by\r\n * the removal is dropped entirely, so it cannot keep a phantom row alive.\r\n */\r\n const rollbackRouteField = (id: string, field: string): void => {\r\n setDraft((current: any) => {\r\n const entry = current[id]\r\n if (entry === undefined || entry[field] === undefined) return current\r\n const nextEntry = { ...entry }\r\n delete nextEntry[field]\r\n const next = { ...current }\r\n if (Object.keys(nextEntry).length === 0) delete next[id]\r\n else next[id] = nextEntry\r\n return next\r\n })\r\n }\r\n\r\n /** One card control: update the draft instantly, persist in the background. */\r\n const bind = (id: string, field: string) => (value: unknown) => {\r\n edit(id, field, value)\r\n if (TEST_RELEVANT_FIELDS.has(field)) invalidateTests([id])\r\n save(`${id}\\u0000${field}`, ['providers', id, field], `${id}.${field}`, value, () =>\r\n rollbackRouteField(id, field),\r\n )\r\n }\r\n\r\n /** One default-block control: same contract, addressed at `defaultProxy`. */\r\n const bindDefault = (field: string) => (value: unknown) => {\r\n editDefault(field, value)\r\n invalidateTests(inheritingIds())\r\n save(`\\u0000default\\u0000${field}`, ['defaultProxy', field], `defaultProxy.${field}`, value, () => {\r\n // Same rule as a card field: drop only this field, and only if the draft\r\n // still holds it, so an already-accepted sibling edit is never discarded.\r\n setDefaultDraft((current: any) => {\r\n if (current[field] === undefined) return current\r\n const next = { ...current }\r\n delete next[field]\r\n return next\r\n })\r\n })\r\n }\r\n\r\n /** One advanced global control: draft, invalidate every check, persist. */\r\n const bindGlobal = (field: 'testUrl' | 'localDirect') => (value: unknown) => {\r\n editGlobal(field, value)\r\n invalidateTests(rows.map(row => row.id))\r\n save(`\\u0000global\\u0000${field}`, [field], field, value, () => {\r\n setGlobalDraft((current: any) => {\r\n if (current[field] === undefined) return current\r\n const next = { ...current }\r\n delete next[field]\r\n return next\r\n })\r\n })\r\n }\r\n\r\n /**\r\n * One debounced write carrying SEVERAL edits at once.\r\n *\r\n * Used for a pasted proxy URL: five separate writes would each rebuild the\r\n * Host's whole proxy table, and a half-applied paste (credentials without the\r\n * host, say) would hit the credential guards mid-burst \u2014 the same trap the\r\n * per-field debounce exists to avoid.\r\n */\r\n const saveMany = (key: string, ops: unknown[], label: string, onRefused: () => void) => {\r\n const secrets = secretsFromOps(ops as any[])\r\n const hidesValues = (ops as any[]).some(op => op?.path?.[op.path.length - 1] === 'password')\r\n const safeLabel = hidesValues ? `${label}\uFF08\u503C\u5DF2\u9690\u85CF\uFF09` : label\r\n scheduleWrite(key, () =>\r\n writeConfig(ctx, ops)\r\n .then(() => {\r\n setSaveError(undefined)\r\n setSavedNote(`\u5DF2\u4FDD\u5B58 ${safeLabel}`)\r\n })\r\n .catch((error: any) => {\r\n const message = redactSensitiveText(String(error?.message ?? error), secrets)\r\n setSavedNote(undefined)\r\n setSaveError({ label: safeLabel, message })\r\n onRefused()\r\n }),\r\n )\r\n }\r\n\r\n /** Undo one set of pasted fields in a card's draft. */\r\n const rollbackRouteFields = (id: string, fields: readonly string[]): void => {\r\n setDraft((current: any) => {\r\n const entry = current[id]\r\n if (entry === undefined) return current\r\n const nextEntry = { ...entry }\r\n for (const field of fields) delete nextEntry[field]\r\n const next = { ...current }\r\n if (Object.keys(nextEntry).length === 0) delete next[id]\r\n else next[id] = nextEntry\r\n return next\r\n })\r\n }\r\n\r\n /** Apply a parsed proxy URL to one card: one draft update, one write. */\r\n const applyCardUrl = (id: string, parts: Record<string, unknown>): void => {\r\n setDraft((current: any) => ({ ...current, [id]: { ...current[id], ...parts } }))\r\n invalidateTests([id])\r\n const fields = Object.keys(parts)\r\n saveMany(\r\n `${id}\\u0000*paste`,\r\n fields.map(field => ({ op: 'set', path: ['providers', id, field], value: parts[field] })),\r\n `${id}.*\uFF08\u7C98\u8D34\u4EE3\u7406 URL\uFF09`,\r\n () => rollbackRouteFields(id, fields),\r\n )\r\n }\r\n\r\n /** Apply a parsed proxy URL to the shared default endpoint. */\r\n const applyDefaultUrl = (parts: Record<string, unknown>): void => {\r\n setDefaultDraft((current: any) => ({ ...current, ...parts }))\r\n invalidateTests(inheritingIds())\r\n const fields = Object.keys(parts)\r\n saveMany(\r\n '\\u0000default\\u0000*paste',\r\n fields.map(field => ({ op: 'set', path: ['defaultProxy', field], value: parts[field] })),\r\n '\u9ED8\u8BA4\u4EE3\u7406\uFF08\u7C98\u8D34\u4EE3\u7406 URL\uFF09',\r\n () => {\r\n setDefaultDraft((current: any) => {\r\n const next = { ...current }\r\n for (const field of fields) delete next[field]\r\n return next\r\n })\r\n },\r\n )\r\n }\r\n\r\n /**\r\n * Promote a card's own endpoint to the shared default.\r\n *\r\n * The reduced form of \"copy this card to another\": once the endpoint lives in\r\n * the default block, every other card opts in with one switch, so a\r\n * multi-select picker would be a second way to do the same thing.\r\n */\r\n const promoteToDefault = (id: string): void => {\r\n if (\r\n defaultComplete &&\r\n inheritingIds().length > 0 &&\r\n globalThis.window?.confirm?.(t.confirmPromoteToDefault) !== true\r\n ) {\r\n return\r\n }\r\n const route = view({ ...configured[id], ...draft[id] })\r\n applyDefaultUrl({\r\n protocol: route.protocol,\r\n host: route.host.trim(),\r\n port: route.port,\r\n username: route.username,\r\n password: route.password,\r\n })\r\n }\r\n\r\n /** Point every card at the default endpoint, in one write. */\r\n const applyDefaultToAll = (): void => {\r\n const ids = rows.map(row => row.id)\r\n if (ids.length === 0) return\r\n setDraft((current: any) => {\r\n const next = { ...current }\r\n for (const id of ids) next[id] = { ...next[id], useDefault: true }\r\n return next\r\n })\r\n invalidateTests(ids)\r\n saveMany(\r\n '\\u0000default\\u0000applyAll',\r\n ids.map(id => ({ op: 'set', path: ['providers', id, 'useDefault'], value: true })),\r\n `\u6240\u6709 provider \u7684 useDefault\uFF08${ids.length} \u4E2A\uFF09`,\r\n () =>\r\n setDraft((current: any) => {\r\n const next = { ...current }\r\n for (const id of ids) {\r\n const entry = next[id]\r\n if (entry === undefined || entry.useDefault === undefined) continue\r\n const nextEntry = { ...entry }\r\n delete nextEntry.useDefault\r\n if (Object.keys(nextEntry).length === 0) delete next[id]\r\n else next[id] = nextEntry\r\n }\r\n return next\r\n }),\r\n )\r\n }\r\n\r\n /**\r\n * A paste handler for any proxy-address field.\r\n *\r\n * Only a RECOGNISED proxy URL is intercepted; anything else falls through to\r\n * the browser so a pasted bare host still lands in the field normally.\r\n */\r\n const onProxyUrlPaste =\r\n (apply: (parts: Record<string, unknown>) => void) =>\r\n (event: any): void => {\r\n const text = event?.clipboardData?.getData?.('text')\r\n if (typeof text !== 'string') return\r\n const parts = splitProxyUrl(text)\r\n if (parts === undefined) return\r\n event.preventDefault?.()\r\n apply(parts)\r\n }\r\n\r\n /**\r\n * The common-client picker, as an \"apply on choose\" `<select>`.\r\n *\r\n * A `<select>` rather than four buttons: the panel already has a lot of\r\n * buttons, and this control has exactly the shape of a picker \u2014 choose one of\r\n * a fixed list, fill the fields, then edit them. The option carrying the\r\n * environment value appears only when the Host found one, so a composition\r\n * without it shows four plain presets instead of a dead entry.\r\n */\r\n const quickImportSelect = (\r\n key: string,\r\n apply: (parts: Record<string, unknown>) => void,\r\n ): unknown => {\r\n const detected = state.environmentProxy ?? null\r\n const select = h(\r\n 'select',\r\n {\r\n className: styles.input,\r\n style: { ...S.input, flex: 'none', width: 'auto' },\r\n key: `${key}:select`,\r\n value: '',\r\n 'aria-label': t.quickImport,\r\n onChange: (event: any) => {\r\n const value = String(event.target.value ?? '')\r\n if (value.length === 0) return\r\n if (value === 'environment') {\r\n if (detected === null) return\r\n apply({\r\n protocol: detected.protocol,\r\n host: detected.host,\r\n port: detected.port,\r\n })\r\n return\r\n }\r\n const preset = proxyClientPreset(value)\r\n if (preset === undefined) return\r\n apply({ protocol: preset.protocol, host: preset.host, port: preset.port })\r\n },\r\n },\r\n h('option', { key: 'none', value: '' }, t.quickImport),\r\n ...PROXY_CLIENT_PRESETS.map(preset =>\r\n h('option', { key: preset.id, value: preset.id }, preset.label),\r\n ),\r\n h(\r\n 'option',\r\n { key: 'environment', value: 'environment', disabled: detected === null },\r\n detected === null ? t.quickImportEnvNone : `${t.quickImportEnv}${detected.source}`,\r\n ),\r\n )\r\n return h(\r\n 'div',\r\n { key, style: { display: 'flex', flexDirection: 'column', gap: '2px', minWidth: '0' } },\r\n select,\r\n detected !== null && detected.hadCredentials\r\n ? h('span', { style: { ...S.hint, gridColumn: 'auto' } }, t.quickImportEnvCredentials)\r\n : null,\r\n )\r\n }\r\n\r\n const field = (\r\n label: string,\r\n control: unknown,\r\n hint?: string,\r\n hintError?: boolean,\r\n fullWidth?: boolean,\r\n ): unknown =>\r\n h(\r\n 'label',\r\n {\r\n className: `${styles.field}${fullWidth ? ` ${styles.formGridFull}` : ''}`,\r\n style: {\r\n ...S.field,\r\n ...(fullWidth ? S.formGridFull : {}),\r\n },\r\n key: label,\r\n },\r\n h('span', { className: styles.label, style: S.label }, label),\r\n control,\r\n hint === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n {\r\n className: styles.hint,\r\n style: {\r\n ...S.hint,\r\n marginTop: '2px',\r\n // A warning that a value can never work is an answer, not\r\n // decoration \u2014 same rule as the failed self-check text.\r\n ...(hintError === true\r\n ? { color: 'var(--dsw-alias-state-error-primary, #f85149)' }\r\n : {}),\r\n },\r\n },\r\n hint,\r\n ),\r\n )\r\n\r\n /**\r\n * A collapsible panel: summary line, optional lead, then the content.\r\n *\r\n * Four panels used to be spelled out separately, which is how they drifted\r\n * into three different paddings and two different corner radii. One\r\n * constructor keeps them identical, and `open` is controlled so a panel can\r\n * open itself (adding a preset must reveal the new row).\r\n */\r\n const panel = (options: {\r\n key: string\r\n summary: string\r\n lead?: string\r\n open?: boolean\r\n onToggle?: (open: boolean) => void\r\n children: unknown[]\r\n }): unknown =>\r\n h(\r\n 'details',\r\n {\r\n className: `${styles.diag} ${styles.panel}`,\r\n style: S.diag,\r\n key: options.key,\r\n ...(options.open === undefined ? {} : { open: options.open }),\r\n ...(options.onToggle === undefined\r\n ? {}\r\n : {\r\n onToggle: (event: any) => {\r\n const open = event?.currentTarget?.open\r\n if (typeof open === 'boolean') options.onToggle?.(open)\r\n },\r\n }),\r\n },\r\n h('summary', { className: styles.diagSummary }, options.summary),\r\n h(\r\n 'div',\r\n { style: S.panelBody },\r\n options.lead === undefined\r\n ? null\r\n : h('p', { className: styles.defaultLead, style: S.defaultLead }, options.lead),\r\n ...options.children,\r\n ),\r\n )\r\n\r\n /**\r\n * The shared endpoint block, always rendered.\r\n *\r\n * It is the only place the address can be entered, so hiding it until some\r\n * card opts in would leave no way to configure it in the first place.\r\n */\r\n const storedDefault = (snapshot.value?.defaultProxy ?? {}) as Partial<RouteValue>\r\n const defaultView = view({ ...storedDefault, ...defaultDraft })\r\n // The SAME predicate the Host applies, imported rather than re-written: a\r\n // browser copy that only checked \"host non-empty and port in range\" called\r\n // `https://1.2.3.4` complete and enabled the bulk button, while the Host refused\r\n // every route pointed at it.\r\n //\r\n // The REASON is kept as well as the verdict: the block refuses for several\r\n // reasons (no host, a scheme-carrying host, a bad port, a half-filled\r\n // credential), and a card that said \"missing host or port\" for all of them sent\r\n // the user to the one field that was already correct.\r\n const defaultWhy = defaultProxyProblem(defaultView)\r\n // An empty optional block is \"not configured\", not a typed mistake. Only an\r\n // invalid NON-empty host gets the error colour under the input.\r\n const defaultHostWhy = defaultView.host.trim().length === 0\r\n ? undefined\r\n : proxyHostProblem(defaultView.host)\r\n const defaultComplete = defaultWhy === undefined\r\n const defaultOrigin = `${defaultView.protocol}://${defaultView.host}:${defaultView.port}`\r\n\r\n /**\r\n * What one card will actually use, and whether that is usable.\r\n *\r\n * One function for every card, because the question \"which endpoint does this\r\n * card take\" is asked in five places (state pill, test gate, refusal text,\r\n * compact row, promote button). Answers that disagreed produced the classic\r\n * bug: a green pill on a card the Host refused.\r\n */\r\n const cardEndpoint = (\r\n route: RouteValue,\r\n ): {\r\n binding: ReturnType<typeof routeBindingOf>\r\n endpoint?: ProfileValue\r\n /** Set when the bound preset no longer exists. */\r\n missingProfile?: string\r\n /** Why the resolved endpoint cannot carry a request. */\r\n why?: string\r\n /** Whether this card has an endpoint worth testing. */\r\n complete: boolean\r\n } => {\r\n const binding = routeBindingOf(route)\r\n if (binding.kind === 'profile') {\r\n const endpoint = profileValueOf(binding.profileId)\r\n if (endpoint === undefined) return { binding, missingProfile: binding.profileId, complete: false }\r\n const why = defaultProxyProblem(endpoint)\r\n return { binding, endpoint, why, complete: why === undefined }\r\n }\r\n if (binding.kind === 'default') {\r\n return { binding, endpoint: defaultView, why: defaultWhy, complete: defaultComplete }\r\n }\r\n const complete =\r\n route.host.trim().length > 0 &&\r\n Number.isInteger(route.port) &&\r\n route.port >= 1 &&\r\n route.port <= 65535\r\n return { binding, why: defaultProxyProblem(route), complete }\r\n }\r\n\r\n /**\r\n * The refusal text for one card, or `undefined` when it will be built.\r\n *\r\n * The wording distinguishes the three ways an endpoint can be unusable \u2014 a\r\n * missing preset, a preset/default that is itself incomplete, and the card's\r\n * own half-typed fields \u2014 because each one sends the user to a different\r\n * place to fix it.\r\n */\r\n const cardProblemText = (state: ReturnType<typeof cardEndpoint>): string | undefined => {\r\n if (state.missingProfile !== undefined) {\r\n return `${t.profileMissing}${state.missingProfile}${t.profileMissingSuffix}`\r\n }\r\n if (state.why === undefined) return undefined\r\n if (state.binding.kind === 'profile') {\r\n return `${t.profileUnusable}${state.binding.profileId}${t.profileUnusableSuffix}${state.why}`\r\n }\r\n if (state.binding.kind === 'default') return `${t.defaultMissing}${state.why}`\r\n return state.why\r\n }\r\n\r\n /**\r\n * The named presets, stored and drafted.\r\n *\r\n * `stored` is what the Host has; `profileDraft` overlays edits that have not\r\n * been written yet, exactly like a card's draft. The union of both is what the\r\n * page renders, so a just-added preset appears before its write lands.\r\n */\r\n const storedProfiles = (snapshot.value?.proxyProfiles ?? {}) as Record<string, Partial<ProfileValue>>\r\n const profileEntries = profileNames({ ...storedProfiles, ...profileDraft }).map(name => ({\r\n name,\r\n value: profileView({ ...storedProfiles[name], ...profileDraft[name] }),\r\n }))\r\n const profileValueOf = (name: string): ProfileValue | undefined => {\r\n if (storedProfiles[name] === undefined && profileDraft[name] === undefined) return undefined\r\n return profileView({ ...storedProfiles[name], ...profileDraft[name] })\r\n }\r\n\r\n /**\r\n * Persist the WHOLE preset dictionary in one write.\r\n *\r\n * Add, rename and delete all use this: a dictionary-level `set` can express a\r\n * rename (which a per-field write cannot, because the key itself changes) and\r\n * guarantees the Host sees one consistent dictionary rather than a moment\r\n * where both the old and the new name exist.\r\n */\r\n const writeProfiles = (\r\n key: string,\r\n next: Record<string, Partial<ProfileValue>>,\r\n label: string,\r\n onRefused: () => void,\r\n ): void => {\r\n // Every entry is normalized before it is written: the draft may hold a\r\n // single field of a preset, and a half object would make the file depend on\r\n // schema defaults the user never sees.\r\n const full: Record<string, ProfileValue> = {}\r\n for (const [name, value] of Object.entries(next)) full[name] = profileView(value)\r\n saveMany(key, [{ op: 'set', path: ['proxyProfiles'], value: full }], label, onRefused)\r\n }\r\n\r\n /** Add a preset from the inline name field. */\r\n const addProfile = (): void => {\r\n const name = String(newProfileName ?? '').trim()\r\n const problem = profileNameProblem(name)\r\n if (problem !== undefined) {\r\n setSavedNote(undefined)\r\n setSaveError({ label: t.profileNameLabel, message: problem })\r\n return\r\n }\r\n if (storedProfiles[name] !== undefined || profileDraft[name] !== undefined) {\r\n setSavedNote(undefined)\r\n setSaveError({ label: t.profileNameLabel, message: t.profileNameTaken })\r\n return\r\n }\r\n const next: Record<string, ProfileValue> = { ...storedProfiles, ...profileDraft } as Record<\r\n string,\r\n ProfileValue\r\n >\r\n next[name] = profileView({})\r\n setNewProfileName('')\r\n setProfileDraft((current: any) => ({ ...current, [name]: profileView({}) }))\r\n // A new row is worthless if it is still collapsed under the manager or\r\n // scrolled out of view, so the manager is opened with the new row.\r\n setProfileManagerOpen(true)\r\n writeProfiles(`\\u0000profile\\u0000add`, next, `${t.profileNameLabel} ${name}`, () => {\r\n setProfileDraft((current: any) => {\r\n if (current[name] === undefined) return current\r\n const nextDraft = { ...current }\r\n delete nextDraft[name]\r\n return nextDraft\r\n })\r\n })\r\n }\r\n\r\n /** Rename one preset, carrying its fields and every binding with it. */\r\n const renameProfile = (from: string): void => {\r\n const to = String(renameDraft ?? '').trim()\r\n setRenamingProfile(undefined)\r\n setRenameDraft('')\r\n if (to === from) return\r\n const problem = profileNameProblem(to)\r\n if (problem !== undefined) {\r\n setSavedNote(undefined)\r\n setSaveError({ label: t.profileNameLabel, message: problem })\r\n return\r\n }\r\n if (storedProfiles[to] !== undefined || profileDraft[to] !== undefined) {\r\n setSavedNote(undefined)\r\n setSaveError({ label: t.profileNameLabel, message: t.profileNameTaken })\r\n return\r\n }\r\n const source = profileValueOf(from) ?? profileView({})\r\n const next: Record<string, ProfileValue> = { ...storedProfiles, ...profileDraft } as Record<\r\n string,\r\n ProfileValue\r\n >\r\n delete next[from]\r\n next[to] = source\r\n const bound = routesBoundTo({ ...configured, ...draft }, from)\r\n setProfileDraft((current: any) => {\r\n const nextDraft = { ...current }\r\n delete nextDraft[from]\r\n nextDraft[to] = source\r\n return nextDraft\r\n })\r\n if (bound.length > 0) {\r\n setDraft((current: any) => {\r\n const nextDraft = { ...current }\r\n for (const id of bound) nextDraft[id] = { ...nextDraft[id], profileId: to }\r\n return nextDraft\r\n })\r\n }\r\n invalidateTests(bound)\r\n saveMany(\r\n '\\u0000profile\\u0000rename',\r\n [\r\n { op: 'set', path: ['proxyProfiles'], value: next },\r\n ...bound.map(id => ({ op: 'set', path: ['providers', id, 'profileId'], value: to })),\r\n ],\r\n `${t.profileNameLabel} ${from} \u2192 ${to}`,\r\n () => undefined,\r\n )\r\n }\r\n\r\n /** Delete one preset. Routes bound to it keep their id, and say it is gone. */\r\n const deleteProfile = (name: string): void => {\r\n const bound = routesBoundTo({ ...configured, ...draft }, name)\r\n if (\r\n globalThis.window?.confirm?.(\r\n bound.length === 0 ? t.profileDeleteConfirm : `${t.profileDeleteInUse}${bound.join('\u3001')}\\n\\n${t.profileDeleteConfirm}`,\r\n ) !== true\r\n ) {\r\n return\r\n }\r\n const next: Record<string, ProfileValue> = { ...storedProfiles, ...profileDraft } as Record<\r\n string,\r\n ProfileValue\r\n >\r\n delete next[name]\r\n setProfileDraft((current: any) => {\r\n const nextDraft = { ...current }\r\n delete nextDraft[name]\r\n return nextDraft\r\n })\r\n invalidateTests(bound)\r\n writeProfiles(`\\u0000profile\\u0000delete`, next, `${t.profileNameLabel} ${name}`, () => undefined)\r\n }\r\n\r\n /** One preset control: draft first, then a debounced write to its own key. */\r\n const bindProfile = (name: string, field: string) => (value: unknown) => {\r\n editProfile(name, field, value)\r\n invalidateTests(routesBoundTo({ ...configured, ...draft }, name))\r\n save(\r\n `\\u0000profile\\u0000${name}\\u0000${field}`,\r\n ['proxyProfiles', name, field],\r\n `${name}.${field}`,\r\n value,\r\n () => {\r\n setProfileDraft((current: any) => {\r\n const entry = current[name]\r\n if (entry === undefined || entry[field] === undefined) return current\r\n const nextEntry = { ...entry }\r\n delete nextEntry[field]\r\n const nextDraft = { ...current }\r\n if (Object.keys(nextEntry).length === 0) delete nextDraft[name]\r\n else nextDraft[name] = nextEntry\r\n return nextDraft\r\n })\r\n },\r\n )\r\n }\r\n\r\n /**\r\n * Point one card at a preset, at the built-in default, or back at its own\r\n * fields.\r\n *\r\n * BOTH binding fields are always written, in ONE write.\r\n *\r\n * This is not tidiness: `profileId` wins over `useDefault`, so writing only\r\n * one of them leaves the file describing a binding the user did not pick.\r\n * Clearing `profileId` in the draft while persisting `useDefault: true` left\r\n * the saved file still naming the OLD preset, and the next check kept routing\r\n * through it \u2014 the reported \"switch back to the working proxy, still\r\n * unreachable\". `bindingFields` expresses the three states in one place.\r\n */\r\n const bindRouteProfile = (id: string) => (value: string) => {\r\n // `bindingFields` is the SHARED mapping the Host reasons with, imported\r\n // rather than re-spelled: a second copy is how the two halves drift into\r\n // writing a binding the other one does not read the same way.\r\n const fields = bindingFields(\r\n value === DEFAULT_PROFILE_BINDING\r\n ? { kind: 'default' }\r\n : value.length === 0\r\n ? { kind: 'own' }\r\n : { kind: 'profile', profileId: value },\r\n )\r\n edit(id, 'profileId', fields.profileId)\r\n edit(id, 'useDefault', fields.useDefault)\r\n invalidateTests([id])\r\n saveMany(\r\n `${id}\\u0000*profile`,\r\n [\r\n { op: 'set', path: ['providers', id, 'profileId'], value: fields.profileId },\r\n { op: 'set', path: ['providers', id, 'useDefault'], value: fields.useDefault },\r\n ],\r\n `${id}.profileId`,\r\n () => {\r\n rollbackRouteField(id, 'profileId')\r\n rollbackRouteField(id, 'useDefault')\r\n },\r\n )\r\n }\r\n const defaultBlock = h(\r\n 'div',\r\n { className: styles.defaultCard, style: S.defaultCard, key: 'default-proxy' },\r\n h(\r\n 'header',\r\n { className: styles.cardHead, style: S.head },\r\n h(\r\n 'div',\r\n { className: styles.cardTitles, style: S.titles },\r\n h('span', { className: styles.name, style: S.name }, t.defaultTitle),\r\n ),\r\n h(\r\n 'span',\r\n {\r\n className: defaultComplete ? styles.pillOn : styles.pillOff,\r\n style: { ...S.pill, ...(defaultComplete ? S.pillOn : S.pillOff) },\r\n },\r\n defaultComplete ? t.complete : t.notConfigured,\r\n ),\r\n ),\r\n h('p', { className: styles.defaultLead, style: S.defaultLead }, t.defaultLead),\r\n h(\r\n 'div',\r\n { style: S.testRow, key: 'default:quick-import' },\r\n quickImportSelect('default:quick-import', applyDefaultUrl),\r\n ),\r\n h(\r\n 'div',\r\n { className: styles.formGrid, style: S.formGrid, key: 'default:form-grid' },\r\n field(\r\n t.protocol,\r\n h(\r\n 'select',\r\n {\r\n className: styles.input,\r\n style: S.input,\r\n value: defaultView.protocol,\r\n onChange: (event: any) => bindDefault('protocol')(event.target.value),\r\n },\r\n ...PROTOCOLS.map(protocol =>\r\n h('option', { key: protocol, value: protocol }, protocol.toUpperCase()),\r\n ),\r\n ),\r\n ),\r\n field(\r\n t.host,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: '127.0.0.1',\r\n value: defaultView.host,\r\n onChange: (event: any) => bindDefault('host')(event.target.value),\r\n // Same convenience as the cards: a full URL fills the whole block.\r\n onPaste: onProxyUrlPaste(applyDefaultUrl),\r\n }),\r\n defaultHostWhy ?? t.hostHint,\r\n defaultHostWhy !== undefined,\r\n ),\r\n field(\r\n t.port,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n type: 'number',\r\n min: 1,\r\n max: 65535,\r\n placeholder: '7890',\r\n value: defaultView.port === 0 ? '' : String(defaultView.port),\r\n onChange: (event: any) => {\r\n const parsed = Number.parseInt(event.target.value, 10)\r\n bindDefault('port')(Number.isNaN(parsed) ? 0 : parsed)\r\n },\r\n }),\r\n ),\r\n field(\r\n t.username,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n autoComplete: 'off',\r\n value: defaultView.username,\r\n onChange: (event: any) => bindDefault('username')(event.target.value),\r\n }),\r\n ),\r\n field(\r\n t.password,\r\n h(\r\n 'div',\r\n { style: S.passwordControl },\r\n h('input', {\r\n className: styles.input,\r\n style: { ...S.input, paddingRight: '36px' },\r\n type: defaultPasswordVisible === true ? 'text' : 'password',\r\n autoComplete: 'off',\r\n value: defaultView.password,\r\n onChange: (event: any) => bindDefault('password')(event.target.value),\r\n }),\r\n passwordToggle(defaultPasswordVisible === true, toggleDefaultPassword),\r\n ),\r\n t.passwordHintProxy,\r\n false,\r\n true,\r\n ),\r\n ),\r\n // Bulk opt-in, in ONE write: a per-card walk would rebuild the table N times.\r\n // Disabled while the default configuration is incomplete, because pointing every card at an\r\n // empty endpoint would just refuse them all.\r\n h(\r\n 'div',\r\n { style: S.testRow, key: 'default:apply' },\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n disabled: !defaultComplete || rows.length === 0,\r\n onClick: applyDefaultToAll,\r\n },\r\n `${t.applyDefaultAll}\uFF08${rows.length}\uFF09`,\r\n ),\r\n ),\r\n )\r\n\r\n const storedTestUrl =\r\n typeof snapshot.value?.testUrl === 'string' ? snapshot.value.testUrl : DEFAULT_TEST_URL\r\n\r\n /**\r\n * The preset manager.\r\n *\r\n * Collapsed by default: a user with one proxy never needs it, and the block\r\n * otherwise competes with the default endpoint for attention. It always\r\n * lists the built-in default preset \u2014 that is what makes the top-level\r\n * `defaultProxy` discoverable as \"just another preset\" instead of a second\r\n * concept.\r\n */\r\n const profileManager = panel({\r\n key: 'profile-manager',\r\n summary: `${t.profileManagerTitle} (${profileEntries.length})`,\r\n lead: t.profileManagerLead,\r\n open: profileManagerOpen === true,\r\n onToggle: open => setProfileManagerOpen(open),\r\n children: [\r\n h(\r\n 'div',\r\n { style: { ...S.testRow, alignItems: 'stretch' }, key: 'profile:add' },\r\n h('input', {\r\n className: styles.input,\r\n style: { ...S.input, flex: '1 1 160px', minWidth: '0' },\r\n placeholder: t.profileNamePlaceholder,\r\n value: newProfileName,\r\n 'aria-label': t.profileNameLabel,\r\n onChange: (event: any) => setNewProfileName(event.target.value),\r\n // Enter is the obvious gesture in a one-field form; without it the user\r\n // has to reach for the button after typing, which is the same dead end\r\n // the native prompt left them in.\r\n onKeyDown: (event: any) => {\r\n if (event?.key !== 'Enter') return\r\n event.preventDefault?.()\r\n addProfile()\r\n },\r\n }),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, flex: 'none' },\r\n type: 'button',\r\n onClick: addProfile,\r\n },\r\n t.profileAdd,\r\n ),\r\n ),\r\n // The built-in preset is EDITED in the default block above (one source of\r\n // truth); here it is only listed, so the picker's options and this list\r\n // agree.\r\n h(\r\n 'div',\r\n { key: 'profile:builtin', style: S.inheritNote },\r\n `${DEFAULT_PROFILE_LABEL} \u2014 ${endpointSummary(defaultView)}`,\r\n ),\r\n ...profileEntries.map(entry => {\r\n const bound = routesBoundTo({ ...configured, ...draft }, entry.name)\r\n const why = defaultProxyProblem(entry.value)\r\n return h(\r\n 'div',\r\n {\r\n key: `profile:${entry.name}`,\r\n className: styles.profileCard,\r\n style: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: '8px',\r\n padding: '12px 14px',\r\n border: '1px solid var(--dsw-alias-border-l1)',\r\n borderRadius: '10px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n },\r\n },\r\n h(\r\n 'div',\r\n { style: S.head },\r\n h(\r\n 'div',\r\n { style: S.titles },\r\n h('span', { style: S.name }, entry.name),\r\n h(\r\n 'span',\r\n {\r\n className: why === undefined ? styles.pillOn : styles.pillOff,\r\n style: { ...S.pill, ...(why === undefined ? S.pillOn : S.pillOff) },\r\n },\r\n why === undefined ? t.complete : t.notConfigured,\r\n ),\r\n ),\r\n h(\r\n 'div',\r\n { style: { display: 'flex', gap: '6px', flex: 'none' } },\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, padding: '3px 8px', fontSize: '11px' },\r\n type: 'button',\r\n onClick: () => {\r\n setRenamingProfile(entry.name)\r\n setRenameDraft(entry.name)\r\n },\r\n },\r\n t.profileRename,\r\n ),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, padding: '3px 8px', fontSize: '11px' },\r\n type: 'button',\r\n onClick: () => deleteProfile(entry.name),\r\n },\r\n t.profileDelete,\r\n ),\r\n ),\r\n ),\r\n // The rename field, shown in place of the row title's edit gesture.\r\n // Inline rather than a modal, for the same reason the add field is\r\n // inline: the Desktop build has no `window.prompt`.\r\n renamingProfile !== entry.name\r\n ? null\r\n : h(\r\n 'div',\r\n { style: { ...S.testRow, alignItems: 'stretch' }, key: `profile:${entry.name}:rename` },\r\n h('input', {\r\n className: styles.input,\r\n style: { ...S.input, flex: '1 1 160px', minWidth: '0' },\r\n value: renameDraft,\r\n placeholder: t.profileRenamePrompt,\r\n 'aria-label': t.profileRenamePrompt,\r\n autoFocus: true,\r\n onChange: (event: any) => setRenameDraft(event.target.value),\r\n onKeyDown: (event: any) => {\r\n if (event?.key === 'Escape') {\r\n setRenamingProfile(undefined)\r\n setRenameDraft('')\r\n return\r\n }\r\n if (event?.key !== 'Enter') return\r\n event.preventDefault?.()\r\n renameProfile(entry.name)\r\n },\r\n }),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, flex: 'none' },\r\n type: 'button',\r\n onClick: () => renameProfile(entry.name),\r\n },\r\n t.profileRenameConfirm,\r\n ),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, flex: 'none' },\r\n type: 'button',\r\n onClick: () => {\r\n setRenamingProfile(undefined)\r\n setRenameDraft('')\r\n },\r\n },\r\n t.cancel,\r\n ),\r\n ),\r\n bound.length === 0\r\n ? null\r\n : h('p', { style: S.inheritNote }, `${t.profileUsedBy}${bound.join('\u3001')}`),\r\n h(\r\n 'div',\r\n { style: S.testRow },\r\n quickImportSelect(`profile:${entry.name}:quick-import`, parts => {\r\n // One draft update and ONE write for the three transport fields, for\r\n // the same reason a pasted URL is applied in one go: a half-applied\r\n // fill can hit the credential guards between fields.\r\n setProfileDraft((current: any) => ({\r\n ...current,\r\n [entry.name]: { ...current[entry.name], ...parts },\r\n }))\r\n invalidateTests(bound)\r\n saveMany(\r\n `\\u0000profile\\u0000${entry.name}\\u0000*quick`,\r\n Object.keys(parts).map(field => ({\r\n op: 'set',\r\n path: ['proxyProfiles', entry.name, field],\r\n value: (parts as Record<string, unknown>)[field],\r\n })),\r\n `${entry.name}\uFF08\u5FEB\u6377\u5BFC\u5165\uFF09`,\r\n () => {\r\n setProfileDraft((current: any) => {\r\n const value = current[entry.name]\r\n if (value === undefined) return current\r\n const nextValue = { ...value }\r\n for (const field of Object.keys(parts)) delete nextValue[field]\r\n const next = { ...current }\r\n if (Object.keys(nextValue).length === 0) delete next[entry.name]\r\n else next[entry.name] = nextValue\r\n return next\r\n })\r\n },\r\n )\r\n }),\r\n ),\r\n h(\r\n 'div',\r\n { className: styles.formGrid, style: S.formGrid },\r\n field(\r\n t.protocol,\r\n h(\r\n 'select',\r\n {\r\n className: styles.input,\r\n style: S.input,\r\n value: entry.value.protocol,\r\n onChange: (event: any) => bindProfile(entry.name, 'protocol')(event.target.value),\r\n },\r\n ...PROTOCOLS.map(protocol =>\r\n h('option', { key: protocol, value: protocol }, protocol.toUpperCase()),\r\n ),\r\n ),\r\n undefined,\r\n ),\r\n field(\r\n t.host,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: '127.0.0.1',\r\n value: entry.value.host,\r\n onChange: (event: any) => bindProfile(entry.name, 'host')(event.target.value),\r\n }),\r\n entry.value.host.trim().length === 0 ? undefined : proxyHostProblem(entry.value.host),\r\n entry.value.host.trim().length > 0 && proxyHostProblem(entry.value.host) !== undefined,\r\n ),\r\n field(\r\n t.port,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n type: 'number',\r\n min: 1,\r\n max: 65535,\r\n placeholder: '7891',\r\n value: entry.value.port === 0 ? '' : String(entry.value.port),\r\n onChange: (event: any) => {\r\n const parsed = Number.parseInt(event.target.value, 10)\r\n bindProfile(entry.name, 'port')(Number.isNaN(parsed) ? 0 : parsed)\r\n },\r\n }),\r\n undefined,\r\n ),\r\n field(\r\n t.username,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n autoComplete: 'off',\r\n value: entry.value.username,\r\n onChange: (event: any) => bindProfile(entry.name, 'username')(event.target.value),\r\n }),\r\n undefined,\r\n ),\r\n field(\r\n t.password,\r\n h(\r\n 'div',\r\n { style: S.passwordControl },\r\n h('input', {\r\n className: styles.input,\r\n style: { ...S.input, paddingRight: '36px' },\r\n type: 'password',\r\n autoComplete: 'off',\r\n value: entry.value.password,\r\n onChange: (event: any) => bindProfile(entry.name, 'password')(event.target.value),\r\n }),\r\n ),\r\n t.passwordHintProxy,\r\n false,\r\n true,\r\n ),\r\n ),\r\n )\r\n }),\r\n ],\r\n })\r\n\r\n const storedLocalDirect = snapshot.value?.localDirect !== false\r\n const globalTestUrl = typeof globalDraft.testUrl === 'string' ? globalDraft.testUrl : storedTestUrl\r\n const globalLocalDirect =\r\n typeof globalDraft.localDirect === 'boolean' ? globalDraft.localDirect : storedLocalDirect\r\n const globalTestUrlHint = testUrlHint(globalTestUrl, t)\r\n\r\n /**\r\n * Download the current configuration as JSON.\r\n *\r\n * The password question is asked EVERY time rather than remembered: an export\r\n * that silently started carrying credentials because of an earlier \"yes\" is\r\n * exactly the kind of sticky choice nobody expects. Default is \"no\".\r\n */\r\n const exportBackup = (): void => {\r\n const includePasswords =\r\n globalThis.window?.confirm?.(t.backupIncludePasswords) === true\r\n const document = buildBackup(\r\n {\r\n providers: { ...configured, ...draft },\r\n proxyProfiles: { ...storedProfiles, ...profileDraft },\r\n defaultProxy: { ...storedDefault, ...defaultDraft },\r\n localDirect: globalLocalDirect,\r\n testUrl: globalTestUrl,\r\n },\r\n { includePasswords },\r\n )\r\n try {\r\n const text = JSON.stringify(document, null, 2)\r\n const blob = new globalThis.Blob([text], { type: 'application/json' })\r\n const url = globalThis.URL.createObjectURL(blob)\r\n const anchor = globalThis.document.createElement('a')\r\n anchor.href = url\r\n anchor.download = backupFileName()\r\n anchor.click()\r\n globalThis.setTimeout(() => globalThis.URL.revokeObjectURL(url), 0)\r\n setSavedNote(`${t.backupExported}${includePasswords ? t.backupWithPasswords : t.backupWithoutPasswords}`)\r\n } catch (error: any) {\r\n setSavedNote(undefined)\r\n setSaveError({ label: t.backupExport, message: String(error?.message ?? error) })\r\n }\r\n }\r\n\r\n /**\r\n * Read, validate, confirm, then overwrite in ONE write.\r\n *\r\n * A file is parsed and checked BEFORE the user is asked to confirm, so the\r\n * prompt never appears for a file that cannot be applied. The whole restore is\r\n * a single `mutate` call, which is what makes a revision conflict fail the\r\n * restore instead of leaving half of it in place.\r\n */\r\n const importBackupFile = async (file: any): Promise<void> => {\r\n let text: string\r\n try {\r\n text = await file.text()\r\n } catch (error: any) {\r\n setSaveError({ label: t.backupImport, message: String(error?.message ?? error) })\r\n return\r\n }\r\n const parsed = parseBackup(text)\r\n if (!parsed.ok) {\r\n setSavedNote(undefined)\r\n setSaveError({ label: t.backupImport, message: parsed.error })\r\n return\r\n }\r\n const counts = backupCounts(parsed.document)\r\n const confirmed = globalThis.window?.confirm?.(\r\n `${t.backupConfirm}${counts.providers}${t.backupConfirmProviders}${counts.profiles}${t.backupConfirmProfiles}`,\r\n )\r\n if (confirmed !== true) return\r\n try {\r\n await enqueueWrite(() => writeConfig(ctx, backupOps(parsed.document)))\r\n setSaveError(undefined)\r\n setSavedNote(`${t.backupRestored}${counts.providers}`)\r\n // The restored values must show immediately: the settings store may not\r\n // republish within this render, so every draft layer is cleared.\r\n setDraft({})\r\n setDefaultDraft({})\r\n setProfileDraft({})\r\n setGlobalDraft({})\r\n } catch (error: any) {\r\n setSavedNote(undefined)\r\n setSaveError({ label: t.backupImport, message: String(error?.message ?? error) })\r\n }\r\n }\r\n\r\n const backupBlock = h(\r\n 'div',\r\n { style: S.backupBar, key: 'backup' },\r\n h(\r\n 'div',\r\n { style: { display: 'flex', flexDirection: 'column', gap: '2px', minWidth: '0' } },\r\n h('span', { style: { ...S.name, fontSize: '12px' } }, t.backupTitle),\r\n h('span', { style: S.defaultLead }, t.backupLead),\r\n ),\r\n h(\r\n 'div',\r\n { style: { ...S.testRow, flex: 'none' } },\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n onClick: exportBackup,\r\n },\r\n t.backupExport,\r\n ),\r\n h(\r\n 'label',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, display: 'inline-flex', alignItems: 'center' },\r\n key: 'backup:import',\r\n },\r\n t.backupImport,\r\n h('input', {\r\n type: 'file',\r\n accept: 'application/json,.json',\r\n style: { display: 'none' },\r\n onChange: (event: any) => {\r\n const file = event?.target?.files?.[0]\r\n if (file !== undefined) void importBackupFile(file)\r\n // Allow the same file to be chosen twice in a row.\r\n if (event?.target !== undefined) event.target.value = ''\r\n },\r\n }),\r\n ),\r\n ),\r\n )\r\n\r\n const globalBlock = panel({\r\n key: 'global-settings',\r\n summary: t.globalTitle,\r\n lead: t.globalLead,\r\n children: [\r\n h(\r\n 'label',\r\n { className: styles.field, style: S.field },\r\n h('span', { className: styles.label, style: S.label }, t.testUrl),\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n value: globalTestUrl,\r\n onChange: (event: any) => bindGlobal('testUrl')(event.target.value),\r\n }),\r\n globalTestUrlHint === undefined\r\n ? h('span', { className: styles.hint, style: S.hint }, t.testUrlHint)\r\n : h(\r\n 'span',\r\n {\r\n className: styles.hint,\r\n style: {\r\n ...S.hint,\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n },\r\n },\r\n globalTestUrlHint,\r\n ),\r\n ),\r\n h(\r\n 'div',\r\n { style: S.testRow },\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n onClick: () => bindGlobal('testUrl')(DEFAULT_TEST_URL),\r\n },\r\n t.restoreDefaultTestUrl,\r\n ),\r\n ),\r\n h(\r\n 'label',\r\n { className: styles.toggle, style: S.toggle },\r\n h('input', {\r\n type: 'checkbox',\r\n checked: globalLocalDirect,\r\n onChange: (event: any) => bindGlobal('localDirect')(event.target.checked === true),\r\n }),\r\n h('span', null, t.localDirect),\r\n ),\r\n h(\r\n 'p',\r\n { className: styles.hint, style: { ...S.hint, margin: '2px 0 0' } },\r\n globalLocalDirect ? t.localDirectOnHint : t.localDirectOffHint,\r\n ),\r\n ],\r\n })\r\n\r\n const routeStateOf = (row: ProviderRow): 'proxied' | 'direct' | 'rejected' => {\r\n const route = view({ ...configured[row.id], ...draft[row.id] })\r\n const recorded = problems[row.id]\r\n const state = cardEndpoint(route)\r\n const problemText = recorded !== undefined\r\n ? recorded\r\n : route.enabled\r\n ? cardProblemText(state)\r\n : undefined\r\n if (route.enabled && problemText !== undefined) return 'rejected'\r\n if (route.enabled) return 'proxied'\r\n return 'direct'\r\n }\r\n\r\n const query = filter.trim().toLowerCase()\r\n const matchedKeywordRows =\r\n query.length === 0\r\n ? rows\r\n : rows.filter(row => `${row.id} ${row.name}`.toLowerCase().includes(query))\r\n\r\n const countActive = matchedKeywordRows.filter(r => routeStateOf(r) === 'proxied').length\r\n const countDirect = matchedKeywordRows.filter(r => routeStateOf(r) === 'direct').length\r\n const countRejected = matchedKeywordRows.filter(r => routeStateOf(r) === 'rejected').length\r\n\r\n const shown = matchedKeywordRows.filter(row => {\r\n if (statusFilter === 'all') return true\r\n return routeStateOf(row) === statusFilter\r\n })\r\n\r\n /**\r\n * The list toolbar: status chips, search, bulk test and the view switch.\r\n *\r\n * All four act on the SAME list, so they live in one bordered block directly\r\n * above it. They used to be two loose rows placed after every page-level\r\n * panel, which put the controls four blocks away from what they control.\r\n */\r\n const listToolbar =\r\n rows.length === 0\r\n ? null\r\n : h(\r\n 'div',\r\n { style: S.toolbar, key: 'list-toolbar' },\r\n h(\r\n 'div',\r\n { className: styles.chipRow, style: S.chipRow, key: 'status-chips' },\r\n ([\r\n { id: 'all', label: `${t.filterStatusAll} (${matchedKeywordRows.length})` },\r\n { id: 'proxied', label: `${t.filterStatusProxied} (${countActive})` },\r\n { id: 'direct', label: `${t.filterStatusDirect} (${countDirect})` },\r\n { id: 'rejected', label: `${t.filterStatusRejected} (${countRejected})` },\r\n ] as const).map(({ id, label }) =>\r\n h(\r\n 'button',\r\n {\r\n key: id,\r\n type: 'button',\r\n className: statusFilter === id ? styles.chipActive : styles.chip,\r\n style: {\r\n ...S.chip,\r\n ...(statusFilter === id ? S.chipActive : {}),\r\n },\r\n // Selection is a STATE, not a decoration: `aria-pressed`\r\n // makes exactly one chip self-describing to assistive tech,\r\n // and it is what the regression test reads instead of\r\n // trusting a colour.\r\n 'aria-pressed': statusFilter === id,\r\n onClick: () => {\r\n setStatusFilter(id)\r\n writeViewPrefs({ statusFilter: id })\r\n },\r\n },\r\n label,\r\n ),\r\n ),\r\n ),\r\n h(\r\n 'div',\r\n { className: styles.toolbarRow, style: S.toolbarRow, key: 'list-actions' },\r\n h('input', {\r\n className: styles.input,\r\n style: { ...S.input, flex: '1 1 180px', minWidth: '0' },\r\n placeholder: t.filterPlaceholder,\r\n 'aria-label': t.filterLabel,\r\n value: filter,\r\n onChange: (event: any) => setFilter(event.target.value),\r\n }),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, flex: 'none', whiteSpace: 'nowrap' },\r\n type: 'button',\r\n disabled: countActive === 0 || batchProgress !== null,\r\n onClick: runBatchTest,\r\n },\r\n batchProgress !== null\r\n ? `${t.batchTesting} (${batchProgress.done}/${batchProgress.total})`\r\n : `${t.batchTest} (${countActive})`,\r\n ),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, flex: 'none', whiteSpace: 'nowrap' },\r\n type: 'button',\r\n onClick: () =>\r\n setViewMode((m: 'card' | 'compact') => {\r\n const next = m === 'card' ? 'compact' : 'card'\r\n // Written where the STATE changes, not in an effect: the\r\n // map callback sees the same `next` the state receives, so\r\n // storage can never disagree with what is on screen.\r\n writeViewPrefs({ viewMode: next })\r\n return next\r\n }),\r\n },\r\n viewMode === 'card' ? t.viewCompact : t.viewCard,\r\n ),\r\n ),\r\n )\r\n\r\n // The empty slot answers three different questions: still loading, the read\r\n // failed, or truly nothing to show. Only the last is the empty message.\r\n // With saved cards present, a failed first read is reported above them instead.\r\n const catalogueStatus = rows.length === 0\r\n ? state.pending\r\n ? { text: t.catalogueLoading, error: false }\r\n : state.error !== undefined\r\n ? { text: `${t.catalogueError}${state.error}`, error: true }\r\n : undefined\r\n : undefined\r\n const catalogueNotice =\r\n state.error !== undefined && rows.length > 0\r\n ? h(\r\n 'p',\r\n { key: 'catalogue-error', style: S.inheritWarning },\r\n `${t.catalogueStale}${state.error}`,\r\n )\r\n : null\r\n\r\n // ALWAYS an array: a single element is not iterable, and spreading one threw\r\n // \"Spread syntax requires ...iterable[Symbol.iterator]\" on an empty list.\r\n const body: unknown[] = shown.length === 0\r\n ? [\r\n h(\r\n 'p',\r\n {\r\n className: styles.empty,\r\n key: 'empty',\r\n style: {\r\n margin: '0',\r\n padding: '16px',\r\n border: '1px dashed var(--dsw-alias-border-l1)',\r\n borderRadius: '8px',\r\n fontSize: '12px',\r\n textAlign: 'center',\r\n color: catalogueStatus?.error === true\r\n ? 'var(--dsw-alias-state-error-primary, #f85149)'\r\n : 'var(--dsw-alias-state-idle-primary)',\r\n ...(catalogueStatus?.error === true ? { fontWeight: '500' } : {}),\r\n },\r\n },\r\n catalogueStatus?.text ?? (query.length > 0 ? t.noMatch : t.empty),\r\n ),\r\n ]\r\n : shown.map(row => {\r\n // The MERGED value, so a just-typed value shows immediately.\r\n const route = view({ ...configured[row.id], ...draft[row.id] })\r\n // The endpoint controls are editable whether or not the route is on: the\r\n // point of the self-check below is to verify a setting BEFORE switching\r\n // it on, which is impossible if the fields can only be typed into while\r\n // traffic is already flowing through them. `enabled` gates routing only.\r\n // The line exists only once a route has actually carried a request, so an\r\n // ENABLED route with no record yet says so \u2014 otherwise a missing line is\r\n // indistinguishable from the feature not existing. A disabled route stays\r\n // silent: it cannot have a record, and saying so on every off card is noise.\r\n const lastText = lastUseText(row.id) ?? (route.enabled ? t.noRecord : undefined)\r\n const result = tests[row.id]\r\n // Rule entries that can never match: flagged under the input instead of\r\n // failing silently \u2014 a dead `onlyHosts` entry means fail-closed sends\r\n // the traffic DIRECT while the user believes it is proxied.\r\n const onlyDead = deadRuleEntries(route.onlyHosts)\r\n const bypassDead = deadRuleEntries(route.bypassHosts)\r\n const hostTemplate = providerHostTemplate(row.id)\r\n const useDefault = route.useDefault === true\r\n const boundProfile = route.profileId.trim()\r\n const endpointState = cardEndpoint(route)\r\n // Whether this card has an endpoint worth checking: an inheriting card\r\n // depends on the shared default being configured, an own-endpoint card on\r\n // its host and port being complete. Mirrors the Host's own build gate.\r\n const endpointStored = endpointState.complete\r\n const showTest = route.enabled || endpointStored\r\n // The Host's recorded problem is authoritative (it also covers dispatcher\r\n // construction); until the next catalogue poll, the shared predicate can\r\n // already prove the common endpoint mistakes. An unused route is never\r\n // \"rejected\" \u2014 it has not asked for anything yet.\r\n const problemText = ((): string | undefined => {\r\n const recorded = problems[row.id]\r\n if (recorded !== undefined) return recorded\r\n return route.enabled ? cardProblemText(endpointState) : undefined\r\n })()\r\n const rejected = route.enabled && problemText !== undefined\r\n // Built once and either rendered (this route carries its own address) or\r\n // replaced by a one-line note (it inherits the shared default), so a card\r\n // can never show an input that does not apply to it.\r\n const endpointFields = [\r\n field(\r\n t.protocol,\r\n h(\r\n 'select',\r\n {\r\n className: styles.input,\r\n style: S.input,\r\n value: route.protocol,\r\n onChange: (event: any) => bind(row.id, 'protocol')(event.target.value),\r\n },\r\n ...PROTOCOLS.map(protocol =>\r\n h('option', { key: protocol, value: protocol }, protocol.toUpperCase()),\r\n ),\r\n ),\r\n route.protocol === 'socks5' ? t.socks5Hint : undefined,\r\n ),\r\n field(\r\n t.host,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: '127.0.0.1',\r\n value: route.host,\r\n onChange: (event: any) => bind(row.id, 'host')(event.target.value),\r\n // A pasted full proxy URL fills every transport field at once.\r\n onPaste: onProxyUrlPaste(parts => applyCardUrl(row.id, parts)),\r\n }),\r\n t.hostHint,\r\n ),\r\n field(\r\n t.port,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n type: 'number',\r\n min: 1,\r\n max: 65535,\r\n placeholder: '7890',\r\n value: route.port === 0 ? '' : String(route.port),\r\n onChange: (event: any) => {\r\n const parsed = Number.parseInt(event.target.value, 10)\r\n bind(row.id, 'port')(Number.isNaN(parsed) ? 0 : parsed)\r\n },\r\n }),\r\n ),\r\n field(\r\n t.username,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n autoComplete: 'off',\r\n value: route.username,\r\n onChange: (event: any) => bind(row.id, 'username')(event.target.value),\r\n }),\r\n ),\r\n // Every transport accepts a password: SOCKS5 hands it to\r\n // Socks5ProxyAgent as an option, HTTP/HTTPS embed it in the proxy URL\r\n // userinfo (undici turns that into Proxy-Authorization). It is stored on\r\n // the route, so it lands in the settings file with the rest of the\r\n // config; the diagnostics only ever surface a credential-free origin.\r\n field(\r\n t.password,\r\n h(\r\n 'div',\r\n { style: S.passwordControl },\r\n h('input', {\r\n className: styles.input,\r\n style: { ...S.input, paddingRight: '36px' },\r\n type: passwordVisible[row.id] === true ? 'text' : 'password',\r\n autoComplete: 'off',\r\n value: route.password,\r\n onChange: (event: any) => bind(row.id, 'password')(event.target.value),\r\n }),\r\n passwordToggle(passwordVisible[row.id] === true, () => togglePassword(row.id)),\r\n ),\r\n route.protocol === 'socks5' ? t.passwordHint : t.passwordHintProxy,\r\n false,\r\n true,\r\n ),\r\n ]\r\n // The pill describes the ROUTE, never provider availability: a saved\r\n // route can outlive the Host directory, and whether that directory lists\r\n // it must not make the proxy switch read as \"offline\" or \"proxied\".\r\n const pill = rejected\r\n ? { className: styles.pillRejected, style: { ...S.pill, ...S.pillRejected }, text: t.rejected }\r\n : route.enabled\r\n ? { className: styles.pillOn, style: { ...S.pill, ...S.pillOn }, text: t.on }\r\n : { className: styles.pillLive, style: { ...S.pill, ...S.pillLive }, text: t.off }\r\n const cardSection = h(\r\n 'section',\r\n {\r\n className: rejected ? styles.cardRejected : route.enabled ? styles.cardActive : styles.card,\r\n style: rejected\r\n ? { ...S.card, ...S.cardRejected }\r\n : route.enabled\r\n ? { ...S.card, ...S.cardActive }\r\n : S.card,\r\n key: row.id,\r\n },\r\n h(\r\n 'header',\r\n { className: styles.cardHead, style: S.head },\r\n h(\r\n 'div',\r\n { className: styles.cardTitles, style: S.titles },\r\n h('span', { className: styles.name, style: S.name }, row.name),\r\n h('span', { className: styles.id, style: S.id }, row.id),\r\n // A disabled route can never have hits, so \"0\" there would only add\r\n // noise; the count shows once the route is on (or has counted).\r\n route.enabled || (hits[row.id] ?? 0) > 0\r\n ? h(\r\n 'span',\r\n { style: S.hits },\r\n `${t.hitCountPrefix}${hits[row.id] ?? 0}${t.hitCountSuffix}`,\r\n )\r\n : null,\r\n // The last-use line. A failure takes the error colour, same rule as\r\n // a failed self-check: it is an answer, not decoration.\r\n lastText === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n {\r\n style: {\r\n ...S.hits,\r\n ...(lastUse[row.id]?.ok === false ? S.inheritWarning : {}),\r\n },\r\n },\r\n lastText,\r\n ),\r\n ),\r\n h('span', { className: pill.className, style: pill.style }, pill.text),\r\n ),\r\n // The two route-level controls, on ONE row and in ONE shape: each is\r\n // a label over its control. They were a bare `label` (checkbox) next to\r\n // a two-column `field` (picker), so the card's own row looked like two\r\n // unrelated widgets stacked.\r\n h(\r\n 'div',\r\n { className: styles.controlRow, style: S.controlRow, key: `${row.id}:controls` },\r\n h(\r\n 'label',\r\n { style: S.controlCell },\r\n h('span', { className: styles.label, style: S.label }, t.enableLabel),\r\n h(\r\n 'span',\r\n { className: styles.toggle, style: { ...S.toggle, paddingTop: '0' } },\r\n h('input', {\r\n type: 'checkbox',\r\n checked: route.enabled,\r\n onChange: (event: any) =>\r\n bind(row.id, 'enabled')(event.target.checked === true),\r\n }),\r\n h('span', { style: { fontSize: '12px' } }, t.useProxy),\r\n ),\r\n ),\r\n // Which endpoint this card takes.\r\n //\r\n // Always a picker, never a checkbox: the decision has three possible\r\n // shapes (own fields / the built-in default / a named preset), and a\r\n // checkbox can only express the first two. Every option carries the\r\n // address it will use, because \"\u9884\u8BBE: \u9999\u6E2F\u4E13\u7EBF\" alone does not tell a\r\n // user which port it points at.\r\n h(\r\n 'label',\r\n { style: S.controlCell, key: `${row.id}:profile` },\r\n h('span', { className: styles.label, style: S.label }, t.profileBinding),\r\n h(\r\n 'select',\r\n {\r\n className: styles.input,\r\n style: S.input,\r\n value: boundProfile.length > 0 ? boundProfile : useDefault ? DEFAULT_PROFILE_BINDING : '',\r\n onChange: (event: any) => {\r\n const value = String(event.target.value)\r\n // Every branch writes BOTH binding fields.\r\n //\r\n // `profileId` wins over `useDefault` when both are present,\r\n // so clearing one in the draft while persisting the other\r\n // left the disk holding the OLD preset id: picking \"default\r\n // preset\" then still routed through the previous preset, and\r\n // picking \"custom fields\" still routed through a preset.\r\n // Two drafts + one write is the only shape with no such\r\n // half-applied window.\r\n bindRouteProfile(row.id)(value)\r\n },\r\n },\r\n h('option', { key: 'own', value: '' }, t.profileBindingOwn),\r\n h(\r\n 'option',\r\n { key: 'default', value: DEFAULT_PROFILE_BINDING },\r\n `${t.profileBindingPrefix}${DEFAULT_PROFILE_LABEL.replace(\r\n ' (Default)',\r\n '',\r\n )} (${endpointAddress(defaultView)})`,\r\n ),\r\n ...profileEntries.map(entry =>\r\n h(\r\n 'option',\r\n { key: entry.name, value: entry.name },\r\n `${t.profileBindingPrefix}${entry.name} (${endpointAddress(entry.value)})`,\r\n ),\r\n ),\r\n // A route may still point at a preset that was deleted while this\r\n // page was open. Without an option for it the select would render\r\n // blank, which reads as \"no choice made\".\r\n boundProfile.length > 0 && !profileEntries.some(entry => entry.name === boundProfile)\r\n ? h(\r\n 'option',\r\n { key: `missing:${boundProfile}`, value: boundProfile },\r\n `${t.profileBindingPrefix}${boundProfile}${t.profileMissingOption}`,\r\n )\r\n : null,\r\n ),\r\n ),\r\n ),\r\n problemText !== undefined\r\n ? h('p', { key: `${row.id}:problem`, style: S.inheritWarning }, problemText)\r\n : boundProfile.length > 0\r\n ? h(\r\n 'p',\r\n { key: `${row.id}:profile-note`, style: S.inheritNote },\r\n `${t.inheritingProfile}${boundProfile}\uFF1A${endpointSummary(endpointState.endpoint ?? {})}`,\r\n )\r\n : useDefault\r\n ? h(\r\n 'p',\r\n { key: `${row.id}:inherit`, style: S.inheritNote },\r\n `${t.inheritingDefault}${defaultOrigin}`,\r\n )\r\n : null,\r\n ...(useDefault || boundProfile.length > 0\r\n ? []\r\n : [\r\n h(\r\n 'div',\r\n { style: S.testRow, key: `${row.id}:quick-import` },\r\n quickImportSelect(`${row.id}:quick-import`, parts => applyCardUrl(row.id, parts)),\r\n ),\r\n h('div', { className: styles.formGrid, style: S.formGrid, key: `${row.id}:form-grid` }, ...endpointFields),\r\n ]),\r\n // The self-check is offered whenever there is something to check: an\r\n // enabled route (the Host's table carries it, and a rejected one still\r\n // reports WHY), or a disabled one whose endpoint is already complete \u2014\r\n // the Host builds that one for the check alone. A disabled route with\r\n // no endpoint has nothing to test and would only answer \"not enabled\".\r\n showTest\r\n ? h(\r\n 'div',\r\n { style: S.testRow, key: `${row.id}:test` },\r\n // A check on a route that is still off is a trial run, and it says\r\n // so \u2014 otherwise the result reads as though the route were live.\r\n route.enabled ? null : h('span', { style: S.testResult }, t.testDisabledNote),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n disabled: result?.pending === true,\r\n onClick: () => runTest(row.id),\r\n },\r\n result?.pending === true ? t.testRunning : t.testButton,\r\n ),\r\n result?.pending === false\r\n ? h(\r\n 'div',\r\n { style: S.testResult },\r\n result.ok === true\r\n ? [\r\n // The band colour belongs to the LATENCY alone. The\r\n // status sits beside it in the plain label colour:\r\n // colouring the whole line made a successful check\r\n // over 1500 ms read as a failure.\r\n h(\r\n 'span',\r\n { key: 'lat', style: { color: latencyColor(result.ms) } },\r\n `\u2713 ${typeof result.ms === 'number' ? result.ms : '\u2014'} ms`,\r\n ),\r\n typeof result.status === 'number'\r\n ? h(\r\n 'span',\r\n { key: 'status' },\r\n `HTTP ${result.status}`,\r\n )\r\n : null,\r\n result.ip === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n { key: 'ip', style: { display: 'inline-flex', alignItems: 'center', gap: '3px' } },\r\n `${t.exitIpLabel}${result.ip}`,\r\n copyButton(`${row.id}:ip`, result.ip, t.copy),\r\n ),\r\n result.direct === true\r\n ? h('span', { key: 'direct' }, t.directLabel)\r\n : null,\r\n result.cached === true\r\n ? h('span', { key: 'cached' }, t.cachedLabel)\r\n : null,\r\n result.target === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n {\r\n key: 'target',\r\n style: {\r\n flexBasis: '100%',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n wordBreak: 'break-all',\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n gap: '3px',\r\n },\r\n },\r\n `${t.testTargetLabel}${result.target}${targetSourceSuffix(result, t)}`,\r\n copyButton(`${row.id}:target`, result.target, t.copy),\r\n ),\r\n ]\r\n : [\r\n h(\r\n 'span',\r\n { key: 'err', style: { ...S.testFailure, display: 'inline-flex', alignItems: 'center', gap: '3px' } },\r\n `\u2717 ${result.error}`,\r\n copyButton(`${row.id}:err`, String(result.error), t.copy),\r\n ),\r\n typeof result.status === 'number'\r\n ? h('span', { key: 'status' }, `HTTP ${result.status}`)\r\n : null,\r\n result.target === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n {\r\n key: 'target',\r\n style: {\r\n flexBasis: '100%',\r\n fontSize: '11px',\r\n color: 'var(--dsw-alias-label-secondary)',\r\n wordBreak: 'break-all',\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n gap: '3px',\r\n },\r\n },\r\n `${t.testTargetLabel}${result.target}${targetSourceSuffix(result, t)}`,\r\n copyButton(`${row.id}:target`, result.target, t.copy),\r\n ),\r\n ],\r\n )\r\n : null,\r\n // Promote this card's endpoint to the shared default. Offered only\r\n // when the card carries its OWN endpoint: an inheriting card would\r\n // just be copying the default onto itself.\r\n endpointStored && !useDefault && boundProfile.length === 0\r\n ? h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: S.testButton,\r\n type: 'button',\r\n onClick: () => promoteToDefault(row.id),\r\n },\r\n t.setAsDefault,\r\n )\r\n : null,\r\n )\r\n : null,\r\n // Target-host rules, collapsed so the common case stays one short card.\r\n h(\r\n 'details',\r\n { style: S.advanced, key: `${row.id}:rules` },\r\n h('summary', { style: S.advancedSummary }, t.advanced),\r\n field(\r\n t.onlyHosts,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: 'api.example.com',\r\n value: route.onlyHosts,\r\n onChange: (event: any) => bind(row.id, 'onlyHosts')(event.target.value),\r\n }),\r\n onlyDead.length === 0 ? t.onlyHostsHint : `${t.ruleDeadHint}${onlyDead.join('\u3001')}`,\r\n onlyDead.length > 0,\r\n ),\r\n // The official-upstream pill. Offered only for a provider whose id\r\n // maps to a known template: a button that guessed a hostname for an\r\n // arbitrary relay would be worse than no button at all.\r\n hostTemplate === undefined\r\n ? null\r\n : h(\r\n 'div',\r\n { style: S.chipRow, key: `${row.id}:host-template` },\r\n h(\r\n 'button',\r\n {\r\n className: styles.chip,\r\n style: S.chip,\r\n type: 'button',\r\n title: hostTemplate.hosts,\r\n onClick: () =>\r\n bind(row.id, 'onlyHosts')(\r\n appendHostRules(route.onlyHosts, hostTemplate.hosts),\r\n ),\r\n },\r\n `${t.loadHostTemplate}${hostTemplate.label}: ${hostTemplate.hosts}`,\r\n ),\r\n ),\r\n field(\r\n t.bypassHosts,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: 'localhost',\r\n value: route.bypassHosts,\r\n onChange: (event: any) => bind(row.id, 'bypassHosts')(event.target.value),\r\n }),\r\n bypassDead.length === 0 ? t.bypassHostsHint : `${t.ruleDeadHint}${bypassDead.join('\u3001')}`,\r\n bypassDead.length > 0,\r\n ),\r\n // The self-check target: empty uses the top-level testUrl, set makes\r\n // this card's Test request this URL \u2014 a real upstream proves the whole\r\n // path, not just the proxy hop.\r\n field(\r\n t.testTarget,\r\n h('input', {\r\n className: styles.input,\r\n style: S.input,\r\n placeholder: 'https://api.example.com',\r\n value: route.testTarget,\r\n onChange: (event: any) => bind(row.id, 'testTarget')(event.target.value),\r\n }),\r\n t.testTargetHint,\r\n ),\r\n ),\r\n )\r\n\r\n const isExpanded = expandedCards[row.id] === true\r\n /**\r\n * The endpoint line for the compact row, in the same words the card\r\n * uses: which source it came from, then the resolved address.\r\n */\r\n const endpointText =\r\n endpointState.missingProfile !== undefined\r\n ? `${t.profileBindingPrefix}${endpointState.missingProfile}${t.profileMissingOption}`\r\n : boundProfile.length > 0\r\n ? `${t.profileBindingPrefix}${boundProfile}: ${endpointSummary(endpointState.endpoint ?? {})}`\r\n : useDefault\r\n ? `${t.useDefault}: ${defaultOrigin}`\r\n // Lower-case, matching the resolved-endpoint wording above so the\r\n // same address never appears in two spellings on one page.\r\n : `${route.protocol}://${route.host || '\u2014'}:${route.port || '\u2014'}`\r\n const compactRowElement = h(\r\n 'section',\r\n {\r\n className: rejected ? styles.compactRowRejected : route.enabled ? styles.compactRowActive : styles.compactRow,\r\n style: rejected\r\n ? { ...S.compactRow, ...S.compactRowRejected }\r\n : route.enabled\r\n ? { ...S.compactRow, ...S.compactRowActive }\r\n : S.compactRow,\r\n key: `compact:${row.id}`,\r\n },\r\n // Row 1 \u2014 who this is and which proxy actually carries it. The\r\n // endpoint shown is the RESOLVED one, so a preset-bound row never\r\n // claims an address it will not use.\r\n h(\r\n 'div',\r\n { style: S.compactLine, key: `compact:${row.id}:info` },\r\n h('span', { className: styles.name, style: { ...S.name, maxWidth: '160px' } }, row.name),\r\n h('span', { className: styles.id, style: S.id }, row.id),\r\n h(\r\n 'span',\r\n {\r\n style: {\r\n ...S.compactEndpoint,\r\n ...(endpointState.missingProfile !== undefined || endpointState.why !== undefined\r\n ? { color: 'var(--dsw-alias-state-error-primary, #f85149)' }\r\n : {}),\r\n },\r\n title: endpointText,\r\n },\r\n endpointText,\r\n ),\r\n lastText === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n {\r\n style: {\r\n ...S.compactEndpoint,\r\n ...(lastUse[row.id]?.ok === false ? S.inheritWarning : {}),\r\n },\r\n },\r\n lastText,\r\n ),\r\n ),\r\n // Row 2 \u2014 everything actionable, including the endpoint source. The\r\n // source picker lives here rather than in row 1 because it is a\r\n // CONTROL: putting it among the read-only facts made the row look\r\n // uniform while one element was silently editable.\r\n h(\r\n 'div',\r\n { style: S.compactActions, key: `compact:${row.id}:actions` },\r\n h(\r\n 'label',\r\n {\r\n style: { display: 'inline-flex', alignItems: 'center', gap: '6px', flex: 'none' },\r\n },\r\n h('input', {\r\n type: 'checkbox',\r\n checked: route.enabled,\r\n onChange: (event: any) => bind(row.id, 'enabled')(event.target.checked === true),\r\n }),\r\n h('span', { style: { fontSize: '11px', color: 'var(--dsw-alias-label-secondary)' } }, t.useProxy),\r\n ),\r\n h(\r\n 'select',\r\n {\r\n className: styles.input,\r\n style: { ...S.input, flex: '0 1 190px', minWidth: '120px', padding: '3px 6px' },\r\n 'aria-label': t.profileBinding,\r\n value: boundProfile.length > 0 ? boundProfile : useDefault ? DEFAULT_PROFILE_BINDING : '',\r\n onChange: (event: any) => bindRouteProfile(row.id)(String(event.target.value)),\r\n },\r\n h('option', { key: 'own', value: '' }, t.profileBindingOwn),\r\n h(\r\n 'option',\r\n { key: 'default', value: DEFAULT_PROFILE_BINDING },\r\n `${t.profileBindingPrefix}${DEFAULT_PROFILE_LABEL.replace(' (Default)', '')} (${endpointAddress(defaultView)})`,\r\n ),\r\n ...profileEntries.map(entry =>\r\n h(\r\n 'option',\r\n { key: entry.name, value: entry.name },\r\n `${t.profileBindingPrefix}${entry.name} (${endpointAddress(entry.value)})`,\r\n ),\r\n ),\r\n boundProfile.length > 0 && !profileEntries.some(entry => entry.name === boundProfile)\r\n ? h(\r\n 'option',\r\n { key: `missing:${boundProfile}`, value: boundProfile },\r\n `${t.profileBindingPrefix}${boundProfile}${t.profileMissingOption}`,\r\n )\r\n : null,\r\n ),\r\n h('span', { className: pill.className, style: pill.style }, pill.text),\r\n showTest\r\n ? h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, padding: '3px 8px', fontSize: '11px' },\r\n type: 'button',\r\n disabled: result?.pending === true,\r\n onClick: () => runTest(row.id),\r\n },\r\n result?.pending === true ? t.testRunning : t.testButton,\r\n )\r\n : null,\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, padding: '3px 8px', fontSize: '11px' },\r\n type: 'button',\r\n onClick: () => setExpandedCards((curr: any) => ({ ...curr, [row.id]: !curr[row.id] })),\r\n },\r\n isExpanded ? t.collapseDetails : t.expandDetails,\r\n ),\r\n ),\r\n // Row 3 \u2014 the self-check outcome, on its OWN line.\r\n //\r\n // Kept out of the control line so a running or failing check can never\r\n // shift the picker or the buttons under the cursor, and so a long\r\n // failure message has the full width instead of being squeezed\r\n // between two controls. It appears only when there is something to\r\n // report: an always-present empty row is just extra height.\r\n result === undefined || result.ok === undefined\r\n ? null\r\n : h(\r\n 'div',\r\n { style: S.compactResultLine, key: `compact:${row.id}:result` },\r\n result.pending === true\r\n ? h('span', { style: { color: 'var(--dsw-alias-label-secondary)' } }, t.testRunning)\r\n : result.ok === true\r\n ? [\r\n h(\r\n 'span',\r\n { key: 'lat', style: { color: latencyColor(result.ms), fontWeight: '500' } },\r\n `\u2713 ${result.ms ?? '\u2014'} ms`,\r\n ),\r\n typeof result.status === 'number'\r\n ? h('span', { key: 'status' }, `HTTP ${result.status}`)\r\n : null,\r\n result.ip === undefined\r\n ? null\r\n : h(\r\n 'span',\r\n { key: 'ip', style: { display: 'inline-flex', alignItems: 'center', gap: '3px' } },\r\n `${t.exitIpLabel}${result.ip}`,\r\n copyButton(`${row.id}:compact:ip`, String(result.ip), t.copy),\r\n ),\r\n result.direct === true ? h('span', { key: 'direct' }, t.directLabel) : null,\r\n result.cached === true ? h('span', { key: 'cached' }, t.cachedLabel) : null,\r\n ]\r\n : [\r\n h(\r\n 'span',\r\n {\r\n key: 'err',\r\n style: { ...S.testFailure, display: 'inline-flex', alignItems: 'center', gap: '3px' },\r\n },\r\n `\u2717 ${result.error}`,\r\n copyButton(`${row.id}:compact:err`, String(result.error), t.copy),\r\n ),\r\n typeof result.status === 'number'\r\n ? h('span', { key: 'status' }, `HTTP ${result.status}`)\r\n : null,\r\n ],\r\n ),\r\n )\r\n\r\n if (viewMode === 'compact') {\r\n return isExpanded\r\n ? h('div', { key: `compact-wrap:${row.id}` }, compactRowElement, cardSection)\r\n : compactRowElement\r\n }\r\n return cardSection\r\n })\r\n\r\n return h(\r\n 'div',\r\n { className: styles.root, style: S.root },\r\n h('p', { className: styles.lead, style: { margin: '0 0 4px', fontSize: '12px', lineHeight: '1.6', color: 'var(--dsw-alias-label-secondary)' } }, t.lead),\r\n saveError === undefined\r\n ? null\r\n : h(\r\n 'div',\r\n {\r\n role: 'alert',\r\n key: 'save-error',\r\n style: {\r\n display: 'flex',\r\n alignItems: 'flex-start',\r\n justifyContent: 'space-between',\r\n gap: '10px',\r\n padding: '8px 10px',\r\n border: '1px solid var(--dsw-alias-state-error-primary, #f85149)',\r\n borderRadius: '8px',\r\n background: 'var(--dsw-alias-bg-layer-1)',\r\n color: 'var(--dsw-alias-state-error-primary, #f85149)',\r\n fontSize: '12px',\r\n fontWeight: '500',\r\n wordBreak: 'break-all',\r\n },\r\n },\r\n h('span', null, `${t.saveFailedPrefix}${saveError.label} \u2014 ${saveError.message}`),\r\n h(\r\n 'button',\r\n {\r\n className: styles.testButton,\r\n style: { ...S.testButton, flex: 'none' },\r\n type: 'button',\r\n onClick: () => setSaveError(undefined),\r\n },\r\n t.close,\r\n ),\r\n ),\r\n // Page-level settings, as one group: they apply to the whole page, not to\r\n // one provider.\r\n h(\r\n 'div',\r\n { style: S.group, key: 'page-settings' },\r\n h('h3', { style: S.groupTitle }, t.sectionSettings),\r\n defaultBlock,\r\n profileManager,\r\n globalBlock,\r\n backupBlock,\r\n ),\r\n // The provider list, as its own group: heading, toolbar, then the cards.\r\n h(\r\n 'div',\r\n { style: S.group, key: 'provider-list' },\r\n h('h3', { style: S.groupTitle }, t.sectionProviders),\r\n catalogueNotice,\r\n listToolbar,\r\n ...body,\r\n ),\r\n panel({\r\n key: 'diag',\r\n summary:\r\n problemCount === 0 ? t.diagnostics : `${t.diagnostics} (${problemCount})`,\r\n children: [\r\n h(\r\n 'ul',\r\n { className: styles.diagList, style: { margin: '6px 0 0', paddingLeft: '18px' } },\r\n ...(problemCount === 0 && diagnostics.length === 0 && savedNote === undefined\r\n ? [h('li', { key: 'none' }, t.diagPending)]\r\n : [\r\n ...problemLines,\r\n ...(catalogueMismatchLine === undefined ? [] : [catalogueMismatchLine]),\r\n ...(savedNote === undefined ? [] : [h('li', { key: 'saved' }, savedNote)]),\r\n ...diagnostics.map((line, index) => h('li', { key: `d${index}` }, line)),\r\n ]),\r\n ),\r\n ],\r\n }),\r\n )\r\n}\r\n\r\nconst EN = {\r\n lead: 'Route selected model providers through your own forward proxy. Other providers stay direct. Requests to loopback or private addresses (localhost, 127.x, private ranges) go direct by default; set the top-level localDirect to false to proxy them instead \u2014 a forward proxy normally cannot reach your own machine.',\r\n empty: 'No providers found yet.',\r\n catalogueLoading: 'Loading providers\u2026',\r\n catalogueError: 'Could not load the provider list: ',\r\n catalogueStale: 'Could not load the provider list; showing the saved configuration: ',\r\n useProxy: 'Use a proxy for this provider',\r\n useDefault: 'Use the default proxy',\r\n defaultTitle: 'Default proxy',\r\n defaultLead: 'One endpoint, reused by every provider that turns on \"Use the default proxy\". The status only reports configuration completeness; use the Test button on a card to verify reachability.',\r\n inheritingDefault: 'Using the default proxy: ',\r\n defaultMissing: 'The default proxy configuration is incomplete, so this provider is not proxied: ',\r\n filterLabel: 'Filter',\r\n filterPlaceholder: 'Filter by name or id\u2026',\r\n filterStatusAll: 'All',\r\n filterStatusProxied: 'Proxied',\r\n filterStatusDirect: 'Direct',\r\n filterStatusRejected: 'Rejected',\r\n noMatch: 'No provider matches the filter.',\r\n setAsDefault: 'Set as the default proxy',\r\n applyDefaultAll: 'Use the default proxy for all providers',\r\n protocol: 'Type',\r\n host: 'IP / host',\r\n port: 'Port',\r\n username: 'Username',\r\n password: 'Password',\r\n showPassword: 'Show',\r\n hidePassword: 'Hide',\r\n confirmPromoteToDefault:\r\n 'The default proxy is already in use by one or more providers. Replace it with this card\\'s endpoint?',\r\n hostHint: 'IP or domain only; paste full URL supported',\r\n passwordHint: 'Sent to the SOCKS5 proxy for authentication; stored with this setting.',\r\n passwordHintProxy: 'Sent to the proxy as an authentication password; stored with this setting.',\r\n hitCountPrefix: '',\r\n hitCountSuffix: ' proxied',\r\n recentOk: 'last ok ',\r\n recentFail: 'last failure ',\r\n recentStarted: 'last call ',\r\n noRecord: 'no proxied request yet',\r\n justNow: 'just now',\r\n minutesAgo: ' min ago',\r\n hoursAgo: ' h ago',\r\n daysAgo: ' d ago',\r\n viewCard: 'Card view',\r\n viewCompact: 'Compact view',\r\n expandDetails: 'Edit',\r\n collapseDetails: 'Collapse',\r\n batchTest: 'Test active',\r\n batchTesting: 'Testing',\r\n testButton: 'Test',\r\n testRunning: 'Testing\u2026',\r\n testDisabledNote: 'Not enabled \u2014 test only: ',\r\n testFailed: 'Test failed',\r\n exitIpLabel: 'exit IP ',\r\n directLabel: 'direct (not through the proxy)',\r\n cachedLabel: 'cached',\r\n testTargetLabel: 'Target: ',\r\n targetSourceRoute: \" (this card's own target)\",\r\n targetSourceUpstream: \" (this provider's real upstream)\",\r\n targetSourceTestUrl: ' (global self-check URL)',\r\n globalTitle: 'Global settings (advanced)',\r\n globalLead: 'These fields are saved with the plugin rather than per provider. Leave testUrl empty to use the built-in default; comma/space separated candidates are tried in order and only the first 5 are used. localDirect is on by default; turn it off only when the proxy itself is a loopback or private target.',\r\n testUrl: 'Self-check URL',\r\n testUrlHint: 'Comma/space separated; http(s) URLs in the order they should be tried.',\r\n testUrlEmptyHint: 'Empty means the Host uses its built-in default URL.',\r\n testUrlInvalidHint: 'Some candidates are not absolute http(s) URLs. They are saved, but those checks will fail.',\r\n testUrlTooManyHint: 'More than 5 candidates are listed; only the first 5 take effect.',\r\n restoreDefaultTestUrl: 'Restore default',\r\n localDirect: 'Loopback / private targets go direct',\r\n localDirectOnHint: 'On: localhost, 127.x and private ranges bypass the proxy.',\r\n localDirectOffHint: 'Off: loopback/private targets also use the proxy. Enable only when the proxy itself is the target.',\r\n advanced: 'Advanced: target host rules',\r\n onlyHosts: 'Proxy only',\r\n onlyHostsHint: 'Comma/space separated; when set, only requests to these hosts are proxied (suffix match, * for all).',\r\n bypassHosts: 'Bypass',\r\n bypassHostsHint: 'Comma/space separated; requests to these hosts go direct, taking priority.',\r\n ruleDeadHint: 'These entries never match \u2014 use bare host names (no port, scheme or path); a wildcard must be `*` or start with `*.`: ',\r\n testTarget: 'Self-check target',\r\n testTargetHint: 'Empty uses the top-level testUrl; when set, this card\\'s Test requests this URL instead \u2014 point it at a real upstream to verify the end-to-end path.',\r\n socks5Hint: 'SOCKS5 tunnels the connection; the proxy resolves the target host name.',\r\n on: 'proxied',\r\n rejected: 'config rejected',\r\n off: 'direct',\r\n complete: 'complete',\r\n notConfigured: 'not configured',\r\n diagnostics: 'Connection diagnostics',\r\n diagPending: '(collecting\u2026)',\r\n catalogueMismatch: 'Saved but not listed by the Host catalogue: ',\r\n catalogueMismatchSuffix: '. Their proxy settings are kept.',\r\n saveFailedPrefix: 'Save failed: ',\r\n close: 'Close',\r\n copy: 'Copy',\r\n copied: 'Copied',\r\n profileManagerTitle: 'Proxy presets',\r\n profileManagerLead:\r\n 'Named endpoints you can reuse across providers. The built-in \"Default preset\" is the default proxy block above; edit it there.',\r\n profileAdd: 'Add preset',\r\n profileRename: 'Rename',\r\n profileDelete: 'Delete',\r\n profileNameLabel: 'Preset name',\r\n profileNamePlaceholder: 'New preset name, e.g. HK-Proxy',\r\n profileNamePrompt: 'Name for the new proxy preset:',\r\n profileRenamePrompt: 'New name for this proxy preset:',\r\n profileRenameConfirm: 'Save name',\r\n cancel: 'Cancel',\r\n profileNameTaken: 'A preset with that name already exists.',\r\n profileDeleteConfirm: 'Delete this proxy preset?',\r\n profileDeleteInUse:\r\n 'These providers are bound to this preset and will stop being proxied until they are rebound:\\n',\r\n profileUsedBy: 'Used by: ',\r\n profileBinding: 'Endpoint',\r\n profileBindingOwn: 'Custom (this card)',\r\n profileBindingPrefix: 'Preset: ',\r\n inheritingProfile: 'Using preset ',\r\n profileMissing: 'The bound preset \"',\r\n profileMissingSuffix: '\" no longer exists, so this provider is not proxied.',\r\n profileMissingOption: ' (missing)',\r\n profileUnusable: 'The bound preset \"',\r\n profileUnusableSuffix: '\" is not usable, so this provider is not proxied: ',\r\n quickImport: 'Quick import\u2026',\r\n quickImportEnv: 'From environment: ',\r\n quickImportEnvNone: 'From environment (none detected)',\r\n quickImportEnvCredentials: 'The environment variable also carried credentials; enter them below.',\r\n loadHostTemplate: 'Load official upstream hosts: ',\r\n backupExport: 'Back up configuration',\r\n backupImport: 'Restore configuration',\r\n backupIncludePasswords:\r\n 'Include proxy passwords in the backup?\\n\\nOK = include, Cancel = leave every password empty.',\r\n backupWithPasswords: 'Exported backup (passwords included \u2014 store it safely)',\r\n backupWithoutPasswords: 'Exported backup (passwords omitted)',\r\n backupConfirm:\r\n 'Restore this backup? The current configuration will be replaced.\\n\\nProviders: ',\r\n backupConfirmProviders: ', presets: ',\r\n backupConfirmProfiles: ' entry/entries.',\r\n backupRestored: 'Restored from backup, providers: ',\r\n backupTitle: 'Backup and restore',\r\n backupLead: 'Save the whole proxy configuration to a JSON file, or load one back.',\r\n sectionSettings: 'Page settings',\r\n sectionProviders: 'Providers',\r\n enableLabel: 'Enabled',\r\n}\r\n\r\nconst ZH = {\r\n lead: '\u8BA9\u6307\u5B9A\u7684 provider \u8D70\u4F60\u81EA\u5DF1\u7684\u6B63\u5411\u4EE3\u7406\uFF0C\u5176\u5B83 provider \u4FDD\u6301\u76F4\u8FDE\u3002\u6307\u5411\u672C\u673A\u6216\u5185\u7F51\u5730\u5740\uFF08localhost\u3001127.x\u3001\u79C1\u6709\u7F51\u6BB5\uFF09\u7684\u8BF7\u6C42\u9ED8\u8BA4\u76F4\u8FDE\uFF0C\u9876\u5C42 localDirect \u8BBE\u4E3A false \u65F6\u6062\u590D\u8D70\u4EE3\u7406\u2014\u2014\u6B63\u5411\u4EE3\u7406\u901A\u5E38\u591F\u4E0D\u5230\u4F60\u81EA\u5DF1\u7684\u673A\u5668\u3002',\r\n empty: '\u6CA1\u6709\u68C0\u6D4B\u5230\u4EFB\u4F55 provider\u3002',\r\n catalogueLoading: '\u6B63\u5728\u8BFB\u53D6 provider \u5217\u8868\u2026',\r\n catalogueError: '\u8BFB\u53D6 provider \u5217\u8868\u5931\u8D25\uFF1A',\r\n catalogueStale: 'provider \u5217\u8868\u8BFB\u53D6\u5931\u8D25\uFF0C\u4E0B\u9762\u663E\u793A\u7684\u662F\u5DF2\u4FDD\u5B58\u7684\u914D\u7F6E\uFF1A',\r\n useProxy: '\u4E3A\u8BE5 provider \u542F\u7528\u4EE3\u7406',\r\n useDefault: '\u4F7F\u7528\u9ED8\u8BA4\u4EE3\u7406',\r\n defaultTitle: '\u9ED8\u8BA4\u4EE3\u7406',\r\n defaultLead: '\u4E3A\u52FE\u9009\u300C\u4F7F\u7528\u9ED8\u8BA4\u4EE3\u7406\u300D\u7684 provider \u590D\u7528\u7684\u7AEF\u70B9\uFF0C\u53EA\u586B\u4E00\u6B21\u3002\u72B6\u6001\u53EA\u8868\u793A\u914D\u7F6E\u662F\u5426\u5B8C\u6574\uFF1B\u4EE3\u7406\u662F\u5426\u53EF\u8FBE\u8BF7\u7528\u5361\u7247\u4E0A\u7684\u300C\u6D4B\u8BD5\u300D\u9A8C\u8BC1\u3002',\r\n inheritingDefault: '\u4F7F\u7528\u9ED8\u8BA4\u4EE3\u7406\uFF1A',\r\n defaultMissing: '\u9876\u5C42\u9ED8\u8BA4\u4EE3\u7406\u914D\u7F6E\u4E0D\u5B8C\u6574\uFF0C\u8BE5 provider \u4E0D\u4F1A\u8D70\u4EE3\u7406\uFF1A',\r\n filterLabel: '\u8FC7\u6EE4',\r\n filterPlaceholder: '\u6309\u540D\u79F0\u6216 id \u8FC7\u6EE4\u2026',\r\n filterStatusAll: '\u5168\u90E8',\r\n filterStatusProxied: '\u8D70\u4EE3\u7406',\r\n filterStatusDirect: '\u76F4\u8FDE',\r\n filterStatusRejected: '\u914D\u7F6E\u88AB\u62D2',\r\n noMatch: '\u6CA1\u6709\u5339\u914D\u7684 provider\u3002',\r\n setAsDefault: '\u8BBE\u4E3A\u9ED8\u8BA4\u4EE3\u7406',\r\n applyDefaultAll: '\u6240\u6709 provider \u4F7F\u7528\u9ED8\u8BA4\u4EE3\u7406',\r\n protocol: '\u7C7B\u578B',\r\n host: 'IP / \u4E3B\u673A',\r\n port: '\u7AEF\u53E3',\r\n username: '\u7528\u6237\u540D',\r\n password: '\u5BC6\u7801',\r\n showPassword: '\u663E\u793A',\r\n hidePassword: '\u9690\u85CF',\r\n confirmPromoteToDefault: '\u5DF2\u6709 provider \u6B63\u5728\u4F7F\u7528\u9ED8\u8BA4\u4EE3\u7406\u3002\u8981\u7528\u8FD9\u5F20\u5361\u7247\u7684\u7AEF\u70B9\u8986\u76D6\u5B83\u5417\uFF1F',\r\n hostHint: '\u4EC5\u9650 IP \u6216\u57DF\u540D\uFF0C\u652F\u6301\u7C98\u8D34\u5B8C\u6574\u4EE3\u7406 URL',\r\n passwordHint: '\u4EC5\u4F5C\u4E3A SOCKS5 \u8BA4\u8BC1\u53E3\u4EE4\u53D1\u9001\u7ED9\u4EE3\u7406\uFF1B\u968F\u8BE5\u8BBE\u7F6E\u4E00\u8D77\u4FDD\u5B58\u3002',\r\n passwordHintProxy: '\u4F5C\u4E3A\u4EE3\u7406\u8BA4\u8BC1\u53E3\u4EE4\u53D1\u9001\u7ED9\u4EE3\u7406\uFF1B\u968F\u8BE5\u8BBE\u7F6E\u4E00\u8D77\u4FDD\u5B58\u3002',\r\n hitCountPrefix: '\u5DF2\u4EE3\u7406 ',\r\n hitCountSuffix: ' \u6B21',\r\n recentOk: '\u6700\u8FD1\u6210\u529F ',\r\n recentFail: '\u6700\u8FD1\u5931\u8D25 ',\r\n recentStarted: '\u6700\u8FD1\u8C03\u7528 ',\r\n noRecord: '\u5C1A\u65E0\u4EE3\u7406\u8BB0\u5F55',\r\n justNow: '\u521A\u521A',\r\n minutesAgo: ' \u5206\u949F\u524D',\r\n hoursAgo: ' \u5C0F\u65F6\u524D',\r\n daysAgo: ' \u5929\u524D',\r\n viewCard: '\u5361\u7247\u89C6\u56FE',\r\n viewCompact: '\u7D27\u51D1\u89C6\u56FE',\r\n expandDetails: '\u7F16\u8F91',\r\n collapseDetails: '\u6536\u8D77',\r\n batchTest: '\u6D4B\u8BD5\u5DF2\u542F\u7528',\r\n batchTesting: '\u6B63\u5728\u6D4B\u8BD5',\r\n testButton: '\u6D4B\u8BD5',\r\n testRunning: '\u6D4B\u8BD5\u4E2D\u2026',\r\n testDisabledNote: '\u672A\u542F\u7528\uFF0C\u4EC5\u6D4B\u8BD5\uFF1A',\r\n testFailed: '\u6D4B\u8BD5\u5931\u8D25',\r\n exitIpLabel: '\u51FA\u53E3 IP ',\r\n directLabel: '\u76F4\u8FDE\uFF08\u672A\u7ECF\u8FC7\u4EE3\u7406\uFF09',\r\n cachedLabel: '\u7F13\u5B58',\r\n testTargetLabel: '\u76EE\u6807 ',\r\n targetSourceRoute: '\uFF08\u672C\u5361\u7247\u81EA\u68C0\u76EE\u6807\uFF09',\r\n targetSourceUpstream: '\uFF08\u8BE5 provider \u7684\u771F\u5B9E\u4E0A\u6E38\uFF09',\r\n targetSourceTestUrl: '\uFF08\u5168\u5C40\u81EA\u68C0\u5730\u5740\uFF09',\r\n globalTitle: '\u5168\u5C40\u8BBE\u7F6E\uFF08\u9AD8\u7EA7\uFF09',\r\n globalLead: '\u8FD9\u91CC\u7684\u4E24\u9879\u5C5E\u4E8E\u63D2\u4EF6\u5168\u5C40\u8BBE\u7F6E\u3002testUrl \u7559\u7A7A\u65F6 Host \u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u503C\uFF1B\u591A\u4E2A\u5019\u9009\u7528\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF0C\u6309\u987A\u5E8F\u56DE\u9000\uFF0C\u53EA\u6709\u524D 5 \u4E2A\u751F\u6548\u3002localDirect \u9ED8\u8BA4\u5F00\u542F\uFF1B\u53EA\u6709\u4EE3\u7406\u672C\u8EAB\u5C31\u662F\u672C\u673A\u6216\u5185\u7F51\u76EE\u6807\u65F6\u624D\u9700\u8981\u5173\u95ED\u3002',\r\n testUrl: '\u81EA\u68C0\u5730\u5740',\r\n testUrlHint: '\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u6309\u987A\u5E8F\u5C1D\u8BD5\u7684 http(s) URL\u3002',\r\n testUrlEmptyHint: '\u7559\u7A7A\u65F6 Host \u4F7F\u7528\u5185\u7F6E\u9ED8\u8BA4\u5730\u5740\u3002',\r\n testUrlInvalidHint: '\u90E8\u5206\u5019\u9009\u4E0D\u662F\u7EDD\u5BF9\u7684 http(s) URL\u3002\u4ECD\u4F1A\u4FDD\u5B58\uFF0C\u4F46\u8FD9\u4E9B\u5019\u9009\u4F1A\u6D4B\u8BD5\u5931\u8D25\u3002',\r\n testUrlTooManyHint: '\u5019\u9009\u8D85\u8FC7 5 \u4E2A\uFF0C\u53EA\u6709\u524D 5 \u4E2A\u751F\u6548\u3002',\r\n restoreDefaultTestUrl: '\u6062\u590D\u9ED8\u8BA4',\r\n localDirect: '\u672C\u673A / \u5185\u7F51\u76EE\u6807\u76F4\u8FDE',\r\n localDirectOnHint: '\u5F00\u542F\uFF1Alocalhost\u3001127.x \u4E0E\u79C1\u6709\u7F51\u6BB5\u7ED5\u8FC7\u4EE3\u7406\u3002',\r\n localDirectOffHint: '\u5173\u95ED\uFF1A\u672C\u673A / \u5185\u7F51\u76EE\u6807\u4E5F\u8D70\u4EE3\u7406\uFF1B\u4EC5\u5728\u4EE3\u7406\u672C\u8EAB\u5C31\u662F\u76EE\u6807\u65F6\u4F7F\u7528\u3002',\r\n advanced: '\u9AD8\u7EA7\uFF1A\u76EE\u6807\u57DF\u540D\u89C4\u5219',\r\n onlyHosts: '\u4EC5\u8D70\u4EE3\u7406',\r\n onlyHostsHint: '\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u975E\u7A7A\u65F6\u53EA\u6709\u5339\u914D\u8FD9\u4E9B\u4E3B\u673A\u7684\u8BF7\u6C42\u8D70\u4EE3\u7406\uFF08\u540E\u7F00\u5339\u914D\uFF0C* \u8868\u793A\u5168\u90E8\uFF09\u3002',\r\n bypassHosts: '\u76F4\u8FDE',\r\n bypassHostsHint: '\u9017\u53F7\u6216\u7A7A\u683C\u5206\u9694\uFF1B\u5339\u914D\u8FD9\u4E9B\u4E3B\u673A\u7684\u8BF7\u6C42\u76F4\u8FDE\uFF0C\u4F18\u5148\u4E8E\u4E0A\u4E00\u9879\u3002',\r\n ruleDeadHint: '\u4EE5\u4E0B\u6761\u76EE\u6C38\u8FDC\u5339\u914D\u4E0D\u4E0A\u2014\u2014\u89C4\u5219\u53EA\u8BA4\u4E3B\u673A\u540D\uFF08\u4E0D\u8981\u5E26\u7AEF\u53E3\u3001\u534F\u8BAE\u524D\u7F00\u6216\u8DEF\u5F84\uFF09\uFF0C\u901A\u914D\u7B26\u53EA\u80FD\u662F\u5355\u72EC\u7684 * \u6216\u4EE5 *. \u5F00\u5934\uFF1A',\r\n testTarget: '\u81EA\u68C0\u76EE\u6807',\r\n testTargetHint: '\u7559\u7A7A\u7528\u9876\u5C42 testUrl\uFF1B\u586B\u5199\u540E\u8BE5\u5361\u7247\u7684\u300C\u6D4B\u8BD5\u300D\u6539\u4E3A\u8BF7\u6C42\u8FD9\u4E2A\u5730\u5740\uFF0C\u53EF\u62FF\u771F\u5B9E\u4E0A\u6E38\u9A8C\u8BC1\u7AEF\u5230\u7AEF\u8DEF\u5F84\u3002',\r\n socks5Hint: 'SOCKS5 \u4F1A\u5EFA\u7ACB\u96A7\u9053\uFF0C\u76EE\u6807\u57DF\u540D\u7531\u4EE3\u7406\u7AEF\u89E3\u6790\u3002',\r\n on: '\u8D70\u4EE3\u7406',\r\n rejected: '\u914D\u7F6E\u88AB\u62D2',\r\n off: '\u76F4\u8FDE',\r\n complete: '\u914D\u7F6E\u5B8C\u6574',\r\n notConfigured: '\u672A\u914D\u7F6E',\r\n diagnostics: '\u8FDE\u63A5\u8BCA\u65AD',\r\n diagPending: '\uFF08\u6B63\u5728\u6536\u96C6\u2026\uFF09',\r\n catalogueMismatch: '\u5DF2\u4FDD\u5B58\u4F46\u672A\u51FA\u73B0\u5728 Host \u76EE\u5F55\u4E2D\u7684 provider\uFF1A',\r\n catalogueMismatchSuffix: '\u3002\u4EE3\u7406\u914D\u7F6E\u4ECD\u4F1A\u4FDD\u7559\u3002',\r\n saveFailedPrefix: '\u4FDD\u5B58\u5931\u8D25\uFF1A',\r\n close: '\u5173\u95ED',\r\n copy: '\u590D\u5236',\r\n copied: '\u5DF2\u590D\u5236',\r\n profileManagerTitle: '\u4EE3\u7406\u9884\u8BBE',\r\n profileManagerLead:\r\n '\u53EF\u88AB\u591A\u4E2A provider \u590D\u7528\u7684\u547D\u540D\u7AEF\u70B9\u3002\u5185\u7F6E\u7684\u300C\u9ED8\u8BA4\u9884\u8BBE\u300D\u5C31\u662F\u4E0A\u65B9\u300C\u9ED8\u8BA4\u4EE3\u7406\u300D\u533A\u5757\uFF0C\u76F4\u63A5\u5728\u90A3\u91CC\u7F16\u8F91\u3002',\r\n profileAdd: '\u6DFB\u52A0\u9884\u8BBE',\r\n profileRename: '\u91CD\u547D\u540D',\r\n profileDelete: '\u5220\u9664',\r\n profileNameLabel: '\u9884\u8BBE\u540D\u79F0',\r\n profileNamePlaceholder: '\u65B0\u9884\u8BBE\u540D\u79F0\uFF0C\u4F8B\u5982 HK-Proxy',\r\n profileNamePrompt: '\u65B0\u4EE3\u7406\u9884\u8BBE\u7684\u540D\u79F0\uFF1A',\r\n profileRenamePrompt: '\u8BE5\u4EE3\u7406\u9884\u8BBE\u7684\u65B0\u540D\u79F0\uFF1A',\r\n profileRenameConfirm: '\u4FDD\u5B58\u540D\u79F0',\r\n cancel: '\u53D6\u6D88',\r\n profileNameTaken: '\u5DF2\u5B58\u5728\u540C\u540D\u9884\u8BBE\u3002',\r\n profileDeleteConfirm: '\u786E\u8BA4\u5220\u9664\u8BE5\u4EE3\u7406\u9884\u8BBE\uFF1F',\r\n profileDeleteInUse: '\u4EE5\u4E0B provider \u7ED1\u5B9A\u5728\u8BE5\u9884\u8BBE\u4E0A\uFF0C\u5220\u9664\u540E\u5C06\u4E0D\u518D\u8D70\u4EE3\u7406\uFF0C\u76F4\u5230\u91CD\u65B0\u7ED1\u5B9A\uFF1A\\n',\r\n profileUsedBy: '\u88AB\u4EE5\u4E0B provider \u4F7F\u7528\uFF1A',\r\n profileBinding: '\u7AEF\u70B9\u6765\u6E90',\r\n profileBindingOwn: '\u72EC\u7ACB\u81EA\u5B9A\u4E49\u914D\u7F6E',\r\n profileBindingPrefix: '\u9884\u8BBE\uFF1A',\r\n inheritingProfile: '\u4F7F\u7528\u9884\u8BBE ',\r\n profileMissing: '\u7ED1\u5B9A\u7684\u9884\u8BBE\u300C',\r\n profileMissingSuffix: '\u300D\u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BE5 provider \u4E0D\u4F1A\u8D70\u4EE3\u7406\u3002',\r\n profileMissingOption: '\uFF08\u5DF2\u7F3A\u5931\uFF09',\r\n profileUnusable: '\u7ED1\u5B9A\u7684\u9884\u8BBE\u300C',\r\n profileUnusableSuffix: '\u300D\u4E0D\u53EF\u7528\uFF0C\u8BE5 provider \u4E0D\u4F1A\u8D70\u4EE3\u7406\uFF1A',\r\n quickImport: '\u5E38\u7528\u5BA2\u6237\u7AEF\u2026',\r\n quickImportEnv: '\u4ECE\u73AF\u5883\u53D8\u91CF\uFF1A',\r\n quickImportEnvNone: '\u4ECE\u73AF\u5883\u53D8\u91CF\uFF08\u672A\u68C0\u6D4B\u5230\uFF09',\r\n quickImportEnvCredentials: '\u8BE5\u73AF\u5883\u53D8\u91CF\u8FD8\u5E26\u4E86\u51ED\u636E\uFF0C\u8BF7\u5728\u4E0B\u65B9\u8865\u586B\u3002',\r\n loadHostTemplate: '\u8F7D\u5165\u5B98\u65B9\u4E0A\u6E38\u57DF\u540D\uFF1A',\r\n backupExport: '\u5907\u4EFD\u914D\u7F6E',\r\n backupImport: '\u6062\u590D\u914D\u7F6E',\r\n backupIncludePasswords: '\u5907\u4EFD\u4E2D\u662F\u5426\u5305\u542B\u4EE3\u7406\u5BC6\u7801\uFF1F\\n\\n\u786E\u5B9A = \u5305\u542B\uFF1B\u53D6\u6D88 = \u6240\u6709\u5BC6\u7801\u5B57\u6BB5\u7559\u7A7A\u3002',\r\n backupWithPasswords: '\u5DF2\u5BFC\u51FA\u5907\u4EFD\uFF08\u5305\u542B\u5BC6\u7801\uFF0C\u8BF7\u59A5\u5584\u4FDD\u7BA1\uFF09',\r\n backupWithoutPasswords: '\u5DF2\u5BFC\u51FA\u5907\u4EFD\uFF08\u672A\u5305\u542B\u5BC6\u7801\uFF09',\r\n backupConfirm: '\u786E\u8BA4\u7528\u8BE5\u5907\u4EFD\u8986\u76D6\u5F53\u524D\u914D\u7F6E\uFF1F\\n\\nprovider\uFF1A',\r\n backupConfirmProviders: '\uFF0C\u9884\u8BBE\uFF1A',\r\n backupConfirmProfiles: ' \u4E2A\u3002',\r\n backupRestored: '\u5DF2\u4ECE\u5907\u4EFD\u6062\u590D\uFF0Cprovider\uFF1A',\r\n backupTitle: '\u5907\u4EFD\u4E0E\u6062\u590D',\r\n backupLead: '\u628A\u6574\u4EFD\u4EE3\u7406\u914D\u7F6E\u5B58\u6210 JSON \u6587\u4EF6\uFF0C\u6216\u4ECE\u6587\u4EF6\u6062\u590D\u3002',\r\n sectionSettings: '\u9875\u9762\u8BBE\u7F6E',\r\n sectionProviders: 'Provider \u5217\u8868',\r\n enableLabel: '\u542F\u7528',\r\n}\r\n\r\n/**\r\n * Pick the dictionary for this render.\r\n *\r\n * The shell's own locale dictionary wins when it carries a translated entry, so\r\n * the page follows the application language instead of second-guessing it.\r\n * Chinese is the fallback because that is the operator's language.\r\n */\r\nfunction stringsFor(ctx: any): Record<string, string> {\r\n const language = localeOf(ctx)\r\n const bundled = language === 'zh' ? ZH : EN\r\n const translated = ((): Record<string, string> | undefined => {\r\n try {\r\n const service = optionalService(ctx, 'locale')\r\n const bound = service?.bind?.('dshProviderProxy')\r\n const value = typeof bound === 'function' ? bound('title') : undefined\r\n if (typeof value === 'string' && value.length > 0) return { title: value } as never\r\n } catch {\r\n // no locale dictionary available\r\n }\r\n return undefined\r\n })()\r\n return { ...bundled, ...(translated ?? {}) }\r\n}\r\n\r\n/**\r\n * The client module system's resolver.\r\n *\r\n * The loader calls `factory(require)` and that parameter shadows Node's\r\n * `require` inside the emitted CJS, so this describes the module-table\r\n * resolver, not Node's.\r\n */\r\ndeclare function require(specifier: string): unknown\r\n", "/**\r\n * Target-host rule parsing shared by the Host matcher and the settings page.\r\n *\r\n * This module deliberately has no undici import: the browser bundle imports it\r\n * too, and the two halves must agree on what an entry means before either can\r\n * safely warn about an entry that will never match.\r\n */\r\n\r\n/** Split a host-rule string into raw, non-empty tokens. */\r\nexport function splitHostRules(raw: string): string[] {\r\n return raw\r\n .split(/[,\\s]+/)\r\n .map(entry => entry.trim())\r\n .filter(entry => entry.length > 0)\r\n}\r\n\r\n/**\r\n * Normalize one raw rule for suffix matching.\r\n *\r\n * A leading `.` or `*.` is dropped: both spellings mean \"this host and its\r\n * subdomains\". Lower-casing belongs here as well, because the Host compares\r\n * against a WHATWG hostname that is already lower-cased.\r\n */\r\nexport function normalizeHostRule(raw: string): string {\r\n return raw.trim().replace(/^\\*?\\./, '').toLowerCase()\r\n}\r\n\r\n/** Split and normalize a host-rule string into matchable entries. */\r\nexport function parseHostList(raw: string): string[] {\r\n return splitHostRules(raw)\r\n .map(normalizeHostRule)\r\n .filter(entry => entry.length > 0)\r\n}\r\n\r\n/**\r\n * Whether a host is covered by one rule list.\r\n *\r\n * `*` matches everything; otherwise a rule matches the host itself or any\r\n * subdomain of it (`example.com` covers `api.example.com`).\r\n */\r\nexport function hostMatches(host: string, rules: readonly string[]): boolean {\r\n for (const rule of rules) {\r\n if (rule === '*') return true\r\n if (host === rule || host.endsWith(`.${rule}`)) return true\r\n }\r\n return false\r\n}\r\n\r\n/** Whether a raw token is a bracketed IPv6 literal, e.g. `[::1]`. */\r\nfunction isBracketedIpv6(token: string): boolean {\r\n return /^\\[[0-9a-f:.]+\\]$/i.test(token)\r\n}\r\n\r\n/** Whether a raw token can never match the Host's hostname comparison. */\r\nexport function hostRuleProblem(raw: string): string | undefined {\r\n const token = raw.trim()\r\n if (token.length === 0) return undefined\r\n // A bare `*.` normalizes to an empty string and disappears from the match\r\n // list entirely; report it rather than silently accepting a no-op.\r\n if (token === '*.' || normalizeHostRule(token).length === 0) return '\u7A7A\u901A\u914D\u7B26'\r\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(token)) return '\u5E26\u534F\u8BAE\u524D\u7F00'\r\n if (token.includes('/')) return '\u5E26\u8DEF\u5F84'\r\n // Host compares hostnames, never `host:port`; a bracketed IPv6 literal is the\r\n // one legitimate colon in a hostname.\r\n if (token.includes(':') && !isBracketedIpv6(token)) return '\u5E26\u7AEF\u53E3\u6216\u975E\u6CD5\u5192\u53F7'\r\n // Host strips only a leading `.`/`*.`; any other `*` cannot be a hostname.\r\n const withoutLeadingWildcard = token.replace(/^\\*\\./, '')\r\n if (withoutLeadingWildcard.includes('*') && token !== '*') return '\u6742\u6563\u901A\u914D\u7B26'\r\n return undefined\r\n}\r\n\r\n/** Every raw token that will never match, in the order it was typed. */\r\nexport function deadRuleEntries(raw: string): string[] {\r\n return splitHostRules(raw).filter(entry => hostRuleProblem(entry) !== undefined)\r\n}\r\n\r\n/**\r\n * The official upstream hosts of well-known providers.\r\n *\r\n * The point is not completeness \u2014 an adapter may point anywhere \u2014 but that the\r\n * ONE spelling a user is likely to need is written down centrally instead of\r\n * being recalled from memory. Every entry is asserted to be a live rule by the\r\n * test suite, so a template can never introduce a dead entry; a dead `onlyHosts`\r\n * entry is silent and makes fail-closed send traffic direct while the user\r\n * believes it is proxied.\r\n *\r\n * The value is the text that goes into `onlyHosts`: bare host names and `*.`\r\n * wildcards only, which is exactly what `hostRuleProblem` accepts.\r\n */\r\nexport const PROVIDER_HOST_TEMPLATES: Readonly<\r\n Record<string, { label: string; hosts: string }>\r\n> = {\r\n openai: { label: 'OpenAI', hosts: 'api.openai.com, *.openai.com' },\r\n anthropic: { label: 'Anthropic', hosts: 'api.anthropic.com' },\r\n google: { label: 'Google', hosts: 'generativelanguage.googleapis.com' },\r\n deepseek: { label: 'DeepSeek', hosts: 'api.deepseek.com' },\r\n}\r\n\r\n/**\r\n * The template for one provider id, or `undefined` when there is none.\r\n *\r\n * Provider ids in the wild carry suffixes (`openai-responses`, `deepseek-chat`)\r\n * and may be namespaced. The id is therefore matched on its FIRST segment when\r\n * split on `-`, `_`, `/`, `:` or `.`, case-insensitively \u2014 that is the part the\r\n * adapters share. An id that merely CONTAINS a known name in a later segment\r\n * (a relay called `my-openai`) is deliberately not matched: a template is a\r\n * guess, and a wrong guess silently narrows where traffic goes.\r\n */\r\nexport function providerHostTemplate(\r\n providerId: string,\r\n): { id: string; label: string; hosts: string } | undefined {\r\n const key = providerId.trim().toLowerCase().split(/[-_/:.]/)[0] ?? ''\r\n const template = PROVIDER_HOST_TEMPLATES[key]\r\n return template === undefined ? undefined : { id: key, ...template }\r\n}\r\n\r\n/**\r\n * Append template hosts to an existing rule string, without duplicating any\r\n * entry the user already wrote.\r\n *\r\n * Appending rather than replacing is deliberate: a card may carry a relay host\r\n * of its own, and silently discarding it would break that route. Comparison is\r\n * on the NORMALIZED entries, so `*.openai.com` and `.openai.com` count as the\r\n * same rule and neither is added twice.\r\n */\r\nexport function appendHostRules(raw: string, hosts: string): string {\r\n const existing = new Set(parseHostList(raw))\r\n // Dedupe on the NORMALIZED rule (so `*.openai.com` and `.openai.com` are the\r\n // same rule) but append the TEMPLATE's own spelling, which is the text the\r\n // pill promised to load.\r\n const additions: string[] = []\r\n for (const token of splitHostRules(hosts)) {\r\n const normalized = normalizeHostRule(token)\r\n if (normalized.length === 0 || existing.has(normalized)) continue\r\n existing.add(normalized)\r\n additions.push(token)\r\n }\r\n if (additions.length === 0) return raw.trim()\r\n const prefix = raw.trim()\r\n return prefix.length === 0 ? additions.join(', ') : `${prefix}, ${additions.join(', ')}`\r\n}\r\n", "/**\n * The proxy-endpoint usability predicate, in ONE place.\n *\n * This lives in its own module \u2014 free of Node and schemastery imports \u2014 so the\n * BROWSER half can import the very same rule the Host applies. It exists because\n * the browser used to keep its own weaker copy that checked only \"host non-empty\n * and port in range\": against `https://1.2.3.4` that copy lit the default block\n * green and enabled the bulk \"use the default\" button, while the Host refused\n * every route that pointed at it (a host carrying a scheme or path is rejected by\n * `normalizeRoute`). One predicate, imported by both halves, cannot disagree\n * with itself.\n */\nexport interface ProxyEndpoint {\n /**\n * Proxy host or IP, without scheme, port, or path.\n *\n * Optional because the browser calls this with whatever the settings document\n * currently holds, which mid-edit is not yet a complete endpoint.\n */\n host?: string\n /** Proxy port. 0 means \"not configured\". */\n port?: number\n /**\n * Credential parts, if the endpoint carries any. A HALF-filled pair is a\n * problem, the same way it is on the route itself \u2014 see below.\n */\n username?: string\n password?: string\n}\n\nconst PROXY_HOST_INVALID = '\u4EE3\u7406\u5730\u5740\u53EA\u80FD\u586B IPv4\u3001IPv6 \u6216\u57DF\u540D'\nconst IPV4 = /^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/\nconst DOMAIN = /^(?=.*[a-z])(?=.{1,253}$)(?!.*\\.\\d+$)[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?(?:\\.[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?)*$/i\nconst IPV6_CHARS = /^[0-9a-f:.]+$/i\n\n/**\n * Accept exactly one of: IPv4, IPv6, or a DNS host name. The field carries the\n * proxy address only; a port, scheme, path, credential, or other URL text belongs\n * in its own field and is rejected here.\n */\nexport function proxyHostProblem(rawHost?: string): string | undefined {\n const host = (rawHost ?? '').trim().replace(/\\.$/, '')\n if (host.length === 0) return '\u672A\u586B\u5199\u4EE3\u7406\u5730\u5740'\n if (IPV4.test(host)) return undefined\n\n // A colon or bracket means the value is claiming to be IPv6. Validate it as\n // an IPv6 literal; never fall back to accepting the text as a host name.\n if (host.includes(':') || host.startsWith('[')) {\n const literal = host.startsWith('[') && host.endsWith(']') ? host.slice(1, -1) : host\n if (!IPV6_CHARS.test(literal)) return PROXY_HOST_INVALID\n try {\n new URL(`http://[${literal}]:1`)\n return undefined\n } catch {\n return PROXY_HOST_INVALID\n }\n }\n\n return DOMAIN.test(host) ? undefined : PROXY_HOST_INVALID\n}\n\n/**\n * Why this endpoint cannot carry a request, or `undefined` when it can.\n *\n * The host and port checks mirror `normalizeRoute` exactly, so the browser's\n * verdict and the Host's are the same verdict. The credential pairing check\n * mirrors the guards in `buildRouteEntry`, which is what makes this predicate a\n * truthful preview of whether a route that opts into the default will actually be\n * built: without it, a default carrying `alice` and no password lit the block\n * green and enabled the bulk button, and every card it pointed at was then\n * refused by the credential guard with `entries.size === 0`.\n *\n * Tolerates a partial object (`{}`, `host: undefined`) rather than throwing: the\n * browser calls this with whatever the settings document currently holds, which\n * during a half-typed edit is not yet a complete endpoint.\n */\nexport function defaultProxyProblem(endpoint: ProxyEndpoint): string | undefined {\n const hostProblem = proxyHostProblem(endpoint.host)\n if (hostProblem !== undefined) return hostProblem\n // `?? 0` rather than a throw: an absent port is \"not configured\", which is the\n // same thing 0 already means everywhere else in this plugin.\n const port = endpoint.port ?? 0\n if (!Number.isInteger(port) || port < 1 || port > 65535) {\n return '\u4EE3\u7406\u7AEF\u53E3\u65E0\u6548\uFF08\u9700\u4E3A 1-65535 \u7684\u6574\u6570\uFF09'\n }\n // \"Both or neither\", exactly as `buildRouteEntry` enforces per transport. The\n // wording stays transport-neutral here because the default block carries a\n // protocol the user may still change; the route-level guards spell out the\n // protocol-specific reason once it is pinned. The Host trims the username\n // before its guards, so this predicate must trim it too; the password is not\n // trimmed by either side.\n const hasUser = (endpoint.username ?? '').trim().length > 0\n const hasPassword = (endpoint.password ?? '').length > 0\n if (hasUser !== hasPassword) {\n return hasUser\n ? '\u914D\u7F6E\u4E86\u4EE3\u7406\u7528\u6237\u540D\u4F46\u6CA1\u6709\u5BC6\u7801\uFF1B\u8BF7\u8865\u5168\u5BC6\u7801\u6216\u6E05\u7A7A\u7528\u6237\u540D'\n : '\u914D\u7F6E\u4E86\u4EE3\u7406\u5BC6\u7801\u4F46\u6CA1\u6709\u7528\u6237\u540D\uFF1B\u8BF7\u8865\u5168\u7528\u6237\u540D\u6216\u6E05\u7A7A\u5BC6\u7801'\n }\n return undefined\n}\n", "/**\r\n * Named proxy presets, shared by the Host and the settings page.\r\n *\r\n * A preset is a named copy of the transport fields that already exist on\r\n * `DefaultProxy`. Keeping the resolution rule HERE \u2014 rather than re-deriving it\r\n * in the table, the self-check key and the browser \u2014 is what keeps \"which\r\n * endpoint does this card actually use\" answerable in exactly one way.\r\n *\r\n * Backward compatibility is the reason the top-level `defaultProxy` is not\r\n * migrated into `proxyProfiles`: a 0.8.0 file has no `proxyProfiles` key at all,\r\n * and its routes keep resolving through `useDefault` untouched. The default\r\n * endpoint is merely DISPLAYED as the built-in preset \"\u9ED8\u8BA4\u9884\u8BBE (Default)\".\r\n */\r\n\r\nimport type { DefaultProxyValue, ProviderProxyRouteValue } from './config.js'\r\n\r\n/** Preset dictionary as it arrives from settings (every value may be partial). */\r\nexport type ProfileMap = Readonly<Record<string, Partial<DefaultProxyValue> | undefined>>\r\n\r\n/** The built-in preset name. Never stored as a key in `proxyProfiles`. */\r\nexport const DEFAULT_PROFILE_LABEL = '\u9ED8\u8BA4\u9884\u8BBE (Default)'\r\n\r\n/**\r\n * The `<select>` value that means \"the built-in default preset\".\r\n *\r\n * A select needs one flat value per option, so the two bindings that are not a\r\n * named preset get fixed sentinels. This one is RESERVED: `profileNameProblem`\r\n * refuses it as a name, so it can never collide with a preset the user creates.\r\n */\r\nexport const DEFAULT_PROFILE_BINDING = '__default__'\r\n\r\n/**\r\n * Which endpoint a route points at.\r\n *\r\n * `own` and `default` are exactly the 0.8.0 states; `profile` is new. `own`\r\n * keeps the route's own transport fields, `default` borrows `defaultProxy`, and\r\n * `profile` borrows one named preset.\r\n */\r\nexport type RouteBinding =\r\n | { kind: 'own' }\r\n | { kind: 'default' }\r\n | { kind: 'profile'; profileId: string }\r\n\r\n/**\r\n * Resolve the binding of one route.\r\n *\r\n * A non-empty `profileId` always wins, even if `useDefault` is still true: the\r\n * page clears `useDefault` when the user picks a preset, but a hand-edited file\r\n * may carry both, and \"the field the user just filled\" is the safer winner.\r\n */\r\nexport function routeBindingOf(\r\n route: Partial<ProviderProxyRouteValue> | undefined,\r\n): RouteBinding {\r\n const profileId = (route?.profileId ?? '').trim()\r\n if (profileId.length > 0) return { kind: 'profile', profileId }\r\n if (route?.useDefault === true) return { kind: 'default' }\r\n return { kind: 'own' }\r\n}\r\n\r\n/** The two route fields that together express one binding, for a settings write. */\r\nexport function bindingFields(binding: RouteBinding): {\r\n profileId: string\r\n useDefault: boolean\r\n} {\r\n switch (binding.kind) {\r\n case 'profile':\r\n return { profileId: binding.profileId, useDefault: false }\r\n case 'default':\r\n return { profileId: '', useDefault: true }\r\n case 'own':\r\n return { profileId: '', useDefault: false }\r\n }\r\n}\r\n\r\n/** One resolved endpoint, or why the route cannot be built with its binding. */\r\nexport type EndpointResolution =\r\n | { ok: true; binding: RouteBinding; endpoint?: Partial<DefaultProxyValue> }\r\n | { ok: false; binding: RouteBinding; problem: string }\r\n\r\n/**\r\n * Resolve the endpoint a route's transport fields come from.\r\n *\r\n * `own` carries no endpoint: the route's own fields are used as-is. A missing\r\n * preset is an ERROR rather than a fallback to the route's own (usually empty)\r\n * fields \u2014 falling back would silently route through nothing while the card\r\n * still claimed to be using a preset.\r\n */\r\nexport function resolveEndpoint(\r\n provider: string,\r\n route: Partial<ProviderProxyRouteValue> | undefined,\r\n defaultProxy: Partial<DefaultProxyValue> | undefined,\r\n profiles: ProfileMap | undefined,\r\n): EndpointResolution {\r\n const binding = routeBindingOf(route)\r\n if (binding.kind === 'own') return { ok: true, binding }\r\n if (binding.kind === 'default') return { ok: true, binding, endpoint: defaultProxy ?? {} }\r\n const preset = profiles?.[binding.profileId]\r\n if (preset === undefined) {\r\n return {\r\n ok: false,\r\n binding,\r\n problem: `dsh-provider-proxy: provider \"${provider}\" \u7ED1\u5B9A\u7684\u9884\u8BBE\u300C${binding.profileId}\u300D\u4E0D\u5B58\u5728\uFF1B\u8BF7\u9009\u62E9\u4E00\u4E2A\u73B0\u6709\u9884\u8BBE\u6216\u6539\u7528\u81EA\u5B9A\u4E49\u914D\u7F6E`,\r\n }\r\n }\r\n return { ok: true, binding, endpoint: preset }\r\n}\r\n\r\n/** Normalize a preset name, or explain why it cannot be used. */\r\nexport function profileNameProblem(raw: string): string | undefined {\r\n const name = raw.trim()\r\n if (name.length === 0) return '\u9884\u8BBE\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A'\r\n if (name.length > 40) return '\u9884\u8BBE\u540D\u79F0\u4E0D\u80FD\u8D85\u8FC7 40 \u4E2A\u5B57\u7B26'\r\n // A control character cannot be typed into a settings key meaningfully and\r\n // would make the dictionary entry impossible to reference from the UI.\r\n if (/[\\u0000-\\u001f\\u007f]/.test(name)) return '\u9884\u8BBE\u540D\u79F0\u4E0D\u80FD\u5305\u542B\u63A7\u5236\u5B57\u7B26'\r\n if (name === DEFAULT_PROFILE_LABEL) return '\u8BE5\u540D\u79F0\u7531\u5185\u7F6E\u9ED8\u8BA4\u9884\u8BBE\u4FDD\u7559\uFF0C\u8BF7\u6362\u4E00\u4E2A\u540D\u79F0'\r\n if (name === DEFAULT_PROFILE_BINDING) return '\u8BE5\u540D\u79F0\u7531\u63D2\u4EF6\u4FDD\u7559\uFF0C\u8BF7\u6362\u4E00\u4E2A\u540D\u79F0'\r\n return undefined\r\n}\r\n\r\n/**\r\n * A route whose TRANSPORT fields have been replaced by one endpoint.\r\n *\r\n * Only transport moves: `onlyHosts`/`bypassHosts`/`testTarget` belong to the\r\n * provider's traffic, not to the proxy, so they stay the route's own.\r\n */\r\nexport function withEndpoint(\r\n route: Partial<ProviderProxyRouteValue>,\r\n endpoint: Partial<DefaultProxyValue>,\r\n): Partial<ProviderProxyRouteValue> {\r\n return {\r\n ...route,\r\n protocol: endpoint.protocol ?? 'http',\r\n host: endpoint.host ?? '',\r\n port: endpoint.port ?? 0,\r\n username: endpoint.username ?? '',\r\n password: endpoint.password ?? '',\r\n }\r\n}\r\n\r\n/**\r\n * The route as it will actually be built, for fingerprinting and diagnostics.\r\n *\r\n * An unresolvable binding (a deleted preset) yields the route unchanged: the\r\n * table records a problem for it, and pretending it had an endpoint would make\r\n * the card look configured.\r\n */\r\nexport function effectiveRoute(\r\n route: Partial<ProviderProxyRouteValue> | undefined,\r\n defaultProxy: Partial<DefaultProxyValue> | undefined,\r\n profiles: ProfileMap | undefined,\r\n): Partial<ProviderProxyRouteValue> {\r\n const base = route ?? {}\r\n const binding = routeBindingOf(base)\r\n if (binding.kind === 'own') return base\r\n const resolved = resolveEndpoint('', base, defaultProxy, profiles)\r\n if (!resolved.ok || resolved.endpoint === undefined) return base\r\n return withEndpoint(base, resolved.endpoint)\r\n}\r\n\r\n/** Every preset name, sorted for stable rendering. */\r\nexport function profileNames(profiles: ProfileMap | undefined): string[] {\r\n return Object.keys(profiles ?? {}).sort((a, b) => a.localeCompare(b))\r\n}\r\n\r\n/** Every route id currently bound to one preset. */\r\nexport function routesBoundTo(\r\n routes: Readonly<Record<string, Partial<ProviderProxyRouteValue> | undefined>> | undefined,\r\n profileId: string,\r\n): string[] {\r\n const out: string[] = []\r\n for (const [id, route] of Object.entries(routes ?? {})) {\r\n if ((route?.profileId ?? '').trim() === profileId) out.push(id)\r\n }\r\n return out.sort()\r\n}\r\n\r\n/** A short, credential-free endpoint summary, e.g. `http://127.0.0.1:7890`. */\r\nexport function endpointSummary(endpoint: Partial<DefaultProxyValue> | undefined): string {\r\n const protocol = endpoint?.protocol ?? 'http'\r\n const host = (endpoint?.host ?? '').trim() || '\u2014'\r\n const port = endpoint?.port ?? 0\r\n return `${protocol}://${host}:${port === 0 ? '\u2014' : port}`\r\n}\r\n\r\n/**\r\n * A very short endpoint summary for a picker option, e.g. `127.0.0.1:7890`.\r\n *\r\n * The protocol is deliberately omitted: every option in the picker comes from\r\n * this plugin and the card shows the full origin underneath once it is chosen.\r\n * What a user needs while CHOOSING is the address, because that is what tells\r\n * the four local clients apart.\r\n */\r\nexport function endpointAddress(endpoint: Partial<DefaultProxyValue> | undefined): string {\r\n const host = (endpoint?.host ?? '').trim()\r\n const port = endpoint?.port ?? 0\r\n if (host.length === 0 || port === 0) return '\u672A\u914D\u7F6E'\r\n return `${host}:${port}`\r\n}\r\n", "/**\r\n * One-click endpoints for proxy clients people actually run locally.\r\n *\r\n * The values are the SHIPPED defaults of each client, not guesses: Clash and\r\n * Mihomo default to 7890, Clash Verge / Meta to 7897, and V2Ray / Xray exports\r\n * 10809 for HTTP and 10808 for SOCKS5. A user who changed the port obviously\r\n * still edits the field afterwards \u2014 the button only saves the typing, it does\r\n * not pretend to know the configuration.\r\n *\r\n * This module has no Node or React imports so the settings page can use the\r\n * exact list its tests assert on.\r\n */\r\n\r\nimport type { Protocol } from './config.js'\r\n\r\nexport interface ProxyClientPreset {\r\n /** Stable id, also used as the `<option>` value. */\r\n id: string\r\n /** Shown in the picker. */\r\n label: string\r\n protocol: Protocol\r\n host: string\r\n port: number\r\n}\r\n\r\nexport const PROXY_CLIENT_PRESETS: readonly ProxyClientPreset[] = [\r\n { id: 'clash', label: 'Clash / Mihomo (127.0.0.1:7890)', protocol: 'http', host: '127.0.0.1', port: 7890 },\r\n { id: 'clash-verge', label: 'Clash Verge / Meta (127.0.0.1:7897)', protocol: 'http', host: '127.0.0.1', port: 7897 },\r\n { id: 'v2ray-http', label: 'V2Ray / Xray HTTP (127.0.0.1:10809)', protocol: 'http', host: '127.0.0.1', port: 10809 },\r\n { id: 'v2ray-socks', label: 'V2Ray / Xray SOCKS5 (127.0.0.1:10808)', protocol: 'socks5', host: '127.0.0.1', port: 10808 },\r\n] as const\r\n\r\n/** One preset by id, or `undefined` for an id this build does not offer. */\r\nexport function proxyClientPreset(id: string): ProxyClientPreset | undefined {\r\n return PROXY_CLIENT_PRESETS.find(preset => preset.id === id)\r\n}\r\n", "/**\r\n * Configuration backup and restore, shared by the settings page and its tests.\r\n *\r\n * The document mirrors the settings schema, so a backup can also be pasted back\r\n * into `cordis.patch.yml` by hand. Export and import are the same set of\r\n * functions on purpose: an export that wrote a shape the import rejects would\r\n * only be discovered by a user who had already lost their configuration.\r\n *\r\n * SECURITY: the password fields are the ONLY values with a redaction switch.\r\n * Everything else is address-like, and the plan's promise \u2014 a password lives\r\n * only in memory and `cordis.patch.yml` \u2014 is preserved because a redacted\r\n * export is the default the page offers.\r\n */\r\n\r\n// Type-only, so nothing is pulled in at run time. This matters: the browser\r\n// bundle imports this module too, and `config.ts` requires `node:module` to\r\n// resolve schemastery, which esbuild refuses to bundle for the browser.\r\nimport type {\r\n DefaultProxyValue,\r\n Protocol,\r\n ProviderProxyRouteValue,\r\n} from './config.js'\r\nimport { proxyHostProblem } from './proxy-address.js'\r\n\r\n/** Mirrors `PROTOCOLS` in config.ts; kept here so the browser never loads it. */\r\nconst PROTOCOLS: readonly Protocol[] = ['http', 'https', 'socks5']\r\n\r\n/**\r\n * Schema defaults for one endpoint.\r\n *\r\n * A local copy rather than `normalizeDefaultProxy` for the bundling reason\r\n * above. The schema and this function are asserted to agree by\r\n * `tests/backup.test.ts`, so a drift shows up as a failing test instead of a\r\n * backup that quietly differs from the settings it describes.\r\n */\r\nfunction normalizeEndpoint(raw: Partial<DefaultProxyValue> | undefined): DefaultProxyValue {\r\n const value = raw ?? {}\r\n return {\r\n protocol: PROTOCOLS.includes(value.protocol as Protocol) ? (value.protocol as Protocol) : 'http',\r\n host: typeof value.host === 'string' ? value.host.trim() : '',\r\n port: typeof value.port === 'number' && Number.isFinite(value.port) ? value.port : 0,\r\n username: typeof value.username === 'string' ? value.username.trim() : '',\r\n password: typeof value.password === 'string' ? value.password : '',\r\n }\r\n}\r\n\r\n/** The document shape a backup carries. `version` identifies it. */\r\nexport interface BackupDocument {\r\n version: 1\r\n exportedAt: string\r\n providers: Record<string, ProviderProxyRouteValue>\r\n proxyProfiles: Record<string, DefaultProxyValue>\r\n defaultProxy: DefaultProxyValue\r\n localDirect: boolean\r\n testUrl: string\r\n}\r\n\r\n/** What the page holds, as far as export is concerned. */\r\nexport interface BackupSource {\r\n providers?: Readonly<Record<string, Partial<ProviderProxyRouteValue> | undefined>>\r\n proxyProfiles?: Readonly<Record<string, Partial<DefaultProxyValue> | undefined>>\r\n defaultProxy?: Partial<DefaultProxyValue>\r\n localDirect?: boolean\r\n testUrl?: string\r\n}\r\n\r\n/** Mirrors the schema default, so an empty export is still self-explanatory. */\r\nconst FALLBACK_TEST_URL = 'https://api.ipify.org?format=json'\r\n\r\n/**\r\n * Schema defaults for one raw route, WITHOUT enforcing endpoint completeness.\r\n *\r\n * A backup of a half-configured card must still round-trip: the Host already\r\n * reports such a route as rejected, and refusing the whole file would strand\r\n * every other setting in it.\r\n */\r\nfunction fillRoute(raw: Partial<ProviderProxyRouteValue> | undefined): ProviderProxyRouteValue {\r\n const value = raw ?? {}\r\n return {\r\n enabled: value.enabled === true,\r\n profileId: typeof value.profileId === 'string' ? value.profileId.trim() : '',\r\n useDefault: value.useDefault === true,\r\n protocol: PROTOCOLS.includes(value.protocol as Protocol)\r\n ? (value.protocol as Protocol)\r\n : 'http',\r\n host: typeof value.host === 'string' ? value.host.trim() : '',\r\n port: typeof value.port === 'number' && Number.isFinite(value.port) ? value.port : 0,\r\n username: typeof value.username === 'string' ? value.username.trim() : '',\r\n password: typeof value.password === 'string' ? value.password : '',\r\n onlyHosts: typeof value.onlyHosts === 'string' ? value.onlyHosts : '',\r\n bypassHosts: typeof value.bypassHosts === 'string' ? value.bypassHosts : '',\r\n testTarget: typeof value.testTarget === 'string' ? value.testTarget : '',\r\n }\r\n}\r\n\r\n/**\r\n * Build the document to write to disk.\r\n *\r\n * Redaction EMPTIES both password fields rather than deleting them: a missing\r\n * field would be re-defaulted to `''` on import anyway, and keeping the key\r\n * makes the redaction visible to anyone who opens the file.\r\n */\r\nexport function buildBackup(\r\n source: BackupSource,\r\n options: { includePasswords: boolean; now?: Date } = { includePasswords: false },\r\n): BackupDocument {\r\n const include = options.includePasswords === true\r\n const hide = (password: string): string => (include ? password : '')\r\n\r\n const providers: Record<string, ProviderProxyRouteValue> = {}\r\n for (const [id, raw] of Object.entries(source.providers ?? {})) {\r\n const filled = fillRoute(raw)\r\n providers[id] = { ...filled, password: hide(filled.password) }\r\n }\r\n\r\n const proxyProfiles: Record<string, DefaultProxyValue> = {}\r\n for (const [name, raw] of Object.entries(source.proxyProfiles ?? {})) {\r\n const filled = normalizeEndpoint(raw)\r\n proxyProfiles[name] = { ...filled, password: hide(filled.password) }\r\n }\r\n\r\n const defaultProxy = normalizeEndpoint(source.defaultProxy)\r\n return {\r\n version: 1,\r\n exportedAt: (options.now ?? new Date()).toISOString(),\r\n providers,\r\n proxyProfiles,\r\n defaultProxy: { ...defaultProxy, password: hide(defaultProxy.password) },\r\n localDirect: source.localDirect !== false,\r\n testUrl:\r\n typeof source.testUrl === 'string' && source.testUrl.trim().length > 0\r\n ? source.testUrl\r\n : FALLBACK_TEST_URL,\r\n }\r\n}\r\n\r\n/** The file name the page offers, e.g. `dsh-proxy-backup-2026-10-27.json`. */\r\nexport function backupFileName(now: Date = new Date()): string {\r\n const pad = (n: number): string => String(n).padStart(2, '0')\r\n return `dsh-proxy-backup-${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}.json`\r\n}\r\n\r\n/** A validated restore, ready to be written. */\r\nexport type BackupParseResult =\r\n | { ok: true; document: BackupDocument }\r\n | { ok: false; error: string }\r\n\r\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value)\r\n}\r\n\r\n/**\r\n * Parse and validate a backup file.\r\n *\r\n * The point is to refuse BEFORE anything is written: an import that half applied\r\n * would leave the user with a configuration assembled from two different files.\r\n * Unknown keys are ignored (a newer export must not break an older page), but a\r\n * KNOWN key carrying the wrong type is an error \u2014 silently coercing it is how a\r\n * broken restore looks successful.\r\n */\r\nexport function parseBackup(text: string): BackupParseResult {\r\n let parsed: unknown\r\n try {\r\n parsed = JSON.parse(text)\r\n } catch (error) {\r\n return {\r\n ok: false,\r\n error: `\u4E0D\u662F\u5408\u6CD5\u7684 JSON\uFF1A${error instanceof Error ? error.message : String(error)}`,\r\n }\r\n }\r\n if (!isPlainObject(parsed)) return { ok: false, error: '\u5907\u4EFD\u6587\u4EF6\u7684\u9876\u5C42\u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61' }\r\n\r\n const root = parsed\r\n if (\r\n root.providers === undefined &&\r\n root.defaultProxy === undefined &&\r\n root.proxyProfiles === undefined\r\n ) {\r\n return {\r\n ok: false,\r\n error: '\u5907\u4EFD\u6587\u4EF6\u7F3A\u5C11 providers / proxyProfiles / defaultProxy\uFF0C\u65E0\u6CD5\u8BC6\u522B\u4E3A\u4EE3\u7406\u914D\u7F6E',\r\n }\r\n }\r\n\r\n if (root.providers !== undefined && !isPlainObject(root.providers)) {\r\n return { ok: false, error: 'providers \u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61' }\r\n }\r\n if (root.proxyProfiles !== undefined && !isPlainObject(root.proxyProfiles)) {\r\n return { ok: false, error: 'proxyProfiles \u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61' }\r\n }\r\n if (root.defaultProxy !== undefined && !isPlainObject(root.defaultProxy)) {\r\n return { ok: false, error: 'defaultProxy \u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61' }\r\n }\r\n if (root.localDirect !== undefined && typeof root.localDirect !== 'boolean') {\r\n return { ok: false, error: 'localDirect \u5FC5\u987B\u662F\u5E03\u5C14\u503C' }\r\n }\r\n if (root.testUrl !== undefined && typeof root.testUrl !== 'string') {\r\n return { ok: false, error: 'testUrl \u5FC5\u987B\u662F\u5B57\u7B26\u4E32' }\r\n }\r\n\r\n /** Field-type check shared by every endpoint-shaped object. */\r\n const endpoint = (value: Record<string, unknown>, label: string): string | undefined => {\r\n if (value.protocol !== undefined && !PROTOCOLS.includes(value.protocol as Protocol)) {\r\n return `${label}.protocol \u5FC5\u987B\u662F ${PROTOCOLS.join(' / ')}`\r\n }\r\n for (const key of ['host', 'username', 'password'] as const) {\r\n if (value[key] !== undefined && typeof value[key] !== 'string') {\r\n return `${label}.${key} \u5FC5\u987B\u662F\u5B57\u7B26\u4E32`\r\n }\r\n }\r\n if (\r\n value.port !== undefined &&\r\n (typeof value.port !== 'number' || !Number.isFinite(value.port))\r\n ) {\r\n return `${label}.port \u5FC5\u987B\u662F\u6570\u5B57`\r\n }\r\n return undefined\r\n }\r\n\r\n const providers: Record<string, ProviderProxyRouteValue> = {}\r\n for (const [id, value] of Object.entries((root.providers ?? {}) as Record<string, unknown>)) {\r\n if (!isPlainObject(value)) return { ok: false, error: `providers.${id} \u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61` }\r\n const why = endpoint(value, `providers.${id}`)\r\n if (why !== undefined) return { ok: false, error: why }\r\n for (const key of ['enabled', 'useDefault'] as const) {\r\n if (value[key] !== undefined && typeof value[key] !== 'boolean') {\r\n return { ok: false, error: `providers.${id}.${key} \u5FC5\u987B\u662F\u5E03\u5C14\u503C` }\r\n }\r\n }\r\n for (const key of ['profileId', 'onlyHosts', 'bypassHosts', 'testTarget'] as const) {\r\n if (value[key] !== undefined && typeof value[key] !== 'string') {\r\n return { ok: false, error: `providers.${id}.${key} \u5FC5\u987B\u662F\u5B57\u7B26\u4E32` }\r\n }\r\n }\r\n providers[id] = fillRoute(value as Partial<ProviderProxyRouteValue>)\r\n }\r\n\r\n const proxyProfiles: Record<string, DefaultProxyValue> = {}\r\n for (const [name, value] of Object.entries(\r\n (root.proxyProfiles ?? {}) as Record<string, unknown>,\r\n )) {\r\n if (!isPlainObject(value)) return { ok: false, error: `proxyProfiles.${name} \u5FC5\u987B\u662F\u4E00\u4E2A\u5BF9\u8C61` }\r\n const why = endpoint(value, `proxyProfiles.${name}`)\r\n if (why !== undefined) return { ok: false, error: why }\r\n proxyProfiles[name] = normalizeEndpoint(value as Partial<DefaultProxyValue>)\r\n }\r\n\r\n if (root.defaultProxy !== undefined) {\r\n const why = endpoint(root.defaultProxy as Record<string, unknown>, 'defaultProxy')\r\n if (why !== undefined) return { ok: false, error: why }\r\n }\r\n\r\n const document: BackupDocument = {\r\n version: 1,\r\n exportedAt: typeof root.exportedAt === 'string' ? root.exportedAt : '',\r\n providers,\r\n proxyProfiles,\r\n defaultProxy: normalizeEndpoint((root.defaultProxy ?? {}) as Partial<DefaultProxyValue>),\r\n localDirect: root.localDirect !== false,\r\n testUrl:\r\n typeof root.testUrl === 'string' && root.testUrl.trim().length > 0\r\n ? root.testUrl\r\n : FALLBACK_TEST_URL,\r\n }\r\n return { ok: true, document }\r\n}\r\n\r\n/**\r\n * The settings writes that apply a document.\r\n *\r\n * Dictionaries are written WHOLE rather than per key: a restore must also\r\n * REMOVE entries the backup does not contain, and one `op: set` per key can only\r\n * add. Keeping every write in ONE array means a revision mismatch fails the\r\n * whole restore instead of leaving it half applied.\r\n */\r\nexport function backupOps(document: BackupDocument): unknown[] {\r\n return [\r\n { op: 'set', path: ['providers'], value: document.providers },\r\n { op: 'set', path: ['proxyProfiles'], value: document.proxyProfiles },\r\n { op: 'set', path: ['defaultProxy'], value: document.defaultProxy },\r\n { op: 'set', path: ['localDirect'], value: document.localDirect },\r\n { op: 'set', path: ['testUrl'], value: document.testUrl },\r\n ]\r\n}\r\n\r\n/** Counts for the confirmation dialog, so the user knows what they are replacing. */\r\nexport function backupCounts(document: BackupDocument): {\r\n providers: number\r\n profiles: number\r\n enabled: number\r\n} {\r\n return {\r\n providers: Object.keys(document.providers).length,\r\n profiles: Object.keys(document.proxyProfiles).length,\r\n enabled: Object.values(document.providers).filter(route => route.enabled).length,\r\n }\r\n}\r\n\r\n/**\r\n * Endpoint validation for routes that are ENABLED and bound to nothing.\r\n *\r\n * Only those routes need complete fields of their own; a route bound to a preset\r\n * or to the default is checked by the Host against that endpoint. Kept separate\r\n * from `parseBackup` so a file with one broken card still restores the rest \u2014\r\n * the Host reports that card as rejected, which is where it already belongs.\r\n */\r\nexport function validateEnabledRoutes(\r\n document: BackupDocument,\r\n): { provider: string; problem: string } | undefined {\r\n for (const [id, route] of Object.entries(document.providers)) {\r\n if (!route.enabled) continue\r\n if (route.profileId.length > 0 || route.useDefault) continue\r\n // The same two checks `normalizeRoute` applies to an enabled route, in the\r\n // same order and with the same wording.\r\n const hostProblem = proxyHostProblem(route.host)\r\n if (hostProblem !== undefined) {\r\n return {\r\n provider: id,\r\n problem:\r\n hostProblem === '\u672A\u586B\u5199\u4EE3\u7406\u5730\u5740'\r\n ? `provider \"${id}\" \u542F\u7528\u4E86\u4EE3\u7406\uFF0C\u4F46\u672A\u586B\u5199\u4EE3\u7406\u5730\u5740`\r\n : `provider \"${id}\" \u7684${hostProblem}`,\r\n }\r\n }\r\n if (!Number.isInteger(route.port) || route.port < 1 || route.port > 65535) {\r\n return { provider: id, problem: `provider \"${id}\" \u7684\u4EE3\u7406\u7AEF\u53E3\u65E0\u6548\uFF08\u9700\u4E3A 1-65535 \u7684\u6574\u6570\uFF09` }\r\n }\r\n }\r\n return undefined\r\n}\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["module", "document", "PROTOCOLS", "field", "styles", "body", "apply", "state", "PROTOCOLS", "document"]
|
|
7
7
|
}
|